module FitParser class File module Types def self.types=(value) @types = value end def self.types @types ||= {} end def self.add_type(name, type, option = {}) Types.types[name] = option.merge(basic_type: type) end def self.get_type_definition(name) return Types.types[name] if Types.types.has_key?(name) nil end def self.date_time_value(time, values, parameters) val = values.invert if time < val['min'] time.to_s else res= parameters[:utc] ? Time.utc(1989, 12, 31) + time : Time.local(1989, 12, 31) + time res.to_s end end def self.message_index_value(msg_index, values, parameters = nil) val = values.invert msg_index & val['mask'] end def self.bitfield_value(bitfield, values, parameters = nil) res = '' values.each do |key, val| if key & bitfield != 0 res << '/' unless res.empty? res << val end end res end end end end # basic types FitParser::File::Types.add_type :enum, nil, invalid: 0xFF FitParser::File::Types.add_type :sint8, nil, invalid: 0x7F FitParser::File::Types.add_type :uint8, nil, invalid: 0xFF FitParser::File::Types.add_type :sint16, nil, invalid: 0x7FFF FitParser::File::Types.add_type :uint16, nil, invalid: 0xFFFF FitParser::File::Types.add_type :sint32, nil, invalid: 0x7FFFFFFF FitParser::File::Types.add_type :uint32, nil, invalid: 0xFFFFFFFF FitParser::File::Types.add_type :string, nil, invalid: 0x00 FitParser::File::Types.add_type :float32, nil, invalid: 0xFFFFFFFF FitParser::File::Types.add_type :float64, nil, invalid: 0xFFFFFFFFFFFFFFFF FitParser::File::Types.add_type :uint8z, nil, invalid: 0x00 FitParser::File::Types.add_type :uint16z, nil, invalid: 0x0000 FitParser::File::Types.add_type :uint32z, nil, invalid: 0x00000000 FitParser::File::Types.add_type :byte, nil, invalid: 0xFF FitParser::File::Types.add_type :sint64, nil, invalid: 0x7FFFFFFFFFFFFFFF FitParser::File::Types.add_type :uint64, nil, invalid: 0xFFFFFFFFFFFFFFFF FitParser::File::Types.add_type :uint64z, nil, invalid: 0x0000000000000000 # derived types FitParser::File::Types.add_type :file, :enum, values: { 1 => 'device', 2 => 'settings', 3 => 'sport', 4 => 'activity', 5 => 'workout', 6 => 'course', 7 => 'schedules', 9 => 'weight', 10 => 'totals', 11 => 'goals', 14 => 'blood_pressure', 15 => 'monitoring_a', 20 => 'activity_summary', 28 => 'monitoring_daily', 32 => 'monitoring_b', 34 => 'segment', 35 => 'segment_list', 40 => 'exd_configuration', 247 => 'mfg_range_min', 254 => 'mfg_range_max' } FitParser::File::Types.add_type :mesg_num, :uint16, values: { 0 => 'file_id', 1 => 'capabilities', 2 => 'device_settings', 3 => 'user_profile', 4 => 'hrm_profile', 5 => 'sdm_profile', 6 => 'bike_profile', 7 => 'zones_target', 8 => 'hr_zone', 9 => 'power_zone', 10 => 'met_zone', 12 => 'sport', 15 => 'goal', 18 => 'session', 19 => 'lap', 20 => 'record', 21 => 'event', 23 => 'device_info', 26 => 'workout', 27 => 'workout_step', 28 => 'schedule', 30 => 'weight_scale', 31 => 'course', 32 => 'course_point', 33 => 'totals', 34 => 'activity', 35 => 'software', 37 => 'file_capabilities', 38 => 'mesg_capabilities', 39 => 'field_capabilities', 49 => 'file_creator', 51 => 'blood_pressure', 53 => 'speed_zone', 55 => 'monitoring', 72 => 'training_file', 78 => 'hrv', 101 => 'length', 103 => 'monitoring_info', 105 => 'pad', 106 => 'slave_device', 131 => 'cadence_zone', 145 => 'memo_glob', 148 => 'segment_id', 149 => 'segment_leaderboard_entry', 150 => 'segment_point', 151 => 'segment_file', 159 => 'watchface_settings', 160 => 'gps_metadata', 161 => 'camera_event', 162 => 'timestamp_correlation', 164 => 'gyroscope_data', 165 => 'accelerometer_data', 167 => 'three_d_sensor_calibration', 169 => 'video_frame', 174 => 'obdii_data', 177 => 'nmea_sentence', 178 => 'aviation_attitude', 184 => 'video', 185 => 'video_title', 186 => 'video_description', 187 => 'video_clip', 188 => 'ohr_settings', 200 => 'exd_screen_configuration', 201 => 'exd_data_field_configuration', 202 => 'exd_data_concept_configuration', 206 => 'field_description', 207 => 'developer_data_id', 208 => 'magnetometer_data', 65280 => 'mfg_range_min', 65534 => 'mfg_range_max' } FitParser::File::Types.add_type :checksum, :uint8, values: { 0 => 'clear', 1 => 'ok' } FitParser::File::Types.add_type :file_flags, :uint8z, values: { 0x02 => 'read', 0x04 => 'write', 0x08 => 'erase' }, method: :bitfield_value FitParser::File::Types.add_type :mesg_count, :enum, values: { 0 => 'num_per_file', 1 => 'max_per_file', 2 => 'max_per_file_type' } FitParser::File::Types.add_type :date_time, :uint32, values: { 268435456 => 'min' }, method: :date_time_value, parameters: {utc: true} FitParser::File::Types.add_type :local_date_time, :uint32, values: { 268435456 => 'min' }, method: :date_time_value, parameters: {utc: false} FitParser::File::Types.add_type :message_index, :uint16, values: { 32768 => 'selected', 26872 => 'reserved', 4095 => 'mask' }, method: :message_index_value FitParser::File::Types.add_type :device_index, :uint8, values: { 0 => 'creator' } FitParser::File::Types.add_type :gender, :enum, values: { 0 => 'female', 1 => 'male' } FitParser::File::Types.add_type :language, :enum, values: { 0 => 'english', 1 => 'french', 2 => 'italian', 3 => 'german', 4 => 'spanish', 5 => 'croatian', 6 => 'czech', 7 => 'danish', 8 => 'dutch', 9 => 'finnish', 10 => 'greek', 11 => 'hungarian', 12 => 'norwegian', 13 => 'polish', 14 => 'portuguese', 15 => 'slovakian', 16 => 'slovenian', 17 => 'swedish', 18 => 'russian', 19 => 'turkish', 20 => 'latvian', 21 => 'ukrainian', 22 => 'arabic', 23 => 'farsi', 24 => 'bulgarian', 25 => 'romanian', 26 => 'chinese', 27 => 'japanese', 28 => 'korean', 29 => 'taiwanese', 30 => 'thai', 31 => 'hebrew', 32 => 'brazilian_portuguese', 33 => 'indonesian', 254 => 'custom' } FitParser::File::Types.add_type :language_bits_0, :uint8z, values: { 0x01 => 'english', 0x02 => 'french', 0x04 => 'italian', 0x08 => 'german', 0x10 => 'spanish', 0x20 => 'croatian', 0x40 => 'czech', 0x80 => 'danish' } FitParser::File::Types.add_type :language_bits_1, :uint8z, values: { 0x01 => 'dutch', 0x02 => 'finnish', 0x04 => 'greek', 0x08 => 'hungarian', 0x10 => 'norwegian', 0x20 => 'polish', 0x40 => 'portuguese', 0x80 => 'slovakian' } FitParser::File::Types.add_type :language_bits_2, :uint8z, values: { 0x01 => 'slovenian', 0x02 => 'swedish', 0x04 => 'russian', 0x08 => 'turkish', 0x10 => 'latvian', 0x20 => 'ukrainian', 0x40 => 'arabic', 0x80 => 'farsi' } FitParser::File::Types.add_type :language_bits_3, :uint8z, values: { 0x01 => 'bulgarian', 0x02 => 'romanian', 0x04 => 'chinese', 0x08 => 'japanese', 0x10 => 'korean', 0x20 => 'taiwanese', 0x40 => 'thai', 0x80 => 'hebrew' } FitParser::File::Types.add_type :language_bits_4, :uint8z, values: { 0x01 => 'brazilian_portuguese', 0x02 => 'indonesian' } FitParser::File::Types.add_type :time_zone, :enum, values: { 0 => 'almaty', 1 => 'bangkok', 2 => 'bombay', 3 => 'brasilia', 4 => 'cairo', 5 => 'cape_verde_is', 6 => 'darwin', 7 => 'eniwetok', 8 => 'fiji', 9 => 'hong_kong', 10 => 'islamabad', 11 => 'kabul', 12 => 'magadan', 13 => 'mid_atlantic', 14 => 'moscow', 15 => 'muscat', 16 => 'newfoundland', 17 => 'samoa', 18 => 'sydney', 19 => 'tehran', 20 => 'tokyo', 21 => 'us_alaska', 22 => 'us_atlantic', 23 => 'us_central', 24 => 'us_eastern', 25 => 'us_hawaii', 26 => 'us_mountain', 27 => 'us_pacific', 28 => 'other', 29 => 'auckland', 30 => 'kathmandu', 31 => 'europe_western_wet', 32 => 'europe_central_cet', 33 => 'europe_eastern_eet', 34 => 'jakarta', 35 => 'perth', 36 => 'adelaide', 37 => 'brisbane', 38 => 'tasmania', 39 => 'iceland', 40 => 'amsterdam', 41 => 'athens', 42 => 'barcelona', 43 => 'berlin', 44 => 'brussels', 45 => 'budapest', 46 => 'copenhagen', 47 => 'dublin', 48 => 'helsinki', 49 => 'lisbon', 50 => 'london', 51 => 'madrid', 52 => 'munich', 53 => 'oslo', 54 => 'paris', 55 => 'prague', 56 => 'reykjavik', 57 => 'rome', 58 => 'stockholm', 59 => 'vienna', 60 => 'warsaw', 61 => 'zurich', 62 => 'quebec', 63 => 'ontario', 64 => 'manitoba', 65 => 'saskatchewan', 66 => 'alberta', 67 => 'british_columbia', 68 => 'boise', 69 => 'boston', 70 => 'chicago', 71 => 'dallas', 72 => 'denver', 73 => 'kansas_city', 74 => 'las_vegas', 75 => 'los_angeles', 76 => 'miami', 77 => 'minneapolis', 78 => 'new_york', 79 => 'new_orleans', 80 => 'phoenix', 81 => 'santa_fe', 82 => 'seattle', 83 => 'washington_dc', 84 => 'us_arizona', 85 => 'chita', 86 => 'ekaterinburg', 87 => 'irkutsk', 88 => 'kaliningrad', 89 => 'krasnoyarsk', 90 => 'novosibirsk', 91 => 'petropavlovsk_kamchatskiy', 92 => 'samara', 93 => 'vladivostok', 94 => 'mexico_central', 95 => 'mexico_mountain', 96 => 'mexico_pacific', 97 => 'cape_town', 98 => 'winkhoek', 99 => 'lagos', 100 => 'riyahd', 101 => 'venezuela', 102 => 'australia_lh', 103 => 'santiago', 253 => 'manual', 254 => 'automatic' } FitParser::File::Types.add_type :display_measure, :enum, values: { 0 => 'metric', 1 => 'statute' } FitParser::File::Types.add_type :display_heart, :enum, values: { 0 => 'bpm', 1 => 'max', 2 => 'reserve' } FitParser::File::Types.add_type :display_power, :enum, values: { 0 => 'watts', 1 => 'percent_ftp' } FitParser::File::Types.add_type :display_position, :enum, values: { 0 => 'degree', 1 => 'degree_minute', 2 => 'degree_minute_second', 3 => 'austrian_grid', 4 => 'british_grid', 5 => 'dutch_grid', 6 => 'hungarian_grid', 7 => 'finnish_grid', 8 => 'german_grid', 9 => 'icelandic_grid', 10 => 'indonesian_equatorial', 11 => 'indonesian_irian', 12 => 'indonesian_southern', 13 => 'india_zone_0', 14 => 'india_zone_IA', 15 => 'india_zone_IB', 16 => 'india_zone_IIA', 17 => 'india_zone_IIB', 18 => 'india_zone_IIIA', 19 => 'india_zone_IIIB', 20 => 'india_zone_IVA', 21 => 'india_zone_IVB', 22 => 'irish_transverse', 23 => 'irish_grid', 24 => 'loran', 25 => 'maidenhead_grid', 26 => 'mgrs_grid', 27 => 'new_zealand_grid', 28 => 'new_zealand_transverse', 29 => 'qatar_grid', 30 => 'modified_swedish_grid', 31 => 'swedish_grid', 32 => 'south_african_grid', 33 => 'swiss_grid', 34 => 'taiwan_grid', 35 => 'united_states_grid', 36 => 'utm_ups_grid', 37 => 'west_malayan', 38 => 'borneo_rso', 39 => 'estonian_grid', 40 => 'latvian_grid', 41 => 'swedish_ref_99_grid' } FitParser::File::Types.add_type :switch, :enum, values: { 0 => 'off', 1 => 'on', 2 => 'auto' } FitParser::File::Types.add_type :sport, :enum, values: { 0 => 'generic', 1 => 'running', 2 => 'cycling', 3 => 'transition', 4 => 'fitness_equipment', 5 => 'swimming', 6 => 'basketball', 7 => 'soccer', 8 => 'tennis', 9 => 'american_football', 10 => 'training', 11 => 'walking', 12 => 'cross_country_skiing', 13 => 'alpine_skiing', 14 => 'snowboarding', 15 => 'rowing', 16 => 'mountaineering', 17 => 'hiking', 18 => 'multisport', 19 => 'paddling', 20 => 'flying', 21 => 'e_biking', 22 => 'motorcycling', 23 => 'boating', 24 => 'driving', 25 => 'golf', 26 => 'hang_gliding', 27 => 'horseback_riding', 28 => 'hunting', 29 => 'fishing', 30 => 'inline_skating', 31 => 'rock_climbing', 32 => 'sailing', 33 => 'ice_skating', 34 => 'sky_diving', 35 => 'snowshoeing', 36 => 'snowmobiling', 37 => 'stand_up_paddleboarding', 38 => 'surfing', 39 => 'wakeboarding', 40 => 'water_skiing', 41 => 'kayaking', 42 => 'rafting', 43 => 'windsurfing', 44 => 'kitesurfing', 45 => 'tactical', 46 => 'jumpmaster', 47 => 'boxing', 48 => 'floor_climbing', 254 => 'all' } FitParser::File::Types.add_type :sport_bits_0, :uint8z, values: { 1 => 'generic', 2 => 'running', 4 => 'cycling', 8 => 'transition', 16 => 'fitness_equipment', 32 => 'swimming', 64 => 'basketball', 128 => 'soccer' } FitParser::File::Types.add_type :sport_bits_1, :uint8z, values: { 1 => 'tennis', 2 => 'american_football', 4 => 'training', 8 => 'walking', 16 => 'cross_country_skiing', 32 => 'alpine_skiing', 64 => 'snowboarding', 128 => 'rowing' } FitParser::File::Types.add_type :sport_bits_2, :uint8z, values: { 1 => 'mountaineering', 2 => 'hiking', 4 => 'multisport', 8 => 'paddling', 16 => 'flying', 32 => 'e_biking', 64 => 'motorcycling', 128 => 'boating' } FitParser::File::Types.add_type :sport_bits_3, :uint8z, values: { 1 => 'driving', 2 => 'golf', 4 => 'hang_gliding', 8 => 'horseback_riding', 16 => 'hunting', 32 => 'fishing', 64 => 'inline_skating', 128 => 'rock_climbing' } FitParser::File::Types.add_type :sport_bits_4, :uint8z, values: { 1 => 'sailing', 2 => 'ice_skating', 4 => 'sky_diving', 8 => 'snowshoeing', 16 => 'snowmobiling', 32 => 'stand_up_paddleboarding', 64 => 'surfing', 128 => 'wakeboarding' } FitParser::File::Types.add_type :sport_bits_5, :uint8z, values: { 1 => 'water_skiing', 2 => 'kayaking', 4 => 'rafting', 8 => 'windsurfing', 16 => 'kitesurfing', 32 => 'tactical', 64 => 'jumpmaster', 128 => 'boxing' } FitParser::File::Types.add_type :sport_bits_6, :uint8z, values: { 1 => 'floor_climbing' } FitParser::File::Types.add_type :sub_sport, :enum, values: { 0 => 'generic', 1 => 'treadmill', 2 => 'street', 3 => 'trail', 4 => 'track', 5 => 'spin', 6 => 'indoor_cycling', 7 => 'road', 8 => 'mountain', 9 => 'downhill', 10 => 'recumbent', 11 => 'cyclocross', 12 => 'hand_cycling', 13 => 'track_cycling', 14 => 'indoor_rowing', 15 => 'elliptical', 16 => 'stair_climbing', 17 => 'lap_swimming', 18 => 'open_water', 19 => 'flexibility_training', 20 => 'strength_training', 21 => 'warm_up', 22 => 'match', 23 => 'exercise', 24 => 'challenge', 25 => 'indoor_skiing', 26 => 'cardio_training', 27 => 'indoor_walking', 28 => 'e_bike_fitness', 29 => 'bmx', 30 => 'casual_walking', 31 => 'speed_walking', 32 => 'bike_to_run_transition', 33 => 'run_to_bike_transition', 34 => 'swim_to_bike_transition', 35 => 'atv', 36 => 'motocross', 37 => 'backcountry', 38 => 'resort', 39 => 'rc_drone', 40 => 'wingsuit', 41 => 'whitewater', 42 => 'skate_skiing', 43 => 'yoga', 44 => 'pilates', 45 => 'indoor_running', 46 => 'gravel_cycling', 47 => 'e_bike_mountain', 48 => 'commuting', 49 => 'mixed_surface', 50 => 'navigate', 51 => 'track_me', 254 => 'all' } FitParser::File::Types.add_type :sport_event, :enum, values: { 0 => 'uncategorized', 1 => 'geocaching', 2 => 'fitness', 3 => 'recreation', 4 => 'race', 5 => 'special_event', 6 => 'training', 7 => 'transportation', 8 => 'touring' } FitParser::File::Types.add_type :activity, :enum, values: { 0 => 'manual', 1 => 'auto_multi_sport' } FitParser::File::Types.add_type :intensity, :enum, values: { 0 => 'active', 1 => 'rest', 2 => 'warmup', 3 => 'cooldown' } FitParser::File::Types.add_type :session_trigger, :enum, values: { 0 => 'activity_end', 1 => 'manual', 2 => 'auto_multi_sport', 3 => 'fitness_equipment' } FitParser::File::Types.add_type :autolap_trigger, :enum, values: { 0 => 'time', 1 => 'distance', 2 => 'position_start', 3 => 'position_lap', 4 => 'position_waypoint', 5 => 'position_marked', 6 => 'off' } FitParser::File::Types.add_type :lap_trigger, :enum, values: { 0 => 'manual', 1 => 'time', 2 => 'distance', 3 => 'position_start', 4 => 'position_lap', 5 => 'position_waypoint', 6 => 'position_marked', 7 => 'session_end', 8 => 'fitness_equipment' } FitParser::File::Types.add_type :time_mode, :enum, values: { 0 => 'hour12', 1 => 'hour24', 2 => 'military', 3 => 'hour_12_with_seconds', 4 => 'hour_24_with_seconds', 5 => 'utc' } FitParser::File::Types.add_type :backlight_mode, :enum, values: { 0 => 'off', 1 => 'manual', 2 => 'key_and_messages', 3 => 'auto_brightness', 4 => 'smart_notifications', 5 => 'key_and_messages_night', 6 => 'key_and_messages_and_smart_notifications' } FitParser::File::Types.add_type :date_mode, :enum, values: { 0 => 'day_month', 1 => 'month_day' } FitParser::File::Types.add_type :event, :enum, values: { 0 => 'timer', 3 => 'workout', 4 => 'workout_step', 5 => 'power_down', 6 => 'power_up', 7 => 'off_course', 8 => 'session', 9 => 'lap', 10 => 'course_point', 11 => 'battery', 12 => 'virtual_partner_pace', 13 => 'hr_high_alert', 14 => 'hr_low_alert', 15 => 'speed_high_alert', 16 => 'speed_low_alert', 17 => 'cad_high_alert', 18 => 'cad_low_alert', 19 => 'power_high_alert', 20 => 'power_low_alert', 21 => 'recovery_hr', 22 => 'battery_low', 23 => 'time_duration_alert', 24 => 'distance_duration_alert', 25 => 'calorie_duration_alert', 26 => 'activity', 27 => 'fitness_equipment', 28 => 'length', 32 => 'user_marker', 33 => 'sport_point', 36 => 'calibration', 42 => 'front_gear_change', 43 => 'rear_gear_change', 45 => 'elev_high_alert', 46 => 'elev_low_alert', 47 => 'comm_timeout' } FitParser::File::Types.add_type :event_type, :enum, values: { 0 => 'start', 1 => 'stop', 2 => 'consecutive_depreciated', 3 => 'marker', 4 => 'stop_all', 5 => 'begin_depreciated', 6 => 'end_depreciated', 7 => 'end_all_depreciated', 8 => 'stop_disable', 9 => 'stop_disable_all' } FitParser::File::Types.add_type :timer_trigger, :enum, values: { 0 => 'manual', 1 => 'auto', 2 => 'fitness_equipment' } FitParser::File::Types.add_type :fitness_equipment_state, :enum, values: { 0 => 'ready', 1 => 'in_use', 2 => 'paused', 3 => 'unknown' } FitParser::File::Types.add_type :autoscroll, :enum, values: { 0 => 'none', 1 => 'slow', 2 => 'medium', 3 => 'fast' } FitParser::File::Types.add_type :activity_class, :enum, values: { 127 => 'level', 100 => 'level_max', 128 => 'athlete' } FitParser::File::Types.add_type :hr_zone_calc, :enum, values: { 0 => 'custom', 1 => 'percent_max_hr', 2 => 'percent_hrr' } FitParser::File::Types.add_type :pwr_zone_calc, :enum, values: { 0 => 'custom', 1 => 'percent_ftp' } FitParser::File::Types.add_type :wkt_step_duration, :enum, values: { 0 => 'time', 1 => 'distance', 2 => 'hr_less_than', 3 => 'hr_greater_than', 4 => 'calories', 5 => 'open', 6 => 'repeat_until_steps_cmplt', 7 => 'repeat_until_time', 8 => 'repeat_until_distance', 9 => 'repeat_until_calories', 10 => 'repeat_until_hr_less_than', 11 => 'repeat_until_hr_greater_than', 12 => 'repeat_until_power_less_than', 13 => 'repeat_until_power_greater_than', 14 => 'power_less_than', 15 => 'power_greater_than', 28 => 'repetition_time' } FitParser::File::Types.add_type :wkt_step_target, :enum, values: { 0 => 'speed', 1 => 'heart_rate', 2 => 'open', 3 => 'cadence', 4 => 'power', 5 => 'grade', 6 => 'resistance' } FitParser::File::Types.add_type :goal, :enum, values: { 0 => 'time', 1 => 'distance', 2 => 'calories', 3 => 'frequency', 4 => 'steps', 5 => 'ascent', 6 => 'active_minutes' } FitParser::File::Types.add_type :goal_recurrence, :enum, values: { 0 => 'off', 1 => 'daily', 2 => 'weekly', 3 => 'monthly', 4 => 'yearly', 5 => 'custom' } FitParser::File::Types.add_type :goal_source, :enum, values: { 0 => 'auto', 1 => 'community', 2 => 'user' } FitParser::File::Types.add_type :schedule, :enum, values: { 0 => 'workout', 1 => 'course' } FitParser::File::Types.add_type :course_point, :enum, values: { 0 => 'generic', 1 => 'summit', 2 => 'valley', 3 => 'water', 4 => 'food', 5 => 'danger', 6 => 'left', 7 => 'right', 8 => 'straight', 9 => 'first_aid', 10 => 'fourth_category', 11 => 'third_category', 12 => 'second_category', 13 => 'first_category', 14 => 'hors_category', 15 => 'sprint', 16 => 'left_fork', 17 => 'right_fork', 18 => 'middle_fork', 19 => 'slight_left', 20 => 'sharp_left', 21 => 'slight_right', 22 => 'sharp_right', 23 => 'u_turn', 24 => 'segment_start', 25 => 'segment_end' } FitParser::File::Types.add_type :manufacturer, :uint16, values: { 1 => 'garmin', 2 => 'garmin_fr405_antfs', 3 => 'zephyr', 4 => 'dayton', 5 => 'idt', 6 => 'srm', 7 => 'quarq', 8 => 'ibike', 9 => 'saris', 10 => 'spark_hk', 11 => 'tanita', 12 => 'echowell', 13 => 'dynastream_oem', 14 => 'nautilus', 15 => 'dynastream', 16 => 'timex', 17 => 'metrigear', 18 => 'xelic', 19 => 'beurer', 20 => 'cardiosport', 21 => 'a_and_d', 22 => 'hmm', 23 => 'suunto', 24 => 'thita_elektronik', 25 => 'gpulse', 26 => 'clean_mobile', 27 => 'pedal_brain', 28 => 'peaksware', 29 => 'saxonar', 30 => 'lemond_fitness', 31 => 'dexcom', 32 => 'wahoo_fitness', 33 => 'octane_fitness', 34 => 'archinoetics', 35 => 'the_hurt_box', 36 => 'citizen_systems', 37 => 'magellan', 38 => 'osynce', 39 => 'holux', 40 => 'concept2', 42 => 'one_giant_leap', 43 => 'ace_sensor', 44 => 'brim_brothers', 45 => 'xplova', 46 => 'perception_digital', 47 => 'bf1systems', 48 => 'pioneer', 49 => 'spantec', 50 => 'metalogics', 51 => '4iiiis', 52 => 'seiko_epson', 53 => 'seiko_epson_oem', 54 => 'ifor_powell', 55 => 'maxwell_guider', 56 => 'star_trac', 57 => 'breakaway', 58 => 'alatech_technology_ltd', 59 => 'mio_technology_europe', 60 => 'rotor', 61 => 'geonaute', 62 => 'id_bike', 63 => 'specialized', 64 => 'wtek', 65 => 'physical_enterprises', 66 => 'north_pole_engineering', 67 => 'bkool', 68 => 'cateye', 69 => 'stages_cycling', 70 => 'sigmasport', 71 => 'tomtom', 72 => 'peripedal', 73 => 'wattbike', 76 => 'moxy', 77 => 'ciclosport', 78 => 'powerbahn', 79 => 'acorn_projects_aps', 80 => 'lifebeam', 81 => 'bontrager', 82 => 'wellgo', 83 => 'scosche', 84 => 'magura', 85 => 'woodway', 86 => 'elite', 87 => 'nielsen_kellerman', 88 => 'dk_city', 89 => 'tacx', 90 => 'direction_technology', 91 => 'magtonic', 92 => '1partcarbon', 93 => 'inside_ride_technologies', 94 => 'sound_of_motion', 95 => 'stryd', 96 => 'icg', 97 => 'MiPulse', 98 => 'bsx_athletics', 99 => 'look', 100 => 'campagnolo_srl', 101 => 'body_bike_smart', 102 => 'praxisworks', 103 => 'limits_technology', 104 => 'topaction_technology', 105 => 'cosinuss', 106 => 'fitcare', 255 => 'development', 257 => 'healthandlife', 258 => 'lezyne', 259 => 'scribe_labs', 260 => 'zwift', 261 => 'watteam', 262 => 'recon', 263 => 'favero_electronics', 264 => 'dynovelo', 265 => 'strava', 266 => 'precor', 267 => 'bryton', 268 => 'sram', 269 => 'navman', 270 => 'cobi', 271 => 'spivi', 272 => 'mio_magellan', 273 => 'evesports', 274 => 'sensitivus_gauge', 5759 => 'actigraphcorp' } FitParser::File::Types.add_type :garmin_product, :uint16, values: { 1 => 'hrm1', 2 => 'axh01', 3 => 'axb01', 4 => 'axb02', 5 => 'hrm2ss', 6 => 'dsi_alf02', 7 => 'hrm3ss', 8 => 'hrm_run_single_byte_product_id', 9 => 'bsm', 10 => 'bcm', 11 => 'axs01', 12 => 'hrm_tri_single_byte_product_id', 14 => 'fr225_single_byte_product_id', 473 => 'fr301_china', 474 => 'fr301_japan', 475 => 'fr301_korea', 494 => 'fr301_taiwan', 717 => 'fr405', 782 => 'fr50', 987 => 'fr405_japan', 988 => 'fr60', 1011 => 'dsi_alf01', 1018 => 'fr310xt', 1036 => 'edge500', 1124 => 'fr110', 1169 => 'edge800', 1199 => 'edge500_taiwan', 1213 => 'edge500_japan', 1253 => 'chirp', 1274 => 'fr110_japan', 1325 => 'edge200', 1328 => 'fr910xt', 1333 => 'edge800_taiwan', 1334 => 'edge800_japan', 1341 => 'alf04', 1345 => 'fr610', 1360 => 'fr210_japan', 1380 => 'vector_ss', 1381 => 'vector_cp', 1386 => 'edge800_china', 1387 => 'edge500_china', 1410 => 'fr610_japan', 1422 => 'edge500_korea', 1436 => 'fr70', 1446 => 'fr310xt_4t', 1461 => 'amx', 1482 => 'fr10', 1497 => 'edge800_korea', 1499 => 'swim', 1537 => 'fr910xt_china', 1551 => 'fenix', 1555 => 'edge200_taiwan', 1561 => 'edge510', 1567 => 'edge810', 1570 => 'tempe', 1600 => 'fr910xt_japan', 1623 => 'fr620', 1632 => 'fr220', 1664 => 'fr910xt_korea', 1688 => 'fr10_japan', 1721 => 'edge810_japan', 1735 => 'virb_elite', 1736 => 'edge_touring', 1742 => 'edge510_japan', 1752 => 'hrm_run', 1765 => 'fr920xt', 1821 => 'edge510_asia', 1822 => 'edge810_china', 1823 => 'edge810_taiwan', 1836 => 'edge1000', 1837 => 'vivo_fit', 1853 => 'virb_remote', 1885 => 'vivo_ki', 1903 => 'fr15', 1907 => 'vivo_active', 1918 => 'edge510_korea', 1928 => 'fr620_japan', 1929 => 'fr620_china', 1930 => 'fr220_japan', 1931 => 'fr220_china', 1967 => 'fenix2', 1988 => 'epix', 2050 => 'fenix3', 2052 => 'edge1000_taiwan', 2053 => 'edge1000_japan', 2061 => 'fr15_japan', 2067 => 'edge520', 2070 => 'edge1000_china', 2072 => 'fr620_russia', 2073 => 'fr220_russia', 2079 => 'vector_s', 2100 => 'edge1000_korea', 2130 => 'fr920xt_taiwan', 2131 => 'fr920xt_china', 2132 => 'fr920xt_japan', 2134 => 'virbx', 2135 => 'vivo_smart_apac', 2140 => 'etrex_touch', 2147 => 'edge25', 2148 => 'fr25', 2150 => 'vivo_fit2', 2153 => 'fr225', 2156 => 'fr630', 2157 => 'fr230', 2160 => 'vivo_active_apac', 2161 => 'vector_2', 2162 => 'vector_2s', 2172 => 'virbxe', 2173 => 'fr620_taiwan', 2174 => 'fr220_taiwan', 2175 => 'truswing', 2188 => 'fenix3_china', 2189 => 'fenix3_twn', 2192 => 'varia_headlight', 2193 => 'varia_taillight_old', 2204 => 'edge_explore_1000', 2219 => 'fr225_asia', 2225 => 'varia_radar_taillight', 2226 => 'varia_radar_display', 2238 => 'edge20', 2262 => 'd2_bravo', 2266 => 'approach_s20', 2276 => 'varia_remote', 2327 => 'hrm4_run', 2337 => 'vivo_active_hr', 2347 => 'vivo_smart_gps_hr', 2348 => 'vivo_smart_hr', 2368 => 'vivo_move', 2398 => 'varia_vision', 2406 => 'vivo_fit3', 2413 => 'fenix3_hr', 2429 => 'index_smart_scale', 2431 => 'fr235', 2441 => 'oregon7xx', 2444 => 'rino7xx', 2496 => 'nautix', 2530 => 'edge_820', 2531 => 'edge_explore_820', 10007 => 'sdm4', 10014 => 'edge_remote', 20119 => 'training_center', 65532 => 'android_antplus_plugin', 65534 => 'connect' } FitParser::File::Types.add_type :antplus_device_type, :uint8, values: { 1 => 'antfs', 11 => 'bike_power', 12 => 'environment_sensor_legacy', 15 => 'multi_sport_speed_distance', 16 => 'control', 17 => 'fitness_equipment', 18 => 'blood_pressure', 19 => 'geocache_node', 20 => 'light_electric_vehicle', 25 => 'env_sensor', 26 => 'racquet', 27 => 'control_hub', 31 => 'muscle_oxygen', 35 => 'bike_light_main', 36 => 'bike_light_shared', 38 => 'exd', 40 => 'bike_radar', 119 => 'weight_scale', 120 => 'heart_rate', 121 => 'bike_speed_cadence', 122 => 'bike_cadence', 123 => 'bike_speed', 124 => 'stride_speed_distance' } FitParser::File::Types.add_type :ant_network, :enum, values: { 0 => 'public', 1 => 'antplus', 2 => 'antfs', 3 => 'private' } FitParser::File::Types.add_type :workout_capabilities, :uint32z, values: { 0x00000001 => 'interval', 0x00000002 => 'custom', 0x00000004 => 'fitness_equipment', 0x00000008 => 'firstbeat', 0x00000010 => 'new_leaf', 0x00000020 => 'tcx', 0x00000080 => 'speed', 0x00000100 => 'heart_rate', 0x00000200 => 'distance', 0x00000400 => 'cadence', 0x00000800 => 'power', 0x00001000 => 'grade', 0x00002000 => 'resistance', 0x00004000 => 'protected' }, method: :bitfield_value FitParser::File::Types.add_type :battery_status, :uint8, values: { 1 => 'new', 2 => 'good', 3 => 'ok', 4 => 'low', 5 => 'critical', 6 => 'charging', 7 => 'unknown' } FitParser::File::Types.add_type :hr_type, :enum, values: { 0 => 'normal', 1 => 'irregular' } FitParser::File::Types.add_type :course_capabilities, :uint32z, values: { 0x00000001 => 'processed', 0x00000002 => 'valid', 0x00000004 => 'time', 0x00000008 => 'distance', 0x00000010 => 'position', 0x00000020 => 'heart_rate', 0x00000040 => 'power', 0x00000080 => 'cadence', 0x00000100 => 'training', 0x00000200 => 'navigation', 0x00000400 => 'bikeway' }, method: :bitfield_value FitParser::File::Types.add_type :weight, :uint16, values: { 65534 => 'calculating' } FitParser::File::Types.add_type :workout_hr, :uint32, values: { 100 => 'bpm_offset' } FitParser::File::Types.add_type :workout_power, :uint32, values: { 1000 => 'watts_offset' } FitParser::File::Types.add_type :bp_status, :enum, values: { 0 => 'no_error', 1 => 'error_incomplete_data', 2 => 'error_no_measurement', 3 => 'error_data_out_of_range', 4 => 'error_irregular_heart_rate' } FitParser::File::Types.add_type :user_local_id, :uint16, values: { 0 => 'local_min', 15 => 'local_max', 16 => 'stationary_min', 255 => 'stationary_max', 256 => 'portable_min', 65534 => 'portable_max' } FitParser::File::Types.add_type :swim_stroke, :enum, values: { 0 => 'freestyle', 1 => 'backstroke', 2 => 'breaststroke', 3 => 'butterfly', 4 => 'drill', 5 => 'mixed', 6 => 'im' } FitParser::File::Types.add_type :activity_type, :enum, values: { 0 => 'generic', 1 => 'running', 2 => 'cycling', 3 => 'transition', 4 => 'fitness_equipment', 5 => 'swimming', 6 => 'walking', 8 => 'sedentary', 254 => 'all' } FitParser::File::Types.add_type :activity_subtype, :enum, values: { 0 => 'generic', 1 => 'treadmill', 2 => 'street', 3 => 'trail', 4 => 'track', 5 => 'spin', 6 => 'indoor_cycling', 7 => 'road', 8 => 'mountain', 9 => 'downhill', 10 => 'recumbent', 11 => 'cyclocross', 12 => 'hand_cycling', 13 => 'track_cycling', 14 => 'indoor_rowing', 15 => 'elliptical', 16 => 'stair_climbing', 17 => 'lap_swimming', 18 => 'open_water', 254 => 'all' } FitParser::File::Types.add_type :activity_level, :enum, values: { 0 => 'low', 1 => 'medium', 2 => 'high' } FitParser::File::Types.add_type :side, :enum, values: { 0 => 'right', 1 => 'left' } FitParser::File::Types.add_type :left_right_balance, :uint8, values: { 127 => 'mask', 128 => 'right' } FitParser::File::Types.add_type :left_right_balance_100, :uint16, values: { 16383 => 'mask', 32768 => 'right' } FitParser::File::Types.add_type :length_type, :enum, values: { 0 => 'idle', 1 => 'active' } FitParser::File::Types.add_type :day_of_week, :enum, values: { 0 => 'sunday', 1 => 'monday', 2 => 'tuesday', 3 => 'wednesday', 4 => 'thursday', 5 => 'friday', 6 => 'saturday' } FitParser::File::Types.add_type :connectivity_capabilities, :uint32z, values: { 1 => 'bluetooth', 2 => 'bluetooth_le', 4 => 'ant', 8 => 'activity_upload', 16 => 'course_download', 32 => 'workout_download', 64 => 'live_track', 128 => 'weather_conditions', 256 => 'weather_alerts', 512 => 'gps_ephemeris_download', 1024 => 'explicit_archive', 2048 => 'setup_incomplete', 4096 => 'continue_sync_after_software_update', 8192 => 'connect_iq_app_download', 16384 => 'golf_course_download', 32768 => 'device_initiates_sync', 65536 => 'connect_iq_watch_app_download', 131072 => 'connect_iq_widget_download', 262144 => 'connect_iq_watch_face_download', 524288 => 'connect_iq_data_field_download', 1048576 => 'connect_iq_app_managment', 2097152 => 'swing_sensor', 4194304 => 'swing_sensor_remote', 8388608 => 'incident_detection', 16777216 => 'audio_prompts', 33554432 => 'wifi_verification', 67108864 => 'true_up', 134217728 => 'find_my_watch', 268435456 => 'remote_manual_sync', 536870912 => 'live_track_auto_start', 1073741824 => 'live_track_messaging' } FitParser::File::Types.add_type :stroke_type, :enum, values: { 0 => 'no_event', 1 => 'other', 2 => 'serve', 3 => 'forehand', 4 => 'backhand', 5 => 'smash' } FitParser::File::Types.add_type :body_location, :enum, values: { 0 => 'left_leg', 1 => 'left_calf', 2 => 'left_shin', 3 => 'left_hamstring', 4 => 'left_quad', 5 => 'left_glute', 6 => 'right_leg', 7 => 'right_calf', 8 => 'right_shin', 9 => 'right_hamstring', 10 => 'right_quad', 11 => 'right_glute', 12 => 'torso_back', 13 => 'left_lower_back', 14 => 'left_upper_back', 15 => 'right_lower_back', 16 => 'right_upper_back', 17 => 'torso_front', 18 => 'left_abdomen', 19 => 'left_chest', 20 => 'right_abdomen', 21 => 'right_chest', 22 => 'left_arm', 23 => 'left_shoulder', 24 => 'left_bicep', 25 => 'left_tricep', 26 => 'left_brachioradialis', 27 => 'left_forearm_extensors', 28 => 'right_arm', 29 => 'right_shoulder', 30 => 'right_bicep', 31 => 'right_tricep', 32 => 'right_brachioradialis', 33 => 'right_forearm_extensors', 34 => 'neck', 35 => 'throat', 36 => 'waist_mid_back', 37 => 'waist_front', 38 => 'waist_left', 39 => 'waist_right' } FitParser::File::Types.add_type :source_type, :enum, values: { 0 => 'ant', 1 => 'antplus', 2 => 'bluetooth', 3 => 'bluetooth_low_energy', 4 => 'wifi', 5 => 'local' } FitParser::File::Types.add_type :attitude_stage, :enum, values: { 0 => 'failed', 1 => 'aligning', 2 => 'degraded', 3 => 'valid' } FitParser::File::Types.add_type :attitude_validity, :uint16, values: { 0x0001 => 'track_angle_heading_valid', 0x0002 => 'pitch_valid', 0x0004 => 'roll_valid', 0x0008 => 'lateral_body_accel_valid', 0x0010 => 'normal_body_accel_valid', 0x0020 => 'turn_rate_valid', 0x0040 => 'hw_fail', 0x0080 => 'mag_invalid', 0x0100 => 'no_gps', 0x0200 => 'gps_invalid', 0x0400 => 'solution_coasting', 0x0800 => 'true_track_angle', 0x1000 => 'magnetic_heading' } FitParser::File::Types.add_type :auto_sync_frequency, :enum, values: { 0 => 'never', 1 => 'occasionally', 2 => 'frequent', 3 => 'once_a_day' } FitParser::File::Types.add_type :exd_layout, :enum, values: { 0 => 'full_screen', 1 => 'half_vertical', 2 => 'half_horizontal', 3 => 'half_vertical_right_split', 4 => 'half_horizontal_bottom_split', 5 => 'full_quarter_split', 6 => 'half_vertical_left_split', 7 => 'half_horizontal_top_split' } FitParser::File::Types.add_type :exd_display_type, :enum, values: { 0 => 'numerical', 1 => 'simple', 2 => 'graph', 3 => 'bar', 4 => 'circle_graph', 5 => 'virtual_partner', 6 => 'balance', 7 => 'string_list', 8 => 'string', 9 => 'simple_dynamic_icon', 10 => 'gauge' } FitParser::File::Types.add_type :exd_data_units, :enum, values: { 0 => 'no_units', 1 => 'laps', 2 => 'miles_per_hour', 3 => 'kilometers_per_hour', 4 => 'feet_per_hour', 5 => 'meters_per_hour', 6 => 'degrees_celsius', 7 => 'degrees_farenheit', 8 => 'zone', 9 => 'gear', 10 => 'rpm', 11 => 'bpm', 12 => 'degrees', 13 => 'millimeters', 14 => 'meters', 15 => 'kilometers', 16 => 'feet', 17 => 'yards', 18 => 'kilofeet', 19 => 'miles', 20 => 'time', 21 => 'enum_turn_type', 22 => 'percent', 23 => 'watts', 24 => 'watts_per_kilogram', 25 => 'enum_battery_status', 26 => 'enum_bike_light_beam_angle_mode', 27 => 'enum_bike_light_battery_status', 28 => 'enum_bike_light_network_config_type', 29 => 'lights', 30 => 'seconds', 31 => 'minutes', 32 => 'hours', 33 => 'calories', 34 => 'kilojoules', 35 => 'milliseconds', 36 => 'second_per_mile', 37 => 'second_per_kilometer', 38 => 'centimeter', 39 => 'enum_course_point', 40 => 'bradians', 41 => 'enum_sport' } FitParser::File::Types.add_type :exd_qualifiers, :enum, values: { 0 => 'no_qualifier', 1 => 'instantaneous', 2 => 'average', 3 => 'lap', 4 => 'maximum', 5 => 'maximum_average', 6 => 'maximum_lap', 7 => 'last_lap', 8 => 'average_lap', 9 => 'to_destination', 10 => 'to_go', 11 => 'to_next', 12 => 'next_course_point', 13 => 'total', 14 => 'three_second_average', 15 => 'ten_second_average', 16 => 'thirty_second_average', 17 => 'percent_maximum', 18 => 'percent_maximum_average', 19 => 'lap_percent_maximum', 20 => 'elapsed', 21 => 'sunrise', 22 => 'sunset', 23 => 'compared_to_virtual_partner', 24 => 'maximum_24h', 25 => 'minimum_24h', 26 => 'minimum', 27 => 'first', 28 => 'second', 29 => 'third', 30 => 'shifter', 31 => 'last_sport', 242 => 'zone_9', 243 => 'zone_8', 244 => 'zone_7', 245 => 'zone_6', 246 => 'zone_5', 247 => 'zone_4', 248 => 'zone_3', 249 => 'zone_2', 250 => 'zone_1' } FitParser::File::Types.add_type :exd_descriptors, :enum, values: { 0 => 'bike_light_battery_status', 1 => 'beam_angle_status', 2 => 'batery_level', 3 => 'light_network_mode', 4 => 'number_lights_connected', 5 => 'cadence', 6 => 'distance', 7 => 'estimated_time_of_arrival', 8 => 'heading', 9 => 'time', 10 => 'battery_level', 11 => 'trainer_resistance', 12 => 'trainer_target_power', 13 => 'time_seated', 14 => 'time_standing', 15 => 'elevation', 16 => 'grade', 17 => 'ascent', 18 => 'descent', 19 => 'vertical_speed', 20 => 'di2_battery_level', 21 => 'front_gear', 22 => 'rear_gear', 23 => 'gear_ratio', 24 => 'heart_rate', 25 => 'heart_rate_zone', 26 => 'time_in_heart_rate_zone', 27 => 'heart_rate_reserve', 28 => 'calories', 29 => 'gps_accuracy', 30 => 'gps_signal_strength', 31 => 'temperature', 32 => 'time_of_day', 33 => 'balance', 34 => 'pedal_smoothness', 35 => 'power', 36 => 'functional_threshold_power', 37 => 'intensity_factor', 38 => 'work', 39 => 'power_ratio', 40 => 'normalized_power', 41 => 'training_stress_Score', 42 => 'time_on_zone', 43 => 'speed', 44 => 'laps', 45 => 'reps', 46 => 'workout_step', 47 => 'course_distance', 48 => 'navigation_distance', 49 => 'course_estimated_time_of_arrival', 50 => 'navigation_estimated_time_of_arrival', 51 => 'course_time', 52 => 'navigation_time', 53 => 'course_heading', 54 => 'navigation_heading', 55 => 'power_zone', 56 => 'torque_effectiveness', 57 => 'timer_time', 58 => 'power_weight_ratio', 59 => 'left_platform_center_offset', 60 => 'right_platform_center_offset', 61 => 'left_power_phase_start_angle', 62 => 'right_power_phase_start_angle', 63 => 'left_power_phase_finish_angle', 64 => 'right_power_phase_finish_angle', 65 => 'gears', 66 => 'pace', 67 => 'training_effect', 68 => 'vertical_oscillation', 69 => 'vertical_ratio', 70 => 'ground_contact_time', 71 => 'left_ground_contact_time_balance', 72 => 'right_ground_contact_time_balance', 73 => 'stride_length', 74 => 'running_cadence', 75 => 'performance_condition', 76 => 'course_type', 77 => 'time_in_power_zone', 78 => 'navigation_turn', 79 => 'course_location', 80 => 'navigation_location', 81 => 'compass', 82 => 'gear_combo', 83 => 'muscle_oxygen', 84 => 'icon' } FitParser::File::Types.add_type :auto_activity_detect, :uint32, values: { 0x00000000 => 'none', 0x00000001 => 'running', 0x00000002 => 'cycling', 0x00000004 => 'swimming', 0x00000008 => 'walking', 0x00000020 => 'elliptical', 0x00000400 => 'sedentary' } FitParser::File::Types.add_type :supported_exd_screen_layouts, :uint32z, values: { 0x00000001 => 'full_screen', 0x00000002 => 'half_vertical', 0x00000004 => 'half_horizontal', 0x00000008 => 'half_vertical_right_split', 0x00000010 => 'half_horizontal_bottom_split', 0x00000020 => 'full_quarter_split', 0x00000040 => 'half_vertical_left_split', 0x00000080 => 'half_horizontal_top_split' } FitParser::File::Types.add_type :fit_base_type, :uint8, values: { 0 => 'enum', 1 => 'sint8', 2 => 'uint8', 131 => 'sint16', 132 => 'uint16', 133 => 'sint32', 134 => 'uint32', 7 => 'string', 136 => 'float32', 137 => 'float64', 10 => 'uint8z', 139 => 'uint16z', 140 => 'uint32z', 13 => 'byte', 142 => 'sint64', 143 => 'uint64', 144 => 'uint64z' } FitParser::File::Types.add_type :turn_type, :enum, values: { 0 => 'arriving_idx', 1 => 'arriving_left_idx', 2 => 'arriving_right_idx', 3 => 'arriving_via_idx', 4 => 'arriving_via_left_idx', 5 => 'arriving_via_right_idx', 6 => 'bear_keep_left_idx', 7 => 'bear_keep_right_idx', 8 => 'continue_idx', 9 => 'exit_left_idx', 10 => 'exit_right_idx', 11 => 'ferry_idx', 12 => 'roundabout_45_idx', 13 => 'roundabout_90_idx', 14 => 'roundabout_135_idx', 15 => 'roundabout_180_idx', 16 => 'roundabout_225_idx', 17 => 'roundabout_270_idx', 18 => 'roundabout_315_idx', 19 => 'roundabout_360_idx', 20 => 'roundabout_neg_45_idx', 21 => 'roundabout_neg_90_idx', 22 => 'roundabout_neg_135_idx', 23 => 'roundabout_neg_180_idx', 24 => 'roundabout_neg_225_idx', 25 => 'roundabout_neg_270_idx', 26 => 'roundabout_neg_315_idx', 27 => 'roundabout_neg_360_idx', 28 => 'roundabout_generic_idx', 29 => 'roundabout_neg_generic_idx', 30 => 'sharp_turn_left_idx', 31 => 'sharp_turn_right_idx', 32 => 'turn_left_idx', 33 => 'turn_right_idx', 34 => 'uturn_left_idx', 35 => 'uturn_right_idx', 36 => 'icon_inv_idx', 37 => 'icon_idx_cnt' } FitParser::File::Types.add_type :bike_light_beam_angle_mode, :uint8, values: { 0 => 'manual', 1 => 'auto' } FitParser::File::Types.add_type :fit_base_unit, :uint16, values: { 0 => 'other' } # the type below is assigned to some fileds, but # it is not defined in terms of values and basic type in FIT SDK as # of 2015-01-29 FitParser::File::Types.add_type :bool, :uint8, values: { 0 => false, 1 => true }