Module: Fit4Ruby

Defined in:
lib/fit4ruby/GeoMath.rb,
lib/fit4ruby.rb,
lib/fit4ruby/HRV.rb,
lib/fit4ruby/Lap.rb,
lib/fit4ruby/Log.rb,
lib/fit4ruby/Event.rb,
lib/fit4ruby/FileId.rb,
lib/fit4ruby/Record.rb,
lib/fit4ruby/FitFile.rb,
lib/fit4ruby/Session.rb,
lib/fit4ruby/version.rb,
lib/fit4ruby/Activity.rb,
lib/fit4ruby/Software.rb,
lib/fit4ruby/FitFilter.rb,
lib/fit4ruby/FitHeader.rb,
lib/fit4ruby/FitRecord.rb,
lib/fit4ruby/Converters.rb,
lib/fit4ruby/DeviceInfo.rb,
lib/fit4ruby/Monitoring.rb,
lib/fit4ruby/DataSources.rb,
lib/fit4ruby/FileCreator.rb,
lib/fit4ruby/UserProfile.rb,
lib/fit4ruby/Monitoring_B.rb,
lib/fit4ruby/FileNameCoder.rb,
lib/fit4ruby/FitDataRecord.rb,
lib/fit4ruby/FitDefinition.rb,
lib/fit4ruby/FitFileEntity.rb,
lib/fit4ruby/MonitoringInfo.rb,
lib/fit4ruby/FitRecordHeader.rb,
lib/fit4ruby/PersonalRecords.rb,
lib/fit4ruby/FitMessageRecord.rb,
lib/fit4ruby/GlobalFitMessage.rb,
lib/fit4ruby/RecordAggregator.rb,
lib/fit4ruby/GlobalFitDictList.rb,
lib/fit4ruby/GlobalFitMessages.rb,
lib/fit4ruby/FitDefinitionField.rb,
lib/fit4ruby/FitMessageIdMapper.rb,
lib/fit4ruby/GlobalFitDictionaries.rb

Overview

FitMessageIdMapper.rb – Fit4Ruby - FIT file processing library for Ruby

Copyright © 2014 by Chris Schlaeger <[email protected]>

This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation.

Defined Under Namespace

Modules: Converters, GeoMath, RecordAggregator Classes: Activity, DataSources, DeviceInfo, Error, Event, FileCreator, FileId, FileNameCoder, FitDataRecord, FitDefinition, FitDefinitionField, FitFile, FitFileEntity, FitFilter, FitHeader, FitMessageIdMapper, FitMessageRecord, FitRecord, FitRecordHeader, GlobalFitDict, GlobalFitDictList, GlobalFitMessage, GlobalFitMessageList, HRV, ILogger, Lap, Monitoring, MonitoringInfo, Monitoring_B, PersonalRecords, Record, Session, Software, UserProfile

Constant Summary collapse

Log =
ILogger.instance
VERSION =

The version number of the library.

'0.0.11'
GlobalFitMessages =
GlobalFitMessageList.new do
  message 0, 'file_id'
  field 0, 'enum', 'type', :dict => 'file'
  field 1, 'uint16', 'manufacturer', :dict => 'manufacturer'
  alt_field 2, 'manufacturer' do
    field :default, 'uint16', 'product'
    field 'garmin', 'uint16', 'garmin_product', :dict => 'garmin_product'
  end
  field 3, 'uint32z', 'serial_number'
  field 4, 'uint32', 'time_created', :type => 'date_time'
  field 5, 'uint16', 'number'
  field 6, 'uint16', 'undocumented_field_6'
  field 7, 'uint32', 'undocumented_field_7'

  message 12, 'sport'
  field 0, 'enum', 'sport', :dict => 'sport'
  field 1, 'enum', 'sub_sport', :dict => 'sub_sport'
  field 3, 'string', 'name'
  field 4, 'uint16', 'undocumented_field_4'
  field 5, 'enum', 'undocumented_field_5'
  field 6, 'enum', 'undocumented_field_6'
  field 10, 'uint8', 'undocumented_field_10', :array => true
  field 11, 'enum', 'undocumented_field_11'

  message 18, 'session'
  field 0, 'enum', 'event', :dict => 'event'
  field 1, 'enum', 'event_type', :dict => 'event_type'
  field 2, 'uint32', 'start_time', :type => 'date_time'
  field 3, 'sint32', 'start_position_lat', :type => 'coordinate'
  field 4, 'sint32', 'start_position_long', :type => 'coordinate'
  field 5, 'enum', 'sport', :dict => 'sport'
  field 6, 'enum', 'sub_sport', :dict => 'sub_sport'
  field 7, 'uint32', 'total_elapsed_time', :type => 'duration', :scale => 1000
  field 8, 'uint32', 'total_timer_time', :type => 'duration', :scale => 1000
  field 9, 'uint32', 'total_distance', :scale => 100, :unit => 'm'
  alt_field 10, 'sport' do
    field :default, 'uint32', 'total_cycles', :unit => 'cycles'
    field [ 'running', 'walking' ], 'uint32', 'total_strides', :unit => 'strides'
  end
  field 11, 'uint16', 'total_calories', :unit => 'kcal'
  field 13, 'uint16', 'total_fat_calories', :unit => 'kcal'
  field 14, 'uint16', 'avg_speed', :scale => 1000, :unit => 'm/s'
  field 15, 'uint16', 'max_speed', :scale => 1000, :unit => 'm/s'
  field 16, 'uint8', 'avg_heart_rate', :unit => 'bpm'
  field 17, 'uint8', 'max_heart_rate', :unit => 'bpm'
  alt_field 18, 'sport' do
    field :default, 'uint8', 'avg_candence', :unit => 'rpm'
    field 'running', 'uint8', 'avg_running_cadence', :unit => 'strides/min'
  end
  alt_field 19, 'sport' do
    field :default, 'uint8', 'max_cadence', :unit => 'rpm'
    field 'running', 'uint8', 'max_running_cadence', :unit => 'strides/min'
  end
  field 20, 'uint16', 'avg_power', :unit => 'watts'
  field 21, 'uint16', 'max_power', :unit => 'watts'
  field 22, 'uint16', 'total_ascent', :unit => 'm'
  field 23, 'uint16', 'total_descent', :unit => 'm'
  field 24, 'uint8', 'total_training_effect', :scale => 10
  field 25, 'uint16', 'first_lap_index'
  field 26, 'uint16', 'num_laps'
  field 27, 'uint8', 'event_group'
  field 28, 'enum', 'trigger', :dict => 'session_trigger'
  field 29, 'sint32', 'nec_lat', :type => 'coordinate'
  field 30, 'sint32', 'nec_long', :type => 'coordinate'
  field 31, 'sint32', 'swc_lat', :type => 'coordinate'
  field 32, 'sint32', 'swc_long', :type => 'coordinate'
  field 33, 'uint16', 'undefined_value_33'
  field 34, 'uint16', 'normalized_power', :unit => 'watts'
  field 35, 'uint16', 'training_stress_score', :scale => 10, :unit => 'tss'
  field 36, 'uint16', 'intensity_factor', :scale => 1000, :unit => 'if'
  field 37, 'uint16', 'left_right_balance', :dict => 'left_right_balance_100'
  field 41, 'uint32', 'avg_stroke_count', :scale => 10, :unit => 'strokes/lap'
  field 42, 'uint16', 'avg_stroke_distance', :scale => 100, :unit => 'm'
  field 43, 'enum', 'swim_stroke', :dict => 'swim_stroke'
  field 44, 'uint16', 'pool_length', :scale => 100, :unit => 'm'
  field 45, 'uint16', 'undefined_value_45'
  field 46, 'enum', 'pool_length_unit', :dict => 'display_measure'
  field 47, 'uint16', 'num_active_length', :unit => 'lengths'
  field 48, 'uint32', 'total_work', :unit => 'J'
  field 57, 'sint8', 'avg_temperature', :unit => 'C'
  field 58, 'sint8', 'max_temperature', :unit => 'C'
  field 65, 'uint32', 'time_in_hr_zone', :array => true, :scale => 1000, :unit => 's'
  field 68, 'uint32', 'time_in_power_zone', :array => true, :scale => 1000, :unit => 's'
  field 78, 'uint32', 'undocumented_field_78'
  field 79, 'uint16', 'undocumented_field_79'
  field 80, 'uint16', 'undocumented_field_80'
  field 81, 'enum', 'undocumented_field_81'
  field 89, 'uint16', 'avg_vertical_oscillation', :scale => 10, :unit => 'mm'
  field 90, 'uint16', 'avg_stance_time_percent', :scale => 100, :unit => 'percent'
  field 91, 'uint16', 'avg_stance_time', :scale => 10, :unit => 'ms'
  field 92, 'uint8', 'avg_fractional_cadence', :scale => 128, :unit => 'rpm'
  field 93, 'uint8', 'max_fractional_cadence', :scale => 128, :unit => 'rpm'
  field 94, 'uint8', 'total_fractional_cycles', :scale => 128, :unit => 'cycles'
  field 95, 'uint16', 'avg_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL'
  field 96, 'uint16', 'min_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL'
  field 97, 'uint16', 'max_total_hemoglobin_conc', :array => true, :scale => 100, :unit => 'g/dL'
  field 101, 'uint8', 'avg_left_torque_effectiveness', :scale => 2, :unit => 'percent'
  field 102, 'uint8', 'avg_right_torque_effectiveness', :scale => 2, :unit => 'percent'
  field 103, 'uint8', 'avg_left_pedal_smoothness', :scale => 2, :unit => 'percent'
  field 104, 'uint8', 'avg_right_pedal_smoothness', :scale => 2, :unit => 'percent'
  field 105, 'uint8', 'avg_combined_pedal_smoothness', :scale => 2, :unit => 'percent'
  field 107, 'uint16', 'undefined_value_107'
  field 108, 'uint16', 'undefined_value_108'
  field 109, 'uint8', 'undefined_value_109'
  field 110, 'string', 'undefined_value_110'
  field 112, 'uint32', 'time_standing', :scale => 1000, :unit => 's'
  field 113, 'uint16', 'stand_count'
  field 114, 'sint8', 'avg_left_pco', :unit => 'mm'
  field 115, 'sint8', 'avg_right_pco', :unit => 'mm'
  field 116, 'uint8', 'avg_left_power_phase', :array => true, :unit => 'degrees'
  field 117, 'uint8', 'avg_left_power_phase_peak', :array => true, :unit => 'degrees'
  field 118, 'uint8', 'avg_right_power_phase', :array => true, :unit => 'degrees'
  field 119, 'uint8', 'avg_right_power_phase_peak', :array => true, :unit => 'degrees'
  field 120, 'uint16', 'avg_power_position', :array => true, :unit => 'watts'
  field 121, 'uint16', 'max_power_position', :array => true, :unit => 'watts'
  field 122, 'uint8', 'avg_cadence_position', :array => true, :unit => 'rpm'
  field 123, 'uint8', 'max_cadence_position', :array => true, :unit => 'rpm'
  field 132, 'uint16', 'vertical_ratio', :scale => 100, :unit => '%' # guessed
  field 133, 'uint16', 'avg_gct_balance', :scale => 100, :unit => '%' # guessed
  field 134, 'uint16', 'avg_stride_length', :scale => 10000, :unit => 'm' # guessed
  field 253, 'uint32', 'timestamp', :type => 'date_time'
  field 254, 'uint16', 'message_index'

  message 19, 'lap'
  field 0, 'enum', 'event', :dict => 'event'
  field 1, 'enum', 'event_type', :dict => 'event_type'
  field 2, 'uint32', 'start_time', :type => 'date_time'
  field 3, 'sint32', 'start_position_lat', :type => 'coordinate'
  field 4, 'sint32', 'start_position_long', :type => 'coordinate'
  field 5, 'sint32', 'end_position_lat', :type => 'coordinate'
  field 6, 'sint32', 'end_position_long', :type => 'coordinate'
  field 7, 'uint32', 'total_elapsed_time', :type => 'duration', :scale => 1000
  field 8, 'uint32', 'total_timer_time', :type => 'duration', :scale => 1000
  field 9, 'uint32', 'total_distance', :scale => 100, :unit => 'm'
  field 25, 'enum', 'sport', :dict => 'sport'
  alt_field 10, 'sport' do
    field :default, 'uint32', 'total_cycles', :unit => 'cycles'
    field [ 'running', 'walking' ], 'uint32', 'total_strides', :unit => 'strides'
  end
  field 11, 'uint16', 'total_calories', :unit => 'kcal'
  field 12, 'uint16', 'total_fat_calories', :unit => 'kcal'
  field 13, 'uint16', 'avg_speed', :scale => 1000, :unit => 'm/s'
  field 14, 'uint16', 'max_speed', :scale => 1000, :unit => 'm/s'
  field 15, 'uint8', 'avg_heart_rate', :unit => 'bpm'
  field 16, 'uint8', 'max_heart_rate', :unit => 'bpm'
  alt_field 17, 'sport' do
    field :default, 'uint8', 'avg_candence', :unit => 'rpm'
    field 'running', 'uint8', 'avg_running_cadence', :unit => 'strides/min'
  end
  alt_field 18, 'sport' do
    field :default, 'uint8', 'max_cadence', :unit => 'rpm'
    field 'running', 'uint8', 'max_running_cadence', :unit => 'strides/min'
  end
  field 19, 'uint16', 'avg_power', :unit => 'watts'
  field 20, 'uint16', 'max_power', :unit => 'watts'
  field 21, 'uint16', 'total_ascent', :unit => 'm'
  field 22, 'uint16', 'total_descent', :unit => 'm'
  field 23, 'enum', 'intensity', :dict => 'intensity'
  field 24, 'enum', 'lap_trigger', :dict => 'lap_trigger'
  field 26, 'uint8', 'event_group'
  field 27, 'sint32', 'nec_lat', :type => 'coordinate'
  field 28, 'sint32', 'nec_long', :type => 'coordinate'
  field 29, 'sint32', 'swc_lat', :type => 'coordinate'
  field 30, 'sint32', 'swc_long', :type => 'coordinate'
  field 32, 'uint16', 'num_length', :unit => 'lengths'
  field 33, 'uint16', 'normalized_power', :unit => 'watts'
  field 34, 'uint16', 'left_right_balance', :dict => 'left_right_balance_100'
  field 35, 'uint16', 'first_length_index'
  field 37, 'uint16', 'avg_stroke_distance', :scale => 100, :unit => 'm'
  field 38, 'enum', 'swim_stroke', :dict => 'swim_stroke'
  field 39, 'enum', 'sub_sport', :dict => 'sub_sport'
  field 40, 'uint16', 'num_active_length', :unit => 'lengths'
  field 41, 'uint32', 'total_work', :scale => 'J'
  field 57, 'uint32', 'time_in_hr_zone', :array => true, :scale => 1000, :unit => 's'
  field 60, 'uint32', 'avg_pos_vertical_speed', :scale => 1000, :unit => 'm/s'
  field 70, 'uint32', 'undefined_value_70'
  field 71, 'uint16', 'wkt_step_index'
  field 72, 'enum', 'undocumented_field_72'
  field 73, 'uint16', 'undefined_value_73'
  field 77, 'uint16', 'avg_vertical_oscillation', :scale => 10, :unit => 'mm'
  field 78, 'uint16', 'avg_stance_time_percent', :scale => 100, :unit => 'percent'
  field 79, 'uint16', 'avg_stance_time', :scale => 10, :unit => 'ms'
  field 80, 'uint8', 'avg_fractional_cadence', :scale => 128
  field 81, 'uint8', 'max_fractional_cadence', :scale => 128
  field 82, 'uint8', 'total_fractional_cycles', :scale => 128
  field 90, 'uint16', 'undefined_value_90'
  field 91, 'uint8', 'avg_left_torque_effectiveness', :scale => 2, :unit => 'percent'
  field 92, 'uint8', 'avg_right_torque_effectiveness', :scale => 2, :unit => 'percent'
  field 93, 'uint8', 'avg_left_pedal_smoothness', :scale => 2, :unit => 'percent'
  field 94, 'uint8', 'avg_right_pedal_smoothness', :scale => 2, :unit => 'percent'
  field 95, 'uint8', 'avg_combined_pedal_smoothness', :scale => 2, :unit => 'percent'
  field 96, 'uint16', 'undefined_value_96'
  field 97, 'uint16', 'undefined_value_97'
  field 98, 'uint32', 'time_standing', :scale => 1000, :unit => 's'
  field 99, 'uint16', 'stand_count'
  field 100, 'sint8', 'avg_left_pco', :unit => 'mm'
  field 101, 'sint8', 'avg_right_pco', :unit => 'mm'
  field 102, 'uint8', 'avg_left_power_phase', :array => true, :unit => 'degrees'
  field 103, 'uint8', 'avg_left_power_phase_peak', :array => true, :unit => 'degrees'
  field 104, 'uint8', 'avg_right_power_phase', :array => true, :unit => 'degrees'
  field 105, 'uint8', 'avg_right_power_phase_peak', :array => true, :unit => 'degrees'
  field 106, 'uint16', 'avg_power_position', :array => true, :unit => 'watts'
  field 107, 'uint16', 'max_power_position', :array => true, :unit => 'watts'
  field 108, 'uint8', 'avg_cadence_position', :array => true, :unit => 'rpm'
  field 109, 'uint8', 'max_cadence_position', :array => true, :unit => 'rpm'
  field 118, 'uint16', 'vertical_ratio', :scale => 100, :unit => '%' # guessed
  field 119, 'uint16', 'avg_gct_balance', :scale => 100, :unit => '%' # guessed
  field 120, 'uint16', 'avg_stride_length', :scale => 10000, :unit => 'm' # guessed
  field 253, 'uint32', 'timestamp', :type => 'date_time'
  field 254, 'uint16', 'message_index'

  message 20, 'record'
  field 0, 'sint32', 'position_lat', :type => 'coordinate'
  field 1, 'sint32', 'position_long', :type => 'coordinate'
  field 2, 'uint16', 'altitude', :scale => 5, :offset => 500, :unit => 'm'
  field 3, 'uint8', 'heart_rate', :unit => 'bpm'
  field 4, 'uint8', 'cadence', :unit => 'rpm'
  field 5, 'uint32', 'distance', :scale => 100, :unit => 'm'
  field 6, 'uint16', 'speed', :scale => 1000, :unit => 'm/s'
  field 7, 'uint16', 'power', :unit => 'watts'
  field 11, 'sint32', 'time_from_course', :scale => 1000, :unit => 's'
  field 13, 'sint8', 'temperature', :unit => 'C'
  field 29, 'uint32', 'accumulated_power', :unit => 'watts'
  field 30, 'uint8', 'left_right_balance', :dict => 'left_right_balance'
  field 39, 'uint16', 'vertical_oscillation', :scale => 10, :unit => 'mm'
  field 40, 'uint16', 'stance_time_percent', :scale => 100, :unit => 'percent'
  field 41, 'uint16', 'stance_time', :scale => 10, :unit => 'ms'
  field 42, 'enum', 'activity_type', :dict => 'activity_type'
  field 43, 'uint8', 'left_torque_effectiveness', :scale => 2, :unit => '%'
  field 44, 'uint8', 'right_torque_effectiveness', :scale => 2, :unit => '%'
  field 45, 'uint8', 'left_pedal_smoothness', :scale => 2, :unit => '%'
  field 46, 'uint8', 'right_pedal_smoothness', :scale => 2, :unit => '%'
  field 47, 'uint8', 'combined_pedal_smoothness', :scale => 2, :unit => '%'
  field 53, 'uint8', 'fractional_cadence', :scale => 128
  field 61, 'uint16', 'undefined_value_61'
  field 63, 'uint16', 'undefined_value_63'
  field 64, 'uint16', 'undefined_value_64'
  field 65, 'uint16', 'undefined_value_65'
  field 66, 'sint16', 'undefined_value_66'
  field 67, 'sint8', 'left_pco', :unit => 'mm'
  field 68, 'sint8', 'right_pco', :unit => 'mm'
  field 69, 'uint8', 'left_power_phase', :scale => 0.7111111, :unit => 'degrees', :array => true
  field 70, 'uint8', 'left_power_phase_peak', :scale => 0.7111111, :unit => 'degrees', :array => true
  field 71, 'uint8', 'right_power_phase', :scale => 0.7111111, :unit => 'degrees', :array => true
  field 72, 'uint8', 'right_power_phase_peak', :scale => 0.7111111, :unit => 'degrees', :array => true
  field 83, 'uint16', 'vertical_ratio', :scale => 100, :unit => '%' # guessed
  field 84, 'uint16', 'gct_balance', :scale => 100, :unit => '%' # guessed
  field 85, 'uint16', 'stride_length', :scale => 10000, :unit => 'm' # guessed
  field 87, 'uint16', 'undefined_value_87' # first seen on F3 FW6.80
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  message 21, 'event'
  field 0, 'enum', 'event', :dict => 'event'
  field 1, 'enum', 'event_type', :dict => 'event_type'
  field 2, 'uint16', 'data16'
  alt_field 3, 'event' do
    field :default, 'uint32', 'data'
    field 'timer', 'enum', 'timer_trigger', :dict => 'timer_trigger'
    field 'course_point', 'enum', 'message_index', :dict => 'message_index'
    field 'battery', 'uint16', 'battery_level', :scale => 1000, :unit => 'V'
    field 'hr_high_alert', 'uint8', 'hr_high_alert', :unit => 'bpm'
    field 'hr_low_alert', 'uint8', 'hr_low_alert', :unit => 'bpm'
    field 'speed_high_alert', 'uint16', 'speed_high_alert', :scale => 1000, :unit => 'm/s'
    field 'speed_low_alert', 'uint16', 'speed_low_alert', :scale => 1000, :unit => 'm/s'
    field 'cad_high_alert', 'uint16', 'cad_high_alert', :unit => 'bpm'
    field 'cad_low_alert', 'uint16', 'cad_low_alert', :unit => 'bpm'
    field 'power_high_alert', 'uint16', 'power_high_alert', :unit => 'watts'
    field 'power_low_alert', 'uint16', 'power_low_alert', :unit => 'watts'
    field 'time_duration_alert', 'uint32', 'time_duration_alert', :scale => 100, :unit => 's'
    field 'calorie_duration_alert', 'uint32', 'calorie_duration_alert', :unit  => 'calories'
    field 'fitness_equipment', 'enum', 'fitness_equipment_state', :dict => 'fitness_equipment_state'
    field 'rider_position', 'enum', 'rider_position', :dict => 'rider_position_type'
    field 'comm_timeout', 'uint16', 'comm_timeout', :dict => 'comm_timeout_type'
    field 'recovery_hr', 'uint32', 'recovery_hr', :unit => 'bpm'
    field 'recovery_time', 'uint32', 'recovery_time', :unit => 'min'
    field 'recovery_info', 'uint32', 'recovery_info', :unit => 'min'
    field 'vo2max', 'uint32', 'vo2max'
  end
  field 4, 'uint8', 'event_group'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  # Possibly which device is used as metering source.
  # Not documented in FIT SDK, so the field names are all guesses right now.
  message 22, 'data_sources'
  field 0, 'uint8', 'distance'
  field 1, 'uint8', 'speed'
  field 2, 'uint8', 'cadence'
  field 3, 'uint8', 'elevation'
  field 4, 'uint8', 'heart_rate'
  field 5, 'enum', 'mode' # 0 or 3 seen, unknown meaning
  field 6, 'uint8', 'power' # First found in FR920XT
  field 14, 'uint8', 'calories' # First found in FR920XT
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  message 23, 'device_info'
  field 0, 'uint8', 'device_index'
  field 1, 'uint8', 'device_type', :dict => 'device_type'
  field 2, 'uint16', 'manufacturer', :dict => 'manufacturer'
  field 3, 'uint32z', 'serial_number'
  alt_field 4, 'manufacturer' do
    field :default, 'uint16', 'product'
    field [ 'garmin', 'dynastream', 'dynastream_oem' ], 'uint16', 'garmin_product', :dict => 'garmin_product'
  end
  field 5, 'uint16', 'software_version', :scale => 100
  field 6, 'uint8', 'hardware_version'
  field 7, 'uint32', 'cum_operating_time', :type => 'duration'
  field 8, 'uint32', 'undocumented_field_8'
  field 9, 'uint8', 'undocumented_field_9'
  field 10, 'uint16', 'battery_voltage', :scale => 256, :unit => 'V'
  field 11, 'uint8', 'battery_status', :dict => 'battery_status'
  field 15, 'uint32', 'rx_packets_ok' # just a guess
  field 16, 'uint32', 'rx_packets_err' # just a guess
  field 20, 'uint8z', 'ant_transmission_type'
  field 21, 'uint16z', 'ant_device_number'
  field 22, 'enum', 'ant_network', :dict => 'ant_network'
  field 23, 'uint8', 'undocumented_field_23'
  field 25, 'enum', 'source_type', :dict => 'source_type'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  # Message 29 is just a guess. It's not officially documented.
  # Found in LCTNS.FIT on Fenix 3
  message 29, 'location'
  field 0, 'string', 'name'
  field 1, 'sint32', 'position_lat', :type => 'coordinate'
  field 2, 'sint32', 'position_long', :type => 'coordinate'
  field 3, 'uint16', 'undocumented_field_3'
  field 4, 'uint16', 'altitude', :scale => 5, :offset => 500, :unit => 'm'
  field 5, 'uint16', 'undocumented_field_5'
  field 253, 'uint32', 'undocumented_field_253'
  field 254, 'uint16', 'location_index'

  message 33, 'totals'
  field 0, 'uint32', 'timer_time', :unit => 's'
  field 1, 'uint32', 'distance', :unit => 'm'
  field 2, 'uint32', 'calories', :unit => 'kcal'
  field 3, 'enum', 'sport', :dict => 'sport'
  field 4, 'uint32', 'elapsed_time', :unit => 's'
  field 5, 'uint16', 'sessions'
  field 6, 'uint32', 'active_time', :unit => 's'
  field 253, 'uint32', 'timestamp', :type => 'date_time'
  field 254, 'uint16', 'message_index'

  message 34, 'activity'
  field 0, 'uint32', 'total_timer_time', :type => 'duration',  :scale => 1000
  field 1, 'uint16', 'num_sessions'
  field 2, 'enum', 'type', :dict => 'activity_type'
  field 3, 'enum', 'event', :dict => 'event'
  field 4, 'enum', 'event_type', :dict => 'event_type'
  field 5, 'uint32', 'local_timestamp', :type => 'date_time'
  field 6, 'uint8', 'event_group'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  message 35, 'software'
  field 3, 'uint16', 'version', :scale => 100
  field 5, 'string', 'part_number'

  message 49, 'file_creator'
  field 0, 'uint16', 'software_version'
  field 1, 'uint8', 'hardware_version'
  field 254, 'uint16', 'message_index', :dict => 'message_index'

  message 55, 'monitoring'
  field 0, 'enum', 'device_index'
  field 1, 'uint16', 'calories', :unit => 'kcal'
  field 2, 'uint32', 'distance', :scale => 100, :unit => 'm'
  field 5, 'enum', 'activity_type', :dict => 'activity_type'
  alt_field 3, 'activity_type' do
    field :default, 'uint32', 'cycles', :scale => 2, :unit => 'cycles'
    field [ 'walking', 'running' ], 'uint32', 'steps', :unit => 'steps'
    field [ 'cycling', 'swimming' ], 'uint32', 'strokes', :scale => 2, :unit => 'strokes'
  end
  field 4, 'uint32', 'active_time', :scale => 1000, :unit => 's'
  field 6, 'enum', 'activity_sub_type'
  field 7, 'enum', 'activity_level'
  field 8, 'uint16', 'distance_16', :scale => 0.1, :unit => 'km'
  field 9, 'uint16', 'cycles_16', :scale => 0.5, :unit => 'cycles'
  field 10, 'uint16', 'active_time_16', :unit => 's'
  field 11, 'uint16', 'local_timestamp'
  field 19, 'uint16', 'active_calories', :unit => 'kcal'
  field 24, 'byte', 'current_activity_type_intensity', :type => 'activity_intensity'
  field 26, 'uint16', 'timestamp_16', :unit => 's'
  field 27, 'uint8', 'heart_rate', :unit => 'bpm'
  field 29, 'uint16', 'duration_min', :unit => 'min'
  field 30, 'uint32', 'duration', :unit => 's'
  field 31, 'uint32', 'ascent', :scale => 1000, :unit => 'm'
  field 32, 'uint32', 'descent', :scale => 1000, :unit => 'm'
  field 33, 'uint16', 'moderate_activity_minutes', :unit => 'minutes'
  field 34, 'uint16', 'vigorous_activity_minutes', :unit => 'minutes'
  field 35, 'uint32', 'undocumented_field_35'
  field 36, 'uint32', 'undocumented_field_36'
  field 37, 'uint16', 'weekly_moderate_activity_minutes', :unit => 'minutes' # just a guess
  field 38, 'uint16', 'weekly_vigorous_activity_minutes', :unit => 'minutes' # just a guess
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  message 72, 'training_file'
  field 0, 'enum', 'type'
  field 1, 'uint16', 'manufacturer', :dict => 'manufacturer'
  alt_field 2, 'manufacturer' do
    field :default, 'uint16', 'product'
    field 'garmin', 'uint16', 'garmin_product', :dict => 'garmin_product'
  end
  field 3, 'uint32z', 'serial_number'
  field 4, 'uint32', 'time_created', :type => 'date_time'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  message 78, 'hrv'
  field 0, 'uint16', 'time', :array => true, :scale => 1000, :unit => 's'

  # Not part of the official ANT SDK doc
  message 79, 'user_profile'
  field 0, 'uint16', 'metmax', :scale => 1000, :unit => 'MET' # VO2max / 3.5
  field 1, 'uint8', 'age', :unit => 'years'
  field 2, 'uint8', 'height', :scale => 100, :unit => 'm'
  field 3, 'uint16', 'weight', :scale => 10, :unit => 'kg'
  field 4, 'enum', 'gender', :dict => 'gender'
  field 5, 'enum', 'activity_class', :scale => 10
  field 6, 'uint8', 'max_hr', :unit => 'bpm'
  field 7, 'sint8', 'undocumented_field_7' # seems to be always 1
  field 8, 'uint16', 'recovery_time', :scale => 60, :unit => 'hours'
  field 9, 'uint16', 'undocumented_field_9' # maybe activity measurement
  field 10, 'uint8', 'undocumented_field_10'
  field 11, 'uint16', 'undocumented_field_11'
  field 12, 'uint16', 'undocumented_field_12'
  field 13, 'uint16', 'undocumented_field_13'
  field 14, 'uint8', 'undocumented_field_14'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  message 101, 'length'
  field 0, 'enum', 'event', :dict => 'event'
  field 1, 'enum', 'event_type', :dict => 'event_type'
  field 2, 'uint32', 'date_time', :type => 'date_time'
  field 3, 'uint32', 'total_elapsed_time', :scale => 1000, :unit => 's'
  field 4, 'uint32', 'total_timer_time', :scale => 1000, :unit => 's'
  field 5, 'uint16', 'total_strokes', :unit => 'strokes'
  field 6, 'uint16', 'avg_speed', :scale => 1000, :unit => 'm/s'
  field 7, 'enum', 'swim_stroke', :dict => 'swim_stroke'
  field 9, 'uint8', 'avg_swimming_cadence', :unit => 'strokes/min'
  field 10, 'uint8', 'event_group'
  field 11, 'uint16', 'total_calories', :unit => 'kcal'
  field 12, 'enum', 'length_type', :dict => 'length_type'
  field 18, 'uint16', 'player_score'
  field 19, 'uint16', 'opponent_score'
  field 253, 'uint32', 'timestamp', :type => 'date_time'
  field 254, 'uint16', 'message_index'

  message 103, 'monitoring_info'
  field 0, 'uint32', 'local_time', :type => 'date_time'
  field 1, 'enum', 'activity_type', :array => true, :dict => 'activity_type'
  field 3, 'uint16', 'cycles_to_distance', :array => true, :scale => 5000, :unit => 'm/cycle'
  field 4, 'uint16', 'cycle_to_calories', :array => true, :scale => 5000, :unit => 'kcal/cycle'
  field 5, 'uint16', 'resting_metabolic_rate', :unit => 'kcal/day'
  # Just a guess, not officially documented
  field 7, 'uint32', 'goal_cycles', :array => true
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  # Not part of the official ANT SDK doc
  message 113, 'personal_records'
  field 0, 'uint16', 'longest_distance'
  field 1, 'enum', 'sport', :dict => 'sport'
  field 2, 'uint32', 'distance', :scale => 100, :unit => 'm'
  # If longest_distance is 1, field 3 is the distance, not a duration!
  field 3, 'uint32', 'duration', :scale => 1000, :type => 'duration'
  field 4, 'uint32', 'start_time', :type => 'date_time'
  field 5, 'enum', 'new_record'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  # Not part of the official ANT SDK doc
  # It shows up in swimming activities.
  message 125, 'undocumented_125'
  field 1, 'uint8', 'undocumented_field_1', :array => true
  field 2, 'uint16', 'undocumented_field_2', :array => true
  field 3, 'uint16', 'undocumented_field_3'
  field 4, 'uint8', 'undocumented_field_4'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  # Not part of the official ANT SDK doc
  # The values in this message seem to be related to the activity history.
  # If no HRM is used, most of them are 0. Fields 4, 7, 9 and 10 always have
  # non-zero values.
  message 140, 'undocumented_140'
  field 0, 'uint8', 'max_heart_rate', :unit => 'bpm'
  field 1, 'uint8', 'undocumented_field_1'
  field 2, 'sint32', 'undocumented_field_2'
  field 3, 'sint32', 'undocumented_field_3'
  field 4, 'uint8', 'total_training_effect', :scale => 10
  field 5, 'sint32', 'undocumented_field_5'
  field 6, 'sint32', 'undocumented_field_6'
  field 7, 'sint32', 'undocumented_field_7'
  field 8, 'uint8', 'undocumented_field_8'
  field 9, 'uint16', 'recovery_time', :scale => 60, :unit => 'hours'
  field 10, 'uint16', 'undocumented_field_10' # always seems to be 340
  field 11, 'enum', 'undocumented_field_11'
  field 12, 'enum', 'undocumented_field_12'
  field 13, 'uint8', 'undocumented_field_13'
  field 14, 'uint16', 'undocumented_field_14'
  field 15, 'uint16', 'undocumented_field_15'
  field 16, 'uint16', 'undocumented_field_16'
  field 17, 'sint8', 'undocumented_field_17'
  field 18, 'uint8', 'undocumented_field_18'
  field 19, 'uint8', 'undocumented_field_19'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

  # Not part of the official ANT SDK doc
  message 141, 'gps_ephemeris'
  field 0, 'enum', 'valid' # 0 if no data cached, 1 else
  field 1, 'uint32', 'interval_start', :type => 'date_time'
  field 2, 'uint32', 'interval_end', :type => 'date_time'
  field 3, 'uint32', 'undocumented_field_3'
  field 4, 'sint32', 'undocumented_field_4'
  field 5, 'sint32', 'undocumented_field_5'
  field 253, 'uint32', 'timestamp', :type => 'date_time'

end
GlobalFitDictionaries =
GlobalFitDictList.new do

  dict 'activity_type'
  entry 0, 'generic'
  entry 1, 'running'
  entry 2, 'cycling'
  entry 3, 'transition'
  entry 4, 'fitness_equipment'
  entry 5, 'swimming'
  entry 6, 'walking'
  entry 254, 'all'

  dict 'activity_level'
  entry 0, 'low'
  entry 1, 'medium'
  entry 2, 'high'

  dict 'activity_subtype'
  entry 0, 'generic'
  entry 1, 'treadmill'
  entry 2, 'street'
  entry 3, 'trail'
  entry 4, 'track'
  entry 5, 'spin'
  entry 6, 'indoor_cycling'
  entry 7, 'road'
  entry 8, 'mountain'
  entry 9, 'downhill'
  entry 10, 'recumbent'
  entry 11, 'cyclocross'
  entry 12, 'hand_cycling'
  entry 13, 'track_cycling'
  entry 14, 'indoor_rowing'
  entry 15, 'elliptical'
  entry 16, 'stair_climbing'
  entry 17, 'lap_swimming'
  entry 18, 'open_water'
  entry 254, 'all'

  dict 'ant_network'
  entry 0, 'public'
  entry 1, 'antplus'
  entry 2, 'antfs'
  entry 3, 'private'

  dict 'battery_status'
  entry 1, 'new'
  entry 2, 'good'
  entry 3, 'ok'
  entry 4, 'low'
  entry 5, 'critical'

  dict 'comm_timeout_type'
  entry 0, 'wildcard_paring_timeout'
  entry 1, 'pairing_timeout'
  entry 2, 'connection_lost'
  entry 3, 'connection_timeout'


  dict 'device_type'
  entry 0, 'gps' # Just a guess
  entry 3, 'acceleration' # Just a guess
  entry 4, 'barometric_pressure' # Just a guess
  entry 1, 'antfs'
  entry 11, 'bike_power'
  entry 12, 'environment_sensor_legacy'
  entry 13, 'multi_sport_speed_distance'
  entry 14, 'control'
  entry 17, 'fitness_equipment'
  entry 18, 'blood_pressure'
  entry 19, 'geocache_node'
  entry 20, 'light_electric_vehicle'
  entry 25, 'env_sensor'
  entry 26, 'racquet'
  entry 30, 'running_dynamics' # Just a guess
  entry 119, 'weight_scale'
  entry 120, 'heart_rate'
  entry 121, 'bike_speed_cadence'
  entry 122, 'bike_cadence'
  entry 123, 'bike_speed'
  entry 124, 'stride_speed_distance'

  dict 'display_measure'
  entry 0, 'metric'
  entry 1, 'statute'

  dict 'event'
  entry 0, 'timer'
  entry 3, 'workout'
  entry 4, 'workout_step'
  entry 5, 'power_down'
  entry 6, 'power_up'
  entry 7, 'off_course'
  entry 8, 'session'
  entry 9, 'lap'
  entry 10, 'course_point'
  entry 11, 'battery'
  entry 12, 'virtual_partner_pace'
  entry 13, 'hr_high_alert'
  entry 14, 'hr_low_alert'
  entry 15, 'speed_high_alert'
  entry 16, 'speed_low_alert'
  entry 17, 'cad_high_alert'
  entry 18, 'cad_low_alert'
  entry 19, 'power_high_alert'
  entry 20, 'power_low_alert'
  entry 21, 'recovery_hr'
  entry 22, 'battery_low'
  entry 23, 'time_duration_alert'
  entry 24, 'distance_duration_alert'
  entry 25, 'calorie_duration_alert'
  entry 26, 'activity'
  entry 27, 'fitness_equipment'
  entry 28, 'length'
  entry 32, 'user_marker'
  entry 33, 'sport_point'
  entry 36, 'calibration'
  entry 37, 'vo2max' # guess
  entry 38, 'recovery_time' # guess (in minutes)
  entry 39, 'recovery_info' # guess (in minutes, < 24 good, > 24h poor)
  entry 42, 'front_gear_change'
  entry 43, 'rear_gear_change'
  entry 44, 'rider_position_change'
  entry 45, 'elev_high_alert'
  entry 46, 'elev_low_alert'
  entry 47, 'comm_timeout'

  dict 'event_type'
  entry 0, 'start_time'
  entry 1, 'stop'
  entry 2, 'consecutive_depreciated'
  entry 3, 'marker'
  entry 4, 'stop_all'
  entry 5, 'begin_depreciated'
  entry 6, 'end_depreciated'
  entry 7, 'end_all_depreciated'
  entry 8, 'stop_disable'
  entry 9, 'stop_disable_all'

  dict 'file'
  entry 1, 'device'
  entry 2, 'settings'
  entry 3, 'sport'
  entry 4, 'activity'
  entry 5, 'workout'
  entry 6, 'course_point'
  entry 7, 'schedules'
  entry 9, 'weight_scale'
  entry 10, 'totals'
  entry 11, 'goals'
  entry 14, 'blood_pressure'
  entry 15, 'monitoring_a'
  entry 20, 'activity_summary'
  entry 28, 'monitoring_daily'
  entry 32, 'monitoring_b'

  dict 'fitness_equipment_state'
  entry 0, 'ready'
  entry 1, 'in_use'
  entry 2, 'paused'
  entry 3, 'unknown'

  dict 'garmin_product'
  entry 8, 'hrm_run_single_byte_product_id'
  entry 1551, 'fenix'
  # The Fenix3 is rumored to have a Mediatek MT3333 GPS chipset. Not sure if
  # that would be a beter name.
  entry 1620, 'fenix3_gps' # Just a guess
  entry 1623, 'fr620'
  entry 1632, 'fr220'
  # The FR620 is rumored to have a MediaTek MT3339 GPS chipset while the
  # FR920XT is rumored to have a MT3333. Not sure why they have the same ID
  # in the FIT file for the GPS device.
  entry 1689, 'fr620_fr920xt_gps' # Just a guess
  entry 1752, 'hrm_run'
  entry 1765, 'fr920xt'
  entry 1928, 'fr620_japan'
  entry 1929, 'fr620_china'
  entry 1930, 'fr220_japan'
  entry 1931, 'fr220_china'
  entry 1967, 'fenix2'
  entry 1988, 'epix'
  entry 2050, 'fenix3'
  entry 2072, 'fr620_russia'
  entry 2073, 'fr220_russia'
  entry 2130, 'fr920xt_taiwan'
  entry 2131, 'fr920xt_china'
  entry 2132, 'fr920xt_japan'
  entry 2173, 'fr620_taiwan'
  entry 2188, 'fenix3_china'
  entry 2189, 'fenix3_twn'
  entry 10007, 'sdm4'
  entry 20119, 'training_center'
  entry 65532, 'android_antplus_plugin'
  entry 65534, 'connect'

  dict 'gender'
  entry 0, 'female'
  entry 1, 'male'

  dict 'intensity'
  entry 0, 'active'
  entry 1, 'rest'
  entry 2, 'warmup'
  entry 3, 'cooldown'

  dict 'lap_trigger'
  entry 0, 'manual'
  entry 1, 'time'
  entry 2, 'distance'
  entry 3, 'position_start'
  entry 4, 'position_lap'
  entry 5, 'position_waypoint'
  entry 6, 'position_marked'
  entry 7, 'session_end'
  entry 8, 'fitness_equipment'

  dict 'left_right_balance'
  entry 0x7F, 'mask'
  entry 0x80, 'right'

  dict 'left_right_balance_100'
  entry 0x3FFF, 'mask'
  entry 0x8000, 'right'

  dict 'length_type'
  entry 0, 'idle'
  entry 1, 'active'

  dict 'manufacturer'
  entry 1, 'garmin'
  entry 2, 'garmin_fr405_antfs'
  entry 3, 'zephyr'
  entry 4, 'dayton'
  entry 5, 'idt'
  entry 6, 'srm'
  entry 7, 'quarq'
  entry 8, 'ibike'
  entry 9, 'saris'
  entry 10, 'spark_hk'
  entry 11, 'tanita'
  entry 12, 'echowell'
  entry 13, 'dynastream_oem'
  entry 14, 'nautilus'
  entry 15, 'dynastream'
  entry 16, 'timex'
  entry 17, 'metrigear'
  entry 18, 'xelic'
  entry 19, 'beurer'
  entry 20, 'cardiosport'
  entry 21, 'a_and_d'
  entry 22, 'hmm'
  entry 23, 'suunto'
  entry 24, 'thita_elektronik'
  entry 25, 'gpulse'
  entry 26, 'clean_mobile'
  entry 27, 'pedal_brain'
  entry 28, 'peaksware'
  entry 29, 'saxonar'
  entry 30, 'lemond_fitness'
  entry 31, 'dexcom'
  entry 32, 'wahoo_fitness'
  entry 33, 'octane_fitness'
  entry 34, 'archinoetics'
  entry 35, 'the_hurt_box'
  entry 36, 'citizen_systems'
  entry 37, 'magellan'
  entry 38, 'osynce'
  entry 39, 'holux'
  entry 40, 'concept2'
  entry 42, 'one_giant_leap'
  entry 43, 'ace_sensor'
  entry 44, 'brim_brothers'
  entry 45, 'xplova'
  entry 46, 'perception_digital'
  entry 47, 'bf1systems'
  entry 48, 'pioneer'
  entry 49, 'spantec'
  entry 50, 'metalogics'
  entry 51, '4iiiis'
  entry 52, 'seiko_epson'
  entry 53, 'seiko_epson_oem'
  entry 54, 'ifor_powell'
  entry 55, 'maxwell_guider'
  entry 56, 'star_trac'
  entry 57, 'breakaway'
  entry 58, 'alatech_technology_ltd'
  entry 59, 'mio_technology_europe'
  entry 60, 'rotor'
  entry 61, 'geonaute'
  entry 62, 'id_bike'
  entry 63, 'specialized'
  entry 64, 'wtek'
  entry 65, 'physical_enterprises'
  entry 66, 'north_pole_engineering'
  entry 67, 'bkool'
  entry 68, 'cateye'
  entry 69, 'stages_cycling'
  entry 70, 'sigmasport'
  entry 71, 'tomtom'
  entry 72, 'peripedal'
  entry 73, 'wattbike'
  entry 74, 'moxy'
  entry 77, 'ciclosport'
  entry 78, 'powerbahn'
  entry 79, 'acorn_projects_aps'
  entry 80, 'lifebeam'
  entry 81, 'bontrager'
  entry 82, 'wellgo'
  entry 83, 'scosche'
  entry 84, 'magura'
  entry 85, 'woodway'
  entry 86, 'elite'
  entry 255, 'development'
  entry 5759, 'actigraphcorp'

  dict 'message_index'
  entry 0x0FFF, 'mask'
  entry 0x7000, 'reserved'
  entry 0x8000, 'selected'

  dict 'rider_position_type'
  entry 0, 'seated'
  entry 1, 'standing'

  dict 'session_trigger'
  entry 0, 'activity_end'
  entry 1, 'manual'
  entry 2, 'auto_multi_sport'
  entry 3, 'fitness_equipment'

  dict 'source_type'
  entry 0, 'ant'
  entry 1, 'antplus'
  entry 2, 'bluetooth'
  entry 3, 'bluetooth_low_enegery'
  entry 4, 'wifi'
  entry 5, 'local'

  dict 'sport'
  entry 0, 'generic'
  entry 1, 'running'
  entry 2, 'cycling'
  entry 3, 'transition'
  entry 4, 'fitness_equipment'
  entry 5, 'swimming'
  entry 6, 'basketball'
  entry 7, 'soccer'
  entry 8, 'tennis'
  entry 9, 'american_football'
  entry 10, 'training'
  entry 11, 'walking'
  entry 12, 'cross_country_skiing'
  entry 13, 'alpine_skiing'
  entry 14, 'snowboarding'
  entry 15, 'rowing'
  entry 16, 'mountaineering'
  entry 17, 'hiking'
  entry 18, 'multisport'
  entry 19, 'paddling'
  entry 254, 'all'

  dict 'swim_stroke'
  entry 0, 'freestyle'
  entry 1, 'backstroke'
  entry 2, 'breaststrike'
  entry 3, 'butterfly'
  entry 4, 'drill'
  entry 5, 'mixed'
  entry 6, 'im'

  dict 'sub_sport'
  entry 0, 'generic'
  entry 1, 'treadmill'
  entry 2, 'street'
  entry 3, 'trail'
  entry 4, 'track'
  entry 5, 'spin'
  entry 6, 'indoor_cycling'
  entry 7, 'road'
  entry 8, 'mountain'
  entry 9, 'downhill'
  entry 10, 'recumbent'
  entry 11, 'cyclocross'
  entry 12, 'hand_cycling'
  entry 13, 'track_cycling'
  entry 14, 'indoor_rowing'
  entry 15, 'elliptical'
  entry 16, 'stair_climbing'
  entry 17, 'lap_swimming'
  entry 18, 'open_water'
  entry 19, 'flexibility_training'
  entry 20, 'strength_training'
  entry 21, 'warm_up'
  entry 22, 'match'
  entry 23, 'exercise'
  entry 24, 'challenge'
  entry 25, 'indoor_skiing'
  entry 26, 'cardio_training'
  entry 254, 'all'

end

Class Method Summary collapse

Class Method Details

.read(file, filter = nil) ⇒ Object



17
18
19
# File 'lib/fit4ruby.rb', line 17

def self.read(file, filter = nil)
  FitFile.new.read(file, filter)
end

.write(file, top_level_record) ⇒ Object



21
22
23
# File 'lib/fit4ruby.rb', line 21

def self.write(file, top_level_record)
  FitFile.new.write(file, top_level_record)
end