diff --git a/fitparse/base.py b/fitparse/base.py index 125d620..937d021 100644 --- a/fitparse/base.py +++ b/fitparse/base.py @@ -319,7 +319,10 @@ def _parse_data_message(self, header): if field.components: for component in field.components: # Render its raw value - cmp_raw_value = component.render(raw_value) + try: + cmp_raw_value = component.render(raw_value) + except ValueError: + continue # Apply accumulated value if component.accumulate and cmp_raw_value is not None: diff --git a/fitparse/profile.py b/fitparse/profile.py index 3e59617..ad4fe6b 100644 --- a/fitparse/profile.py +++ b/fitparse/profile.py @@ -1,9971 +1,12074 @@ -################# BEGIN AUTOMATICALLY GENERATED FIT PROFILE ################## -########################### DO NOT EDIT THIS FILE ############################ -####### EXPORTED PROFILE FROM SDK VERSION 20.33 AT 2017-05-17 22:36:12 ####### -########## PARSED 118 TYPES (1699 VALUES), 76 MESSAGES (950 FIELDS) ########## - -from fitparse.records import ( - ComponentField, - Field, - FieldType, - MessageType, - ReferenceField, - SubField, - BASE_TYPES, -) - - -FIELD_TYPES = { - 'activity': FieldType( - name='activity', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'manual', - 1: 'auto_multi_sport', - }, - ), - 'activity_class': FieldType( - name='activity_class', - base_type=BASE_TYPES[0x00], # enum - values={ - 100: 'level_max', - 0x7F: 'level', # 0 to 100 - 0x80: 'athlete', - }, - ), - 'activity_level': FieldType( - name='activity_level', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'low', - 1: 'medium', - 2: 'high', - }, - ), - 'activity_subtype': FieldType( - name='activity_subtype', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'generic', - 1: 'treadmill', # Run - 2: 'street', # Run - 3: 'trail', # Run - 4: 'track', # Run - 5: 'spin', # Cycling - 6: 'indoor_cycling', # Cycling - 7: 'road', # Cycling - 8: 'mountain', # Cycling - 9: 'downhill', # Cycling - 10: 'recumbent', # Cycling - 11: 'cyclocross', # Cycling - 12: 'hand_cycling', # Cycling - 13: 'track_cycling', # Cycling - 14: 'indoor_rowing', # Fitness Equipment - 15: 'elliptical', # Fitness Equipment - 16: 'stair_climbing', # Fitness Equipment - 17: 'lap_swimming', # Swimming - 18: 'open_water', # Swimming - 254: 'all', - }, - ), - 'activity_type': FieldType( - name='activity_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'generic', - 1: 'running', - 2: 'cycling', - 3: 'transition', # Mulitsport transition - 4: 'fitness_equipment', - 5: 'swimming', - 6: 'walking', - 8: 'sedentary', - 254: 'all', # All is for goals only to include all sports. - }, - ), - 'analog_watchface_layout': FieldType( - name='analog_watchface_layout', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'minimal', - 1: 'traditional', - 2: 'modern', - }, - ), - 'ant_network': FieldType( - name='ant_network', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'public', - 1: 'antplus', - 2: 'antfs', - 3: 'private', - }, - ), - 'antplus_device_type': FieldType( - name='antplus_device_type', - base_type=BASE_TYPES[0x02], # 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', - }, - ), - 'attitude_stage': FieldType( - name='attitude_stage', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'failed', - 1: 'aligning', - 2: 'degraded', - 3: 'valid', - }, - ), - 'attitude_validity': FieldType( - name='attitude_validity', - base_type=BASE_TYPES[0x84], # 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', - }, - ), - 'auto_activity_detect': FieldType( - name='auto_activity_detect', - base_type=BASE_TYPES[0x86], # uint32 - values={ - 0x00000000: 'none', - 0x00000001: 'running', - 0x00000002: 'cycling', - 0x00000004: 'swimming', - 0x00000008: 'walking', - 0x00000020: 'elliptical', - 0x00000400: 'sedentary', - }, - ), - 'auto_sync_frequency': FieldType( - name='auto_sync_frequency', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'never', - 1: 'occasionally', - 2: 'frequent', - 3: 'once_a_day', - 4: 'remote', - }, - ), - 'autolap_trigger': FieldType( - name='autolap_trigger', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'time', - 1: 'distance', - 2: 'position_start', - 3: 'position_lap', - 4: 'position_waypoint', - 5: 'position_marked', - 6: 'off', - }, - ), - 'autoscroll': FieldType( - name='autoscroll', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'none', - 1: 'slow', - 2: 'medium', - 3: 'fast', - }, - ), - 'backlight_mode': FieldType( - name='backlight_mode', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'battery_status': FieldType( - name='battery_status', - base_type=BASE_TYPES[0x02], # uint8 - values={ - 1: 'new', - 2: 'good', - 3: 'ok', - 4: 'low', - 5: 'critical', - 6: 'charging', - 7: 'unknown', - }, - ), - 'bike_light_beam_angle_mode': FieldType( - name='bike_light_beam_angle_mode', - base_type=BASE_TYPES[0x02], # uint8 - values={ - 0: 'manual', - 1: 'auto', - }, - ), - 'bike_light_network_config_type': FieldType( - name='bike_light_network_config_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'auto', - 4: 'individual', - 5: 'high_visibility', - 6: 'trail', - }, - ), - 'body_location': FieldType( - name='body_location', - base_type=BASE_TYPES[0x00], # 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', # Left anterior forearm - 27: 'left_forearm_extensors', # Left posterior forearm - 28: 'right_arm', - 29: 'right_shoulder', - 30: 'right_bicep', - 31: 'right_tricep', - 32: 'right_brachioradialis', # Right anterior forearm - 33: 'right_forearm_extensors', # Right posterior forearm - 34: 'neck', - 35: 'throat', - 36: 'waist_mid_back', - 37: 'waist_front', - 38: 'waist_left', - 39: 'waist_right', - }, - ), - 'bool': FieldType( - name='bool', - base_type=BASE_TYPES[0x00], # enum - ), - 'bp_status': FieldType( - name='bp_status', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'no_error', - 1: 'error_incomplete_data', - 2: 'error_no_measurement', - 3: 'error_data_out_of_range', - 4: 'error_irregular_heart_rate', - }, - ), - 'camera_event_type': FieldType( - name='camera_event_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'video_start', # Start of video recording - 1: 'video_split', # Mark of video file split (end of one file, beginning of the other) - 2: 'video_end', # End of video recording - 3: 'photo_taken', # Still photo taken - 4: 'video_second_stream_start', - 5: 'video_second_stream_split', - 6: 'video_second_stream_end', - 7: 'video_split_start', # Mark of video file split start - 8: 'video_second_stream_split_start', - 11: 'video_pause', # Mark when a video recording has been paused - 12: 'video_second_stream_pause', - 13: 'video_resume', # Mark when a video recording has been resumed - 14: 'video_second_stream_resume', - }, - ), - 'camera_orientation_type': FieldType( - name='camera_orientation_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'camera_orientation_0', - 1: 'camera_orientation_90', - 2: 'camera_orientation_180', - 3: 'camera_orientation_270', - }, - ), - 'checksum': FieldType( - name='checksum', - base_type=BASE_TYPES[0x02], # uint8 - values={ - 0: 'clear', # Allows clear of checksum for flash memory where can only write 1 to 0 without erasing sector. - 1: 'ok', # Set to mark checksum as valid if computes to invalid values 0 or 0xFF. Checksum can also be set to ok to save encoding computation time. - }, - ), - 'comm_timeout_type': FieldType( - name='comm_timeout_type', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 0: 'wildcard_pairing_timeout', # Timeout pairing to any device - 1: 'pairing_timeout', # Timeout pairing to previously paired device - 2: 'connection_lost', # Temporary loss of communications - 3: 'connection_timeout', # Connection closed due to extended bad communications - }, - ), - 'connectivity_capabilities': FieldType( - name='connectivity_capabilities', - base_type=BASE_TYPES[0x8C], # uint32z - values={ - 0x00000001: 'bluetooth', - 0x00000002: 'bluetooth_le', - 0x00000004: 'ant', - 0x00000008: 'activity_upload', - 0x00000010: 'course_download', - 0x00000020: 'workout_download', - 0x00000040: 'live_track', - 0x00000080: 'weather_conditions', - 0x00000100: 'weather_alerts', - 0x00000200: 'gps_ephemeris_download', - 0x00000400: 'explicit_archive', - 0x00000800: 'setup_incomplete', - 0x00001000: 'continue_sync_after_software_update', - 0x00002000: 'connect_iq_app_download', - 0x00004000: 'golf_course_download', - 0x00008000: 'device_initiates_sync', # Indicates device is in control of initiating all syncs - 0x00010000: 'connect_iq_watch_app_download', - 0x00020000: 'connect_iq_widget_download', - 0x00040000: 'connect_iq_watch_face_download', - 0x00080000: 'connect_iq_data_field_download', - 0x00100000: 'connect_iq_app_managment', # Device supports delete and reorder of apps via GCM - 0x00200000: 'swing_sensor', - 0x00400000: 'swing_sensor_remote', - 0x00800000: 'incident_detection', # Device supports incident detection - 0x01000000: 'audio_prompts', - 0x02000000: 'wifi_verification', # Device supports reporting wifi verification via GCM - 0x04000000: 'true_up', # Device supports True Up - 0x08000000: 'find_my_watch', # Device supports Find My Watch - 0x10000000: 'remote_manual_sync', - 0x20000000: 'live_track_auto_start', # Device supports LiveTrack auto start - 0x40000000: 'live_track_messaging', # Device supports LiveTrack Messaging - 0x80000000: 'instant_input', # Device supports instant input feature - }, - ), - 'course_capabilities': FieldType( - name='course_capabilities', - base_type=BASE_TYPES[0x8C], # 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', - }, - ), - 'course_point': FieldType( - name='course_point', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'date_mode': FieldType( - name='date_mode', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'day_month', - 1: 'month_day', - }, - ), - 'date_time': FieldType( # seconds since UTC 00:00 Dec 31 1989 - name='date_time', - base_type=BASE_TYPES[0x86], # uint32 - ), - 'day_of_week': FieldType( - name='day_of_week', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'sunday', - 1: 'monday', - 2: 'tuesday', - 3: 'wednesday', - 4: 'thursday', - 5: 'friday', - 6: 'saturday', - }, - ), - 'device_index': FieldType( - name='device_index', - base_type=BASE_TYPES[0x02], # uint8 - values={ - 0: 'creator', # Creator of the file is always device index 0. - }, - ), - 'digital_watchface_layout': FieldType( - name='digital_watchface_layout', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'traditional', - 1: 'modern', - 2: 'bold', - }, - ), - 'display_heart': FieldType( - name='display_heart', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'bpm', - 1: 'max', - 2: 'reserve', - }, - ), - 'display_measure': FieldType( - name='display_measure', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'metric', - 1: 'statute', - 2: 'nautical', - }, - ), - 'display_orientation': FieldType( - name='display_orientation', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'auto', # automatic if the device supports it - 1: 'portrait', - 2: 'landscape', - 3: 'portrait_flipped', # portrait mode but rotated 180 degrees - 4: 'landscape_flipped', # landscape mode but rotated 180 degrees - }, - ), - 'display_position': FieldType( - name='display_position', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'degree', # dd.dddddd - 1: 'degree_minute', # dddmm.mmm - 2: 'degree_minute_second', # dddmmss - 3: 'austrian_grid', # Austrian Grid (BMN) - 4: 'british_grid', # British National Grid - 5: 'dutch_grid', # Dutch grid system - 6: 'hungarian_grid', # Hungarian grid system - 7: 'finnish_grid', # Finnish grid system Zone3 KKJ27 - 8: 'german_grid', # Gausss Krueger (German) - 9: 'icelandic_grid', # Icelandic Grid - 10: 'indonesian_equatorial', # Indonesian Equatorial LCO - 11: 'indonesian_irian', # Indonesian Irian LCO - 12: 'indonesian_southern', # Indonesian Southern LCO - 13: 'india_zone_0', # India zone 0 - 14: 'india_zone_IA', # India zone IA - 15: 'india_zone_IB', # India zone IB - 16: 'india_zone_IIA', # India zone IIA - 17: 'india_zone_IIB', # India zone IIB - 18: 'india_zone_IIIA', # India zone IIIA - 19: 'india_zone_IIIB', # India zone IIIB - 20: 'india_zone_IVA', # India zone IVA - 21: 'india_zone_IVB', # India zone IVB - 22: 'irish_transverse', # Irish Transverse Mercator - 23: 'irish_grid', # Irish Grid - 24: 'loran', # Loran TD - 25: 'maidenhead_grid', # Maidenhead grid system - 26: 'mgrs_grid', # MGRS grid system - 27: 'new_zealand_grid', # New Zealand grid system - 28: 'new_zealand_transverse', # New Zealand Transverse Mercator - 29: 'qatar_grid', # Qatar National Grid - 30: 'modified_swedish_grid', # Modified RT-90 (Sweden) - 31: 'swedish_grid', # RT-90 (Sweden) - 32: 'south_african_grid', # South African Grid - 33: 'swiss_grid', # Swiss CH-1903 grid - 34: 'taiwan_grid', # Taiwan Grid - 35: 'united_states_grid', # United States National Grid - 36: 'utm_ups_grid', # UTM/UPS grid system - 37: 'west_malayan', # West Malayan RSO - 38: 'borneo_rso', # Borneo RSO - 39: 'estonian_grid', # Estonian grid system - 40: 'latvian_grid', # Latvian Transverse Mercator - 41: 'swedish_ref_99_grid', # Reference Grid 99 TM (Swedish) - }, - ), - 'display_power': FieldType( - name='display_power', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'watts', - 1: 'percent_ftp', - }, - ), - 'event': FieldType( - name='event', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'timer', # Group 0. Start / stop_all - 3: 'workout', # start / stop - 4: 'workout_step', # Start at beginning of workout. Stop at end of each step. - 5: 'power_down', # stop_all group 0 - 6: 'power_up', # stop_all group 0 - 7: 'off_course', # start / stop group 0 - 8: 'session', # Stop at end of each session. - 9: 'lap', # Stop at end of each lap. - 10: 'course_point', # marker - 11: 'battery', # marker - 12: 'virtual_partner_pace', # Group 1. Start at beginning of activity if VP enabled, when VP pace is changed during activity or VP enabled mid activity. stop_disable when VP disabled. - 13: 'hr_high_alert', # Group 0. Start / stop when in alert condition. - 14: 'hr_low_alert', # Group 0. Start / stop when in alert condition. - 15: 'speed_high_alert', # Group 0. Start / stop when in alert condition. - 16: 'speed_low_alert', # Group 0. Start / stop when in alert condition. - 17: 'cad_high_alert', # Group 0. Start / stop when in alert condition. - 18: 'cad_low_alert', # Group 0. Start / stop when in alert condition. - 19: 'power_high_alert', # Group 0. Start / stop when in alert condition. - 20: 'power_low_alert', # Group 0. Start / stop when in alert condition. - 21: 'recovery_hr', # marker - 22: 'battery_low', # marker - 23: 'time_duration_alert', # Group 1. Start if enabled mid activity (not required at start of activity). Stop when duration is reached. stop_disable if disabled. - 24: 'distance_duration_alert', # Group 1. Start if enabled mid activity (not required at start of activity). Stop when duration is reached. stop_disable if disabled. - 25: 'calorie_duration_alert', # Group 1. Start if enabled mid activity (not required at start of activity). Stop when duration is reached. stop_disable if disabled. - 26: 'activity', # Group 1.. Stop at end of activity. - 27: 'fitness_equipment', # marker - 28: 'length', # Stop at end of each length. - 32: 'user_marker', # marker - 33: 'sport_point', # marker - 36: 'calibration', # start/stop/marker - 42: 'front_gear_change', # marker - 43: 'rear_gear_change', # marker - 44: 'rider_position_change', # marker - 45: 'elev_high_alert', # Group 0. Start / stop when in alert condition. - 46: 'elev_low_alert', # Group 0. Start / stop when in alert condition. - 47: 'comm_timeout', # marker - }, - ), - 'event_type': FieldType( - name='event_type', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'exd_data_units': FieldType( - name='exd_data_units', - base_type=BASE_TYPES[0x00], # 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', - 42: 'inches_hg', - 43: 'mm_hg', - 44: 'mbars', - 45: 'hecto_pascals', - 46: 'feet_per_min', - 47: 'meters_per_min', - 48: 'meters_per_sec', - 49: 'eight_cardinal', - }, - ), - 'exd_descriptors': FieldType( - name='exd_descriptors', - base_type=BASE_TYPES[0x00], # 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', # Combined gear information - 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', - 85: 'compass_heading', - 86: 'gps_heading', - 87: 'gps_elevation', - 88: 'anaerobic_training_effect', - 89: 'course', - 90: 'off_course', - 91: 'glide_ratio', - 92: 'vertical_distance', - 93: 'vmg', - 94: 'ambient_pressure', - 95: 'pressure', - }, - ), - 'exd_display_type': FieldType( - name='exd_display_type', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'exd_layout': FieldType( - name='exd_layout', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'exd_qualifiers': FieldType( - name='exd_qualifiers', - base_type=BASE_TYPES[0x00], # 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', - 32: 'moving', - 33: 'stopped', - 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', - }, - ), - 'file': FieldType( - name='file', - base_type=BASE_TYPES[0x00], # enum - values={ - 1: 'device', # Read only, single file. Must be in root directory. - 2: 'settings', # Read/write, single file. Directory=Settings - 3: 'sport', # Read/write, multiple files, file number = sport type. Directory=Sports - 4: 'activity', # Read/erase, multiple files. Directory=Activities - 5: 'workout', # Read/write/erase, multiple files. Directory=Workouts - 6: 'course', # Read/write/erase, multiple files. Directory=Courses - 7: 'schedules', # Read/write, single file. Directory=Schedules - 9: 'weight', # Read only, single file. Circular buffer. All message definitions at start of file. Directory=Weight - 10: 'totals', # Read only, single file. Directory=Totals - 11: 'goals', # Read/write, single file. Directory=Goals - 14: 'blood_pressure', # Read only. Directory=Blood Pressure - 15: 'monitoring_a', # Read only. Directory=Monitoring. File number=sub type. - 20: 'activity_summary', # Read/erase, multiple files. Directory=Activities - 28: 'monitoring_daily', - 32: 'monitoring_b', # Read only. Directory=Monitoring. File number=identifier - 34: 'segment', # Read/write/erase. Multiple Files. Directory=Segments - 35: 'segment_list', # Read/write/erase. Single File. Directory=Segments - 40: 'exd_configuration', # Read/write/erase. Single File. Directory=Settings - 0xF7: 'mfg_range_min', # 0xF7 - 0xFE reserved for manufacturer specific file types - 0xFE: 'mfg_range_max', # 0xF7 - 0xFE reserved for manufacturer specific file types - }, - ), - 'file_flags': FieldType( - name='file_flags', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x02: 'read', - 0x04: 'write', - 0x08: 'erase', - }, - ), - 'fit_base_type': FieldType( - name='fit_base_type', - base_type=BASE_TYPES[0x02], # uint8 - values={ - 0: 'enum', - 1: 'sint8', - 2: 'uint8', - 7: 'string', - 10: 'uint8z', - 13: 'byte', - 131: 'sint16', - 132: 'uint16', - 133: 'sint32', - 134: 'uint32', - 136: 'float32', - 137: 'float64', - 139: 'uint16z', - 140: 'uint32z', - 142: 'sint64', - 143: 'uint64', - 144: 'uint64z', - }, - ), - 'fit_base_unit': FieldType( - name='fit_base_unit', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 0: 'other', - 1: 'kilogram', - 2: 'pound', - }, - ), - 'fitness_equipment_state': FieldType( # fitness equipment event data - name='fitness_equipment_state', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'ready', - 1: 'in_use', - 2: 'paused', - 3: 'unknown', # lost connection to fitness equipment - }, - ), - 'garmin_product': FieldType( - name='garmin_product', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 1: 'hrm1', - 2: 'axh01', # AXH01 HRM chipset - 3: 'axb01', - 4: 'axb02', - 5: 'hrm2ss', - 6: 'dsi_alf02', - 7: 'hrm3ss', - 8: 'hrm_run_single_byte_product_id', # hrm_run model for HRM ANT+ messaging - 9: 'bsm', # BSM model for ANT+ messaging - 10: 'bcm', # BCM model for ANT+ messaging - 11: 'axs01', # AXS01 HRM Bike Chipset model for ANT+ messaging - 12: 'hrm_tri_single_byte_product_id', # hrm_tri model for HRM ANT+ messaging - 14: 'fr225_single_byte_product_id', # fr225 model for HRM ANT+ messaging - 473: 'fr301_china', - 474: 'fr301_japan', - 475: 'fr301_korea', - 494: 'fr301_taiwan', - 717: 'fr405', # Forerunner 405 - 782: 'fr50', # Forerunner 50 - 987: 'fr405_japan', - 988: 'fr60', # Forerunner 60 - 1011: 'dsi_alf01', - 1018: 'fr310xt', # Forerunner 310 - 1036: 'edge500', - 1124: 'fr110', # Forerunner 110 - 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', # Also Edge Touring Plus - 1742: 'edge510_japan', - 1743: 'hrm_tri', - 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', - 1936: 'approach_s6', - 1956: 'vivo_smart', - 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', - 2417: 'virb_ultra_30', - 2429: 'index_smart_scale', - 2431: 'fr235', - 2432: 'fenix3_chronos', - 2441: 'oregon7xx', - 2444: 'rino7xx', - 2496: 'nautix', - 2530: 'edge_820', - 2531: 'edge_explore_820', - 2544: 'fenix5s', - 2547: 'd2_bravo_titanium', - 2593: 'running_dynamics_pod', - 2604: 'fenix5x', - 2606: 'vivo_fit_jr', - 2691: 'fr935', - 2697: 'fenix5', - 10007: 'sdm4', # SDM4 footpod - 10014: 'edge_remote', - 20119: 'training_center', - 65531: 'connectiq_simulator', - 65532: 'android_antplus_plugin', - 65534: 'connect', # Garmin Connect website - }, - ), - 'gender': FieldType( - name='gender', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'female', - 1: 'male', - }, - ), - 'goal': FieldType( - name='goal', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'time', - 1: 'distance', - 2: 'calories', - 3: 'frequency', - 4: 'steps', - 5: 'ascent', - 6: 'active_minutes', - }, - ), - 'goal_recurrence': FieldType( - name='goal_recurrence', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'off', - 1: 'daily', - 2: 'weekly', - 3: 'monthly', - 4: 'yearly', - 5: 'custom', - }, - ), - 'goal_source': FieldType( - name='goal_source', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'auto', # Device generated - 1: 'community', # Social network sourced goal - 2: 'user', # Manually generated - }, - ), - 'hr_type': FieldType( - name='hr_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'normal', - 1: 'irregular', - }, - ), - 'hr_zone_calc': FieldType( - name='hr_zone_calc', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'custom', - 1: 'percent_max_hr', - 2: 'percent_hrr', - }, - ), - 'intensity': FieldType( - name='intensity', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'active', - 1: 'rest', - 2: 'warmup', - 3: 'cooldown', - }, - ), - 'language': FieldType( - name='language', - base_type=BASE_TYPES[0x00], # 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', - 34: 'malaysian', - 35: 'vietnamese', - 36: 'burmese', - 37: 'mongolian', - 254: 'custom', - }, - ), - 'language_bits_0': FieldType( # Bit field corresponding to language enum type (1 << language). - name='language_bits_0', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'english', - 0x02: 'french', - 0x04: 'italian', - 0x08: 'german', - 0x10: 'spanish', - 0x20: 'croatian', - 0x40: 'czech', - 0x80: 'danish', - }, - ), - 'language_bits_1': FieldType( - name='language_bits_1', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'dutch', - 0x02: 'finnish', - 0x04: 'greek', - 0x08: 'hungarian', - 0x10: 'norwegian', - 0x20: 'polish', - 0x40: 'portuguese', - 0x80: 'slovakian', - }, - ), - 'language_bits_2': FieldType( - name='language_bits_2', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'slovenian', - 0x02: 'swedish', - 0x04: 'russian', - 0x08: 'turkish', - 0x10: 'latvian', - 0x20: 'ukrainian', - 0x40: 'arabic', - 0x80: 'farsi', - }, - ), - 'language_bits_3': FieldType( - name='language_bits_3', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'bulgarian', - 0x02: 'romanian', - 0x04: 'chinese', - 0x08: 'japanese', - 0x10: 'korean', - 0x20: 'taiwanese', - 0x40: 'thai', - 0x80: 'hebrew', - }, - ), - 'language_bits_4': FieldType( - name='language_bits_4', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'brazilian_portuguese', - 0x02: 'indonesian', - 0x04: 'malaysian', - 0x08: 'vietnamese', - 0x10: 'burmese', - 0x20: 'mongolian', - }, - ), - 'lap_trigger': FieldType( - name='lap_trigger', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'left_right_balance': FieldType( - name='left_right_balance', - base_type=BASE_TYPES[0x02], # uint8 - values={ - 0x7F: 'mask', # % contribution - 0x80: 'right', # data corresponds to right if set, otherwise unknown - }, - ), - 'left_right_balance_100': FieldType( - name='left_right_balance_100', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 0x3FFF: 'mask', # % contribution scaled by 100 - 0x8000: 'right', # data corresponds to right if set, otherwise unknown - }, - ), - 'length_type': FieldType( - name='length_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'idle', # Rest period. Length with no strokes - 1: 'active', # Length with strokes. - }, - ), - 'local_date_time': FieldType( # seconds since 00:00 Dec 31 1989 in local time zone - name='local_date_time', - base_type=BASE_TYPES[0x86], # uint32 - values={ - 0x10000000: 'min', # if date_time is < 0x10000000 then it is system time (seconds from device power on) - }, - ), - 'localtime_into_day': FieldType( # number of seconds into the day since local 00:00:00 - name='localtime_into_day', - base_type=BASE_TYPES[0x86], # uint32 - ), - 'manufacturer': FieldType( - name='manufacturer', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 1: 'garmin', - 2: 'garmin_fr405_antfs', # Do not use. Used by FR405 for ANTFS man id. - 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', # Indoorcycling Group - 97: 'MiPulse', - 98: 'bsx_athletics', - 99: 'look', - 100: 'campagnolo_srl', - 101: 'body_bike_smart', - 102: 'praxisworks', - 103: 'limits_technology', # Limits Technology Ltd. - 104: 'topaction_technology', # TopAction Technology Inc. - 105: 'cosinuss', - 106: 'fitcare', - 107: 'magene', - 108: 'giant_manufacturing_co', - 109: 'tigrasport', # Tigrasport - 110: 'salutron', - 111: 'technogym', - 112: 'bryton_sensors', - 255: 'development', - 257: 'healthandlife', - 258: 'lezyne', - 259: 'scribe_labs', - 260: 'zwift', - 261: 'watteam', - 262: 'recon', - 263: 'favero_electronics', - 264: 'dynovelo', - 265: 'strava', - 266: 'precor', # Amer Sports - 267: 'bryton', - 268: 'sram', - 269: 'navman', # MiTAC Global Corporation (Mio Technology) - 270: 'cobi', # COBI GmbH - 271: 'spivi', - 272: 'mio_magellan', - 273: 'evesports', - 274: 'sensitivus_gauge', - 275: 'podoon', - 276: 'life_time_fitness', - 277: 'falco_e_motors', # Falco eMotors Inc. - 5759: 'actigraphcorp', - }, - ), - 'mesg_count': FieldType( - name='mesg_count', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'num_per_file', - 1: 'max_per_file', - 2: 'max_per_file_type', - }, - ), - 'mesg_num': FieldType( - name='mesg_num', - base_type=BASE_TYPES[0x84], # 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', - 80: 'ant_rx', - 81: 'ant_tx', - 82: 'ant_channel_id', - 101: 'length', - 103: 'monitoring_info', - 105: 'pad', - 106: 'slave_device', - 127: 'connectivity', - 128: 'weather_conditions', - 129: 'weather_alert', - 131: 'cadence_zone', - 132: 'hr', - 142: 'segment_lap', - 145: 'memo_glob', - 148: 'segment_id', - 149: 'segment_leaderboard_entry', - 150: 'segment_point', - 151: 'segment_file', - 158: 'workout_session', - 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', - }, - ), - 'message_index': FieldType( - name='message_index', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 0x0FFF: 'mask', # index - 0x7000: 'reserved', # reserved (default 0) - 0x8000: 'selected', # message is selected if set - }, - ), - 'power_phase_type': FieldType( - name='power_phase_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'power_phase_start_angle', - 1: 'power_phase_end_angle', - 2: 'power_phase_arc_length', - 3: 'power_phase_center', - }, - ), - 'pwr_zone_calc': FieldType( - name='pwr_zone_calc', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'custom', - 1: 'percent_ftp', - }, - ), - 'rider_position_type': FieldType( - name='rider_position_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'seated', - 1: 'standing', - 2: 'transition_to_seated', - 3: 'transition_to_standing', - }, - ), - 'schedule': FieldType( - name='schedule', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'workout', - 1: 'course', - }, - ), - 'segment_delete_status': FieldType( - name='segment_delete_status', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'do_not_delete', - 1: 'delete_one', - 2: 'delete_all', - }, - ), - 'segment_lap_status': FieldType( - name='segment_lap_status', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'end', - 1: 'fail', - }, - ), - 'segment_leaderboard_type': FieldType( - name='segment_leaderboard_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'overall', - 1: 'personal_best', - 2: 'connections', - 3: 'group', - 4: 'challenger', - 5: 'kom', - 6: 'qom', - 7: 'pr', - 8: 'goal', - 9: 'rival', - 10: 'club_leader', - }, - ), - 'segment_selection_type': FieldType( - name='segment_selection_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'starred', - 1: 'suggested', - }, - ), - 'sensor_type': FieldType( - name='sensor_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'accelerometer', - 1: 'gyroscope', - 2: 'compass', # Magnetometer - }, - ), - 'session_trigger': FieldType( - name='session_trigger', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'activity_end', - 1: 'manual', # User changed sport. - 2: 'auto_multi_sport', # Auto multi-sport feature is enabled and user pressed lap button to advance session. - 3: 'fitness_equipment', # Auto sport change caused by user linking to fitness equipment. - }, - ), - 'side': FieldType( - name='side', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'right', - 1: 'left', - }, - ), - 'source_type': FieldType( - name='source_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'ant', # External device connected with ANT - 1: 'antplus', # External device connected with ANT+ - 2: 'bluetooth', # External device connected with BT - 3: 'bluetooth_low_energy', # External device connected with BLE - 4: 'wifi', # External device connected with Wifi - 5: 'local', # Onboard device - }, - ), - 'sport': FieldType( - name='sport', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'generic', - 1: 'running', - 2: 'cycling', - 3: 'transition', # Mulitsport 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', # All is for goals only to include all sports. - }, - ), - 'sport_bits_0': FieldType( # Bit field corresponding to sport enum type (1 << sport). - name='sport_bits_0', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'generic', - 0x02: 'running', - 0x04: 'cycling', - 0x08: 'transition', # Mulitsport transition - 0x10: 'fitness_equipment', - 0x20: 'swimming', - 0x40: 'basketball', - 0x80: 'soccer', - }, - ), - 'sport_bits_1': FieldType( # Bit field corresponding to sport enum type (1 << (sport-8)). - name='sport_bits_1', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'tennis', - 0x02: 'american_football', - 0x04: 'training', - 0x08: 'walking', - 0x10: 'cross_country_skiing', - 0x20: 'alpine_skiing', - 0x40: 'snowboarding', - 0x80: 'rowing', - }, - ), - 'sport_bits_2': FieldType( # Bit field corresponding to sport enum type (1 << (sport-16)). - name='sport_bits_2', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'mountaineering', - 0x02: 'hiking', - 0x04: 'multisport', - 0x08: 'paddling', - 0x10: 'flying', - 0x20: 'e_biking', - 0x40: 'motorcycling', - 0x80: 'boating', - }, - ), - 'sport_bits_3': FieldType( # Bit field corresponding to sport enum type (1 << (sport-24)). - name='sport_bits_3', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'driving', - 0x02: 'golf', - 0x04: 'hang_gliding', - 0x08: 'horseback_riding', - 0x10: 'hunting', - 0x20: 'fishing', - 0x40: 'inline_skating', - 0x80: 'rock_climbing', - }, - ), - 'sport_bits_4': FieldType( # Bit field corresponding to sport enum type (1 << (sport-32)). - name='sport_bits_4', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'sailing', - 0x02: 'ice_skating', - 0x04: 'sky_diving', - 0x08: 'snowshoeing', - 0x10: 'snowmobiling', - 0x20: 'stand_up_paddleboarding', - 0x40: 'surfing', - 0x80: 'wakeboarding', - }, - ), - 'sport_bits_5': FieldType( # Bit field corresponding to sport enum type (1 << (sport-40)). - name='sport_bits_5', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'water_skiing', - 0x02: 'kayaking', - 0x04: 'rafting', - 0x08: 'windsurfing', - 0x10: 'kitesurfing', - 0x20: 'tactical', - 0x40: 'jumpmaster', - 0x80: 'boxing', - }, - ), - 'sport_bits_6': FieldType( # Bit field corresponding to sport enum type (1 << (sport-48)). - name='sport_bits_6', - base_type=BASE_TYPES[0x0A], # uint8z - values={ - 0x01: 'floor_climbing', - }, - ), - 'sport_event': FieldType( - name='sport_event', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'uncategorized', - 1: 'geocaching', - 2: 'fitness', - 3: 'recreation', - 4: 'race', - 5: 'special_event', - 6: 'training', - 7: 'transportation', - 8: 'touring', - }, - ), - 'stroke_type': FieldType( - name='stroke_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'no_event', - 1: 'other', # stroke was detected but cannot be identified - 2: 'serve', - 3: 'forehand', - 4: 'backhand', - 5: 'smash', - }, - ), - 'sub_sport': FieldType( - name='sub_sport', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'generic', - 1: 'treadmill', # Run/Fitness Equipment - 2: 'street', # Run - 3: 'trail', # Run - 4: 'track', # Run - 5: 'spin', # Cycling - 6: 'indoor_cycling', # Cycling/Fitness Equipment - 7: 'road', # Cycling - 8: 'mountain', # Cycling - 9: 'downhill', # Cycling - 10: 'recumbent', # Cycling - 11: 'cyclocross', # Cycling - 12: 'hand_cycling', # Cycling - 13: 'track_cycling', # Cycling - 14: 'indoor_rowing', # Fitness Equipment - 15: 'elliptical', # Fitness Equipment - 16: 'stair_climbing', # Fitness Equipment - 17: 'lap_swimming', # Swimming - 18: 'open_water', # Swimming - 19: 'flexibility_training', # Training - 20: 'strength_training', # Training - 21: 'warm_up', # Tennis - 22: 'match', # Tennis - 23: 'exercise', # Tennis - 24: 'challenge', # Tennis - 25: 'indoor_skiing', # Fitness Equipment - 26: 'cardio_training', # Training - 27: 'indoor_walking', # Walking/Fitness Equipment - 28: 'e_bike_fitness', # E-Biking - 29: 'bmx', # Cycling - 30: 'casual_walking', # Walking - 31: 'speed_walking', # Walking - 32: 'bike_to_run_transition', # Transition - 33: 'run_to_bike_transition', # Transition - 34: 'swim_to_bike_transition', # Transition - 35: 'atv', # Motorcycling - 36: 'motocross', # Motorcycling - 37: 'backcountry', # Alpine Skiing/Snowboarding - 38: 'resort', # Alpine Skiing/Snowboarding - 39: 'rc_drone', # Flying - 40: 'wingsuit', # Flying - 41: 'whitewater', # Kayaking/Rafting - 42: 'skate_skiing', # Cross Country Skiing - 43: 'yoga', # Training - 44: 'pilates', # Training - 45: 'indoor_running', # Run - 46: 'gravel_cycling', # Cycling - 47: 'e_bike_mountain', # Cycling - 48: 'commuting', # Cycling - 49: 'mixed_surface', # Cycling - 50: 'navigate', - 51: 'track_me', - 52: 'map', - 254: 'all', - }, - ), - 'supported_exd_screen_layouts': FieldType( - name='supported_exd_screen_layouts', - base_type=BASE_TYPES[0x8C], # 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', - }, - ), - 'swim_stroke': FieldType( - name='swim_stroke', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'freestyle', - 1: 'backstroke', - 2: 'breaststroke', - 3: 'butterfly', - 4: 'drill', - 5: 'mixed', - 6: 'im', # IM is a mixed interval containing the same number of lengths for each of: Butterfly, Backstroke, Breaststroke, Freestyle, swam in that order. - }, - ), - 'switch': FieldType( - name='switch', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'off', - 1: 'on', - 2: 'auto', - }, - ), - 'time_into_day': FieldType( # number of seconds into the day since 00:00:00 UTC - name='time_into_day', - base_type=BASE_TYPES[0x86], # uint32 - ), - 'time_mode': FieldType( - name='time_mode', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'hour12', - 1: 'hour24', # Does not use a leading zero and has a colon - 2: 'military', # Uses a leading zero and does not have a colon - 3: 'hour_12_with_seconds', - 4: 'hour_24_with_seconds', - 5: 'utc', - }, - ), - 'time_zone': FieldType( - name='time_zone', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'timer_trigger': FieldType( # timer event data - name='timer_trigger', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'manual', - 1: 'auto', - 2: 'fitness_equipment', - }, - ), - 'turn_type': FieldType( - name='turn_type', - base_type=BASE_TYPES[0x00], # 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', - }, - ), - 'user_local_id': FieldType( - name='user_local_id', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 0x0000: 'local_min', - 0x000F: 'local_max', - 0x0010: 'stationary_min', - 0x00FF: 'stationary_max', - 0x0100: 'portable_min', - 0xFFFE: 'portable_max', - }, - ), - 'watchface_mode': FieldType( - name='watchface_mode', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'digital', - 1: 'analog', - 2: 'connect_iq', - 3: 'disabled', - }, - ), - 'weather_report': FieldType( - name='weather_report', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'current', - 1: 'forecast', # Deprecated use hourly_forecast instead - 1: 'hourly_forecast', - 2: 'daily_forecast', - }, - ), - 'weather_severe_type': FieldType( - name='weather_severe_type', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'unspecified', - 1: 'tornado', - 2: 'tsunami', - 3: 'hurricane', - 4: 'extreme_wind', - 5: 'typhoon', - 6: 'inland_hurricane', - 7: 'hurricane_force_wind', - 8: 'waterspout', - 9: 'severe_thunderstorm', - 10: 'wreckhouse_winds', - 11: 'les_suetes_wind', - 12: 'avalanche', - 13: 'flash_flood', - 14: 'tropical_storm', - 15: 'inland_tropical_storm', - 16: 'blizzard', - 17: 'ice_storm', - 18: 'freezing_rain', - 19: 'debris_flow', - 20: 'flash_freeze', - 21: 'dust_storm', - 22: 'high_wind', - 23: 'winter_storm', - 24: 'heavy_freezing_spray', - 25: 'extreme_cold', - 26: 'wind_chill', - 27: 'cold_wave', - 28: 'heavy_snow_alert', - 29: 'lake_effect_blowing_snow', - 30: 'snow_squall', - 31: 'lake_effect_snow', - 32: 'winter_weather', - 33: 'sleet', - 34: 'snowfall', - 35: 'snow_and_blowing_snow', - 36: 'blowing_snow', - 37: 'snow_alert', - 38: 'arctic_outflow', - 39: 'freezing_drizzle', - 40: 'storm', - 41: 'storm_surge', - 42: 'rainfall', - 43: 'areal_flood', - 44: 'coastal_flood', - 45: 'lakeshore_flood', - 46: 'excessive_heat', - 47: 'heat', - 48: 'weather', - 49: 'high_heat_and_humidity', - 50: 'humidex_and_health', - 51: 'humidex', - 52: 'gale', - 53: 'freezing_spray', - 54: 'special_marine', - 55: 'squall', - 56: 'strong_wind', - 57: 'lake_wind', - 58: 'marine_weather', - 59: 'wind', - 60: 'small_craft_hazardous_seas', - 61: 'hazardous_seas', - 62: 'small_craft', - 63: 'small_craft_winds', - 64: 'small_craft_rough_bar', - 65: 'high_water_level', - 66: 'ashfall', - 67: 'freezing_fog', - 68: 'dense_fog', - 69: 'dense_smoke', - 70: 'blowing_dust', - 71: 'hard_freeze', - 72: 'freeze', - 73: 'frost', - 74: 'fire_weather', - 75: 'flood', - 76: 'rip_tide', - 77: 'high_surf', - 78: 'smog', - 79: 'air_quality', - 80: 'brisk_wind', - 81: 'air_stagnation', - 82: 'low_water', - 83: 'hydrological', - 84: 'special_weather', - }, - ), - 'weather_severity': FieldType( - name='weather_severity', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'unknown', - 1: 'warning', - 2: 'watch', - 3: 'advisory', - 4: 'statement', - }, - ), - 'weather_status': FieldType( - name='weather_status', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'clear', - 1: 'partly_cloudy', - 2: 'mostly_cloudy', - 3: 'rain', - 4: 'snow', - 5: 'windy', - 6: 'thunderstorms', - 7: 'wintry_mix', - 8: 'fog', - 11: 'hazy', - 12: 'hail', - 13: 'scattered_showers', - 14: 'scattered_thunderstorms', - 15: 'unknown_precipitation', - 16: 'light_rain', - 17: 'heavy_rain', - 18: 'light_snow', - 19: 'heavy_snow', - 20: 'light_rain_snow', - 21: 'heavy_rain_snow', - 22: 'cloudy', - }, - ), - 'weight': FieldType( - name='weight', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 0xFFFE: 'calculating', - }, - ), - 'wkt_step_duration': FieldType( - name='wkt_step_duration', - base_type=BASE_TYPES[0x00], # 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', - 16: 'training_peaks_tss', - 17: 'repeat_until_power_last_lap_less_than', - 18: 'repeat_until_max_power_last_lap_less_than', - 19: 'power_3s_less_than', - 20: 'power_10s_less_than', - 21: 'power_30s_less_than', - 22: 'power_3s_greater_than', - 23: 'power_10s_greater_than', - 24: 'power_30s_greater_than', - 25: 'power_lap_less_than', - 26: 'power_lap_greater_than', - 27: 'repeat_until_training_peaks_tss', - 28: 'repetition_time', - }, - ), - 'wkt_step_target': FieldType( - name='wkt_step_target', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'speed', - 1: 'heart_rate', - 2: 'open', - 3: 'cadence', - 4: 'power', - 5: 'grade', - 6: 'resistance', - 7: 'power_3s', - 8: 'power_10s', - 9: 'power_30s', - 10: 'power_lap', - 11: 'swim_stroke', - 12: 'speed_lap', - 13: 'heart_rate_lap', - }, - ), - 'workout_capabilities': FieldType( - name='workout_capabilities', - base_type=BASE_TYPES[0x8C], # uint32z - values={ - 0x00000001: 'interval', - 0x00000002: 'custom', - 0x00000004: 'fitness_equipment', - 0x00000008: 'firstbeat', - 0x00000010: 'new_leaf', - 0x00000020: 'tcx', # For backwards compatibility. Watch should add missing id fields then clear flag. - 0x00000080: 'speed', # Speed source required for workout step. - 0x00000100: 'heart_rate', # Heart rate source required for workout step. - 0x00000200: 'distance', # Distance source required for workout step. - 0x00000400: 'cadence', # Cadence source required for workout step. - 0x00000800: 'power', # Power source required for workout step. - 0x00001000: 'grade', # Grade source required for workout step. - 0x00002000: 'resistance', # Resistance source required for workout step. - 0x00004000: 'protected', - }, - ), - 'workout_equipment': FieldType( - name='workout_equipment', - base_type=BASE_TYPES[0x00], # enum - values={ - 0: 'none', - 1: 'swim_fins', - 2: 'swim_kickboard', - 3: 'swim_paddles', - 4: 'swim_pull_buoy', - 5: 'swim_snorkel', - }, - ), - 'workout_hr': FieldType( # 0 - 100 indicates% of max hr; >100 indicates bpm (255 max) plus 100 - name='workout_hr', - base_type=BASE_TYPES[0x86], # uint32 - values={ - 100: 'bpm_offset', - }, - ), - 'workout_power': FieldType( # 0 - 1000 indicates % of functional threshold power; >1000 indicates watts plus 1000. - name='workout_power', - base_type=BASE_TYPES[0x86], # uint32 - values={ - 1000: 'watts_offset', - }, - ), -} - - -FIELD_TYPE_TIMESTAMP = Field(name='timestamp', type=FIELD_TYPES['date_time'], def_num=253, units='s') - - -MESSAGE_TYPES = { - ############################ Common Messages ############################# - 0: MessageType( # Must be first message in file. - name='file_id', - mesg_num=0, - fields={ - 0: Field( - name='type', - type=FIELD_TYPES['file'], - def_num=0, - ), - 1: Field( - name='manufacturer', - type=FIELD_TYPES['manufacturer'], - def_num=1, - ), - 2: Field( - name='product', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - subfields=( - SubField( - name='garmin_product', - def_num=2, - type=FIELD_TYPES['garmin_product'], - ref_fields=( - ReferenceField( - name='manufacturer', - def_num=1, - value='garmin', - raw_value=1, - ), - ReferenceField( - name='manufacturer', - def_num=1, - value='dynastream', - raw_value=15, - ), - ReferenceField( - name='manufacturer', - def_num=1, - value='dynastream_oem', - raw_value=13, - ), - ), - ), - ), - ), - 3: Field( - name='serial_number', - type=BASE_TYPES[0x8C], # uint32z - def_num=3, - ), - 4: Field( # Only set for files that are can be created/erased. - name='time_created', - type=FIELD_TYPES['date_time'], - def_num=4, - ), - 5: Field( # Only set for files that are not created/erased. - name='number', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - ), - 8: Field( # Optional free form string to indicate the devices name or model - name='product_name', - type=BASE_TYPES[0x07], # string - def_num=8, - ), - }, - ), - - - #################################### #################################### - 1: MessageType( - name='capabilities', - mesg_num=1, - fields={ - 0: Field( # Use language_bits_x types where x is index of array. - name='languages', - type=BASE_TYPES[0x0A], # uint8z - def_num=0, - ), - 1: Field( # Use sport_bits_x types where x is index of array. - name='sports', - type=FIELD_TYPES['sport_bits_0'], - def_num=1, - ), - 21: Field( - name='workouts_supported', - type=FIELD_TYPES['workout_capabilities'], - def_num=21, - ), - 23: Field( - name='connectivity_supported', - type=FIELD_TYPES['connectivity_capabilities'], - def_num=23, - ), - }, - ), - 3: MessageType( - name='user_profile', - mesg_num=3, - fields={ - 0: Field( - name='friendly_name', - type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( - name='gender', - type=FIELD_TYPES['gender'], - def_num=1, - ), - 2: Field( - name='age', - type=BASE_TYPES[0x02], # uint8 - def_num=2, - units='years', - ), - 3: Field( - name='height', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - scale=100, - units='m', - ), - 4: Field( - name='weight', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - scale=10, - units='kg', - ), - 5: Field( - name='language', - type=FIELD_TYPES['language'], - def_num=5, - ), - 6: Field( - name='elev_setting', - type=FIELD_TYPES['display_measure'], - def_num=6, - ), - 7: Field( - name='weight_setting', - type=FIELD_TYPES['display_measure'], - def_num=7, - ), - 8: Field( - name='resting_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=8, - units='bpm', - ), - 9: Field( - name='default_max_running_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=9, - units='bpm', - ), - 10: Field( - name='default_max_biking_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=10, - units='bpm', - ), - 11: Field( - name='default_max_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=11, - units='bpm', - ), - 12: Field( - name='hr_setting', - type=FIELD_TYPES['display_heart'], - def_num=12, - ), - 13: Field( - name='speed_setting', - type=FIELD_TYPES['display_measure'], - def_num=13, - ), - 14: Field( - name='dist_setting', - type=FIELD_TYPES['display_measure'], - def_num=14, - ), - 16: Field( - name='power_setting', - type=FIELD_TYPES['display_power'], - def_num=16, - ), - 17: Field( - name='activity_class', - type=FIELD_TYPES['activity_class'], - def_num=17, - ), - 18: Field( - name='position_setting', - type=FIELD_TYPES['display_position'], - def_num=18, - ), - 21: Field( - name='temperature_setting', - type=FIELD_TYPES['display_measure'], - def_num=21, - ), - 22: Field( - name='local_id', - type=FIELD_TYPES['user_local_id'], - def_num=22, - ), - 23: Field( - name='global_id', - type=BASE_TYPES[0x0D], # byte - def_num=23, - ), - 28: Field( # Typical wake time - name='wake_time', - type=FIELD_TYPES['localtime_into_day'], - def_num=28, - ), - 29: Field( # Typical bed time - name='sleep_time', - type=FIELD_TYPES['localtime_into_day'], - def_num=29, - ), - 30: Field( - name='height_setting', - type=FIELD_TYPES['display_measure'], - def_num=30, - ), - 31: Field( # User defined running step length set to 0 for auto length - name='user_running_step_length', - type=BASE_TYPES[0x84], # uint16 - def_num=31, - scale=1000, - units='m', - ), - 32: Field( # User defined walking step length set to 0 for auto length - name='user_walking_step_length', - type=BASE_TYPES[0x84], # uint16 - def_num=32, - scale=1000, - units='m', - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 4: MessageType( - name='hrm_profile', - mesg_num=4, - fields={ - 0: Field( - name='enabled', - type=FIELD_TYPES['bool'], - def_num=0, - ), - 1: Field( - name='hrm_ant_id', - type=BASE_TYPES[0x8B], # uint16z - def_num=1, - ), - 2: Field( - name='log_hrv', - type=FIELD_TYPES['bool'], - def_num=2, - ), - 3: Field( - name='hrm_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=3, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 5: MessageType( - name='sdm_profile', - mesg_num=5, - fields={ - 0: Field( - name='enabled', - type=FIELD_TYPES['bool'], - def_num=0, - ), - 1: Field( - name='sdm_ant_id', - type=BASE_TYPES[0x8B], # uint16z - def_num=1, - ), - 2: Field( - name='sdm_cal_factor', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - scale=10, - units='%', - ), - 3: Field( - name='odometer', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - scale=100, - units='m', - ), - 4: Field( # Use footpod for speed source instead of GPS - name='speed_source', - type=FIELD_TYPES['bool'], - def_num=4, - ), - 5: Field( - name='sdm_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=5, - ), - 7: Field( # Rollover counter that can be used to extend the odometer - name='odometer_rollover', - type=BASE_TYPES[0x02], # uint8 - def_num=7, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 6: MessageType( - name='bike_profile', - mesg_num=6, - fields={ - 0: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=1, - ), - 2: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=2, - ), - 3: Field( - name='odometer', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - scale=100, - units='m', - ), - 4: Field( - name='bike_spd_ant_id', - type=BASE_TYPES[0x8B], # uint16z - def_num=4, - ), - 5: Field( - name='bike_cad_ant_id', - type=BASE_TYPES[0x8B], # uint16z - def_num=5, - ), - 6: Field( - name='bike_spdcad_ant_id', - type=BASE_TYPES[0x8B], # uint16z - def_num=6, - ), - 7: Field( - name='bike_power_ant_id', - type=BASE_TYPES[0x8B], # uint16z - def_num=7, - ), - 8: Field( - name='custom_wheelsize', - type=BASE_TYPES[0x84], # uint16 - def_num=8, - scale=1000, - units='m', - ), - 9: Field( - name='auto_wheelsize', - type=BASE_TYPES[0x84], # uint16 - def_num=9, - scale=1000, - units='m', - ), - 10: Field( - name='bike_weight', - type=BASE_TYPES[0x84], # uint16 - def_num=10, - scale=10, - units='kg', - ), - 11: Field( - name='power_cal_factor', - type=BASE_TYPES[0x84], # uint16 - def_num=11, - scale=10, - units='%', - ), - 12: Field( - name='auto_wheel_cal', - type=FIELD_TYPES['bool'], - def_num=12, - ), - 13: Field( - name='auto_power_zero', - type=FIELD_TYPES['bool'], - def_num=13, - ), - 14: Field( - name='id', - type=BASE_TYPES[0x02], # uint8 - def_num=14, - ), - 15: Field( - name='spd_enabled', - type=FIELD_TYPES['bool'], - def_num=15, - ), - 16: Field( - name='cad_enabled', - type=FIELD_TYPES['bool'], - def_num=16, - ), - 17: Field( - name='spdcad_enabled', - type=FIELD_TYPES['bool'], - def_num=17, - ), - 18: Field( - name='power_enabled', - type=FIELD_TYPES['bool'], - def_num=18, - ), - 19: Field( - name='crank_length', - type=BASE_TYPES[0x02], # uint8 - def_num=19, - scale=2, - offset=-110, - units='mm', - ), - 20: Field( - name='enabled', - type=FIELD_TYPES['bool'], - def_num=20, - ), - 21: Field( - name='bike_spd_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=21, - ), - 22: Field( - name='bike_cad_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=22, - ), - 23: Field( - name='bike_spdcad_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=23, - ), - 24: Field( - name='bike_power_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=24, - ), - 37: Field( # Rollover counter that can be used to extend the odometer - name='odometer_rollover', - type=BASE_TYPES[0x02], # uint8 - def_num=37, - ), - 38: Field( # Number of front gears - name='front_gear_num', - type=BASE_TYPES[0x0A], # uint8z - def_num=38, - ), - 39: Field( # Number of teeth on each gear 0 is innermost - name='front_gear', - type=BASE_TYPES[0x0A], # uint8z - def_num=39, - ), - 40: Field( # Number of rear gears - name='rear_gear_num', - type=BASE_TYPES[0x0A], # uint8z - def_num=40, - ), - 41: Field( # Number of teeth on each gear 0 is innermost - name='rear_gear', - type=BASE_TYPES[0x0A], # uint8z - def_num=41, - ), - 44: Field( - name='shimano_di2_enabled', - type=FIELD_TYPES['bool'], - def_num=44, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 8: MessageType( - name='hr_zone', - mesg_num=8, - fields={ - 1: Field( - name='high_bpm', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - units='bpm', - ), - 2: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=2, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 9: MessageType( - name='power_zone', - mesg_num=9, - fields={ - 1: Field( - name='high_value', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - units='watts', - ), - 2: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=2, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 10: MessageType( - name='met_zone', - mesg_num=10, - fields={ - 1: Field( - name='high_bpm', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - ), - 2: Field( - name='calories', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - scale=10, - units='kcal/min', - ), - 3: Field( - name='fat_calories', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - scale=10, - units='kcal/min', - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 12: MessageType( - name='sport', - mesg_num=12, - fields={ - 0: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=0, - ), - 1: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=1, - ), - 3: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=3, - ), - }, - ), - 18: MessageType( - name='session', - mesg_num=18, - fields={ - 0: Field( # session - name='event', - type=FIELD_TYPES['event'], - def_num=0, - ), - 1: Field( # stop - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=1, - ), - 2: Field( - name='start_time', - type=FIELD_TYPES['date_time'], - def_num=2, - ), - 3: Field( - name='start_position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=3, - units='semicircles', - ), - 4: Field( - name='start_position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=4, - units='semicircles', - ), - 5: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=5, - ), - 6: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=6, - ), - 7: Field( # Time (includes pauses) - name='total_elapsed_time', - type=BASE_TYPES[0x86], # uint32 - def_num=7, - scale=1000, - units='s', - ), - 8: Field( # Timer Time (excludes pauses) - name='total_timer_time', - type=BASE_TYPES[0x86], # uint32 - def_num=8, - scale=1000, - units='s', - ), - 9: Field( - name='total_distance', - type=BASE_TYPES[0x86], # uint32 - def_num=9, - scale=100, - units='m', - ), - 10: Field( - name='total_cycles', - type=BASE_TYPES[0x86], # uint32 - def_num=10, - units='cycles', - subfields=( - SubField( - name='total_strides', - def_num=10, - type=BASE_TYPES[0x86], # uint32 - units='strides', - ref_fields=( - ReferenceField( - name='sport', - def_num=5, - value='running', - raw_value=1, - ), - ReferenceField( - name='sport', - def_num=5, - value='walking', - raw_value=11, - ), - ), - ), - ), - ), - 11: Field( - name='total_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=11, - units='kcal', - ), - 13: Field( # If New Leaf - name='total_fat_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=13, - units='kcal', - ), - 14: Field( # total_distance / total_timer_time - name='avg_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=14, - scale=1000, - units='m/s', - components=( - ComponentField( - name='enhanced_avg_speed', - def_num=124, - scale=1000, - units='m/s', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 15: Field( - name='max_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=15, - scale=1000, - units='m/s', - components=( - ComponentField( - name='enhanced_max_speed', - def_num=125, - scale=1000, - units='m/s', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 16: Field( # average heart rate (excludes pause time) - name='avg_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=16, - units='bpm', - ), - 17: Field( - name='max_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=17, - units='bpm', - ), - 18: Field( # total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time - name='avg_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=18, - units='rpm', - subfields=( - SubField( - name='avg_running_cadence', - def_num=18, - type=BASE_TYPES[0x02], # uint8 - units='strides/min', - ref_fields=( - ReferenceField( - name='sport', - def_num=5, - value='running', - raw_value=1, - ), - ), - ), - ), - ), - 19: Field( - name='max_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=19, - units='rpm', - subfields=( - SubField( - name='max_running_cadence', - def_num=19, - type=BASE_TYPES[0x02], # uint8 - units='strides/min', - ref_fields=( - ReferenceField( - name='sport', - def_num=5, - value='running', - raw_value=1, - ), - ), - ), - ), - ), - 20: Field( # total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time - name='avg_power', - type=BASE_TYPES[0x84], # uint16 - def_num=20, - units='watts', - ), - 21: Field( - name='max_power', - type=BASE_TYPES[0x84], # uint16 - def_num=21, - units='watts', - ), - 22: Field( - name='total_ascent', - type=BASE_TYPES[0x84], # uint16 - def_num=22, - units='m', - ), - 23: Field( - name='total_descent', - type=BASE_TYPES[0x84], # uint16 - def_num=23, - units='m', - ), - 24: Field( - name='total_training_effect', - type=BASE_TYPES[0x02], # uint8 - def_num=24, - scale=10, - ), - 25: Field( - name='first_lap_index', - type=BASE_TYPES[0x84], # uint16 - def_num=25, - ), - 26: Field( - name='num_laps', - type=BASE_TYPES[0x84], # uint16 - def_num=26, - ), - 27: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 - def_num=27, - ), - 28: Field( - name='trigger', - type=FIELD_TYPES['session_trigger'], - def_num=28, - ), - 29: Field( - name='nec_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=29, - units='semicircles', - ), - 30: Field( - name='nec_long', - type=BASE_TYPES[0x85], # sint32 - def_num=30, - units='semicircles', - ), - 31: Field( - name='swc_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=31, - units='semicircles', - ), - 32: Field( - name='swc_long', - type=BASE_TYPES[0x85], # sint32 - def_num=32, - units='semicircles', - ), - 34: Field( - name='normalized_power', - type=BASE_TYPES[0x84], # uint16 - def_num=34, - units='watts', - ), - 35: Field( - name='training_stress_score', - type=BASE_TYPES[0x84], # uint16 - def_num=35, - scale=10, - units='tss', - ), - 36: Field( - name='intensity_factor', - type=BASE_TYPES[0x84], # uint16 - def_num=36, - scale=1000, - units='if', - ), - 37: Field( - name='left_right_balance', - type=FIELD_TYPES['left_right_balance_100'], - def_num=37, - ), - 41: Field( - name='avg_stroke_count', - type=BASE_TYPES[0x86], # uint32 - def_num=41, - scale=10, - units='strokes/lap', - ), - 42: Field( - name='avg_stroke_distance', - type=BASE_TYPES[0x84], # uint16 - def_num=42, - scale=100, - units='m', - ), - 43: Field( - name='swim_stroke', - type=FIELD_TYPES['swim_stroke'], - def_num=43, - units='swim_stroke', - ), - 44: Field( - name='pool_length', - type=BASE_TYPES[0x84], # uint16 - def_num=44, - scale=100, - units='m', - ), - 45: Field( - name='threshold_power', - type=BASE_TYPES[0x84], # uint16 - def_num=45, - units='watts', - ), - 46: Field( - name='pool_length_unit', - type=FIELD_TYPES['display_measure'], - def_num=46, - ), - 47: Field( # # of active lengths of swim pool - name='num_active_lengths', - type=BASE_TYPES[0x84], # uint16 - def_num=47, - units='lengths', - ), - 48: Field( - name='total_work', - type=BASE_TYPES[0x86], # uint32 - def_num=48, - units='J', - ), - 49: Field( - name='avg_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=49, - scale=5, - offset=500, - units='m', - components=( - ComponentField( - name='enhanced_avg_altitude', - def_num=126, - scale=5, - offset=500, - units='m', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 50: Field( - name='max_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=50, - scale=5, - offset=500, - units='m', - components=( - ComponentField( - name='enhanced_max_altitude', - def_num=128, - scale=5, - offset=500, - units='m', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 51: Field( - name='gps_accuracy', - type=BASE_TYPES[0x02], # uint8 - def_num=51, - units='m', - ), - 52: Field( - name='avg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=52, - scale=100, - units='%', - ), - 53: Field( - name='avg_pos_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=53, - scale=100, - units='%', - ), - 54: Field( - name='avg_neg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=54, - scale=100, - units='%', - ), - 55: Field( - name='max_pos_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=55, - scale=100, - units='%', - ), - 56: Field( - name='max_neg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=56, - scale=100, - units='%', - ), - 57: Field( - name='avg_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=57, - units='C', - ), - 58: Field( - name='max_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=58, - units='C', - ), - 59: Field( - name='total_moving_time', - type=BASE_TYPES[0x86], # uint32 - def_num=59, - scale=1000, - units='s', - ), - 60: Field( - name='avg_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=60, - scale=1000, - units='m/s', - ), - 61: Field( - name='avg_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=61, - scale=1000, - units='m/s', - ), - 62: Field( - name='max_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=62, - scale=1000, - units='m/s', - ), - 63: Field( - name='max_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=63, - scale=1000, - units='m/s', - ), - 64: Field( - name='min_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=64, - units='bpm', - ), - 65: Field( - name='time_in_hr_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=65, - scale=1000, - units='s', - ), - 66: Field( - name='time_in_speed_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=66, - scale=1000, - units='s', - ), - 67: Field( - name='time_in_cadence_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=67, - scale=1000, - units='s', - ), - 68: Field( - name='time_in_power_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=68, - scale=1000, - units='s', - ), - 69: Field( - name='avg_lap_time', - type=BASE_TYPES[0x86], # uint32 - def_num=69, - scale=1000, - units='s', - ), - 70: Field( - name='best_lap_index', - type=BASE_TYPES[0x84], # uint16 - def_num=70, - ), - 71: Field( - name='min_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=71, - scale=5, - offset=500, - units='m', - components=( - ComponentField( - name='enhanced_min_altitude', - def_num=127, - scale=5, - offset=500, - units='m', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 82: Field( - name='player_score', - type=BASE_TYPES[0x84], # uint16 - def_num=82, - ), - 83: Field( - name='opponent_score', - type=BASE_TYPES[0x84], # uint16 - def_num=83, - ), - 84: Field( - name='opponent_name', - type=BASE_TYPES[0x07], # string - def_num=84, - ), - 85: Field( # stroke_type enum used as the index - name='stroke_count', - type=BASE_TYPES[0x84], # uint16 - def_num=85, - units='counts', - ), - 86: Field( # zone number used as the index - name='zone_count', - type=BASE_TYPES[0x84], # uint16 - def_num=86, - units='counts', - ), - 87: Field( - name='max_ball_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=87, - scale=100, - units='m/s', - ), - 88: Field( - name='avg_ball_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=88, - scale=100, - units='m/s', - ), - 89: Field( - name='avg_vertical_oscillation', - type=BASE_TYPES[0x84], # uint16 - def_num=89, - scale=10, - units='mm', - ), - 90: Field( - name='avg_stance_time_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=90, - scale=100, - units='percent', - ), - 91: Field( - name='avg_stance_time', - type=BASE_TYPES[0x84], # uint16 - def_num=91, - scale=10, - units='ms', - ), - 92: Field( # fractional part of the avg_cadence - name='avg_fractional_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=92, - scale=128, - units='rpm', - ), - 93: Field( # fractional part of the max_cadence - name='max_fractional_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=93, - scale=128, - units='rpm', - ), - 94: Field( # fractional part of the total_cycles - name='total_fractional_cycles', - type=BASE_TYPES[0x02], # uint8 - def_num=94, - scale=128, - units='cycles', - ), - 95: Field( # Avg saturated and unsaturated hemoglobin - name='avg_total_hemoglobin_conc', - type=BASE_TYPES[0x84], # uint16 - def_num=95, - scale=100, - units='g/dL', - ), - 96: Field( # Min saturated and unsaturated hemoglobin - name='min_total_hemoglobin_conc', - type=BASE_TYPES[0x84], # uint16 - def_num=96, - scale=100, - units='g/dL', - ), - 97: Field( # Max saturated and unsaturated hemoglobin - name='max_total_hemoglobin_conc', - type=BASE_TYPES[0x84], # uint16 - def_num=97, - scale=100, - units='g/dL', - ), - 98: Field( # Avg percentage of hemoglobin saturated with oxygen - name='avg_saturated_hemoglobin_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=98, - scale=10, - units='%', - ), - 99: Field( # Min percentage of hemoglobin saturated with oxygen - name='min_saturated_hemoglobin_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=99, - scale=10, - units='%', - ), - 100: Field( # Max percentage of hemoglobin saturated with oxygen - name='max_saturated_hemoglobin_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=100, - scale=10, - units='%', - ), - 101: Field( - name='avg_left_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=101, - scale=2, - units='percent', - ), - 102: Field( - name='avg_right_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=102, - scale=2, - units='percent', - ), - 103: Field( - name='avg_left_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=103, - scale=2, - units='percent', - ), - 104: Field( - name='avg_right_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=104, - scale=2, - units='percent', - ), - 105: Field( - name='avg_combined_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=105, - scale=2, - units='percent', - ), - 111: Field( - name='sport_index', - type=BASE_TYPES[0x02], # uint8 - def_num=111, - ), - 112: Field( # Total time spend in the standing position - name='time_standing', - type=BASE_TYPES[0x86], # uint32 - def_num=112, - scale=1000, - units='s', - ), - 113: Field( # Number of transitions to the standing state - name='stand_count', - type=BASE_TYPES[0x84], # uint16 - def_num=113, - ), - 114: Field( # Average platform center offset Left - name='avg_left_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=114, - units='mm', - ), - 115: Field( # Average platform center offset Right - name='avg_right_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=115, - units='mm', - ), - 116: Field( # Average left power phase angles. Indexes defined by power_phase_type. - name='avg_left_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=116, - scale=0.7111111, - units='degrees', - ), - 117: Field( # Average left power phase peak angles. Data value indexes defined by power_phase_type. - name='avg_left_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=117, - scale=0.7111111, - units='degrees', - ), - 118: Field( # Average right power phase angles. Data value indexes defined by power_phase_type. - name='avg_right_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=118, - scale=0.7111111, - units='degrees', - ), - 119: Field( # Average right power phase peak angles data value indexes defined by power_phase_type. - name='avg_right_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=119, - scale=0.7111111, - units='degrees', - ), - 120: Field( # Average power by position. Data value indexes defined by rider_position_type. - name='avg_power_position', - type=BASE_TYPES[0x84], # uint16 - def_num=120, - units='watts', - ), - 121: Field( # Maximum power by position. Data value indexes defined by rider_position_type. - name='max_power_position', - type=BASE_TYPES[0x84], # uint16 - def_num=121, - units='watts', - ), - 122: Field( # Average cadence by position. Data value indexes defined by rider_position_type. - name='avg_cadence_position', - type=BASE_TYPES[0x02], # uint8 - def_num=122, - units='rpm', - ), - 123: Field( # Maximum cadence by position. Data value indexes defined by rider_position_type. - name='max_cadence_position', - type=BASE_TYPES[0x02], # uint8 - def_num=123, - units='rpm', - ), - 124: Field( # total_distance / total_timer_time - name='enhanced_avg_speed', - type=BASE_TYPES[0x86], # uint32 - def_num=124, - scale=1000, - units='m/s', - ), - 125: Field( - name='enhanced_max_speed', - type=BASE_TYPES[0x86], # uint32 - def_num=125, - scale=1000, - units='m/s', - ), - 126: Field( - name='enhanced_avg_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=126, - scale=5, - offset=500, - units='m', - ), - 127: Field( - name='enhanced_min_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=127, - scale=5, - offset=500, - units='m', - ), - 128: Field( - name='enhanced_max_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=128, - scale=5, - offset=500, - units='m', - ), - 129: Field( # lev average motor power during session - name='avg_lev_motor_power', - type=BASE_TYPES[0x84], # uint16 - def_num=129, - units='watts', - ), - 130: Field( # lev maximum motor power during session - name='max_lev_motor_power', - type=BASE_TYPES[0x84], # uint16 - def_num=130, - units='watts', - ), - 131: Field( # lev battery consumption during session - name='lev_battery_consumption', - type=BASE_TYPES[0x02], # uint8 - def_num=131, - scale=2, - units='percent', - ), - 132: Field( - name='avg_vertical_ratio', - type=BASE_TYPES[0x84], # uint16 - def_num=132, - scale=100, - units='percent', - ), - 133: Field( - name='avg_stance_time_balance', - type=BASE_TYPES[0x84], # uint16 - def_num=133, - scale=100, - units='percent', - ), - 134: Field( - name='avg_step_length', - type=BASE_TYPES[0x84], # uint16 - def_num=134, - scale=10, - units='mm', - ), - 137: Field( - name='total_anaerobic_training_effect', - type=BASE_TYPES[0x02], # uint8 - def_num=137, - scale=10, - ), - 139: Field( - name='avg_vam', - type=BASE_TYPES[0x84], # uint16 - def_num=139, - scale=1000, - units='m/s', - ), - 253: FIELD_TYPE_TIMESTAMP, # Sesson end time. - 254: Field( # Selected bit is set for the current session. - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 19: MessageType( - name='lap', - mesg_num=19, - fields={ - 0: Field( - name='event', - type=FIELD_TYPES['event'], - def_num=0, - ), - 1: Field( - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=1, - ), - 2: Field( - name='start_time', - type=FIELD_TYPES['date_time'], - def_num=2, - ), - 3: Field( - name='start_position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=3, - units='semicircles', - ), - 4: Field( - name='start_position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=4, - units='semicircles', - ), - 5: Field( - name='end_position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=5, - units='semicircles', - ), - 6: Field( - name='end_position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=6, - units='semicircles', - ), - 7: Field( # Time (includes pauses) - name='total_elapsed_time', - type=BASE_TYPES[0x86], # uint32 - def_num=7, - scale=1000, - units='s', - ), - 8: Field( # Timer Time (excludes pauses) - name='total_timer_time', - type=BASE_TYPES[0x86], # uint32 - def_num=8, - scale=1000, - units='s', - ), - 9: Field( - name='total_distance', - type=BASE_TYPES[0x86], # uint32 - def_num=9, - scale=100, - units='m', - ), - 10: Field( - name='total_cycles', - type=BASE_TYPES[0x86], # uint32 - def_num=10, - units='cycles', - subfields=( - SubField( - name='total_strides', - def_num=10, - type=BASE_TYPES[0x86], # uint32 - units='strides', - ref_fields=( - ReferenceField( - name='sport', - def_num=25, - value='running', - raw_value=1, - ), - ReferenceField( - name='sport', - def_num=25, - value='walking', - raw_value=11, - ), - ), - ), - ), - ), - 11: Field( - name='total_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=11, - units='kcal', - ), - 12: Field( # If New Leaf - name='total_fat_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=12, - units='kcal', - ), - 13: Field( - name='avg_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=13, - scale=1000, - units='m/s', - components=( - ComponentField( - name='enhanced_avg_speed', - def_num=110, - scale=1000, - units='m/s', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 14: Field( - name='max_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=14, - scale=1000, - units='m/s', - components=( - ComponentField( - name='enhanced_max_speed', - def_num=111, - scale=1000, - units='m/s', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 15: Field( - name='avg_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=15, - units='bpm', - ), - 16: Field( - name='max_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=16, - units='bpm', - ), - 17: Field( # total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time - name='avg_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=17, - units='rpm', - subfields=( - SubField( - name='avg_running_cadence', - def_num=17, - type=BASE_TYPES[0x02], # uint8 - units='strides/min', - ref_fields=( - ReferenceField( - name='sport', - def_num=25, - value='running', - raw_value=1, - ), - ), - ), - ), - ), - 18: Field( - name='max_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=18, - units='rpm', - subfields=( - SubField( - name='max_running_cadence', - def_num=18, - type=BASE_TYPES[0x02], # uint8 - units='strides/min', - ref_fields=( - ReferenceField( - name='sport', - def_num=25, - value='running', - raw_value=1, - ), - ), - ), - ), - ), - 19: Field( # total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time - name='avg_power', - type=BASE_TYPES[0x84], # uint16 - def_num=19, - units='watts', - ), - 20: Field( - name='max_power', - type=BASE_TYPES[0x84], # uint16 - def_num=20, - units='watts', - ), - 21: Field( - name='total_ascent', - type=BASE_TYPES[0x84], # uint16 - def_num=21, - units='m', - ), - 22: Field( - name='total_descent', - type=BASE_TYPES[0x84], # uint16 - def_num=22, - units='m', - ), - 23: Field( - name='intensity', - type=FIELD_TYPES['intensity'], - def_num=23, - ), - 24: Field( - name='lap_trigger', - type=FIELD_TYPES['lap_trigger'], - def_num=24, - ), - 25: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=25, - ), - 26: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 - def_num=26, - ), - 32: Field( # # of lengths of swim pool - name='num_lengths', - type=BASE_TYPES[0x84], # uint16 - def_num=32, - units='lengths', - ), - 33: Field( - name='normalized_power', - type=BASE_TYPES[0x84], # uint16 - def_num=33, - units='watts', - ), - 34: Field( - name='left_right_balance', - type=FIELD_TYPES['left_right_balance_100'], - def_num=34, - ), - 35: Field( - name='first_length_index', - type=BASE_TYPES[0x84], # uint16 - def_num=35, - ), - 37: Field( - name='avg_stroke_distance', - type=BASE_TYPES[0x84], # uint16 - def_num=37, - scale=100, - units='m', - ), - 38: Field( - name='swim_stroke', - type=FIELD_TYPES['swim_stroke'], - def_num=38, - ), - 39: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=39, - ), - 40: Field( # # of active lengths of swim pool - name='num_active_lengths', - type=BASE_TYPES[0x84], # uint16 - def_num=40, - units='lengths', - ), - 41: Field( - name='total_work', - type=BASE_TYPES[0x86], # uint32 - def_num=41, - units='J', - ), - 42: Field( - name='avg_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=42, - scale=5, - offset=500, - units='m', - components=( - ComponentField( - name='enhanced_avg_altitude', - def_num=112, - scale=5, - offset=500, - units='m', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 43: Field( - name='max_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=43, - scale=5, - offset=500, - units='m', - components=( - ComponentField( - name='enhanced_max_altitude', - def_num=114, - scale=5, - offset=500, - units='m', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 44: Field( - name='gps_accuracy', - type=BASE_TYPES[0x02], # uint8 - def_num=44, - units='m', - ), - 45: Field( - name='avg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=45, - scale=100, - units='%', - ), - 46: Field( - name='avg_pos_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=46, - scale=100, - units='%', - ), - 47: Field( - name='avg_neg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=47, - scale=100, - units='%', - ), - 48: Field( - name='max_pos_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=48, - scale=100, - units='%', - ), - 49: Field( - name='max_neg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=49, - scale=100, - units='%', - ), - 50: Field( - name='avg_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=50, - units='C', - ), - 51: Field( - name='max_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=51, - units='C', - ), - 52: Field( - name='total_moving_time', - type=BASE_TYPES[0x86], # uint32 - def_num=52, - scale=1000, - units='s', - ), - 53: Field( - name='avg_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=53, - scale=1000, - units='m/s', - ), - 54: Field( - name='avg_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=54, - scale=1000, - units='m/s', - ), - 55: Field( - name='max_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=55, - scale=1000, - units='m/s', - ), - 56: Field( - name='max_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=56, - scale=1000, - units='m/s', - ), - 57: Field( - name='time_in_hr_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=57, - scale=1000, - units='s', - ), - 58: Field( - name='time_in_speed_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=58, - scale=1000, - units='s', - ), - 59: Field( - name='time_in_cadence_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=59, - scale=1000, - units='s', - ), - 60: Field( - name='time_in_power_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=60, - scale=1000, - units='s', - ), - 61: Field( - name='repetition_num', - type=BASE_TYPES[0x84], # uint16 - def_num=61, - ), - 62: Field( - name='min_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=62, - scale=5, - offset=500, - units='m', - components=( - ComponentField( - name='enhanced_min_altitude', - def_num=113, - scale=5, - offset=500, - units='m', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 63: Field( - name='min_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=63, - units='bpm', - ), - 71: Field( - name='wkt_step_index', - type=FIELD_TYPES['message_index'], - def_num=71, - ), - 74: Field( - name='opponent_score', - type=BASE_TYPES[0x84], # uint16 - def_num=74, - ), - 75: Field( # stroke_type enum used as the index - name='stroke_count', - type=BASE_TYPES[0x84], # uint16 - def_num=75, - units='counts', - ), - 76: Field( # zone number used as the index - name='zone_count', - type=BASE_TYPES[0x84], # uint16 - def_num=76, - units='counts', - ), - 77: Field( - name='avg_vertical_oscillation', - type=BASE_TYPES[0x84], # uint16 - def_num=77, - scale=10, - units='mm', - ), - 78: Field( - name='avg_stance_time_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=78, - scale=100, - units='percent', - ), - 79: Field( - name='avg_stance_time', - type=BASE_TYPES[0x84], # uint16 - def_num=79, - scale=10, - units='ms', - ), - 80: Field( # fractional part of the avg_cadence - name='avg_fractional_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=80, - scale=128, - units='rpm', - ), - 81: Field( # fractional part of the max_cadence - name='max_fractional_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=81, - scale=128, - units='rpm', - ), - 82: Field( # fractional part of the total_cycles - name='total_fractional_cycles', - type=BASE_TYPES[0x02], # uint8 - def_num=82, - scale=128, - units='cycles', - ), - 83: Field( - name='player_score', - type=BASE_TYPES[0x84], # uint16 - def_num=83, - ), - 84: Field( # Avg saturated and unsaturated hemoglobin - name='avg_total_hemoglobin_conc', - type=BASE_TYPES[0x84], # uint16 - def_num=84, - scale=100, - units='g/dL', - ), - 85: Field( # Min saturated and unsaturated hemoglobin - name='min_total_hemoglobin_conc', - type=BASE_TYPES[0x84], # uint16 - def_num=85, - scale=100, - units='g/dL', - ), - 86: Field( # Max saturated and unsaturated hemoglobin - name='max_total_hemoglobin_conc', - type=BASE_TYPES[0x84], # uint16 - def_num=86, - scale=100, - units='g/dL', - ), - 87: Field( # Avg percentage of hemoglobin saturated with oxygen - name='avg_saturated_hemoglobin_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=87, - scale=10, - units='%', - ), - 88: Field( # Min percentage of hemoglobin saturated with oxygen - name='min_saturated_hemoglobin_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=88, - scale=10, - units='%', - ), - 89: Field( # Max percentage of hemoglobin saturated with oxygen - name='max_saturated_hemoglobin_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=89, - scale=10, - units='%', - ), - 91: Field( - name='avg_left_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=91, - scale=2, - units='percent', - ), - 92: Field( - name='avg_right_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=92, - scale=2, - units='percent', - ), - 93: Field( - name='avg_left_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=93, - scale=2, - units='percent', - ), - 94: Field( - name='avg_right_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=94, - scale=2, - units='percent', - ), - 95: Field( - name='avg_combined_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=95, - scale=2, - units='percent', - ), - 98: Field( # Total time spent in the standing position - name='time_standing', - type=BASE_TYPES[0x86], # uint32 - def_num=98, - scale=1000, - units='s', - ), - 99: Field( # Number of transitions to the standing state - name='stand_count', - type=BASE_TYPES[0x84], # uint16 - def_num=99, - ), - 100: Field( # Average left platform center offset - name='avg_left_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=100, - units='mm', - ), - 101: Field( # Average right platform center offset - name='avg_right_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=101, - units='mm', - ), - 102: Field( # Average left power phase angles. Data value indexes defined by power_phase_type. - name='avg_left_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=102, - scale=0.7111111, - units='degrees', - ), - 103: Field( # Average left power phase peak angles. Data value indexes defined by power_phase_type. - name='avg_left_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=103, - scale=0.7111111, - units='degrees', - ), - 104: Field( # Average right power phase angles. Data value indexes defined by power_phase_type. - name='avg_right_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=104, - scale=0.7111111, - units='degrees', - ), - 105: Field( # Average right power phase peak angles. Data value indexes defined by power_phase_type. - name='avg_right_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=105, - scale=0.7111111, - units='degrees', - ), - 106: Field( # Average power by position. Data value indexes defined by rider_position_type. - name='avg_power_position', - type=BASE_TYPES[0x84], # uint16 - def_num=106, - units='watts', - ), - 107: Field( # Maximum power by position. Data value indexes defined by rider_position_type. - name='max_power_position', - type=BASE_TYPES[0x84], # uint16 - def_num=107, - units='watts', - ), - 108: Field( # Average cadence by position. Data value indexes defined by rider_position_type. - name='avg_cadence_position', - type=BASE_TYPES[0x02], # uint8 - def_num=108, - units='rpm', - ), - 109: Field( # Maximum cadence by position. Data value indexes defined by rider_position_type. - name='max_cadence_position', - type=BASE_TYPES[0x02], # uint8 - def_num=109, - units='rpm', - ), - 110: Field( - name='enhanced_avg_speed', - type=BASE_TYPES[0x86], # uint32 - def_num=110, - scale=1000, - units='m/s', - ), - 111: Field( - name='enhanced_max_speed', - type=BASE_TYPES[0x86], # uint32 - def_num=111, - scale=1000, - units='m/s', - ), - 112: Field( - name='enhanced_avg_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=112, - scale=5, - offset=500, - units='m', - ), - 113: Field( - name='enhanced_min_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=113, - scale=5, - offset=500, - units='m', - ), - 114: Field( - name='enhanced_max_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=114, - scale=5, - offset=500, - units='m', - ), - 115: Field( # lev average motor power during lap - name='avg_lev_motor_power', - type=BASE_TYPES[0x84], # uint16 - def_num=115, - units='watts', - ), - 116: Field( # lev maximum motor power during lap - name='max_lev_motor_power', - type=BASE_TYPES[0x84], # uint16 - def_num=116, - units='watts', - ), - 117: Field( # lev battery consumption during lap - name='lev_battery_consumption', - type=BASE_TYPES[0x02], # uint8 - def_num=117, - scale=2, - units='percent', - ), - 118: Field( - name='avg_vertical_ratio', - type=BASE_TYPES[0x84], # uint16 - def_num=118, - scale=100, - units='percent', - ), - 119: Field( - name='avg_stance_time_balance', - type=BASE_TYPES[0x84], # uint16 - def_num=119, - scale=100, - units='percent', - ), - 120: Field( - name='avg_step_length', - type=BASE_TYPES[0x84], # uint16 - def_num=120, - scale=10, - units='mm', - ), - 121: Field( - name='avg_vam', - type=BASE_TYPES[0x84], # uint16 - def_num=121, - scale=1000, - units='m/s', - ), - 253: FIELD_TYPE_TIMESTAMP, # Lap end time. - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 20: MessageType( - name='record', - mesg_num=20, - fields={ - 0: Field( - name='position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=0, - units='semicircles', - ), - 1: Field( - name='position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=1, - units='semicircles', - ), - 2: Field( - name='altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - scale=5, - offset=500, - units='m', - components=( - ComponentField( - name='enhanced_altitude', - def_num=78, - scale=5, - offset=500, - units='m', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 3: Field( - name='heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - units='bpm', - ), - 4: Field( - name='cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=4, - units='rpm', - ), - 5: Field( - name='distance', - type=BASE_TYPES[0x86], # uint32 - def_num=5, - scale=100, - units='m', - ), - 6: Field( - name='speed', - type=BASE_TYPES[0x84], # uint16 - def_num=6, - scale=1000, - units='m/s', - components=( - ComponentField( - name='enhanced_speed', - def_num=73, - scale=1000, - units='m/s', - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 7: Field( - name='power', - type=BASE_TYPES[0x84], # uint16 - def_num=7, - units='watts', - ), - 8: Field( - name='compressed_speed_distance', - type=BASE_TYPES[0x0D], # byte - def_num=8, - components=( - ComponentField( - name='speed', - def_num=6, - scale=100, - units='m/s', - accumulate=False, - bits=12, - bit_offset=0, - ), - ComponentField( - name='distance', - def_num=5, - scale=16, - units='m', - accumulate=True, - bits=12, - bit_offset=12, - ), - ), - ), - 9: Field( - name='grade', - type=BASE_TYPES[0x83], # sint16 - def_num=9, - scale=100, - units='%', - ), - 10: Field( # Relative. 0 is none 254 is Max. - name='resistance', - type=BASE_TYPES[0x02], # uint8 - def_num=10, - ), - 11: Field( - name='time_from_course', - type=BASE_TYPES[0x85], # sint32 - def_num=11, - scale=1000, - units='s', - ), - 12: Field( - name='cycle_length', - type=BASE_TYPES[0x02], # uint8 - def_num=12, - scale=100, - units='m', - ), - 13: Field( - name='temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=13, - units='C', - ), - 17: Field( # Speed at 1s intervals. Timestamp field indicates time of last array element. - name='speed_1s', - type=BASE_TYPES[0x02], # uint8 - def_num=17, - scale=16, - units='m/s', - ), - 18: Field( - name='cycles', - type=BASE_TYPES[0x02], # uint8 - def_num=18, - components=( - ComponentField( - name='total_cycles', - def_num=19, - units='cycles', - accumulate=True, - bits=8, - bit_offset=0, - ), - ), - ), - 19: Field( - name='total_cycles', - type=BASE_TYPES[0x86], # uint32 - def_num=19, - units='cycles', - ), - 28: Field( - name='compressed_accumulated_power', - type=BASE_TYPES[0x84], # uint16 - def_num=28, - components=( - ComponentField( - name='accumulated_power', - def_num=29, - units='watts', - accumulate=True, - bits=16, - bit_offset=0, - ), - ), - ), - 29: Field( - name='accumulated_power', - type=BASE_TYPES[0x86], # uint32 - def_num=29, - units='watts', - ), - 30: Field( - name='left_right_balance', - type=FIELD_TYPES['left_right_balance'], - def_num=30, - ), - 31: Field( - name='gps_accuracy', - type=BASE_TYPES[0x02], # uint8 - def_num=31, - units='m', - ), - 32: Field( - name='vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=32, - scale=1000, - units='m/s', - ), - 33: Field( - name='calories', - type=BASE_TYPES[0x84], # uint16 - def_num=33, - units='kcal', - ), - 39: Field( - name='vertical_oscillation', - type=BASE_TYPES[0x84], # uint16 - def_num=39, - scale=10, - units='mm', - ), - 40: Field( - name='stance_time_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=40, - scale=100, - units='percent', - ), - 41: Field( - name='stance_time', - type=BASE_TYPES[0x84], # uint16 - def_num=41, - scale=10, - units='ms', - ), - 42: Field( - name='activity_type', - type=FIELD_TYPES['activity_type'], - def_num=42, - ), - 43: Field( - name='left_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=43, - scale=2, - units='percent', - ), - 44: Field( - name='right_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=44, - scale=2, - units='percent', - ), - 45: Field( - name='left_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=45, - scale=2, - units='percent', - ), - 46: Field( - name='right_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=46, - scale=2, - units='percent', - ), - 47: Field( - name='combined_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=47, - scale=2, - units='percent', - ), - 48: Field( - name='time128', - type=BASE_TYPES[0x02], # uint8 - def_num=48, - scale=128, - units='s', - ), - 49: Field( - name='stroke_type', - type=FIELD_TYPES['stroke_type'], - def_num=49, - ), - 50: Field( - name='zone', - type=BASE_TYPES[0x02], # uint8 - def_num=50, - ), - 51: Field( - name='ball_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=51, - scale=100, - units='m/s', - ), - 52: Field( # Log cadence and fractional cadence for backwards compatability - name='cadence256', - type=BASE_TYPES[0x84], # uint16 - def_num=52, - scale=256, - units='rpm', - ), - 53: Field( - name='fractional_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=53, - scale=128, - units='rpm', - ), - 54: Field( # Total saturated and unsaturated hemoglobin - name='total_hemoglobin_conc', - type=BASE_TYPES[0x84], # uint16 - def_num=54, - scale=100, - units='g/dL', - ), - 55: Field( # Min saturated and unsaturated hemoglobin - name='total_hemoglobin_conc_min', - type=BASE_TYPES[0x84], # uint16 - def_num=55, - scale=100, - units='g/dL', - ), - 56: Field( # Max saturated and unsaturated hemoglobin - name='total_hemoglobin_conc_max', - type=BASE_TYPES[0x84], # uint16 - def_num=56, - scale=100, - units='g/dL', - ), - 57: Field( # Percentage of hemoglobin saturated with oxygen - name='saturated_hemoglobin_percent', - type=BASE_TYPES[0x84], # uint16 - def_num=57, - scale=10, - units='%', - ), - 58: Field( # Min percentage of hemoglobin saturated with oxygen - name='saturated_hemoglobin_percent_min', - type=BASE_TYPES[0x84], # uint16 - def_num=58, - scale=10, - units='%', - ), - 59: Field( # Max percentage of hemoglobin saturated with oxygen - name='saturated_hemoglobin_percent_max', - type=BASE_TYPES[0x84], # uint16 - def_num=59, - scale=10, - units='%', - ), - 62: Field( - name='device_index', - type=FIELD_TYPES['device_index'], - def_num=62, - ), - 67: Field( # Left platform center offset - name='left_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=67, - units='mm', - ), - 68: Field( # Right platform center offset - name='right_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=68, - units='mm', - ), - 69: Field( # Left power phase angles. Data value indexes defined by power_phase_type. - name='left_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=69, - scale=0.7111111, - units='degrees', - ), - 70: Field( # Left power phase peak angles. Data value indexes defined by power_phase_type. - name='left_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=70, - scale=0.7111111, - units='degrees', - ), - 71: Field( # Right power phase angles. Data value indexes defined by power_phase_type. - name='right_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=71, - scale=0.7111111, - units='degrees', - ), - 72: Field( # Right power phase peak angles. Data value indexes defined by power_phase_type. - name='right_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=72, - scale=0.7111111, - units='degrees', - ), - 73: Field( - name='enhanced_speed', - type=BASE_TYPES[0x86], # uint32 - def_num=73, - scale=1000, - units='m/s', - ), - 78: Field( - name='enhanced_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=78, - scale=5, - offset=500, - units='m', - ), - 81: Field( # lev battery state of charge - name='battery_soc', - type=BASE_TYPES[0x02], # uint8 - def_num=81, - scale=2, - units='percent', - ), - 82: Field( # lev motor power - name='motor_power', - type=BASE_TYPES[0x84], # uint16 - def_num=82, - units='watts', - ), - 83: Field( - name='vertical_ratio', - type=BASE_TYPES[0x84], # uint16 - def_num=83, - scale=100, - units='percent', - ), - 84: Field( - name='stance_time_balance', - type=BASE_TYPES[0x84], # uint16 - def_num=84, - scale=100, - units='percent', - ), - 85: Field( - name='step_length', - type=BASE_TYPES[0x84], # uint16 - def_num=85, - scale=10, - units='mm', - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 21: MessageType( - name='event', - mesg_num=21, - fields={ - 0: Field( - name='event', - type=FIELD_TYPES['event'], - def_num=0, - ), - 1: Field( - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=1, - ), - 2: Field( - name='data16', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - components=( - ComponentField( - name='data', - def_num=3, - accumulate=False, - bits=16, - bit_offset=0, - ), - ), - ), - 3: Field( - name='data', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - subfields=( - SubField( - name='battery_level', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - scale=1000, - units='V', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='battery', - raw_value=11, - ), - ), - ), - SubField( - name='cad_high_alert', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - units='rpm', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='cad_high_alert', - raw_value=17, - ), - ), - ), - SubField( - name='cad_low_alert', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - units='rpm', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='cad_low_alert', - raw_value=18, - ), - ), - ), - SubField( - name='calorie_duration_alert', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - units='calories', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='calorie_duration_alert', - raw_value=25, - ), - ), - ), - SubField( - name='comm_timeout', - def_num=3, - type=FIELD_TYPES['comm_timeout_type'], - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='comm_timeout', - raw_value=47, - ), - ), - ), - SubField( - name='course_point_index', - def_num=3, - type=FIELD_TYPES['message_index'], - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='course_point', - raw_value=10, - ), - ), - ), - SubField( - name='distance_duration_alert', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - scale=100, - units='m', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='distance_duration_alert', - raw_value=24, - ), - ), - ), - SubField( - name='fitness_equipment_state', - def_num=3, - type=FIELD_TYPES['fitness_equipment_state'], - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='fitness_equipment', - raw_value=27, - ), - ), - ), - SubField( - name='gear_change_data', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='front_gear_change', - raw_value=42, - ), - ReferenceField( - name='event', - def_num=0, - value='rear_gear_change', - raw_value=43, - ), - ), - components=( - ComponentField( - name='rear_gear_num', - def_num=11, - accumulate=False, - bits=8, - bit_offset=0, - ), - ComponentField( - name='rear_gear', - def_num=12, - accumulate=False, - bits=8, - bit_offset=8, - ), - ComponentField( - name='front_gear_num', - def_num=9, - accumulate=False, - bits=8, - bit_offset=16, - ), - ComponentField( - name='front_gear', - def_num=10, - accumulate=False, - bits=8, - bit_offset=24, - ), - ), - ), - SubField( - name='hr_high_alert', - def_num=3, - type=BASE_TYPES[0x02], # uint8 - units='bpm', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='hr_high_alert', - raw_value=13, - ), - ), - ), - SubField( - name='hr_low_alert', - def_num=3, - type=BASE_TYPES[0x02], # uint8 - units='bpm', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='hr_low_alert', - raw_value=14, - ), - ), - ), - SubField( - name='power_high_alert', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - units='watts', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='power_high_alert', - raw_value=19, - ), - ), - ), - SubField( - name='power_low_alert', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - units='watts', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='power_low_alert', - raw_value=20, - ), - ), - ), - SubField( # Indicates the rider position value. - name='rider_position', - def_num=3, - type=FIELD_TYPES['rider_position_type'], - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='rider_position_change', - raw_value=44, - ), - ), - ), - SubField( - name='speed_high_alert', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - scale=1000, - units='m/s', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='speed_high_alert', - raw_value=15, - ), - ), - ), - SubField( - name='speed_low_alert', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - scale=1000, - units='m/s', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='speed_low_alert', - raw_value=16, - ), - ), - ), - SubField( - name='sport_point', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='sport_point', - raw_value=33, - ), - ), - components=( - ComponentField( - name='score', - def_num=7, - accumulate=False, - bits=16, - bit_offset=0, - ), - ComponentField( - name='opponent_score', - def_num=8, - accumulate=False, - bits=16, - bit_offset=16, - ), - ), - ), - SubField( - name='time_duration_alert', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - scale=1000, - units='s', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='time_duration_alert', - raw_value=23, - ), - ), - ), - SubField( - name='timer_trigger', - def_num=3, - type=FIELD_TYPES['timer_trigger'], - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='timer', - raw_value=0, - ), - ), - ), - SubField( - name='virtual_partner_speed', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - scale=1000, - units='m/s', - ref_fields=( - ReferenceField( - name='event', - def_num=0, - value='virtual_partner_pace', - raw_value=12, - ), - ), - ), - ), - ), - 4: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 - def_num=4, - ), - 7: Field( # Do not populate directly. Autogenerated by decoder for sport_point subfield components - name='score', - type=BASE_TYPES[0x84], # uint16 - def_num=7, - ), - 8: Field( # Do not populate directly. Autogenerated by decoder for sport_point subfield components - name='opponent_score', - type=BASE_TYPES[0x84], # uint16 - def_num=8, - ), - 9: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Front gear number. 1 is innermost. - name='front_gear_num', - type=BASE_TYPES[0x0A], # uint8z - def_num=9, - ), - 10: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Number of front teeth. - name='front_gear', - type=BASE_TYPES[0x0A], # uint8z - def_num=10, - ), - 11: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Rear gear number. 1 is innermost. - name='rear_gear_num', - type=BASE_TYPES[0x0A], # uint8z - def_num=11, - ), - 12: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Number of rear teeth. - name='rear_gear', - type=BASE_TYPES[0x0A], # uint8z - def_num=12, - ), - 13: Field( - name='device_index', - type=FIELD_TYPES['device_index'], - def_num=13, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 23: MessageType( - name='device_info', - mesg_num=23, - fields={ - 0: Field( - name='device_index', - type=FIELD_TYPES['device_index'], - def_num=0, - ), - 1: Field( - name='device_type', - type=FIELD_TYPES['antplus_device_type'], # uint8 - def_num=1, - subfields=( - SubField( - name='ant_device_type', - def_num=1, - type=BASE_TYPES[0x02], # uint8 - ref_fields=( - ReferenceField( - name='source_type', - def_num=25, - value='ant', - raw_value=0, - ), - ), - ), - SubField( - name='antplus_device_type', - def_num=1, - type=FIELD_TYPES['antplus_device_type'], - ref_fields=( - ReferenceField( - name='source_type', - def_num=25, - value='antplus', - raw_value=1, - ), - ), - ), - ), - ), - 2: Field( - name='manufacturer', - type=FIELD_TYPES['manufacturer'], - def_num=2, - ), - 3: Field( - name='serial_number', - type=BASE_TYPES[0x8C], # uint32z - def_num=3, - ), - 4: Field( - name='product', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - subfields=( - SubField( - name='garmin_product', - def_num=4, - type=FIELD_TYPES['garmin_product'], - ref_fields=( - ReferenceField( - name='manufacturer', - def_num=2, - value='garmin', - raw_value=1, - ), - ReferenceField( - name='manufacturer', - def_num=2, - value='dynastream', - raw_value=15, - ), - ReferenceField( - name='manufacturer', - def_num=2, - value='dynastream_oem', - raw_value=13, - ), - ), - ), - ), - ), - 5: Field( - name='software_version', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - scale=100, - ), - 6: Field( - name='hardware_version', - type=BASE_TYPES[0x02], # uint8 - def_num=6, - ), - 7: Field( # Reset by new battery or charge. - name='cum_operating_time', - type=BASE_TYPES[0x86], # uint32 - def_num=7, - units='s', - ), - 10: Field( - name='battery_voltage', - type=BASE_TYPES[0x84], # uint16 - def_num=10, - scale=256, - units='V', - ), - 11: Field( - name='battery_status', - type=FIELD_TYPES['battery_status'], - def_num=11, - ), - 18: Field( # Indicates the location of the sensor - name='sensor_position', - type=FIELD_TYPES['body_location'], - def_num=18, - ), - 19: Field( # Used to describe the sensor or location - name='descriptor', - type=BASE_TYPES[0x07], # string - def_num=19, - ), - 20: Field( - name='ant_transmission_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=20, - ), - 21: Field( - name='ant_device_number', - type=BASE_TYPES[0x8B], # uint16z - def_num=21, - ), - 22: Field( - name='ant_network', - type=FIELD_TYPES['ant_network'], - def_num=22, - ), - 25: Field( - name='source_type', - type=FIELD_TYPES['source_type'], - def_num=25, - ), - 27: Field( # Optional free form string to indicate the devices name or model - name='product_name', - type=BASE_TYPES[0x07], # string - def_num=27, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 27: MessageType( - name='workout_step', - mesg_num=27, - fields={ - 0: Field( - name='wkt_step_name', - type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( - name='duration_type', - type=FIELD_TYPES['wkt_step_duration'], - def_num=1, - ), - 2: Field( - name='duration_value', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - subfields=( - SubField( - name='duration_calories', - def_num=2, - type=BASE_TYPES[0x86], # uint32 - units='calories', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='calories', - raw_value=4, - ), - ), - ), - SubField( - name='duration_distance', - def_num=2, - type=BASE_TYPES[0x86], # uint32 - scale=100, - units='m', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='distance', - raw_value=1, - ), - ), - ), - SubField( - name='duration_hr', - def_num=2, - type=FIELD_TYPES['workout_hr'], - units='% or bpm', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='hr_less_than', - raw_value=2, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='hr_greater_than', - raw_value=3, - ), - ), - ), - SubField( - name='duration_power', - def_num=2, - type=FIELD_TYPES['workout_power'], - units='% or watts', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='power_less_than', - raw_value=14, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='power_greater_than', - raw_value=15, - ), - ), - ), - SubField( # message_index of step to loop back to. Steps are assumed to be in the order by message_index. custom_name and intensity members are undefined for this duration type. - name='duration_step', - def_num=2, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_steps_cmplt', - raw_value=6, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_time', - raw_value=7, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_distance', - raw_value=8, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_calories', - raw_value=9, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_hr_less_than', - raw_value=10, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_hr_greater_than', - raw_value=11, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_power_less_than', - raw_value=12, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_power_greater_than', - raw_value=13, - ), - ), - ), - SubField( - name='duration_time', - def_num=2, - type=BASE_TYPES[0x86], # uint32 - scale=1000, - units='s', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='time', - raw_value=0, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repetition_time', - raw_value=28, - ), - ), - ), - ), - ), - 3: Field( - name='target_type', - type=FIELD_TYPES['wkt_step_target'], - def_num=3, - ), - 4: Field( - name='target_value', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - subfields=( - SubField( - name='repeat_calories', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - units='calories', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_calories', - raw_value=9, - ), - ), - ), - SubField( - name='repeat_distance', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - scale=100, - units='m', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_distance', - raw_value=8, - ), - ), - ), - SubField( - name='repeat_hr', - def_num=4, - type=FIELD_TYPES['workout_hr'], - units='% or bpm', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_hr_less_than', - raw_value=10, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_hr_greater_than', - raw_value=11, - ), - ), - ), - SubField( - name='repeat_power', - def_num=4, - type=FIELD_TYPES['workout_power'], - units='% or watts', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_power_less_than', - raw_value=12, - ), - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_power_greater_than', - raw_value=13, - ), - ), - ), - SubField( # # of repetitions - name='repeat_steps', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_steps_cmplt', - raw_value=6, - ), - ), - ), - SubField( - name='repeat_time', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - scale=1000, - units='s', - ref_fields=( - ReferenceField( - name='duration_type', - def_num=1, - value='repeat_until_time', - raw_value=7, - ), - ), - ), - SubField( # Zone (1-?); Custom = 0; - name='target_cadence_zone', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='cadence', - raw_value=3, - ), - ), - ), - SubField( # hr zone (1-5);Custom =0; - name='target_hr_zone', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='heart_rate', - raw_value=1, - ), - ), - ), - SubField( # Power Zone ( 1-7); Custom = 0; - name='target_power_zone', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='power', - raw_value=4, - ), - ), - ), - SubField( # speed zone (1-10);Custom =0; - name='target_speed_zone', - def_num=4, - type=BASE_TYPES[0x86], # uint32 - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='speed', - raw_value=0, - ), - ), - ), - SubField( - name='target_stroke_type', - def_num=4, - type=FIELD_TYPES['swim_stroke'], - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='swim_stroke', - raw_value=11, - ), - ), - ), - ), - ), - 5: Field( - name='custom_target_value_low', - type=BASE_TYPES[0x86], # uint32 - def_num=5, - subfields=( - SubField( - name='custom_target_cadence_low', - def_num=5, - type=BASE_TYPES[0x86], # uint32 - units='rpm', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='cadence', - raw_value=3, - ), - ), - ), - SubField( - name='custom_target_heart_rate_low', - def_num=5, - type=FIELD_TYPES['workout_hr'], - units='% or bpm', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='heart_rate', - raw_value=1, - ), - ), - ), - SubField( - name='custom_target_power_low', - def_num=5, - type=FIELD_TYPES['workout_power'], - units='% or watts', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='power', - raw_value=4, - ), - ), - ), - SubField( - name='custom_target_speed_low', - def_num=5, - type=BASE_TYPES[0x86], # uint32 - scale=1000, - units='m/s', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='speed', - raw_value=0, - ), - ), - ), - ), - ), - 6: Field( - name='custom_target_value_high', - type=BASE_TYPES[0x86], # uint32 - def_num=6, - subfields=( - SubField( - name='custom_target_cadence_high', - def_num=6, - type=BASE_TYPES[0x86], # uint32 - units='rpm', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='cadence', - raw_value=3, - ), - ), - ), - SubField( - name='custom_target_heart_rate_high', - def_num=6, - type=FIELD_TYPES['workout_hr'], - units='% or bpm', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='heart_rate', - raw_value=1, - ), - ), - ), - SubField( - name='custom_target_power_high', - def_num=6, - type=FIELD_TYPES['workout_power'], - units='% or watts', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='power', - raw_value=4, - ), - ), - ), - SubField( - name='custom_target_speed_high', - def_num=6, - type=BASE_TYPES[0x86], # uint32 - scale=1000, - units='m/s', - ref_fields=( - ReferenceField( - name='target_type', - def_num=3, - value='speed', - raw_value=0, - ), - ), - ), - ), - ), - 7: Field( - name='intensity', - type=FIELD_TYPES['intensity'], - def_num=7, - ), - 8: Field( - name='notes', - type=BASE_TYPES[0x07], # string - def_num=8, - ), - 9: Field( - name='equipment', - type=FIELD_TYPES['workout_equipment'], - def_num=9, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 32: MessageType( - name='course_point', - mesg_num=32, - fields={ - 1: Field( - name='timestamp', - type=FIELD_TYPES['date_time'], - def_num=1, - ), - 2: Field( - name='position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=2, - units='semicircles', - ), - 3: Field( - name='position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=3, - units='semicircles', - ), - 4: Field( - name='distance', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - scale=100, - units='m', - ), - 5: Field( - name='type', - type=FIELD_TYPES['course_point'], - def_num=5, - ), - 6: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=6, - ), - 8: Field( - name='favorite', - type=FIELD_TYPES['bool'], - def_num=8, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 37: MessageType( - name='file_capabilities', - mesg_num=37, - fields={ - 0: Field( - name='type', - type=FIELD_TYPES['file'], - def_num=0, - ), - 1: Field( - name='flags', - type=FIELD_TYPES['file_flags'], - def_num=1, - ), - 2: Field( - name='directory', - type=BASE_TYPES[0x07], # string - def_num=2, - ), - 3: Field( - name='max_count', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - ), - 4: Field( - name='max_size', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - units='bytes', - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 38: MessageType( - name='mesg_capabilities', - mesg_num=38, - fields={ - 0: Field( - name='file', - type=FIELD_TYPES['file'], - def_num=0, - ), - 1: Field( - name='mesg_num', - type=FIELD_TYPES['mesg_num'], - def_num=1, - ), - 2: Field( - name='count_type', - type=FIELD_TYPES['mesg_count'], - def_num=2, - ), - 3: Field( - name='count', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - subfields=( - SubField( - name='max_per_file', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - ref_fields=( - ReferenceField( - name='count_type', - def_num=2, - value='max_per_file', - raw_value=1, - ), - ), - ), - SubField( - name='max_per_file_type', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - ref_fields=( - ReferenceField( - name='count_type', - def_num=2, - value='max_per_file_type', - raw_value=2, - ), - ), - ), - SubField( - name='num_per_file', - def_num=3, - type=BASE_TYPES[0x84], # uint16 - ref_fields=( - ReferenceField( - name='count_type', - def_num=2, - value='num_per_file', - raw_value=0, - ), - ), - ), - ), - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 39: MessageType( - name='field_capabilities', - mesg_num=39, - fields={ - 0: Field( - name='file', - type=FIELD_TYPES['file'], - def_num=0, - ), - 1: Field( - name='mesg_num', - type=FIELD_TYPES['mesg_num'], - def_num=1, - ), - 2: Field( - name='field_num', - type=BASE_TYPES[0x02], # uint8 - def_num=2, - ), - 3: Field( - name='count', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 49: MessageType( - name='file_creator', - mesg_num=49, - fields={ - 0: Field( - name='software_version', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - ), - 1: Field( - name='hardware_version', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - ), - }, - ), - 53: MessageType( - name='speed_zone', - mesg_num=53, - fields={ - 0: Field( - name='high_value', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - scale=1000, - units='m/s', - ), - 1: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 55: MessageType( - name='monitoring', - mesg_num=55, - fields={ - 0: Field( # Associates this data to device_info message. Not required for file with single device (sensor). - name='device_index', - type=FIELD_TYPES['device_index'], - def_num=0, - ), - 1: Field( # Accumulated total calories. Maintained by MonitoringReader for each activity_type. See SDK documentation - name='calories', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - units='kcal', - ), - 2: Field( # Accumulated distance. Maintained by MonitoringReader for each activity_type. See SDK documentation. - name='distance', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - scale=100, - units='m', - ), - 3: Field( # Accumulated cycles. Maintained by MonitoringReader for each activity_type. See SDK documentation. - name='cycles', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - scale=2, - units='cycles', - subfields=( - SubField( - name='steps', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - units='steps', - ref_fields=( - ReferenceField( - name='activity_type', - def_num=5, - value='walking', - raw_value=6, - ), - ReferenceField( - name='activity_type', - def_num=5, - value='running', - raw_value=1, - ), - ), - ), - SubField( - name='strokes', - def_num=3, - type=BASE_TYPES[0x86], # uint32 - scale=2, - units='strokes', - ref_fields=( - ReferenceField( - name='activity_type', - def_num=5, - value='cycling', - raw_value=2, - ), - ReferenceField( - name='activity_type', - def_num=5, - value='swimming', - raw_value=5, - ), - ), - ), - ), - ), - 4: Field( - name='active_time', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - scale=1000, - units='s', - ), - 5: Field( - name='activity_type', - type=FIELD_TYPES['activity_type'], - def_num=5, - ), - 6: Field( - name='activity_subtype', - type=FIELD_TYPES['activity_subtype'], - def_num=6, - ), - 7: Field( - name='activity_level', - type=FIELD_TYPES['activity_level'], - def_num=7, - ), - 8: Field( - name='distance_16', - type=BASE_TYPES[0x84], # uint16 - def_num=8, - units='100*m', - ), - 9: Field( - name='cycles_16', - type=BASE_TYPES[0x84], # uint16 - def_num=9, - units='2*cycles or steps', - ), - 10: Field( - name='active_time_16', - type=BASE_TYPES[0x84], # uint16 - def_num=10, - units='s', - ), - 11: Field( # Must align to logging interval, for example, time must be 00:00:00 for daily log. - name='local_timestamp', - type=FIELD_TYPES['local_date_time'], - def_num=11, - ), - 12: Field( # Avg temperature during the logging interval ended at timestamp - name='temperature', - type=BASE_TYPES[0x83], # sint16 - def_num=12, - scale=100, - units='C', - ), - 14: Field( # Min temperature during the logging interval ended at timestamp - name='temperature_min', - type=BASE_TYPES[0x83], # sint16 - def_num=14, - scale=100, - units='C', - ), - 15: Field( # Max temperature during the logging interval ended at timestamp - name='temperature_max', - type=BASE_TYPES[0x83], # sint16 - def_num=15, - scale=100, - units='C', - ), - 16: Field( # Indexed using minute_activity_level enum - name='activity_time', - type=BASE_TYPES[0x84], # uint16 - def_num=16, - units='minutes', - ), - 19: Field( - name='active_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=19, - units='kcal', - ), - 24: Field( # Indicates single type / intensity for duration since last monitoring message. - name='current_activity_type_intensity', - type=BASE_TYPES[0x0D], # byte - def_num=24, - components=( - ComponentField( - name='activity_type', - def_num=5, - accumulate=False, - bits=5, - bit_offset=0, - ), - ComponentField( - name='intensity', - def_num=28, - accumulate=False, - bits=3, - bit_offset=5, - ), - ), - ), - 25: Field( - name='timestamp_min_8', - type=BASE_TYPES[0x02], # uint8 - def_num=25, - units='min', - ), - 26: Field( - name='timestamp_16', - type=BASE_TYPES[0x84], # uint16 - def_num=26, - units='s', - ), - 27: Field( - name='heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=27, - units='bpm', - ), - 28: Field( - name='intensity', - type=BASE_TYPES[0x02], # uint8 - def_num=28, - scale=10, - ), - 29: Field( - name='duration_min', - type=BASE_TYPES[0x84], # uint16 - def_num=29, - units='min', - ), - 30: Field( - name='duration', - type=BASE_TYPES[0x86], # uint32 - def_num=30, - units='s', - ), - 31: Field( - name='ascent', - type=BASE_TYPES[0x86], # uint32 - def_num=31, - scale=1000, - units='m', - ), - 32: Field( - name='descent', - type=BASE_TYPES[0x86], # uint32 - def_num=32, - scale=1000, - units='m', - ), - 33: Field( - name='moderate_activity_minutes', - type=BASE_TYPES[0x84], # uint16 - def_num=33, - units='minutes', - ), - 34: Field( - name='vigorous_activity_minutes', - type=BASE_TYPES[0x84], # uint16 - def_num=34, - units='minutes', - ), - 253: FIELD_TYPE_TIMESTAMP, # Must align to logging interval, for example, time must be 00:00:00 for daily log. - }, - ), - 72: MessageType( # Corresponds to file_id of workout or course. - name='training_file', - mesg_num=72, - fields={ - 0: Field( - name='type', - type=FIELD_TYPES['file'], - def_num=0, - ), - 1: Field( - name='manufacturer', - type=FIELD_TYPES['manufacturer'], - def_num=1, - ), - 2: Field( - name='product', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - subfields=( - SubField( - name='garmin_product', - def_num=2, - type=FIELD_TYPES['garmin_product'], - ref_fields=( - ReferenceField( - name='manufacturer', - def_num=1, - value='garmin', - raw_value=1, - ), - ReferenceField( - name='manufacturer', - def_num=1, - value='dynastream', - raw_value=15, - ), - ReferenceField( - name='manufacturer', - def_num=1, - value='dynastream_oem', - raw_value=13, - ), - ), - ), - ), - ), - 3: Field( - name='serial_number', - type=BASE_TYPES[0x8C], # uint32z - def_num=3, - ), - 4: Field( - name='time_created', - type=FIELD_TYPES['date_time'], - def_num=4, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 78: MessageType( # Heart rate variability - name='hrv', - mesg_num=78, - fields={ - 0: Field( # Time between beats - name='time', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - scale=1000, - units='s', - ), - }, - ), - 80: MessageType( - name='ant_rx', - mesg_num=80, - fields={ - 0: Field( - name='fractional_timestamp', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - scale=32768, - units='s', - ), - 1: Field( - name='mesg_id', - type=BASE_TYPES[0x0D], # byte - def_num=1, - ), - 2: Field( - name='mesg_data', - type=BASE_TYPES[0x0D], # byte - def_num=2, - components=( - ComponentField( - name='channel_number', - def_num=3, - accumulate=False, - bits=8, - bit_offset=0, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=8, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=16, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=24, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=32, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=40, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=48, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=56, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=64, - ), - ), - ), - 3: Field( - name='channel_number', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - ), - 4: Field( - name='data', - type=BASE_TYPES[0x0D], # byte - def_num=4, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 81: MessageType( - name='ant_tx', - mesg_num=81, - fields={ - 0: Field( - name='fractional_timestamp', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - scale=32768, - units='s', - ), - 1: Field( - name='mesg_id', - type=BASE_TYPES[0x0D], # byte - def_num=1, - ), - 2: Field( - name='mesg_data', - type=BASE_TYPES[0x0D], # byte - def_num=2, - components=( - ComponentField( - name='channel_number', - def_num=3, - accumulate=False, - bits=8, - bit_offset=0, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=8, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=16, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=24, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=32, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=40, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=48, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=56, - ), - ComponentField( - name='data', - def_num=4, - accumulate=False, - bits=8, - bit_offset=64, - ), - ), - ), - 3: Field( - name='channel_number', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - ), - 4: Field( - name='data', - type=BASE_TYPES[0x0D], # byte - def_num=4, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 82: MessageType( - name='ant_channel_id', - mesg_num=82, - fields={ - 0: Field( - name='channel_number', - type=BASE_TYPES[0x02], # uint8 - def_num=0, - ), - 1: Field( - name='device_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=1, - ), - 2: Field( - name='device_number', - type=BASE_TYPES[0x8B], # uint16z - def_num=2, - ), - 3: Field( - name='transmission_type', - type=BASE_TYPES[0x0A], # uint8z - def_num=3, - ), - 4: Field( - name='device_index', - type=FIELD_TYPES['device_index'], - def_num=4, - ), - }, - ), - 101: MessageType( - name='length', - mesg_num=101, - fields={ - 0: Field( - name='event', - type=FIELD_TYPES['event'], - def_num=0, - ), - 1: Field( - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=1, - ), - 2: Field( - name='start_time', - type=FIELD_TYPES['date_time'], - def_num=2, - ), - 3: Field( - name='total_elapsed_time', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - scale=1000, - units='s', - ), - 4: Field( - name='total_timer_time', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - scale=1000, - units='s', - ), - 5: Field( - name='total_strokes', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - units='strokes', - ), - 6: Field( - name='avg_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=6, - scale=1000, - units='m/s', - ), - 7: Field( - name='swim_stroke', - type=FIELD_TYPES['swim_stroke'], - def_num=7, - units='swim_stroke', - ), - 9: Field( - name='avg_swimming_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=9, - units='strokes/min', - ), - 10: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 - def_num=10, - ), - 11: Field( - name='total_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=11, - units='kcal', - ), - 12: Field( - name='length_type', - type=FIELD_TYPES['length_type'], - def_num=12, - ), - 18: Field( - name='player_score', - type=BASE_TYPES[0x84], # uint16 - def_num=18, - ), - 19: Field( - name='opponent_score', - type=BASE_TYPES[0x84], # uint16 - def_num=19, - ), - 20: Field( # stroke_type enum used as the index - name='stroke_count', - type=BASE_TYPES[0x84], # uint16 - def_num=20, - units='counts', - ), - 21: Field( # zone number used as the index - name='zone_count', - type=BASE_TYPES[0x84], # uint16 - def_num=21, - units='counts', - ), - 253: FIELD_TYPE_TIMESTAMP, - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 106: MessageType( - name='slave_device', - mesg_num=106, - fields={ - 0: Field( - name='manufacturer', - type=FIELD_TYPES['manufacturer'], - def_num=0, - ), - 1: Field( - name='product', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - subfields=( - SubField( - name='garmin_product', - def_num=1, - type=FIELD_TYPES['garmin_product'], - ref_fields=( - ReferenceField( - name='manufacturer', - def_num=0, - value='garmin', - raw_value=1, - ), - ReferenceField( - name='manufacturer', - def_num=0, - value='dynastream', - raw_value=15, - ), - ReferenceField( - name='manufacturer', - def_num=0, - value='dynastream_oem', - raw_value=13, - ), - ), - ), - ), - ), - }, - ), - 127: MessageType( - name='connectivity', - mesg_num=127, - fields={ - 0: Field( # Use Bluetooth for connectivity features - name='bluetooth_enabled', - type=FIELD_TYPES['bool'], - def_num=0, - ), - 1: Field( # Use Bluetooth Low Energy for connectivity features - name='bluetooth_le_enabled', - type=FIELD_TYPES['bool'], - def_num=1, - ), - 2: Field( # Use ANT for connectivity features - name='ant_enabled', - type=FIELD_TYPES['bool'], - def_num=2, - ), - 3: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=3, - ), - 4: Field( - name='live_tracking_enabled', - type=FIELD_TYPES['bool'], - def_num=4, - ), - 5: Field( - name='weather_conditions_enabled', - type=FIELD_TYPES['bool'], - def_num=5, - ), - 6: Field( - name='weather_alerts_enabled', - type=FIELD_TYPES['bool'], - def_num=6, - ), - 7: Field( - name='auto_activity_upload_enabled', - type=FIELD_TYPES['bool'], - def_num=7, - ), - 8: Field( - name='course_download_enabled', - type=FIELD_TYPES['bool'], - def_num=8, - ), - 9: Field( - name='workout_download_enabled', - type=FIELD_TYPES['bool'], - def_num=9, - ), - 10: Field( - name='gps_ephemeris_download_enabled', - type=FIELD_TYPES['bool'], - def_num=10, - ), - 11: Field( - name='incident_detection_enabled', - type=FIELD_TYPES['bool'], - def_num=11, - ), - 12: Field( - name='grouptrack_enabled', - type=FIELD_TYPES['bool'], - def_num=12, - ), - }, - ), - 128: MessageType( - name='weather_conditions', - mesg_num=128, - fields={ - 0: Field( # Current or forecast - name='weather_report', - type=FIELD_TYPES['weather_report'], - def_num=0, - ), - 1: Field( - name='temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=1, - units='C', - ), - 2: Field( # Corresponds to GSC Response weatherIcon field - name='condition', - type=FIELD_TYPES['weather_status'], - def_num=2, - ), - 3: Field( - name='wind_direction', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - units='degrees', - ), - 4: Field( - name='wind_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - scale=1000, - units='m/s', - ), - 5: Field( # range 0-100 - name='precipitation_probability', - type=BASE_TYPES[0x02], # uint8 - def_num=5, - ), - 6: Field( # Heat Index if GCS heatIdx above or equal to 90F or wind chill if GCS windChill below or equal to 32F - name='temperature_feels_like', - type=BASE_TYPES[0x01], # sint8 - def_num=6, - units='C', - ), - 7: Field( - name='relative_humidity', - type=BASE_TYPES[0x02], # uint8 - def_num=7, - ), - 8: Field( # string corresponding to GCS response location string - name='location', - type=BASE_TYPES[0x07], # string - def_num=8, - ), - 9: Field( - name='observed_at_time', - type=FIELD_TYPES['date_time'], - def_num=9, - ), - 10: Field( - name='observed_location_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=10, - units='semicircles', - ), - 11: Field( - name='observed_location_long', - type=BASE_TYPES[0x85], # sint32 - def_num=11, - units='semicircles', - ), - 12: Field( - name='day_of_week', - type=FIELD_TYPES['day_of_week'], - def_num=12, - ), - 13: Field( - name='high_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=13, - units='C', - ), - 14: Field( - name='low_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=14, - units='C', - ), - 253: FIELD_TYPE_TIMESTAMP, # time of update for current conditions, else forecast time - }, - ), - 129: MessageType( - name='weather_alert', - mesg_num=129, - fields={ - 0: Field( # Unique identifier from GCS report ID string, length is 12 - name='report_id', - type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( # Time alert was issued - name='issue_time', - type=FIELD_TYPES['date_time'], - def_num=1, - ), - 2: Field( # Time alert expires - name='expire_time', - type=FIELD_TYPES['date_time'], - def_num=2, - ), - 3: Field( # Warning, Watch, Advisory, Statement - name='severity', - type=FIELD_TYPES['weather_severity'], - def_num=3, - ), - 4: Field( # Tornado, Severe Thunderstorm, etc. - name='type', - type=FIELD_TYPES['weather_severe_type'], - def_num=4, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 131: MessageType( - name='cadence_zone', - mesg_num=131, - fields={ - 0: Field( - name='high_value', - type=BASE_TYPES[0x02], # uint8 - def_num=0, - units='rpm', - ), - 1: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 132: MessageType( - name='hr', - mesg_num=132, - fields={ - 0: Field( - name='fractional_timestamp', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - scale=32768, - units='s', - ), - 1: Field( - name='time256', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - components=( - ComponentField( - name='fractional_timestamp', - def_num=0, - scale=256, - units='s', - accumulate=False, - bits=8, - bit_offset=0, - ), - ), - ), - 6: Field( - name='filtered_bpm', - type=BASE_TYPES[0x02], # uint8 - def_num=6, - units='bpm', - ), - 9: Field( - name='event_timestamp', - type=BASE_TYPES[0x86], # uint32 - def_num=9, - scale=1024, - units='s', - ), - 10: Field( - name='event_timestamp_12', - type=BASE_TYPES[0x0D], # byte - def_num=10, - components=( - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=0, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=12, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=24, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=36, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=48, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=60, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=72, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=84, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=96, - ), - ComponentField( - name='event_timestamp', - def_num=9, - scale=1024, - units='s', - accumulate=True, - bits=12, - bit_offset=108, - ), - ), - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - 142: MessageType( - name='segment_lap', - mesg_num=142, - fields={ - 0: Field( - name='event', - type=FIELD_TYPES['event'], - def_num=0, - ), - 1: Field( - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=1, - ), - 2: Field( - name='start_time', - type=FIELD_TYPES['date_time'], - def_num=2, - ), - 3: Field( - name='start_position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=3, - units='semicircles', - ), - 4: Field( - name='start_position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=4, - units='semicircles', - ), - 5: Field( - name='end_position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=5, - units='semicircles', - ), - 6: Field( - name='end_position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=6, - units='semicircles', - ), - 7: Field( # Time (includes pauses) - name='total_elapsed_time', - type=BASE_TYPES[0x86], # uint32 - def_num=7, - scale=1000, - units='s', - ), - 8: Field( # Timer Time (excludes pauses) - name='total_timer_time', - type=BASE_TYPES[0x86], # uint32 - def_num=8, - scale=1000, - units='s', - ), - 9: Field( - name='total_distance', - type=BASE_TYPES[0x86], # uint32 - def_num=9, - scale=100, - units='m', - ), - 10: Field( - name='total_cycles', - type=BASE_TYPES[0x86], # uint32 - def_num=10, - units='cycles', - subfields=( - SubField( - name='total_strokes', - def_num=10, - type=BASE_TYPES[0x86], # uint32 - units='strokes', - ref_fields=( - ReferenceField( - name='sport', - def_num=23, - value='cycling', - raw_value=2, - ), - ), - ), - ), - ), - 11: Field( - name='total_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=11, - units='kcal', - ), - 12: Field( # If New Leaf - name='total_fat_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=12, - units='kcal', - ), - 13: Field( - name='avg_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=13, - scale=1000, - units='m/s', - ), - 14: Field( - name='max_speed', - type=BASE_TYPES[0x84], # uint16 - def_num=14, - scale=1000, - units='m/s', - ), - 15: Field( - name='avg_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=15, - units='bpm', - ), - 16: Field( - name='max_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=16, - units='bpm', - ), - 17: Field( # total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time - name='avg_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=17, - units='rpm', - ), - 18: Field( - name='max_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=18, - units='rpm', - ), - 19: Field( # total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time - name='avg_power', - type=BASE_TYPES[0x84], # uint16 - def_num=19, - units='watts', - ), - 20: Field( - name='max_power', - type=BASE_TYPES[0x84], # uint16 - def_num=20, - units='watts', - ), - 21: Field( - name='total_ascent', - type=BASE_TYPES[0x84], # uint16 - def_num=21, - units='m', - ), - 22: Field( - name='total_descent', - type=BASE_TYPES[0x84], # uint16 - def_num=22, - units='m', - ), - 23: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=23, - ), - 24: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 - def_num=24, - ), - 25: Field( # North east corner latitude. - name='nec_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=25, - units='semicircles', - ), - 26: Field( # North east corner longitude. - name='nec_long', - type=BASE_TYPES[0x85], # sint32 - def_num=26, - units='semicircles', - ), - 27: Field( # South west corner latitude. - name='swc_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=27, - units='semicircles', - ), - 28: Field( # South west corner latitude. - name='swc_long', - type=BASE_TYPES[0x85], # sint32 - def_num=28, - units='semicircles', - ), - 29: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=29, - ), - 30: Field( - name='normalized_power', - type=BASE_TYPES[0x84], # uint16 - def_num=30, - units='watts', - ), - 31: Field( - name='left_right_balance', - type=FIELD_TYPES['left_right_balance_100'], - def_num=31, - ), - 32: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=32, - ), - 33: Field( - name='total_work', - type=BASE_TYPES[0x86], # uint32 - def_num=33, - units='J', - ), - 34: Field( - name='avg_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=34, - scale=5, - offset=500, - units='m', - ), - 35: Field( - name='max_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=35, - scale=5, - offset=500, - units='m', - ), - 36: Field( - name='gps_accuracy', - type=BASE_TYPES[0x02], # uint8 - def_num=36, - units='m', - ), - 37: Field( - name='avg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=37, - scale=100, - units='%', - ), - 38: Field( - name='avg_pos_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=38, - scale=100, - units='%', - ), - 39: Field( - name='avg_neg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=39, - scale=100, - units='%', - ), - 40: Field( - name='max_pos_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=40, - scale=100, - units='%', - ), - 41: Field( - name='max_neg_grade', - type=BASE_TYPES[0x83], # sint16 - def_num=41, - scale=100, - units='%', - ), - 42: Field( - name='avg_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=42, - units='C', - ), - 43: Field( - name='max_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=43, - units='C', - ), - 44: Field( - name='total_moving_time', - type=BASE_TYPES[0x86], # uint32 - def_num=44, - scale=1000, - units='s', - ), - 45: Field( - name='avg_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=45, - scale=1000, - units='m/s', - ), - 46: Field( - name='avg_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=46, - scale=1000, - units='m/s', - ), - 47: Field( - name='max_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=47, - scale=1000, - units='m/s', - ), - 48: Field( - name='max_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=48, - scale=1000, - units='m/s', - ), - 49: Field( - name='time_in_hr_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=49, - scale=1000, - units='s', - ), - 50: Field( - name='time_in_speed_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=50, - scale=1000, - units='s', - ), - 51: Field( - name='time_in_cadence_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=51, - scale=1000, - units='s', - ), - 52: Field( - name='time_in_power_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=52, - scale=1000, - units='s', - ), - 53: Field( - name='repetition_num', - type=BASE_TYPES[0x84], # uint16 - def_num=53, - ), - 54: Field( - name='min_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=54, - scale=5, - offset=500, - units='m', - ), - 55: Field( - name='min_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=55, - units='bpm', - ), - 56: Field( - name='active_time', - type=BASE_TYPES[0x86], # uint32 - def_num=56, - scale=1000, - units='s', - ), - 57: Field( - name='wkt_step_index', - type=FIELD_TYPES['message_index'], - def_num=57, - ), - 58: Field( - name='sport_event', - type=FIELD_TYPES['sport_event'], - def_num=58, - ), - 59: Field( - name='avg_left_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=59, - scale=2, - units='percent', - ), - 60: Field( - name='avg_right_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=60, - scale=2, - units='percent', - ), - 61: Field( - name='avg_left_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=61, - scale=2, - units='percent', - ), - 62: Field( - name='avg_right_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=62, - scale=2, - units='percent', - ), - 63: Field( - name='avg_combined_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=63, - scale=2, - units='percent', - ), - 64: Field( - name='status', - type=FIELD_TYPES['segment_lap_status'], - def_num=64, - ), - 65: Field( - name='uuid', - type=BASE_TYPES[0x07], # string - def_num=65, - ), - 66: Field( # fractional part of the avg_cadence - name='avg_fractional_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=66, - scale=128, - units='rpm', - ), - 67: Field( # fractional part of the max_cadence - name='max_fractional_cadence', - type=BASE_TYPES[0x02], # uint8 - def_num=67, - scale=128, - units='rpm', - ), - 68: Field( # fractional part of the total_cycles - name='total_fractional_cycles', - type=BASE_TYPES[0x02], # uint8 - def_num=68, - scale=128, - units='cycles', - ), - 69: Field( - name='front_gear_shift_count', - type=BASE_TYPES[0x84], # uint16 - def_num=69, - ), - 70: Field( - name='rear_gear_shift_count', - type=BASE_TYPES[0x84], # uint16 - def_num=70, - ), - 71: Field( # Total time spent in the standing position - name='time_standing', - type=BASE_TYPES[0x86], # uint32 - def_num=71, - scale=1000, - units='s', - ), - 72: Field( # Number of transitions to the standing state - name='stand_count', - type=BASE_TYPES[0x84], # uint16 - def_num=72, - ), - 73: Field( # Average left platform center offset - name='avg_left_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=73, - units='mm', - ), - 74: Field( # Average right platform center offset - name='avg_right_pco', - type=BASE_TYPES[0x01], # sint8 - def_num=74, - units='mm', - ), - 75: Field( # Average left power phase angles. Data value indexes defined by power_phase_type. - name='avg_left_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=75, - scale=0.7111111, - units='degrees', - ), - 76: Field( # Average left power phase peak angles. Data value indexes defined by power_phase_type. - name='avg_left_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=76, - scale=0.7111111, - units='degrees', - ), - 77: Field( # Average right power phase angles. Data value indexes defined by power_phase_type. - name='avg_right_power_phase', - type=BASE_TYPES[0x02], # uint8 - def_num=77, - scale=0.7111111, - units='degrees', - ), - 78: Field( # Average right power phase peak angles. Data value indexes defined by power_phase_type. - name='avg_right_power_phase_peak', - type=BASE_TYPES[0x02], # uint8 - def_num=78, - scale=0.7111111, - units='degrees', - ), - 79: Field( # Average power by position. Data value indexes defined by rider_position_type. - name='avg_power_position', - type=BASE_TYPES[0x84], # uint16 - def_num=79, - units='watts', - ), - 80: Field( # Maximum power by position. Data value indexes defined by rider_position_type. - name='max_power_position', - type=BASE_TYPES[0x84], # uint16 - def_num=80, - units='watts', - ), - 81: Field( # Average cadence by position. Data value indexes defined by rider_position_type. - name='avg_cadence_position', - type=BASE_TYPES[0x02], # uint8 - def_num=81, - units='rpm', - ), - 82: Field( # Maximum cadence by position. Data value indexes defined by rider_position_type. - name='max_cadence_position', - type=BASE_TYPES[0x02], # uint8 - def_num=82, - units='rpm', - ), - 83: Field( # Manufacturer that produced the segment - name='manufacturer', - type=FIELD_TYPES['manufacturer'], - def_num=83, - ), - 253: FIELD_TYPE_TIMESTAMP, # Lap end time. - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 149: MessageType( # Unique Identification data for an individual segment leader within a segment file - name='segment_leaderboard_entry', - mesg_num=149, - fields={ - 0: Field( # Friendly name assigned to leader - name='name', - type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( # Leader classification - name='type', - type=FIELD_TYPES['segment_leaderboard_type'], - def_num=1, - ), - 2: Field( # Primary user ID of this leader - name='group_primary_key', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - ), - 3: Field( # ID of the activity associated with this leader time - name='activity_id', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - ), - 4: Field( # Segment Time (includes pauses) - name='segment_time', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - scale=1000, - units='s', - ), - 5: Field( # String version of the activity_id. 21 characters long, express in decimal - name='activity_id_string', - type=BASE_TYPES[0x07], # string - def_num=5, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 150: MessageType( # Navigation and race evaluation point for a segment decribing a point along the segment path and time it took each segment leader to reach that point - name='segment_point', - mesg_num=150, - fields={ - 1: Field( - name='position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=1, - units='semicircles', - ), - 2: Field( - name='position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=2, - units='semicircles', - ), - 3: Field( # Accumulated distance along the segment at the described point - name='distance', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - scale=100, - units='m', - ), - 4: Field( # Accumulated altitude along the segment at the described point - name='altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - scale=5, - offset=500, - units='m', - ), - 5: Field( # Accumualted time each leader board member required to reach the described point. This value is zero for all leader board members at the starting point of the segment. - name='leader_time', - type=BASE_TYPES[0x86], # uint32 - def_num=5, - scale=1000, - units='s', - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 158: MessageType( - name='workout_session', - mesg_num=158, - fields={ - 0: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=0, - ), - 1: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=1, - ), - 2: Field( - name='num_valid_steps', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - ), - 3: Field( - name='first_step_index', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - ), - 4: Field( - name='pool_length', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - scale=100, - units='m', - ), - 5: Field( - name='pool_length_unit', - type=FIELD_TYPES['display_measure'], - def_num=5, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 159: MessageType( - name='watchface_settings', - mesg_num=159, - fields={ - 0: Field( - name='mode', - type=FIELD_TYPES['watchface_mode'], - def_num=0, - ), - 1: Field( - name='layout', - type=BASE_TYPES[0x0D], # byte - def_num=1, - subfields=( - SubField( - name='analog_layout', - def_num=1, - type=FIELD_TYPES['analog_watchface_layout'], - ref_fields=( - ReferenceField( - name='mode', - def_num=0, - value='analog', - raw_value=1, - ), - ), - ), - SubField( - name='digital_layout', - def_num=1, - type=FIELD_TYPES['digital_watchface_layout'], - ref_fields=( - ReferenceField( - name='mode', - def_num=0, - value='digital', - raw_value=0, - ), - ), - ), - ), - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 160: MessageType( - name='gps_metadata', - mesg_num=160, - fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( - name='position_lat', - type=BASE_TYPES[0x85], # sint32 - def_num=1, - units='semicircles', - ), - 2: Field( - name='position_long', - type=BASE_TYPES[0x85], # sint32 - def_num=2, - units='semicircles', - ), - 3: Field( - name='enhanced_altitude', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - scale=5, - offset=500, - units='m', - ), - 4: Field( - name='enhanced_speed', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - scale=1000, - units='m/s', - ), - 5: Field( - name='heading', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - scale=100, - units='degrees', - ), - 6: Field( # Used to correlate UTC to system time if the timestamp of the message is in system time. This UTC time is derived from the GPS data. - name='utc_timestamp', - type=FIELD_TYPES['date_time'], - def_num=6, - units='s', - ), - 7: Field( # velocity[0] is lon velocity. Velocity[1] is lat velocity. Velocity[2] is altitude velocity. - name='velocity', - type=BASE_TYPES[0x83], # sint16 - def_num=7, - scale=100, - units='m/s', - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp. - }, - ), - 161: MessageType( - name='camera_event', - mesg_num=161, - fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( - name='camera_event_type', - type=FIELD_TYPES['camera_event_type'], - def_num=1, - ), - 2: Field( - name='camera_file_uuid', - type=BASE_TYPES[0x07], # string - def_num=2, - ), - 3: Field( - name='camera_orientation', - type=FIELD_TYPES['camera_orientation_type'], - def_num=3, - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp. - }, - ), - 162: MessageType( - name='timestamp_correlation', - mesg_num=162, - fields={ - 0: Field( # Fractional part of the UTC timestamp at the time the system timestamp was recorded. - name='fractional_timestamp', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - scale=32768, - units='s', - ), - 1: Field( # Whole second part of the system timestamp - name='system_timestamp', - type=FIELD_TYPES['date_time'], - def_num=1, - units='s', - ), - 2: Field( # Fractional part of the system timestamp - name='fractional_system_timestamp', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - scale=32768, - units='s', - ), - 3: Field( # timestamp epoch expressed in local time used to convert timestamps to local time - name='local_timestamp', - type=FIELD_TYPES['local_date_time'], - def_num=3, - units='s', - ), - 4: Field( # Millisecond part of the UTC timestamp at the time the system timestamp was recorded. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - units='ms', - ), - 5: Field( # Millisecond part of the system timestamp - name='system_timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - units='ms', - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of UTC timestamp at the time the system timestamp was recorded. - }, - ), - 164: MessageType( - name='gyroscope_data', - mesg_num=164, - fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( # Each time in the array describes the time at which the gyro sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in gyro_x and gyro_y and gyro_z - name='sample_time_offset', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - units='ms', - ), - 2: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='gyro_x', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - units='counts', - ), - 3: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='gyro_y', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - units='counts', - ), - 4: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='gyro_z', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - units='counts', - ), - 5: Field( # Calibrated gyro reading - name='calibrated_gyro_x', - type=BASE_TYPES[0x88], # float32 - def_num=5, - units='deg/s', - ), - 6: Field( # Calibrated gyro reading - name='calibrated_gyro_y', - type=BASE_TYPES[0x88], # float32 - def_num=6, - units='deg/s', - ), - 7: Field( # Calibrated gyro reading - name='calibrated_gyro_z', - type=BASE_TYPES[0x88], # float32 - def_num=7, - units='deg/s', - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp - }, - ), - 165: MessageType( - name='accelerometer_data', - mesg_num=165, - fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( # Each time in the array describes the time at which the accelerometer sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in accel_x and accel_y and accel_z - name='sample_time_offset', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - units='ms', - ), - 2: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='accel_x', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - units='counts', - ), - 3: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='accel_y', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - units='counts', - ), - 4: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='accel_z', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - units='counts', - ), - 5: Field( # Calibrated accel reading - name='calibrated_accel_x', - type=BASE_TYPES[0x88], # float32 - def_num=5, - units='g', - ), - 6: Field( # Calibrated accel reading - name='calibrated_accel_y', - type=BASE_TYPES[0x88], # float32 - def_num=6, - units='g', - ), - 7: Field( # Calibrated accel reading - name='calibrated_accel_z', - type=BASE_TYPES[0x88], # float32 - def_num=7, - units='g', - ), - 8: Field( # Calibrated accel reading - name='compressed_calibrated_accel_x', - type=BASE_TYPES[0x83], # sint16 - def_num=8, - units='mG', - ), - 9: Field( # Calibrated accel reading - name='compressed_calibrated_accel_y', - type=BASE_TYPES[0x83], # sint16 - def_num=9, - units='mG', - ), - 10: Field( # Calibrated accel reading - name='compressed_calibrated_accel_z', - type=BASE_TYPES[0x83], # sint16 - def_num=10, - units='mG', - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp - }, - ), - 167: MessageType( - name='three_d_sensor_calibration', - mesg_num=167, - fields={ - 0: Field( # Indicates which sensor the calibration is for - name='sensor_type', - type=FIELD_TYPES['sensor_type'], - def_num=0, - ), - 1: Field( # Calibration factor used to convert from raw ADC value to degrees, g, etc. - name='calibration_factor', - type=BASE_TYPES[0x86], # uint32 - def_num=1, - subfields=( - SubField( # Accelerometer calibration factor - name='accel_cal_factor', - def_num=1, - type=BASE_TYPES[0x86], # uint32 - units='g', - ref_fields=( - ReferenceField( - name='sensor_type', - def_num=0, - value='accelerometer', - raw_value=0, - ), - ), - ), - SubField( # Gyro calibration factor - name='gyro_cal_factor', - def_num=1, - type=BASE_TYPES[0x86], # uint32 - units='deg/s', - ref_fields=( - ReferenceField( - name='sensor_type', - def_num=0, - value='gyroscope', - raw_value=1, - ), - ), - ), - ), - ), - 2: Field( # Calibration factor divisor - name='calibration_divisor', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - units='counts', - ), - 3: Field( # Level shift value used to shift the ADC value back into range - name='level_shift', - type=BASE_TYPES[0x86], # uint32 - def_num=3, - ), - 4: Field( # Internal calibration factors, one for each: xy, yx, zx - name='offset_cal', - type=BASE_TYPES[0x85], # sint32 - def_num=4, - ), - 5: Field( # 3 x 3 rotation matrix (row major) - name='orientation_matrix', - type=BASE_TYPES[0x85], # sint32 - def_num=5, - scale=65535, - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp - }, - ), - 169: MessageType( - name='video_frame', - mesg_num=169, - fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( # Number of the frame that the timestamp and timestamp_ms correlate to - name='frame_number', - type=BASE_TYPES[0x86], # uint32 - def_num=1, - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp - }, - ), - 174: MessageType( - name='obdii_data', - mesg_num=174, - fields={ - 0: Field( # Fractional part of timestamp, added to timestamp - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( # Offset of PID reading [i] from start_timestamp+start_timestamp_ms. Readings may span accross seconds. - name='time_offset', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - units='ms', - ), - 2: Field( # Parameter ID - name='pid', - type=BASE_TYPES[0x0D], # byte - def_num=2, - ), - 3: Field( # Raw parameter data - name='raw_data', - type=BASE_TYPES[0x0D], # byte - def_num=3, - ), - 4: Field( # Optional, data size of PID[i]. If not specified refer to SAE J1979. - name='pid_data_size', - type=BASE_TYPES[0x02], # uint8 - def_num=4, - ), - 5: Field( # System time associated with sample expressed in ms, can be used instead of time_offset. There will be a system_time value for each raw_data element. For multibyte pids the system_time is repeated. - name='system_time', - type=BASE_TYPES[0x86], # uint32 - def_num=5, - ), - 6: Field( # Timestamp of first sample recorded in the message. Used with time_offset to generate time of each sample - name='start_timestamp', - type=FIELD_TYPES['date_time'], - def_num=6, - ), - 7: Field( # Fractional part of start_timestamp - name='start_timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=7, - units='ms', - ), - 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output - }, - ), - 177: MessageType( - name='nmea_sentence', - mesg_num=177, - fields={ - 0: Field( # Fractional part of timestamp, added to timestamp - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( # NMEA sentence - name='sentence', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output - }, - ), - 178: MessageType( - name='aviation_attitude', - mesg_num=178, - fields={ - 0: Field( # Fractional part of timestamp, added to timestamp - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( # System time associated with sample expressed in ms. - name='system_time', - type=BASE_TYPES[0x86], # uint32 - def_num=1, - units='ms', - ), - 2: Field( # Range -PI/2 to +PI/2 - name='pitch', - type=BASE_TYPES[0x83], # sint16 - def_num=2, - scale=10430.38, - units='radians', - ), - 3: Field( # Range -PI to +PI - name='roll', - type=BASE_TYPES[0x83], # sint16 - def_num=3, - scale=10430.38, - units='radians', - ), - 4: Field( # Range -78.4 to +78.4 (-8 Gs to 8 Gs) - name='accel_lateral', - type=BASE_TYPES[0x83], # sint16 - def_num=4, - scale=100, - units='m/s^2', - ), - 5: Field( # Range -78.4 to +78.4 (-8 Gs to 8 Gs) - name='accel_normal', - type=BASE_TYPES[0x83], # sint16 - def_num=5, - scale=100, - units='m/s^2', - ), - 6: Field( # Range -8.727 to +8.727 (-500 degs/sec to +500 degs/sec) - name='turn_rate', - type=BASE_TYPES[0x83], # sint16 - def_num=6, - scale=1024, - units='radians/second', - ), - 7: Field( - name='stage', - type=FIELD_TYPES['attitude_stage'], - def_num=7, - ), - 8: Field( # The percent complete of the current attitude stage. Set to 0 for attitude stages 0, 1 and 2 and to 100 for attitude stage 3 by AHRS modules that do not support it. Range - 100 - name='attitude_stage_complete', - type=BASE_TYPES[0x02], # uint8 - def_num=8, - units='%', - ), - 9: Field( # Track Angle/Heading Range 0 - 2pi - name='track', - type=BASE_TYPES[0x84], # uint16 - def_num=9, - scale=10430.38, - units='radians', - ), - 10: Field( - name='validity', - type=FIELD_TYPES['attitude_validity'], - def_num=10, - ), - 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output - }, - ), - 184: MessageType( - name='video', - mesg_num=184, - fields={ - 0: Field( - name='url', - type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( - name='hosting_provider', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 2: Field( # Playback time of video - name='duration', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - units='ms', - ), - }, - ), - 185: MessageType( - name='video_title', - mesg_num=185, - fields={ - 0: Field( # Total number of title parts - name='message_count', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - ), - 1: Field( - name='text', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 254: Field( # Long titles will be split into multiple parts - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 186: MessageType( - name='video_description', - mesg_num=186, - fields={ - 0: Field( # Total number of description parts - name='message_count', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - ), - 1: Field( - name='text', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 254: Field( # Long descriptions will be split into multiple parts - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - 187: MessageType( - name='video_clip', - mesg_num=187, - fields={ - 0: Field( - name='clip_number', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - ), - 1: Field( - name='start_timestamp', - type=FIELD_TYPES['date_time'], - def_num=1, - ), - 2: Field( - name='start_timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - ), - 3: Field( - name='end_timestamp', - type=FIELD_TYPES['date_time'], - def_num=3, - ), - 4: Field( - name='end_timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - ), - 6: Field( # Start of clip in video time - name='clip_start', - type=BASE_TYPES[0x86], # uint32 - def_num=6, - units='ms', - ), - 7: Field( # End of clip in video time - name='clip_end', - type=BASE_TYPES[0x86], # uint32 - def_num=7, - units='ms', - ), - }, - ), - 188: MessageType( - name='ohr_settings', - mesg_num=188, - fields={ - 0: Field( - name='enabled', - type=FIELD_TYPES['switch'], - def_num=0, - ), - }, - ), - 200: MessageType( - name='exd_screen_configuration', - mesg_num=200, - fields={ - 0: Field( - name='screen_index', - type=BASE_TYPES[0x02], # uint8 - def_num=0, - ), - 1: Field( # number of fields in screen - name='field_count', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - ), - 2: Field( - name='layout', - type=FIELD_TYPES['exd_layout'], - def_num=2, - ), - 3: Field( - name='screen_enabled', - type=FIELD_TYPES['bool'], - def_num=3, - ), - }, - ), - 201: MessageType( - name='exd_data_field_configuration', - mesg_num=201, - fields={ - 0: Field( - name='screen_index', - type=BASE_TYPES[0x02], # uint8 - def_num=0, - ), - 1: Field( - name='concept_field', - type=BASE_TYPES[0x0D], # byte - def_num=1, - components=( - ComponentField( - name='field_id', - def_num=2, - accumulate=False, - bits=4, - bit_offset=0, - ), - ComponentField( - name='concept_count', - def_num=3, - accumulate=False, - bits=4, - bit_offset=4, - ), - ), - ), - 2: Field( - name='field_id', - type=BASE_TYPES[0x02], # uint8 - def_num=2, - ), - 3: Field( - name='concept_count', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - ), - 4: Field( - name='display_type', - type=FIELD_TYPES['exd_display_type'], - def_num=4, - ), - 5: Field( - name='title', - type=BASE_TYPES[0x07], # string - def_num=5, - ), - }, - ), - 202: MessageType( - name='exd_data_concept_configuration', - mesg_num=202, - fields={ - 0: Field( - name='screen_index', - type=BASE_TYPES[0x02], # uint8 - def_num=0, - ), - 1: Field( - name='concept_field', - type=BASE_TYPES[0x0D], # byte - def_num=1, - components=( - ComponentField( - name='field_id', - def_num=2, - accumulate=False, - bits=4, - bit_offset=0, - ), - ComponentField( - name='concept_index', - def_num=3, - accumulate=False, - bits=4, - bit_offset=4, - ), - ), - ), - 2: Field( - name='field_id', - type=BASE_TYPES[0x02], # uint8 - def_num=2, - ), - 3: Field( - name='concept_index', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - ), - 4: Field( - name='data_page', - type=BASE_TYPES[0x02], # uint8 - def_num=4, - ), - 5: Field( - name='concept_key', - type=BASE_TYPES[0x02], # uint8 - def_num=5, - ), - 6: Field( - name='scaling', - type=BASE_TYPES[0x02], # uint8 - def_num=6, - ), - 8: Field( - name='data_units', - type=FIELD_TYPES['exd_data_units'], - def_num=8, - ), - 9: Field( - name='qualifier', - type=FIELD_TYPES['exd_qualifiers'], - def_num=9, - ), - 10: Field( - name='descriptor', - type=FIELD_TYPES['exd_descriptors'], - def_num=10, - ), - 11: Field( - name='is_signed', - type=FIELD_TYPES['bool'], - def_num=11, - ), - }, - ), - 206: MessageType( # Must be logged before developer field is used - name='field_description', - mesg_num=206, - fields={ - 0: Field( - name='developer_data_index', - type=BASE_TYPES[0x02], # uint8 - def_num=0, - ), - 1: Field( - name='field_definition_number', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - ), - 2: Field( - name='fit_base_type_id', - type=FIELD_TYPES['fit_base_type'], - def_num=2, - ), - 3: Field( - name='field_name', - type=BASE_TYPES[0x07], # string - def_num=3, - ), - 4: Field( - name='array', - type=BASE_TYPES[0x02], # uint8 - def_num=4, - ), - 5: Field( - name='components', - type=BASE_TYPES[0x07], # string - def_num=5, - ), - 6: Field( - name='scale', - type=BASE_TYPES[0x02], # uint8 - def_num=6, - ), - 7: Field( - name='offset', - type=BASE_TYPES[0x01], # sint8 - def_num=7, - ), - 8: Field( - name='units', - type=BASE_TYPES[0x07], # string - def_num=8, - ), - 9: Field( - name='bits', - type=BASE_TYPES[0x07], # string - def_num=9, - ), - 10: Field( - name='accumulate', - type=BASE_TYPES[0x07], # string - def_num=10, - ), - 13: Field( - name='fit_base_unit_id', - type=FIELD_TYPES['fit_base_unit'], - def_num=13, - ), - 14: Field( - name='native_mesg_num', - type=FIELD_TYPES['mesg_num'], - def_num=14, - ), - 15: Field( - name='native_field_num', - type=BASE_TYPES[0x02], # uint8 - def_num=15, - ), - }, - ), - 207: MessageType( # Must be logged before field description - name='developer_data_id', - mesg_num=207, - fields={ - 0: Field( - name='developer_id', - type=BASE_TYPES[0x0D], # byte - def_num=0, - ), - 1: Field( - name='application_id', - type=BASE_TYPES[0x0D], # byte - def_num=1, - ), - 2: Field( - name='manufacturer_id', - type=FIELD_TYPES['manufacturer'], - def_num=2, - ), - 3: Field( - name='developer_data_index', - type=BASE_TYPES[0x02], # uint8 - def_num=3, - ), - 4: Field( - name='application_version', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - ), - }, - ), - 208: MessageType( - name='magnetometer_data', - mesg_num=208, - fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', - ), - 1: Field( # Each time in the array describes the time at which the compass sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in cmps_x and cmps_y and cmps_z - name='sample_time_offset', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - units='ms', - ), - 2: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='mag_x', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - units='counts', - ), - 3: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='mag_y', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - units='counts', - ), - 4: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. - name='mag_z', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - units='counts', - ), - 5: Field( # Calibrated Magnetometer reading - name='calibrated_mag_x', - type=BASE_TYPES[0x88], # float32 - def_num=5, - units='G', - ), - 6: Field( # Calibrated Magnetometer reading - name='calibrated_mag_y', - type=BASE_TYPES[0x88], # float32 - def_num=6, - units='G', - ), - 7: Field( # Calibrated Magnetometer reading - name='calibrated_mag_z', - type=BASE_TYPES[0x88], # float32 - def_num=7, - units='G', - ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp - }, - ), - - - ######################### Activity File Messages ######################### - 34: MessageType( - name='activity', - mesg_num=34, - fields={ - 0: Field( # Exclude pauses - name='total_timer_time', - type=BASE_TYPES[0x86], # uint32 - def_num=0, - scale=1000, - units='s', - ), - 1: Field( - name='num_sessions', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - ), - 2: Field( - name='type', - type=FIELD_TYPES['activity'], - def_num=2, - ), - 3: Field( - name='event', - type=FIELD_TYPES['event'], - def_num=3, - ), - 4: Field( - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=4, - ), - 5: Field( # timestamp epoch expressed in local time, used to convert activity timestamps to local time - name='local_timestamp', - type=FIELD_TYPES['local_date_time'], - def_num=5, - ), - 6: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 - def_num=6, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - - - ###################### Blood Pressure File Messages ###################### - 51: MessageType( - name='blood_pressure', - mesg_num=51, - fields={ - 0: Field( - name='systolic_pressure', - type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='mmHg', - ), - 1: Field( - name='diastolic_pressure', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - units='mmHg', - ), - 2: Field( - name='mean_arterial_pressure', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - units='mmHg', - ), - 3: Field( - name='map_3_sample_mean', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - units='mmHg', - ), - 4: Field( - name='map_morning_values', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - units='mmHg', - ), - 5: Field( - name='map_evening_values', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - units='mmHg', - ), - 6: Field( - name='heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=6, - units='bpm', - ), - 7: Field( - name='heart_rate_type', - type=FIELD_TYPES['hr_type'], - def_num=7, - ), - 8: Field( - name='status', - type=FIELD_TYPES['bp_status'], - def_num=8, - ), - 9: Field( # Associates this blood pressure message to a user. This corresponds to the index of the user profile message in the blood pressure file. - name='user_profile_index', - type=FIELD_TYPES['message_index'], - def_num=9, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - - - ########################## Course File Messages ########################## - 31: MessageType( - name='course', - mesg_num=31, - fields={ - 4: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=4, - ), - 5: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=5, - ), - 6: Field( - name='capabilities', - type=FIELD_TYPES['course_capabilities'], - def_num=6, - ), - 7: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=7, - ), - }, - ), - - - ########################## Device File Messages ########################## - 35: MessageType( - name='software', - mesg_num=35, - fields={ - 3: Field( - name='version', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - scale=100, - ), - 5: Field( - name='part_number', - type=BASE_TYPES[0x07], # string - def_num=5, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - - - ########################## Goals File Messages ########################### - 15: MessageType( - name='goal', - mesg_num=15, - fields={ - 0: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=0, - ), - 1: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=1, - ), - 2: Field( - name='start_date', - type=FIELD_TYPES['date_time'], - def_num=2, - ), - 3: Field( - name='end_date', - type=FIELD_TYPES['date_time'], - def_num=3, - ), - 4: Field( - name='type', - type=FIELD_TYPES['goal'], - def_num=4, - ), - 5: Field( - name='value', - type=BASE_TYPES[0x86], # uint32 - def_num=5, - ), - 6: Field( - name='repeat', - type=FIELD_TYPES['bool'], - def_num=6, - ), - 7: Field( - name='target_value', - type=BASE_TYPES[0x86], # uint32 - def_num=7, - ), - 8: Field( - name='recurrence', - type=FIELD_TYPES['goal_recurrence'], - def_num=8, - ), - 9: Field( - name='recurrence_value', - type=BASE_TYPES[0x84], # uint16 - def_num=9, - ), - 10: Field( - name='enabled', - type=FIELD_TYPES['bool'], - def_num=10, - ), - 11: Field( - name='source', - type=FIELD_TYPES['goal_source'], - def_num=11, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - - - ######################## Monitoring File Messages ######################## - 103: MessageType( - name='monitoring_info', - mesg_num=103, - fields={ - 0: Field( # Use to convert activity timestamps to local time if device does not support time zone and daylight savings time correction. - name='local_timestamp', - type=FIELD_TYPES['local_date_time'], - def_num=0, - units='s', - ), - 1: Field( - name='activity_type', - type=FIELD_TYPES['activity_type'], - def_num=1, - ), - 3: Field( # Indexed by activity_type - name='cycles_to_distance', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - scale=5000, - units='m/cycle', - ), - 4: Field( # Indexed by activity_type - name='cycles_to_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - scale=5000, - units='kcal/cycle', - ), - 5: Field( - name='resting_metabolic_rate', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - units='kcal/day', - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - - - ############################# Other Messages ############################# - 145: MessageType( - name='memo_glob', - mesg_num=145, - fields={ - 0: Field( # Block of utf8 bytes - name='memo', - type=BASE_TYPES[0x0D], # byte - def_num=0, - ), - 1: Field( # Allows relating glob to another mesg If used only required for first part of each memo_glob - name='message_number', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - ), - 2: Field( # Index of external mesg - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=2, - ), - 250: Field( # Sequence number of memo blocks - name='part_index', - type=BASE_TYPES[0x86], # uint32 - def_num=250, - ), - }, - ), - - - ######################### Schedule File Messages ######################### - 28: MessageType( - name='schedule', - mesg_num=28, - fields={ - 0: Field( # Corresponds to file_id of scheduled workout / course. - name='manufacturer', - type=FIELD_TYPES['manufacturer'], - def_num=0, - ), - 1: Field( # Corresponds to file_id of scheduled workout / course. - name='product', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - subfields=( - SubField( - name='garmin_product', - def_num=1, - type=FIELD_TYPES['garmin_product'], - ref_fields=( - ReferenceField( - name='manufacturer', - def_num=0, - value='garmin', - raw_value=1, - ), - ReferenceField( - name='manufacturer', - def_num=0, - value='dynastream', - raw_value=15, - ), - ReferenceField( - name='manufacturer', - def_num=0, - value='dynastream_oem', - raw_value=13, - ), - ), - ), - ), - ), - 2: Field( # Corresponds to file_id of scheduled workout / course. - name='serial_number', - type=BASE_TYPES[0x8C], # uint32z - def_num=2, - ), - 3: Field( # Corresponds to file_id of scheduled workout / course. - name='time_created', - type=FIELD_TYPES['date_time'], - def_num=3, - ), - 4: Field( # TRUE if this activity has been started - name='completed', - type=FIELD_TYPES['bool'], - def_num=4, - ), - 5: Field( - name='type', - type=FIELD_TYPES['schedule'], - def_num=5, - ), - 6: Field( - name='scheduled_time', - type=FIELD_TYPES['local_date_time'], - def_num=6, - ), - }, - ), - - - ######################### Segment File Messages ########################## - 148: MessageType( # Unique Identification data for a segment file - name='segment_id', - mesg_num=148, - fields={ - 0: Field( # Friendly name assigned to segment - name='name', - type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( # UUID of the segment - name='uuid', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 2: Field( # Sport associated with the segment - name='sport', - type=FIELD_TYPES['sport'], - def_num=2, - ), - 3: Field( # Segment enabled for evaluation - name='enabled', - type=FIELD_TYPES['bool'], - def_num=3, - ), - 4: Field( # Primary key of the user that created the segment - name='user_profile_primary_key', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - ), - 5: Field( # ID of the device that created the segment - name='device_id', - type=BASE_TYPES[0x86], # uint32 - def_num=5, - ), - 6: Field( # Index for the Leader Board entry selected as the default race participant - name='default_race_leader', - type=BASE_TYPES[0x02], # uint8 - def_num=6, - ), - 7: Field( # Indicates if any segments should be deleted - name='delete_status', - type=FIELD_TYPES['segment_delete_status'], - def_num=7, - ), - 8: Field( # Indicates how the segment was selected to be sent to the device - name='selection_type', - type=FIELD_TYPES['segment_selection_type'], - def_num=8, - ), - }, - ), - - - ####################### Segment List File Messages ####################### - 151: MessageType( # Summary of the unique segment and leaderboard information associated with a segment file. This message is used to compile a segment list file describing all segment files on a device. The segment list file is used when refreshing the contents of a segment file with the latest available leaderboard information. - name='segment_file', - mesg_num=151, - fields={ - 1: Field( # UUID of the segment file - name='file_uuid', - type=BASE_TYPES[0x07], # string - def_num=1, - ), - 3: Field( # Enabled state of the segment file - name='enabled', - type=FIELD_TYPES['bool'], - def_num=3, - ), - 4: Field( # Primary key of the user that created the segment file - name='user_profile_primary_key', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - ), - 7: Field( # Leader type of each leader in the segment file - name='leader_type', - type=FIELD_TYPES['segment_leaderboard_type'], - def_num=7, - ), - 8: Field( # Group primary key of each leader in the segment file - name='leader_group_primary_key', - type=BASE_TYPES[0x86], # uint32 - def_num=8, - ), - 9: Field( # Activity ID of each leader in the segment file - name='leader_activity_id', - type=BASE_TYPES[0x86], # uint32 - def_num=9, - ), - 10: Field( # String version of the activity ID of each leader in the segment file. 21 characters long for each ID, express in decimal - name='leader_activity_id_string', - type=BASE_TYPES[0x07], # string - def_num=10, - ), - 11: Field( # Index for the Leader Board entry selected as the default race participant - name='default_race_leader', - type=BASE_TYPES[0x02], # uint8 - def_num=11, - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - - - ######################### Settings File Messages ######################### - 2: MessageType( - name='device_settings', - mesg_num=2, - fields={ - 0: Field( # Index into time zone arrays. - name='active_time_zone', - type=BASE_TYPES[0x02], # uint8 - def_num=0, - ), - 1: Field( # Offset from system time. Required to convert timestamp from system time to UTC. - name='utc_offset', - type=BASE_TYPES[0x86], # uint32 - def_num=1, - ), - 2: Field( # Offset from system time. - name='time_offset', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - units='s', - ), - 4: Field( # Display mode for the time - name='time_mode', - type=FIELD_TYPES['time_mode'], - def_num=4, - ), - 5: Field( # timezone offset in 1/4 hour increments - name='time_zone_offset', - type=BASE_TYPES[0x01], # sint8 - def_num=5, - scale=4, - units='hr', - ), - 12: Field( # Mode for backlight - name='backlight_mode', - type=FIELD_TYPES['backlight_mode'], - def_num=12, - ), - 36: Field( # Enabled state of the activity tracker functionality - name='activity_tracker_enabled', - type=FIELD_TYPES['bool'], - def_num=36, - ), - 39: Field( # UTC timestamp used to set the devices clock and date - name='clock_time', - type=FIELD_TYPES['date_time'], - def_num=39, - ), - 40: Field( # Bitfield to configure enabled screens for each supported loop - name='pages_enabled', - type=BASE_TYPES[0x84], # uint16 - def_num=40, - ), - 46: Field( # Enabled state of the move alert - name='move_alert_enabled', - type=FIELD_TYPES['bool'], - def_num=46, - ), - 47: Field( # Display mode for the date - name='date_mode', - type=FIELD_TYPES['date_mode'], - def_num=47, - ), - 55: Field( - name='display_orientation', - type=FIELD_TYPES['display_orientation'], - def_num=55, - ), - 56: Field( - name='mounting_side', - type=FIELD_TYPES['side'], - def_num=56, - ), - 57: Field( # Bitfield to indicate one page as default for each supported loop - name='default_page', - type=BASE_TYPES[0x84], # uint16 - def_num=57, - ), - 58: Field( # Minimum steps before an autosync can occur - name='autosync_min_steps', - type=BASE_TYPES[0x84], # uint16 - def_num=58, - units='steps', - ), - 59: Field( # Minimum minutes before an autosync can occur - name='autosync_min_time', - type=BASE_TYPES[0x84], # uint16 - def_num=59, - units='minutes', - ), - 80: Field( # Enable auto-detect setting for the lactate threshold feature. - name='lactate_threshold_autodetect_enabled', - type=FIELD_TYPES['bool'], - def_num=80, - ), - 86: Field( # Automatically upload using BLE - name='ble_auto_upload_enabled', - type=FIELD_TYPES['bool'], - def_num=86, - ), - 89: Field( # Helps to conserve battery by changing modes - name='auto_sync_frequency', - type=FIELD_TYPES['auto_sync_frequency'], - def_num=89, - ), - 90: Field( # Allows setting specific activities auto-activity detect enabled/disabled settings - name='auto_activity_detect', - type=FIELD_TYPES['auto_activity_detect'], - def_num=90, - ), - 94: Field( # Number of screens configured to display - name='number_of_screens', - type=BASE_TYPES[0x02], # uint8 - def_num=94, - ), - 95: Field( # Smart Notification display orientation - name='smart_notification_display_orientation', - type=FIELD_TYPES['display_orientation'], - def_num=95, - ), - }, - ), - - - ###################### Sport Settings File Messages ###################### - 7: MessageType( - name='zones_target', - mesg_num=7, - fields={ - 1: Field( - name='max_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - ), - 2: Field( - name='threshold_heart_rate', - type=BASE_TYPES[0x02], # uint8 - def_num=2, - ), - 3: Field( - name='functional_threshold_power', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - ), - 5: Field( - name='hr_calc_type', - type=FIELD_TYPES['hr_zone_calc'], - def_num=5, - ), - 7: Field( - name='pwr_calc_type', - type=FIELD_TYPES['pwr_zone_calc'], - def_num=7, - ), - }, - ), - - - ########################## Totals File Messages ########################## - 33: MessageType( - name='totals', - mesg_num=33, - fields={ - 0: Field( # Excludes pauses - name='timer_time', - type=BASE_TYPES[0x86], # uint32 - def_num=0, - units='s', - ), - 1: Field( - name='distance', - type=BASE_TYPES[0x86], # uint32 - def_num=1, - units='m', - ), - 2: Field( - name='calories', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - units='kcal', - ), - 3: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=3, - ), - 4: Field( # Includes pauses - name='elapsed_time', - type=BASE_TYPES[0x86], # uint32 - def_num=4, - units='s', - ), - 5: Field( - name='sessions', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - ), - 6: Field( - name='active_time', - type=BASE_TYPES[0x86], # uint32 - def_num=6, - units='s', - ), - 9: Field( - name='sport_index', - type=BASE_TYPES[0x02], # uint8 - def_num=9, - ), - 253: FIELD_TYPE_TIMESTAMP, - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), - }, - ), - - - ####################### Weight Scale File Messages ####################### - 30: MessageType( - name='weight_scale', - mesg_num=30, - fields={ - 0: Field( - name='weight', - type=FIELD_TYPES['weight'], - def_num=0, - scale=100, - units='kg', - ), - 1: Field( - name='percent_fat', - type=BASE_TYPES[0x84], # uint16 - def_num=1, - scale=100, - units='%', - ), - 2: Field( - name='percent_hydration', - type=BASE_TYPES[0x84], # uint16 - def_num=2, - scale=100, - units='%', - ), - 3: Field( - name='visceral_fat_mass', - type=BASE_TYPES[0x84], # uint16 - def_num=3, - scale=100, - units='kg', - ), - 4: Field( - name='bone_mass', - type=BASE_TYPES[0x84], # uint16 - def_num=4, - scale=100, - units='kg', - ), - 5: Field( - name='muscle_mass', - type=BASE_TYPES[0x84], # uint16 - def_num=5, - scale=100, - units='kg', - ), - 7: Field( - name='basal_met', - type=BASE_TYPES[0x84], # uint16 - def_num=7, - scale=4, - units='kcal/day', - ), - 8: Field( - name='physique_rating', - type=BASE_TYPES[0x02], # uint8 - def_num=8, - ), - 9: Field( # ~4kJ per kcal, 0.25 allows max 16384 kcal - name='active_met', - type=BASE_TYPES[0x84], # uint16 - def_num=9, - scale=4, - units='kcal/day', - ), - 10: Field( - name='metabolic_age', - type=BASE_TYPES[0x02], # uint8 - def_num=10, - units='years', - ), - 11: Field( - name='visceral_fat_rating', - type=BASE_TYPES[0x02], # uint8 - def_num=11, - ), - 12: Field( # Associates this weight scale message to a user. This corresponds to the index of the user profile message in the weight scale file. - name='user_profile_index', - type=FIELD_TYPES['message_index'], - def_num=12, - ), - 253: FIELD_TYPE_TIMESTAMP, - }, - ), - - - ######################### Workout File Messages ########################## - 26: MessageType( - name='workout', - mesg_num=26, - fields={ - 4: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=4, - ), - 5: Field( - name='capabilities', - type=FIELD_TYPES['workout_capabilities'], - def_num=5, - ), - 6: Field( # number of valid steps - name='num_valid_steps', - type=BASE_TYPES[0x84], # uint16 - def_num=6, - ), - 8: Field( - name='wkt_name', - type=BASE_TYPES[0x07], # string - def_num=8, - ), - 11: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=11, - ), - 14: Field( - name='pool_length', - type=BASE_TYPES[0x84], # uint16 - def_num=14, - scale=100, - units='m', - ), - 15: Field( - name='pool_length_unit', - type=FIELD_TYPES['display_measure'], - def_num=15, - ), - }, - ), -} + +# ***************** BEGIN AUTOMATICALLY GENERATED FIT PROFILE ****************** +# *************************** DO NOT EDIT THIS FILE **************************** +# *********** EXPORTED PROFILE FROM SDK VERSION 20.66 ON 2018-07-18 ************ +# ********* PARSED 161 TYPES (2985 VALUES), 85 MESSAGES (1038 FIELDS) ********** + +from fitparse.records import ( + ComponentField, + Field, + FieldType, + MessageType, + ReferenceField, + SubField, + BASE_TYPES, +) + + +FIELD_NUM_TIMESTAMP = 253 + + +FIELD_TYPES = { + 'activity': FieldType( + name='activity', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'manual', + 1: 'auto_multi_sport', + }, + ), + 'activity_class': FieldType( + name='activity_class', + base_type=BASE_TYPES[0x00], # enum + values={ + 100: 'level_max', + 0x7F: 'level', # 0 to 100 + 0x80: 'athlete', + }, + ), + 'activity_level': FieldType( + name='activity_level', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'low', + 1: 'medium', + 2: 'high', + }, + ), + 'activity_subtype': FieldType( + name='activity_subtype', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'generic', + 1: 'treadmill', # Run + 2: 'street', # Run + 3: 'trail', # Run + 4: 'track', # Run + 5: 'spin', # Cycling + 6: 'indoor_cycling', # Cycling + 7: 'road', # Cycling + 8: 'mountain', # Cycling + 9: 'downhill', # Cycling + 10: 'recumbent', # Cycling + 11: 'cyclocross', # Cycling + 12: 'hand_cycling', # Cycling + 13: 'track_cycling', # Cycling + 14: 'indoor_rowing', # Fitness Equipment + 15: 'elliptical', # Fitness Equipment + 16: 'stair_climbing', # Fitness Equipment + 17: 'lap_swimming', # Swimming + 18: 'open_water', # Swimming + 254: 'all', + }, + ), + 'activity_type': FieldType( + name='activity_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'generic', + 1: 'running', + 2: 'cycling', + 3: 'transition', # Mulitsport transition + 4: 'fitness_equipment', + 5: 'swimming', + 6: 'walking', + 8: 'sedentary', + 254: 'all', # All is for goals only to include all sports. + }, + ), + 'analog_watchface_layout': FieldType( + name='analog_watchface_layout', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'minimal', + 1: 'traditional', + 2: 'modern', + }, + ), + 'ant_network': FieldType( + name='ant_network', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'public', + 1: 'antplus', + 2: 'antfs', + 3: 'private', + }, + ), + 'antplus_device_type': FieldType( + name='antplus_device_type', + base_type=BASE_TYPES[0x02], # 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', + }, + ), + 'attitude_stage': FieldType( + name='attitude_stage', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'failed', + 1: 'aligning', + 2: 'degraded', + 3: 'valid', + }, + ), + 'attitude_validity': FieldType( + name='attitude_validity', + base_type=BASE_TYPES[0x84], # 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', + }, + ), + 'auto_activity_detect': FieldType( + name='auto_activity_detect', + base_type=BASE_TYPES[0x86], # uint32 + values={ + 0x00000000: 'none', + 0x00000001: 'running', + 0x00000002: 'cycling', + 0x00000004: 'swimming', + 0x00000008: 'walking', + 0x00000020: 'elliptical', + 0x00000400: 'sedentary', + }, + ), + 'auto_sync_frequency': FieldType( + name='auto_sync_frequency', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'never', + 1: 'occasionally', + 2: 'frequent', + 3: 'once_a_day', + 4: 'remote', + }, + ), + 'autolap_trigger': FieldType( + name='autolap_trigger', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'time', + 1: 'distance', + 2: 'position_start', + 3: 'position_lap', + 4: 'position_waypoint', + 5: 'position_marked', + 6: 'off', + }, + ), + 'autoscroll': FieldType( + name='autoscroll', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'none', + 1: 'slow', + 2: 'medium', + 3: 'fast', + }, + ), + 'backlight_mode': FieldType( + name='backlight_mode', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'backlight_timeout': FieldType( # Timeout in seconds. + name='backlight_timeout', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'infinite', # Backlight stays on forever. + }, + ), + 'battery_status': FieldType( + name='battery_status', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 1: 'new', + 2: 'good', + 3: 'ok', + 4: 'low', + 5: 'critical', + 6: 'charging', + 7: 'unknown', + }, + ), + 'bench_press_exercise_name': FieldType( + name='bench_press_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'alternating_dumbbell_chest_press_on_swiss_ball', + 1: 'barbell_bench_press', + 2: 'barbell_board_bench_press', + 3: 'barbell_floor_press', + 4: 'close_grip_barbell_bench_press', + 5: 'decline_dumbbell_bench_press', + 6: 'dumbbell_bench_press', + 7: 'dumbbell_floor_press', + 8: 'incline_barbell_bench_press', + 9: 'incline_dumbbell_bench_press', + 10: 'incline_smith_machine_bench_press', + 11: 'isometric_barbell_bench_press', + 12: 'kettlebell_chest_press', + 13: 'neutral_grip_dumbbell_bench_press', + 14: 'neutral_grip_dumbbell_incline_bench_press', + 15: 'one_arm_floor_press', + 16: 'weighted_one_arm_floor_press', + 17: 'partial_lockout', + 18: 'reverse_grip_barbell_bench_press', + 19: 'reverse_grip_incline_bench_press', + 20: 'single_arm_cable_chest_press', + 21: 'single_arm_dumbbell_bench_press', + 22: 'smith_machine_bench_press', + 23: 'swiss_ball_dumbbell_chest_press', + 24: 'triple_stop_barbell_bench_press', + 25: 'wide_grip_barbell_bench_press', + 26: 'alternating_dumbbell_chest_press', + }, + ), + 'bike_light_beam_angle_mode': FieldType( + name='bike_light_beam_angle_mode', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'manual', + 1: 'auto', + }, + ), + 'bike_light_network_config_type': FieldType( + name='bike_light_network_config_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'auto', + 4: 'individual', + 5: 'high_visibility', + 6: 'trail', + }, + ), + 'body_location': FieldType( + name='body_location', + base_type=BASE_TYPES[0x00], # 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', # Left anterior forearm + 27: 'left_forearm_extensors', # Left posterior forearm + 28: 'right_arm', + 29: 'right_shoulder', + 30: 'right_bicep', + 31: 'right_tricep', + 32: 'right_brachioradialis', # Right anterior forearm + 33: 'right_forearm_extensors', # Right posterior forearm + 34: 'neck', + 35: 'throat', + 36: 'waist_mid_back', + 37: 'waist_front', + 38: 'waist_left', + 39: 'waist_right', + }, + ), + 'bool': FieldType( + name='bool', + base_type=BASE_TYPES[0x00], # enum + ), + 'bp_status': FieldType( + name='bp_status', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'no_error', + 1: 'error_incomplete_data', + 2: 'error_no_measurement', + 3: 'error_data_out_of_range', + 4: 'error_irregular_heart_rate', + }, + ), + 'calf_raise_exercise_name': FieldType( + name='calf_raise_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: '3_way_calf_raise', + 1: '3_way_weighted_calf_raise', + 2: '3_way_single_leg_calf_raise', + 3: '3_way_weighted_single_leg_calf_raise', + 4: 'donkey_calf_raise', + 5: 'weighted_donkey_calf_raise', + 6: 'seated_calf_raise', + 7: 'weighted_seated_calf_raise', + 8: 'seated_dumbbell_toe_raise', + 9: 'single_leg_bent_knee_calf_raise', + 10: 'weighted_single_leg_bent_knee_calf_raise', + 11: 'single_leg_decline_push_up', + 12: 'single_leg_donkey_calf_raise', + 13: 'weighted_single_leg_donkey_calf_raise', + 14: 'single_leg_hip_raise_with_knee_hold', + 15: 'single_leg_standing_calf_raise', + 16: 'single_leg_standing_dumbbell_calf_raise', + 17: 'standing_barbell_calf_raise', + 18: 'standing_calf_raise', + 19: 'weighted_standing_calf_raise', + 20: 'standing_dumbbell_calf_raise', + }, + ), + 'camera_event_type': FieldType( + name='camera_event_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'video_start', # Start of video recording + 1: 'video_split', # Mark of video file split (end of one file, beginning of the other) + 2: 'video_end', # End of video recording + 3: 'photo_taken', # Still photo taken + 4: 'video_second_stream_start', + 5: 'video_second_stream_split', + 6: 'video_second_stream_end', + 7: 'video_split_start', # Mark of video file split start + 8: 'video_second_stream_split_start', + 11: 'video_pause', # Mark when a video recording has been paused + 12: 'video_second_stream_pause', + 13: 'video_resume', # Mark when a video recording has been resumed + 14: 'video_second_stream_resume', + }, + ), + 'camera_orientation_type': FieldType( + name='camera_orientation_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'camera_orientation_0', + 1: 'camera_orientation_90', + 2: 'camera_orientation_180', + 3: 'camera_orientation_270', + }, + ), + 'cardio_exercise_name': FieldType( + name='cardio_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'bob_and_weave_circle', + 1: 'weighted_bob_and_weave_circle', + 2: 'cardio_core_crawl', + 3: 'weighted_cardio_core_crawl', + 4: 'double_under', + 5: 'weighted_double_under', + 6: 'jump_rope', + 7: 'weighted_jump_rope', + 8: 'jump_rope_crossover', + 9: 'weighted_jump_rope_crossover', + 10: 'jump_rope_jog', + 11: 'weighted_jump_rope_jog', + 12: 'jumping_jacks', + 13: 'weighted_jumping_jacks', + 14: 'ski_moguls', + 15: 'weighted_ski_moguls', + 16: 'split_jacks', + 17: 'weighted_split_jacks', + 18: 'squat_jacks', + 19: 'weighted_squat_jacks', + 20: 'triple_under', + 21: 'weighted_triple_under', + }, + ), + 'carry_exercise_name': FieldType( + name='carry_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'bar_holds', + 1: 'farmers_walk', + 2: 'farmers_walk_on_toes', + 3: 'hex_dumbbell_hold', + 4: 'overhead_carry', + }, + ), + 'checksum': FieldType( + name='checksum', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'clear', # Allows clear of checksum for flash memory where can only write 1 to 0 without erasing sector. + 1: 'ok', # Set to mark checksum as valid if computes to invalid values 0 or 0xFF. Checksum can also be set to ok to save encoding computation time. + }, + ), + 'chop_exercise_name': FieldType( + name='chop_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'cable_pull_through', + 1: 'cable_rotational_lift', + 2: 'cable_woodchop', + 3: 'cross_chop_to_knee', + 4: 'weighted_cross_chop_to_knee', + 5: 'dumbbell_chop', + 6: 'half_kneeling_rotation', + 7: 'weighted_half_kneeling_rotation', + 8: 'half_kneeling_rotational_chop', + 9: 'half_kneeling_rotational_reverse_chop', + 10: 'half_kneeling_stability_chop', + 11: 'half_kneeling_stability_reverse_chop', + 12: 'kneeling_rotational_chop', + 13: 'kneeling_rotational_reverse_chop', + 14: 'kneeling_stability_chop', + 15: 'kneeling_woodchopper', + 16: 'medicine_ball_wood_chops', + 17: 'power_squat_chops', + 18: 'weighted_power_squat_chops', + 19: 'standing_rotational_chop', + 20: 'standing_split_rotational_chop', + 21: 'standing_split_rotational_reverse_chop', + 22: 'standing_stability_reverse_chop', + }, + ), + 'comm_timeout_type': FieldType( + name='comm_timeout_type', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'wildcard_pairing_timeout', # Timeout pairing to any device + 1: 'pairing_timeout', # Timeout pairing to previously paired device + 2: 'connection_lost', # Temporary loss of communications + 3: 'connection_timeout', # Connection closed due to extended bad communications + }, + ), + 'connectivity_capabilities': FieldType( + name='connectivity_capabilities', + base_type=BASE_TYPES[0x8C], # uint32z + values={ + 0x00000001: 'bluetooth', + 0x00000002: 'bluetooth_le', + 0x00000004: 'ant', + 0x00000008: 'activity_upload', + 0x00000010: 'course_download', + 0x00000020: 'workout_download', + 0x00000040: 'live_track', + 0x00000080: 'weather_conditions', + 0x00000100: 'weather_alerts', + 0x00000200: 'gps_ephemeris_download', + 0x00000400: 'explicit_archive', + 0x00000800: 'setup_incomplete', + 0x00001000: 'continue_sync_after_software_update', + 0x00002000: 'connect_iq_app_download', + 0x00004000: 'golf_course_download', + 0x00008000: 'device_initiates_sync', # Indicates device is in control of initiating all syncs + 0x00010000: 'connect_iq_watch_app_download', + 0x00020000: 'connect_iq_widget_download', + 0x00040000: 'connect_iq_watch_face_download', + 0x00080000: 'connect_iq_data_field_download', + 0x00100000: 'connect_iq_app_managment', # Device supports delete and reorder of apps via GCM + 0x00200000: 'swing_sensor', + 0x00400000: 'swing_sensor_remote', + 0x00800000: 'incident_detection', # Device supports incident detection + 0x01000000: 'audio_prompts', + 0x02000000: 'wifi_verification', # Device supports reporting wifi verification via GCM + 0x04000000: 'true_up', # Device supports True Up + 0x08000000: 'find_my_watch', # Device supports Find My Watch + 0x10000000: 'remote_manual_sync', + 0x20000000: 'live_track_auto_start', # Device supports LiveTrack auto start + 0x40000000: 'live_track_messaging', # Device supports LiveTrack Messaging + 0x80000000: 'instant_input', # Device supports instant input feature + }, + ), + 'core_exercise_name': FieldType( + name='core_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'abs_jabs', + 1: 'weighted_abs_jabs', + 2: 'alternating_plate_reach', + 3: 'barbell_rollout', + 4: 'weighted_barbell_rollout', + 5: 'body_bar_oblique_twist', + 6: 'cable_core_press', + 7: 'cable_side_bend', + 8: 'side_bend', + 9: 'weighted_side_bend', + 10: 'crescent_circle', + 11: 'weighted_crescent_circle', + 12: 'cycling_russian_twist', + 13: 'weighted_cycling_russian_twist', + 14: 'elevated_feet_russian_twist', + 15: 'weighted_elevated_feet_russian_twist', + 16: 'half_turkish_get_up', + 17: 'kettlebell_windmill', + 18: 'kneeling_ab_wheel', + 19: 'weighted_kneeling_ab_wheel', + 20: 'modified_front_lever', + 21: 'open_knee_tucks', + 22: 'weighted_open_knee_tucks', + 23: 'side_abs_leg_lift', + 24: 'weighted_side_abs_leg_lift', + 25: 'swiss_ball_jackknife', + 26: 'weighted_swiss_ball_jackknife', + 27: 'swiss_ball_pike', + 28: 'weighted_swiss_ball_pike', + 29: 'swiss_ball_rollout', + 30: 'weighted_swiss_ball_rollout', + 31: 'triangle_hip_press', + 32: 'weighted_triangle_hip_press', + 33: 'trx_suspended_jackknife', + 34: 'weighted_trx_suspended_jackknife', + 35: 'u_boat', + 36: 'weighted_u_boat', + 37: 'windmill_switches', + 38: 'weighted_windmill_switches', + 39: 'alternating_slide_out', + 40: 'weighted_alternating_slide_out', + 41: 'ghd_back_extensions', + 42: 'weighted_ghd_back_extensions', + 43: 'overhead_walk', + 44: 'inchworm', + 45: 'weighted_modified_front_lever', + }, + ), + 'course_capabilities': FieldType( + name='course_capabilities', + base_type=BASE_TYPES[0x8C], # 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', + }, + ), + 'course_point': FieldType( + name='course_point', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'crunch_exercise_name': FieldType( + name='crunch_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'bicycle_crunch', + 1: 'cable_crunch', + 2: 'circular_arm_crunch', + 3: 'crossed_arms_crunch', + 4: 'weighted_crossed_arms_crunch', + 5: 'cross_leg_reverse_crunch', + 6: 'weighted_cross_leg_reverse_crunch', + 7: 'crunch_chop', + 8: 'weighted_crunch_chop', + 9: 'double_crunch', + 10: 'weighted_double_crunch', + 11: 'elbow_to_knee_crunch', + 12: 'weighted_elbow_to_knee_crunch', + 13: 'flutter_kicks', + 14: 'weighted_flutter_kicks', + 15: 'foam_roller_reverse_crunch_on_bench', + 16: 'weighted_foam_roller_reverse_crunch_on_bench', + 17: 'foam_roller_reverse_crunch_with_dumbbell', + 18: 'foam_roller_reverse_crunch_with_medicine_ball', + 19: 'frog_press', + 20: 'hanging_knee_raise_oblique_crunch', + 21: 'weighted_hanging_knee_raise_oblique_crunch', + 22: 'hip_crossover', + 23: 'weighted_hip_crossover', + 24: 'hollow_rock', + 25: 'weighted_hollow_rock', + 26: 'incline_reverse_crunch', + 27: 'weighted_incline_reverse_crunch', + 28: 'kneeling_cable_crunch', + 29: 'kneeling_cross_crunch', + 30: 'weighted_kneeling_cross_crunch', + 31: 'kneeling_oblique_cable_crunch', + 32: 'knees_to_elbow', + 33: 'leg_extensions', + 34: 'weighted_leg_extensions', + 35: 'leg_levers', + 36: 'mcgill_curl_up', + 37: 'weighted_mcgill_curl_up', + 38: 'modified_pilates_roll_up_with_ball', + 39: 'weighted_modified_pilates_roll_up_with_ball', + 40: 'pilates_crunch', + 41: 'weighted_pilates_crunch', + 42: 'pilates_roll_up_with_ball', + 43: 'weighted_pilates_roll_up_with_ball', + 44: 'raised_legs_crunch', + 45: 'weighted_raised_legs_crunch', + 46: 'reverse_crunch', + 47: 'weighted_reverse_crunch', + 48: 'reverse_crunch_on_a_bench', + 49: 'weighted_reverse_crunch_on_a_bench', + 50: 'reverse_curl_and_lift', + 51: 'weighted_reverse_curl_and_lift', + 52: 'rotational_lift', + 53: 'weighted_rotational_lift', + 54: 'seated_alternating_reverse_crunch', + 55: 'weighted_seated_alternating_reverse_crunch', + 56: 'seated_leg_u', + 57: 'weighted_seated_leg_u', + 58: 'side_to_side_crunch_and_weave', + 59: 'weighted_side_to_side_crunch_and_weave', + 60: 'single_leg_reverse_crunch', + 61: 'weighted_single_leg_reverse_crunch', + 62: 'skater_crunch_cross', + 63: 'weighted_skater_crunch_cross', + 64: 'standing_cable_crunch', + 65: 'standing_side_crunch', + 66: 'step_climb', + 67: 'weighted_step_climb', + 68: 'swiss_ball_crunch', + 69: 'swiss_ball_reverse_crunch', + 70: 'weighted_swiss_ball_reverse_crunch', + 71: 'swiss_ball_russian_twist', + 72: 'weighted_swiss_ball_russian_twist', + 73: 'swiss_ball_side_crunch', + 74: 'weighted_swiss_ball_side_crunch', + 75: 'thoracic_crunches_on_foam_roller', + 76: 'weighted_thoracic_crunches_on_foam_roller', + 77: 'triceps_crunch', + 78: 'weighted_bicycle_crunch', + 79: 'weighted_crunch', + 80: 'weighted_swiss_ball_crunch', + 81: 'toes_to_bar', + 82: 'weighted_toes_to_bar', + 83: 'crunch', + }, + ), + 'curl_exercise_name': FieldType( + name='curl_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'alternating_dumbbell_biceps_curl', + 1: 'alternating_dumbbell_biceps_curl_on_swiss_ball', + 2: 'alternating_incline_dumbbell_biceps_curl', + 3: 'barbell_biceps_curl', + 4: 'barbell_reverse_wrist_curl', + 5: 'barbell_wrist_curl', + 6: 'behind_the_back_barbell_reverse_wrist_curl', + 7: 'behind_the_back_one_arm_cable_curl', + 8: 'cable_biceps_curl', + 9: 'cable_hammer_curl', + 10: 'cheating_barbell_biceps_curl', + 11: 'close_grip_ez_bar_biceps_curl', + 12: 'cross_body_dumbbell_hammer_curl', + 13: 'dead_hang_biceps_curl', + 14: 'decline_hammer_curl', + 15: 'dumbbell_biceps_curl_with_static_hold', + 16: 'dumbbell_hammer_curl', + 17: 'dumbbell_reverse_wrist_curl', + 18: 'dumbbell_wrist_curl', + 19: 'ez_bar_preacher_curl', + 20: 'forward_bend_biceps_curl', + 21: 'hammer_curl_to_press', + 22: 'incline_dumbbell_biceps_curl', + 23: 'incline_offset_thumb_dumbbell_curl', + 24: 'kettlebell_biceps_curl', + 25: 'lying_concentration_cable_curl', + 26: 'one_arm_preacher_curl', + 27: 'plate_pinch_curl', + 28: 'preacher_curl_with_cable', + 29: 'reverse_ez_bar_curl', + 30: 'reverse_grip_wrist_curl', + 31: 'reverse_grip_barbell_biceps_curl', + 32: 'seated_alternating_dumbbell_biceps_curl', + 33: 'seated_dumbbell_biceps_curl', + 34: 'seated_reverse_dumbbell_curl', + 35: 'split_stance_offset_pinky_dumbbell_curl', + 36: 'standing_alternating_dumbbell_curls', + 37: 'standing_dumbbell_biceps_curl', + 38: 'standing_ez_bar_biceps_curl', + 39: 'static_curl', + 40: 'swiss_ball_dumbbell_overhead_triceps_extension', + 41: 'swiss_ball_ez_bar_preacher_curl', + 42: 'twisting_standing_dumbbell_biceps_curl', + 43: 'wide_grip_ez_bar_biceps_curl', + }, + ), + 'date_mode': FieldType( + name='date_mode', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'day_month', + 1: 'month_day', + }, + ), + 'date_time': FieldType( # seconds since UTC 00:00 Dec 31 1989 + name='date_time', + base_type=BASE_TYPES[0x86], # uint32 + ), + 'day_of_week': FieldType( + name='day_of_week', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'sunday', + 1: 'monday', + 2: 'tuesday', + 3: 'wednesday', + 4: 'thursday', + 5: 'friday', + 6: 'saturday', + }, + ), + 'deadlift_exercise_name': FieldType( + name='deadlift_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'barbell_deadlift', + 1: 'barbell_straight_leg_deadlift', + 2: 'dumbbell_deadlift', + 3: 'dumbbell_single_leg_deadlift_to_row', + 4: 'dumbbell_straight_leg_deadlift', + 5: 'kettlebell_floor_to_shelf', + 6: 'one_arm_one_leg_deadlift', + 7: 'rack_pull', + 8: 'rotational_dumbbell_straight_leg_deadlift', + 9: 'single_arm_deadlift', + 10: 'single_leg_barbell_deadlift', + 11: 'single_leg_barbell_straight_leg_deadlift', + 12: 'single_leg_deadlift_with_barbell', + 13: 'single_leg_rdl_circuit', + 14: 'single_leg_romanian_deadlift_with_dumbbell', + 15: 'sumo_deadlift', + 16: 'sumo_deadlift_high_pull', + 17: 'trap_bar_deadlift', + 18: 'wide_grip_barbell_deadlift', + }, + ), + 'device_index': FieldType( + name='device_index', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'creator', # Creator of the file is always device index 0. + }, + ), + 'digital_watchface_layout': FieldType( + name='digital_watchface_layout', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'traditional', + 1: 'modern', + 2: 'bold', + }, + ), + 'display_heart': FieldType( + name='display_heart', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'bpm', + 1: 'max', + 2: 'reserve', + }, + ), + 'display_measure': FieldType( + name='display_measure', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'metric', + 1: 'statute', + 2: 'nautical', + }, + ), + 'display_orientation': FieldType( + name='display_orientation', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'auto', # automatic if the device supports it + 1: 'portrait', + 2: 'landscape', + 3: 'portrait_flipped', # portrait mode but rotated 180 degrees + 4: 'landscape_flipped', # landscape mode but rotated 180 degrees + }, + ), + 'display_position': FieldType( + name='display_position', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'degree', # dd.dddddd + 1: 'degree_minute', # dddmm.mmm + 2: 'degree_minute_second', # dddmmss + 3: 'austrian_grid', # Austrian Grid (BMN) + 4: 'british_grid', # British National Grid + 5: 'dutch_grid', # Dutch grid system + 6: 'hungarian_grid', # Hungarian grid system + 7: 'finnish_grid', # Finnish grid system Zone3 KKJ27 + 8: 'german_grid', # Gausss Krueger (German) + 9: 'icelandic_grid', # Icelandic Grid + 10: 'indonesian_equatorial', # Indonesian Equatorial LCO + 11: 'indonesian_irian', # Indonesian Irian LCO + 12: 'indonesian_southern', # Indonesian Southern LCO + 13: 'india_zone_0', # India zone 0 + 14: 'india_zone_IA', # India zone IA + 15: 'india_zone_IB', # India zone IB + 16: 'india_zone_IIA', # India zone IIA + 17: 'india_zone_IIB', # India zone IIB + 18: 'india_zone_IIIA', # India zone IIIA + 19: 'india_zone_IIIB', # India zone IIIB + 20: 'india_zone_IVA', # India zone IVA + 21: 'india_zone_IVB', # India zone IVB + 22: 'irish_transverse', # Irish Transverse Mercator + 23: 'irish_grid', # Irish Grid + 24: 'loran', # Loran TD + 25: 'maidenhead_grid', # Maidenhead grid system + 26: 'mgrs_grid', # MGRS grid system + 27: 'new_zealand_grid', # New Zealand grid system + 28: 'new_zealand_transverse', # New Zealand Transverse Mercator + 29: 'qatar_grid', # Qatar National Grid + 30: 'modified_swedish_grid', # Modified RT-90 (Sweden) + 31: 'swedish_grid', # RT-90 (Sweden) + 32: 'south_african_grid', # South African Grid + 33: 'swiss_grid', # Swiss CH-1903 grid + 34: 'taiwan_grid', # Taiwan Grid + 35: 'united_states_grid', # United States National Grid + 36: 'utm_ups_grid', # UTM/UPS grid system + 37: 'west_malayan', # West Malayan RSO + 38: 'borneo_rso', # Borneo RSO + 39: 'estonian_grid', # Estonian grid system + 40: 'latvian_grid', # Latvian Transverse Mercator + 41: 'swedish_ref_99_grid', # Reference Grid 99 TM (Swedish) + }, + ), + 'display_power': FieldType( + name='display_power', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'watts', + 1: 'percent_ftp', + }, + ), + 'dive_alarm_type': FieldType( + name='dive_alarm_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'depth', + 1: 'time', + }, + ), + 'dive_backlight_mode': FieldType( + name='dive_backlight_mode', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'at_depth', + 1: 'always_on', + }, + ), + 'dive_gas_status': FieldType( + name='dive_gas_status', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'disabled', + 1: 'enabled', + 2: 'backup_only', + }, + ), + 'event': FieldType( + name='event', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'timer', # Group 0. Start / stop_all + 3: 'workout', # start / stop + 4: 'workout_step', # Start at beginning of workout. Stop at end of each step. + 5: 'power_down', # stop_all group 0 + 6: 'power_up', # stop_all group 0 + 7: 'off_course', # start / stop group 0 + 8: 'session', # Stop at end of each session. + 9: 'lap', # Stop at end of each lap. + 10: 'course_point', # marker + 11: 'battery', # marker + 12: 'virtual_partner_pace', # Group 1. Start at beginning of activity if VP enabled, when VP pace is changed during activity or VP enabled mid activity. stop_disable when VP disabled. + 13: 'hr_high_alert', # Group 0. Start / stop when in alert condition. + 14: 'hr_low_alert', # Group 0. Start / stop when in alert condition. + 15: 'speed_high_alert', # Group 0. Start / stop when in alert condition. + 16: 'speed_low_alert', # Group 0. Start / stop when in alert condition. + 17: 'cad_high_alert', # Group 0. Start / stop when in alert condition. + 18: 'cad_low_alert', # Group 0. Start / stop when in alert condition. + 19: 'power_high_alert', # Group 0. Start / stop when in alert condition. + 20: 'power_low_alert', # Group 0. Start / stop when in alert condition. + 21: 'recovery_hr', # marker + 22: 'battery_low', # marker + 23: 'time_duration_alert', # Group 1. Start if enabled mid activity (not required at start of activity). Stop when duration is reached. stop_disable if disabled. + 24: 'distance_duration_alert', # Group 1. Start if enabled mid activity (not required at start of activity). Stop when duration is reached. stop_disable if disabled. + 25: 'calorie_duration_alert', # Group 1. Start if enabled mid activity (not required at start of activity). Stop when duration is reached. stop_disable if disabled. + 26: 'activity', # Group 1.. Stop at end of activity. + 27: 'fitness_equipment', # marker + 28: 'length', # Stop at end of each length. + 32: 'user_marker', # marker + 33: 'sport_point', # marker + 36: 'calibration', # start/stop/marker + 42: 'front_gear_change', # marker + 43: 'rear_gear_change', # marker + 44: 'rider_position_change', # marker + 45: 'elev_high_alert', # Group 0. Start / stop when in alert condition. + 46: 'elev_low_alert', # Group 0. Start / stop when in alert condition. + 47: 'comm_timeout', # marker + }, + ), + 'event_type': FieldType( + name='event_type', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'exd_data_units': FieldType( + name='exd_data_units', + base_type=BASE_TYPES[0x00], # 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', + 42: 'inches_hg', + 43: 'mm_hg', + 44: 'mbars', + 45: 'hecto_pascals', + 46: 'feet_per_min', + 47: 'meters_per_min', + 48: 'meters_per_sec', + 49: 'eight_cardinal', + }, + ), + 'exd_descriptors': FieldType( + name='exd_descriptors', + base_type=BASE_TYPES[0x00], # 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', # Combined gear information + 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', + 85: 'compass_heading', + 86: 'gps_heading', + 87: 'gps_elevation', + 88: 'anaerobic_training_effect', + 89: 'course', + 90: 'off_course', + 91: 'glide_ratio', + 92: 'vertical_distance', + 93: 'vmg', + 94: 'ambient_pressure', + 95: 'pressure', + 96: 'vam', + }, + ), + 'exd_display_type': FieldType( + name='exd_display_type', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'exd_layout': FieldType( + name='exd_layout', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'exd_qualifiers': FieldType( + name='exd_qualifiers', + base_type=BASE_TYPES[0x00], # 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', + 32: 'moving', + 33: 'stopped', + 34: 'estimated_total', + 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', + }, + ), + 'exercise_category': FieldType( + name='exercise_category', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'bench_press', + 1: 'calf_raise', + 2: 'cardio', + 3: 'carry', + 4: 'chop', + 5: 'core', + 6: 'crunch', + 7: 'curl', + 8: 'deadlift', + 9: 'flye', + 10: 'hip_raise', + 11: 'hip_stability', + 12: 'hip_swing', + 13: 'hyperextension', + 14: 'lateral_raise', + 15: 'leg_curl', + 16: 'leg_raise', + 17: 'lunge', + 18: 'olympic_lift', + 19: 'plank', + 20: 'plyo', + 21: 'pull_up', + 22: 'push_up', + 23: 'row', + 24: 'shoulder_press', + 25: 'shoulder_stability', + 26: 'shrug', + 27: 'sit_up', + 28: 'squat', + 29: 'total_body', + 30: 'triceps_extension', + 31: 'warm_up', + 32: 'run', + 65534: 'unknown', + }, + ), + 'file': FieldType( + name='file', + base_type=BASE_TYPES[0x00], # enum + values={ + 1: 'device', # Read only, single file. Must be in root directory. + 2: 'settings', # Read/write, single file. Directory=Settings + 3: 'sport', # Read/write, multiple files, file number = sport type. Directory=Sports + 4: 'activity', # Read/erase, multiple files. Directory=Activities + 5: 'workout', # Read/write/erase, multiple files. Directory=Workouts + 6: 'course', # Read/write/erase, multiple files. Directory=Courses + 7: 'schedules', # Read/write, single file. Directory=Schedules + 9: 'weight', # Read only, single file. Circular buffer. All message definitions at start of file. Directory=Weight + 10: 'totals', # Read only, single file. Directory=Totals + 11: 'goals', # Read/write, single file. Directory=Goals + 14: 'blood_pressure', # Read only. Directory=Blood Pressure + 15: 'monitoring_a', # Read only. Directory=Monitoring. File number=sub type. + 20: 'activity_summary', # Read/erase, multiple files. Directory=Activities + 28: 'monitoring_daily', + 32: 'monitoring_b', # Read only. Directory=Monitoring. File number=identifier + 34: 'segment', # Read/write/erase. Multiple Files. Directory=Segments + 35: 'segment_list', # Read/write/erase. Single File. Directory=Segments + 40: 'exd_configuration', # Read/write/erase. Single File. Directory=Settings + 0xF7: 'mfg_range_min', # 0xF7 - 0xFE reserved for manufacturer specific file types + 0xFE: 'mfg_range_max', # 0xF7 - 0xFE reserved for manufacturer specific file types + }, + ), + 'file_flags': FieldType( + name='file_flags', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x02: 'read', + 0x04: 'write', + 0x08: 'erase', + }, + ), + 'fit_base_type': FieldType( + name='fit_base_type', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'enum', + 1: 'sint8', + 2: 'uint8', + 7: 'string', + 10: 'uint8z', + 13: 'byte', + 131: 'sint16', + 132: 'uint16', + 133: 'sint32', + 134: 'uint32', + 136: 'float32', + 137: 'float64', + 139: 'uint16z', + 140: 'uint32z', + 142: 'sint64', + 143: 'uint64', + 144: 'uint64z', + }, + ), + 'fit_base_unit': FieldType( + name='fit_base_unit', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'other', + 1: 'kilogram', + 2: 'pound', + }, + ), + 'fitness_equipment_state': FieldType( # fitness equipment event data + name='fitness_equipment_state', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'ready', + 1: 'in_use', + 2: 'paused', + 3: 'unknown', # lost connection to fitness equipment + }, + ), + 'flye_exercise_name': FieldType( + name='flye_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'cable_crossover', + 1: 'decline_dumbbell_flye', + 2: 'dumbbell_flye', + 3: 'incline_dumbbell_flye', + 4: 'kettlebell_flye', + 5: 'kneeling_rear_flye', + 6: 'single_arm_standing_cable_reverse_flye', + 7: 'swiss_ball_dumbbell_flye', + }, + ), + 'garmin_product': FieldType( + name='garmin_product', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 1: 'hrm1', + 2: 'axh01', # AXH01 HRM chipset + 3: 'axb01', + 4: 'axb02', + 5: 'hrm2ss', + 6: 'dsi_alf02', + 7: 'hrm3ss', + 8: 'hrm_run_single_byte_product_id', # hrm_run model for HRM ANT+ messaging + 9: 'bsm', # BSM model for ANT+ messaging + 10: 'bcm', # BCM model for ANT+ messaging + 11: 'axs01', # AXS01 HRM Bike Chipset model for ANT+ messaging + 12: 'hrm_tri_single_byte_product_id', # hrm_tri model for HRM ANT+ messaging + 14: 'fr225_single_byte_product_id', # fr225 model for HRM ANT+ messaging + 473: 'fr301_china', + 474: 'fr301_japan', + 475: 'fr301_korea', + 494: 'fr301_taiwan', + 717: 'fr405', # Forerunner 405 + 782: 'fr50', # Forerunner 50 + 987: 'fr405_japan', + 988: 'fr60', # Forerunner 60 + 1011: 'dsi_alf01', + 1018: 'fr310xt', # Forerunner 310 + 1036: 'edge500', + 1124: 'fr110', # Forerunner 110 + 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', # Also Edge Touring Plus + 1742: 'edge510_japan', + 1743: 'hrm_tri', + 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', + 1936: 'approach_s6', + 1956: 'vivo_smart', + 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', + 2417: 'virb_ultra_30', + 2429: 'index_smart_scale', + 2431: 'fr235', + 2432: 'fenix3_chronos', + 2441: 'oregon7xx', + 2444: 'rino7xx', + 2496: 'nautix', + 2530: 'edge_820', + 2531: 'edge_explore_820', + 2544: 'fenix5s', + 2547: 'd2_bravo_titanium', + 2567: 'varia_ut800', # Varia UT 800 SW + 2593: 'running_dynamics_pod', + 2604: 'fenix5x', + 2606: 'vivo_fit_jr', + 2691: 'fr935', + 2697: 'fenix5', + 10007: 'sdm4', # SDM4 footpod + 10014: 'edge_remote', + 20119: 'training_center', + 65531: 'connectiq_simulator', + 65532: 'android_antplus_plugin', + 65534: 'connect', # Garmin Connect website + }, + ), + 'gender': FieldType( + name='gender', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'female', + 1: 'male', + }, + ), + 'goal': FieldType( + name='goal', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'time', + 1: 'distance', + 2: 'calories', + 3: 'frequency', + 4: 'steps', + 5: 'ascent', + 6: 'active_minutes', + }, + ), + 'goal_recurrence': FieldType( + name='goal_recurrence', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'off', + 1: 'daily', + 2: 'weekly', + 3: 'monthly', + 4: 'yearly', + 5: 'custom', + }, + ), + 'goal_source': FieldType( + name='goal_source', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'auto', # Device generated + 1: 'community', # Social network sourced goal + 2: 'user', # Manually generated + }, + ), + 'hip_raise_exercise_name': FieldType( + name='hip_raise_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'barbell_hip_thrust_on_floor', + 1: 'barbell_hip_thrust_with_bench', + 2: 'bent_knee_swiss_ball_reverse_hip_raise', + 3: 'weighted_bent_knee_swiss_ball_reverse_hip_raise', + 4: 'bridge_with_leg_extension', + 5: 'weighted_bridge_with_leg_extension', + 6: 'clam_bridge', + 7: 'front_kick_tabletop', + 8: 'weighted_front_kick_tabletop', + 9: 'hip_extension_and_cross', + 10: 'weighted_hip_extension_and_cross', + 11: 'hip_raise', + 12: 'weighted_hip_raise', + 13: 'hip_raise_with_feet_on_swiss_ball', + 14: 'weighted_hip_raise_with_feet_on_swiss_ball', + 15: 'hip_raise_with_head_on_bosu_ball', + 16: 'weighted_hip_raise_with_head_on_bosu_ball', + 17: 'hip_raise_with_head_on_swiss_ball', + 18: 'weighted_hip_raise_with_head_on_swiss_ball', + 19: 'hip_raise_with_knee_squeeze', + 20: 'weighted_hip_raise_with_knee_squeeze', + 21: 'incline_rear_leg_extension', + 22: 'weighted_incline_rear_leg_extension', + 23: 'kettlebell_swing', + 24: 'marching_hip_raise', + 25: 'weighted_marching_hip_raise', + 26: 'marching_hip_raise_with_feet_on_a_swiss_ball', + 27: 'weighted_marching_hip_raise_with_feet_on_a_swiss_ball', + 28: 'reverse_hip_raise', + 29: 'weighted_reverse_hip_raise', + 30: 'single_leg_hip_raise', + 31: 'weighted_single_leg_hip_raise', + 32: 'single_leg_hip_raise_with_foot_on_bench', + 33: 'weighted_single_leg_hip_raise_with_foot_on_bench', + 34: 'single_leg_hip_raise_with_foot_on_bosu_ball', + 35: 'weighted_single_leg_hip_raise_with_foot_on_bosu_ball', + 36: 'single_leg_hip_raise_with_foot_on_foam_roller', + 37: 'weighted_single_leg_hip_raise_with_foot_on_foam_roller', + 38: 'single_leg_hip_raise_with_foot_on_medicine_ball', + 39: 'weighted_single_leg_hip_raise_with_foot_on_medicine_ball', + 40: 'single_leg_hip_raise_with_head_on_bosu_ball', + 41: 'weighted_single_leg_hip_raise_with_head_on_bosu_ball', + 42: 'weighted_clam_bridge', + }, + ), + 'hip_stability_exercise_name': FieldType( + name='hip_stability_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'band_side_lying_leg_raise', + 1: 'dead_bug', + 2: 'weighted_dead_bug', + 3: 'external_hip_raise', + 4: 'weighted_external_hip_raise', + 5: 'fire_hydrant_kicks', + 6: 'weighted_fire_hydrant_kicks', + 7: 'hip_circles', + 8: 'weighted_hip_circles', + 9: 'inner_thigh_lift', + 10: 'weighted_inner_thigh_lift', + 11: 'lateral_walks_with_band_at_ankles', + 12: 'pretzel_side_kick', + 13: 'weighted_pretzel_side_kick', + 14: 'prone_hip_internal_rotation', + 15: 'weighted_prone_hip_internal_rotation', + 16: 'quadruped', + 17: 'quadruped_hip_extension', + 18: 'weighted_quadruped_hip_extension', + 19: 'quadruped_with_leg_lift', + 20: 'weighted_quadruped_with_leg_lift', + 21: 'side_lying_leg_raise', + 22: 'weighted_side_lying_leg_raise', + 23: 'sliding_hip_adduction', + 24: 'weighted_sliding_hip_adduction', + 25: 'standing_adduction', + 26: 'weighted_standing_adduction', + 27: 'standing_cable_hip_abduction', + 28: 'standing_hip_abduction', + 29: 'weighted_standing_hip_abduction', + 30: 'standing_rear_leg_raise', + 31: 'weighted_standing_rear_leg_raise', + 32: 'supine_hip_internal_rotation', + 33: 'weighted_supine_hip_internal_rotation', + }, + ), + 'hip_swing_exercise_name': FieldType( + name='hip_swing_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'single_arm_kettlebell_swing', + 1: 'single_arm_dumbbell_swing', + 2: 'step_out_swing', + }, + ), + 'hr_type': FieldType( + name='hr_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'normal', + 1: 'irregular', + }, + ), + 'hr_zone_calc': FieldType( + name='hr_zone_calc', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'custom', + 1: 'percent_max_hr', + 2: 'percent_hrr', + }, + ), + 'hyperextension_exercise_name': FieldType( + name='hyperextension_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'back_extension_with_opposite_arm_and_leg_reach', + 1: 'weighted_back_extension_with_opposite_arm_and_leg_reach', + 2: 'base_rotations', + 3: 'weighted_base_rotations', + 4: 'bent_knee_reverse_hyperextension', + 5: 'weighted_bent_knee_reverse_hyperextension', + 6: 'hollow_hold_and_roll', + 7: 'weighted_hollow_hold_and_roll', + 8: 'kicks', + 9: 'weighted_kicks', + 10: 'knee_raises', + 11: 'weighted_knee_raises', + 12: 'kneeling_superman', + 13: 'weighted_kneeling_superman', + 14: 'lat_pull_down_with_row', + 15: 'medicine_ball_deadlift_to_reach', + 16: 'one_arm_one_leg_row', + 17: 'one_arm_row_with_band', + 18: 'overhead_lunge_with_medicine_ball', + 19: 'plank_knee_tucks', + 20: 'weighted_plank_knee_tucks', + 21: 'side_step', + 22: 'weighted_side_step', + 23: 'single_leg_back_extension', + 24: 'weighted_single_leg_back_extension', + 25: 'spine_extension', + 26: 'weighted_spine_extension', + 27: 'static_back_extension', + 28: 'weighted_static_back_extension', + 29: 'superman_from_floor', + 30: 'weighted_superman_from_floor', + 31: 'swiss_ball_back_extension', + 32: 'weighted_swiss_ball_back_extension', + 33: 'swiss_ball_hyperextension', + 34: 'weighted_swiss_ball_hyperextension', + 35: 'swiss_ball_opposite_arm_and_leg_lift', + 36: 'weighted_swiss_ball_opposite_arm_and_leg_lift', + }, + ), + 'intensity': FieldType( + name='intensity', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'active', + 1: 'rest', + 2: 'warmup', + 3: 'cooldown', + }, + ), + 'language': FieldType( + name='language', + base_type=BASE_TYPES[0x00], # 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', + 34: 'malaysian', + 35: 'vietnamese', + 36: 'burmese', + 37: 'mongolian', + 254: 'custom', + }, + ), + 'language_bits_0': FieldType( # Bit field corresponding to language enum type (1 << language). + name='language_bits_0', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'english', + 0x02: 'french', + 0x04: 'italian', + 0x08: 'german', + 0x10: 'spanish', + 0x20: 'croatian', + 0x40: 'czech', + 0x80: 'danish', + }, + ), + 'language_bits_1': FieldType( + name='language_bits_1', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'dutch', + 0x02: 'finnish', + 0x04: 'greek', + 0x08: 'hungarian', + 0x10: 'norwegian', + 0x20: 'polish', + 0x40: 'portuguese', + 0x80: 'slovakian', + }, + ), + 'language_bits_2': FieldType( + name='language_bits_2', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'slovenian', + 0x02: 'swedish', + 0x04: 'russian', + 0x08: 'turkish', + 0x10: 'latvian', + 0x20: 'ukrainian', + 0x40: 'arabic', + 0x80: 'farsi', + }, + ), + 'language_bits_3': FieldType( + name='language_bits_3', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'bulgarian', + 0x02: 'romanian', + 0x04: 'chinese', + 0x08: 'japanese', + 0x10: 'korean', + 0x20: 'taiwanese', + 0x40: 'thai', + 0x80: 'hebrew', + }, + ), + 'language_bits_4': FieldType( + name='language_bits_4', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'brazilian_portuguese', + 0x02: 'indonesian', + 0x04: 'malaysian', + 0x08: 'vietnamese', + 0x10: 'burmese', + 0x20: 'mongolian', + }, + ), + 'lap_trigger': FieldType( + name='lap_trigger', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'lateral_raise_exercise_name': FieldType( + name='lateral_raise_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: '45_degree_cable_external_rotation', + 1: 'alternating_lateral_raise_with_static_hold', + 2: 'bar_muscle_up', + 3: 'bent_over_lateral_raise', + 4: 'cable_diagonal_raise', + 5: 'cable_front_raise', + 6: 'calorie_row', + 7: 'combo_shoulder_raise', + 8: 'dumbbell_diagonal_raise', + 9: 'dumbbell_v_raise', + 10: 'front_raise', + 11: 'leaning_dumbbell_lateral_raise', + 12: 'lying_dumbbell_raise', + 13: 'muscle_up', + 14: 'one_arm_cable_lateral_raise', + 15: 'overhand_grip_rear_lateral_raise', + 16: 'plate_raises', + 17: 'ring_dip', + 18: 'weighted_ring_dip', + 19: 'ring_muscle_up', + 20: 'weighted_ring_muscle_up', + 21: 'rope_climb', + 22: 'weighted_rope_climb', + 23: 'scaption', + 24: 'seated_lateral_raise', + 25: 'seated_rear_lateral_raise', + 26: 'side_lying_lateral_raise', + 27: 'standing_lift', + 28: 'suspended_row', + 29: 'underhand_grip_rear_lateral_raise', + 30: 'wall_slide', + 31: 'weighted_wall_slide', + }, + ), + 'left_right_balance': FieldType( + name='left_right_balance', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0x7F: 'mask', # % contribution + 0x80: 'right', # data corresponds to right if set, otherwise unknown + }, + ), + 'left_right_balance_100': FieldType( + name='left_right_balance_100', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0x3FFF: 'mask', # % contribution scaled by 100 + 0x8000: 'right', # data corresponds to right if set, otherwise unknown + }, + ), + 'leg_curl_exercise_name': FieldType( + name='leg_curl_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'leg_curl', + 1: 'weighted_leg_curl', + 2: 'good_morning', + 3: 'seated_barbell_good_morning', + 4: 'single_leg_barbell_good_morning', + 5: 'single_leg_sliding_leg_curl', + 6: 'sliding_leg_curl', + 7: 'split_barbell_good_morning', + 8: 'split_stance_extension', + 9: 'staggered_stance_good_morning', + 10: 'swiss_ball_hip_raise_and_leg_curl', + 11: 'zercher_good_morning', + }, + ), + 'leg_raise_exercise_name': FieldType( + name='leg_raise_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'hanging_knee_raise', + 1: 'hanging_leg_raise', + 2: 'weighted_hanging_leg_raise', + 3: 'hanging_single_leg_raise', + 4: 'weighted_hanging_single_leg_raise', + 5: 'kettlebell_leg_raises', + 6: 'leg_lowering_drill', + 7: 'weighted_leg_lowering_drill', + 8: 'lying_straight_leg_raise', + 9: 'weighted_lying_straight_leg_raise', + 10: 'medicine_ball_leg_drops', + 11: 'quadruped_leg_raise', + 12: 'weighted_quadruped_leg_raise', + 13: 'reverse_leg_raise', + 14: 'weighted_reverse_leg_raise', + 15: 'reverse_leg_raise_on_swiss_ball', + 16: 'weighted_reverse_leg_raise_on_swiss_ball', + 17: 'single_leg_lowering_drill', + 18: 'weighted_single_leg_lowering_drill', + 19: 'weighted_hanging_knee_raise', + 20: 'lateral_stepover', + 21: 'weighted_lateral_stepover', + }, + ), + 'length_type': FieldType( + name='length_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'idle', # Rest period. Length with no strokes + 1: 'active', # Length with strokes. + }, + ), + 'local_date_time': FieldType( # seconds since 00:00 Dec 31 1989 in local time zone + name='local_date_time', + base_type=BASE_TYPES[0x86], # uint32 + values={ + 0x10000000: 'min', # if date_time is < 0x10000000 then it is system time (seconds from device power on) + }, + ), + 'local_device_type': FieldType( + name='local_device_type', + base_type=BASE_TYPES[0x02], # uint8 + ), + 'localtime_into_day': FieldType( # number of seconds into the day since local 00:00:00 + name='localtime_into_day', + base_type=BASE_TYPES[0x86], # uint32 + ), + 'lunge_exercise_name': FieldType( + name='lunge_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'overhead_lunge', + 1: 'lunge_matrix', + 2: 'weighted_lunge_matrix', + 3: 'alternating_barbell_forward_lunge', + 4: 'alternating_dumbbell_lunge_with_reach', + 5: 'back_foot_elevated_dumbbell_split_squat', + 6: 'barbell_box_lunge', + 7: 'barbell_bulgarian_split_squat', + 8: 'barbell_crossover_lunge', + 9: 'barbell_front_split_squat', + 10: 'barbell_lunge', + 11: 'barbell_reverse_lunge', + 12: 'barbell_side_lunge', + 13: 'barbell_split_squat', + 14: 'core_control_rear_lunge', + 15: 'diagonal_lunge', + 16: 'drop_lunge', + 17: 'dumbbell_box_lunge', + 18: 'dumbbell_bulgarian_split_squat', + 19: 'dumbbell_crossover_lunge', + 20: 'dumbbell_diagonal_lunge', + 21: 'dumbbell_lunge', + 22: 'dumbbell_lunge_and_rotation', + 23: 'dumbbell_overhead_bulgarian_split_squat', + 24: 'dumbbell_reverse_lunge_to_high_knee_and_press', + 25: 'dumbbell_side_lunge', + 26: 'elevated_front_foot_barbell_split_squat', + 27: 'front_foot_elevated_dumbbell_split_squat', + 28: 'gunslinger_lunge', + 29: 'lawnmower_lunge', + 30: 'low_lunge_with_isometric_adduction', + 31: 'low_side_to_side_lunge', + 32: 'lunge', + 33: 'weighted_lunge', + 34: 'lunge_with_arm_reach', + 35: 'lunge_with_diagonal_reach', + 36: 'lunge_with_side_bend', + 37: 'offset_dumbbell_lunge', + 38: 'offset_dumbbell_reverse_lunge', + 39: 'overhead_bulgarian_split_squat', + 40: 'overhead_dumbbell_reverse_lunge', + 41: 'overhead_dumbbell_split_squat', + 42: 'overhead_lunge_with_rotation', + 43: 'reverse_barbell_box_lunge', + 44: 'reverse_box_lunge', + 45: 'reverse_dumbbell_box_lunge', + 46: 'reverse_dumbbell_crossover_lunge', + 47: 'reverse_dumbbell_diagonal_lunge', + 48: 'reverse_lunge_with_reach_back', + 49: 'weighted_reverse_lunge_with_reach_back', + 50: 'reverse_lunge_with_twist_and_overhead_reach', + 51: 'weighted_reverse_lunge_with_twist_and_overhead_reach', + 52: 'reverse_sliding_box_lunge', + 53: 'weighted_reverse_sliding_box_lunge', + 54: 'reverse_sliding_lunge', + 55: 'weighted_reverse_sliding_lunge', + 56: 'runners_lunge_to_balance', + 57: 'weighted_runners_lunge_to_balance', + 58: 'shifting_side_lunge', + 59: 'side_and_crossover_lunge', + 60: 'weighted_side_and_crossover_lunge', + 61: 'side_lunge', + 62: 'weighted_side_lunge', + 63: 'side_lunge_and_press', + 64: 'side_lunge_jump_off', + 65: 'side_lunge_sweep', + 66: 'weighted_side_lunge_sweep', + 67: 'side_lunge_to_crossover_tap', + 68: 'weighted_side_lunge_to_crossover_tap', + 69: 'side_to_side_lunge_chops', + 70: 'weighted_side_to_side_lunge_chops', + 71: 'siff_jump_lunge', + 72: 'weighted_siff_jump_lunge', + 73: 'single_arm_reverse_lunge_and_press', + 74: 'sliding_lateral_lunge', + 75: 'weighted_sliding_lateral_lunge', + 76: 'walking_barbell_lunge', + 77: 'walking_dumbbell_lunge', + 78: 'walking_lunge', + 79: 'weighted_walking_lunge', + 80: 'wide_grip_overhead_barbell_split_squat', + }, + ), + 'manufacturer': FieldType( + name='manufacturer', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 1: 'garmin', + 2: 'garmin_fr405_antfs', # Do not use. Used by FR405 for ANTFS man id. + 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', # Indoorcycling Group + 97: 'MiPulse', + 98: 'bsx_athletics', + 99: 'look', + 100: 'campagnolo_srl', + 101: 'body_bike_smart', + 102: 'praxisworks', + 103: 'limits_technology', # Limits Technology Ltd. + 104: 'topaction_technology', # TopAction Technology Inc. + 105: 'cosinuss', + 106: 'fitcare', + 107: 'magene', + 108: 'giant_manufacturing_co', + 109: 'tigrasport', # Tigrasport + 110: 'salutron', + 111: 'technogym', + 112: 'bryton_sensors', + 113: 'latitude_limited', + 114: 'soaring_technology', + 115: 'igpsport', + 116: 'thinkrider', + 117: 'gopher_sport', + 118: 'waterrower', + 119: 'orangetheory', + 120: 'inpeak', + 121: 'kinetic', + 122: 'johnson_health_tech', + 123: 'polar_electro', + 124: 'seesense', + 255: 'development', + 257: 'healthandlife', + 258: 'lezyne', + 259: 'scribe_labs', + 260: 'zwift', + 261: 'watteam', + 262: 'recon', + 263: 'favero_electronics', + 264: 'dynovelo', + 265: 'strava', + 266: 'precor', # Amer Sports + 267: 'bryton', + 268: 'sram', + 269: 'navman', # MiTAC Global Corporation (Mio Technology) + 270: 'cobi', # COBI GmbH + 271: 'spivi', + 272: 'mio_magellan', + 273: 'evesports', + 274: 'sensitivus_gauge', + 275: 'podoon', + 276: 'life_time_fitness', + 277: 'falco_e_motors', # Falco eMotors Inc. + 278: 'minoura', + 279: 'cycliq', + 280: 'luxottica', + 281: 'trainer_road', + 282: 'the_sufferfest', + 283: 'fullspeedahead', + 284: 'virtualtraining', + 285: 'feedbacksports', + 286: 'omata', + 287: 'vdo', + 288: 'magneticdays', + 289: 'hammerhead', + 290: 'kinetic_by_kurt', + 291: 'shapelog', + 292: 'dabuziduo', + 293: 'jetblack', + 5759: 'actigraphcorp', + }, + ), + 'mesg_count': FieldType( + name='mesg_count', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'num_per_file', + 1: 'max_per_file', + 2: 'max_per_file_type', + }, + ), + 'mesg_num': FieldType( + name='mesg_num', + base_type=BASE_TYPES[0x84], # 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', + 80: 'ant_rx', + 81: 'ant_tx', + 82: 'ant_channel_id', + 101: 'length', + 103: 'monitoring_info', + 105: 'pad', + 106: 'slave_device', + 127: 'connectivity', + 128: 'weather_conditions', + 129: 'weather_alert', + 131: 'cadence_zone', + 132: 'hr', + 142: 'segment_lap', + 145: 'memo_glob', + 148: 'segment_id', + 149: 'segment_leaderboard_entry', + 150: 'segment_point', + 151: 'segment_file', + 158: 'workout_session', + 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', + 209: 'barometer_data', + 210: 'one_d_sensor_calibration', + 225: 'set', + 227: 'stress_level', + 258: 'dive_settings', + 259: 'dive_gas', + 262: 'dive_alarm', + 264: 'exercise_title', + 268: 'dive_summary', + }, + ), + 'message_index': FieldType( + name='message_index', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0x0FFF: 'mask', # index + 0x7000: 'reserved', # reserved (default 0) + 0x8000: 'selected', # message is selected if set + }, + ), + 'olympic_lift_exercise_name': FieldType( + name='olympic_lift_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'barbell_hang_power_clean', + 1: 'barbell_hang_squat_clean', + 2: 'barbell_power_clean', + 3: 'barbell_power_snatch', + 4: 'barbell_squat_clean', + 5: 'clean_and_jerk', + 6: 'barbell_hang_power_snatch', + 7: 'barbell_hang_pull', + 8: 'barbell_high_pull', + 9: 'barbell_snatch', + 10: 'barbell_split_jerk', + 11: 'clean', + 12: 'dumbbell_clean', + 13: 'dumbbell_hang_pull', + 14: 'one_hand_dumbbell_split_snatch', + 15: 'push_jerk', + 16: 'single_arm_dumbbell_snatch', + 17: 'single_arm_hang_snatch', + 18: 'single_arm_kettlebell_snatch', + 19: 'split_jerk', + 20: 'squat_clean_and_jerk', + }, + ), + 'plank_exercise_name': FieldType( + name='plank_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: '45_degree_plank', + 1: 'weighted_45_degree_plank', + 2: '90_degree_static_hold', + 3: 'weighted_90_degree_static_hold', + 4: 'bear_crawl', + 5: 'weighted_bear_crawl', + 6: 'cross_body_mountain_climber', + 7: 'weighted_cross_body_mountain_climber', + 8: 'elbow_plank_pike_jacks', + 9: 'weighted_elbow_plank_pike_jacks', + 10: 'elevated_feet_plank', + 11: 'weighted_elevated_feet_plank', + 12: 'elevator_abs', + 13: 'weighted_elevator_abs', + 14: 'extended_plank', + 15: 'weighted_extended_plank', + 16: 'full_plank_passe_twist', + 17: 'weighted_full_plank_passe_twist', + 18: 'inching_elbow_plank', + 19: 'weighted_inching_elbow_plank', + 20: 'inchworm_to_side_plank', + 21: 'weighted_inchworm_to_side_plank', + 22: 'kneeling_plank', + 23: 'weighted_kneeling_plank', + 24: 'kneeling_side_plank_with_leg_lift', + 25: 'weighted_kneeling_side_plank_with_leg_lift', + 26: 'lateral_roll', + 27: 'weighted_lateral_roll', + 28: 'lying_reverse_plank', + 29: 'weighted_lying_reverse_plank', + 30: 'medicine_ball_mountain_climber', + 31: 'weighted_medicine_ball_mountain_climber', + 32: 'modified_mountain_climber_and_extension', + 33: 'weighted_modified_mountain_climber_and_extension', + 34: 'mountain_climber', + 35: 'weighted_mountain_climber', + 36: 'mountain_climber_on_sliding_discs', + 37: 'weighted_mountain_climber_on_sliding_discs', + 38: 'mountain_climber_with_feet_on_bosu_ball', + 39: 'weighted_mountain_climber_with_feet_on_bosu_ball', + 40: 'mountain_climber_with_hands_on_bench', + 41: 'mountain_climber_with_hands_on_swiss_ball', + 42: 'weighted_mountain_climber_with_hands_on_swiss_ball', + 43: 'plank', + 44: 'plank_jacks_with_feet_on_sliding_discs', + 45: 'weighted_plank_jacks_with_feet_on_sliding_discs', + 46: 'plank_knee_twist', + 47: 'weighted_plank_knee_twist', + 48: 'plank_pike_jumps', + 49: 'weighted_plank_pike_jumps', + 50: 'plank_pikes', + 51: 'weighted_plank_pikes', + 52: 'plank_to_stand_up', + 53: 'weighted_plank_to_stand_up', + 54: 'plank_with_arm_raise', + 55: 'weighted_plank_with_arm_raise', + 56: 'plank_with_knee_to_elbow', + 57: 'weighted_plank_with_knee_to_elbow', + 58: 'plank_with_oblique_crunch', + 59: 'weighted_plank_with_oblique_crunch', + 60: 'plyometric_side_plank', + 61: 'weighted_plyometric_side_plank', + 62: 'rolling_side_plank', + 63: 'weighted_rolling_side_plank', + 64: 'side_kick_plank', + 65: 'weighted_side_kick_plank', + 66: 'side_plank', + 67: 'weighted_side_plank', + 68: 'side_plank_and_row', + 69: 'weighted_side_plank_and_row', + 70: 'side_plank_lift', + 71: 'weighted_side_plank_lift', + 72: 'side_plank_with_elbow_on_bosu_ball', + 73: 'weighted_side_plank_with_elbow_on_bosu_ball', + 74: 'side_plank_with_feet_on_bench', + 75: 'weighted_side_plank_with_feet_on_bench', + 76: 'side_plank_with_knee_circle', + 77: 'weighted_side_plank_with_knee_circle', + 78: 'side_plank_with_knee_tuck', + 79: 'weighted_side_plank_with_knee_tuck', + 80: 'side_plank_with_leg_lift', + 81: 'weighted_side_plank_with_leg_lift', + 82: 'side_plank_with_reach_under', + 83: 'weighted_side_plank_with_reach_under', + 84: 'single_leg_elevated_feet_plank', + 85: 'weighted_single_leg_elevated_feet_plank', + 86: 'single_leg_flex_and_extend', + 87: 'weighted_single_leg_flex_and_extend', + 88: 'single_leg_side_plank', + 89: 'weighted_single_leg_side_plank', + 90: 'spiderman_plank', + 91: 'weighted_spiderman_plank', + 92: 'straight_arm_plank', + 93: 'weighted_straight_arm_plank', + 94: 'straight_arm_plank_with_shoulder_touch', + 95: 'weighted_straight_arm_plank_with_shoulder_touch', + 96: 'swiss_ball_plank', + 97: 'weighted_swiss_ball_plank', + 98: 'swiss_ball_plank_leg_lift', + 99: 'weighted_swiss_ball_plank_leg_lift', + 100: 'swiss_ball_plank_leg_lift_and_hold', + 101: 'swiss_ball_plank_with_feet_on_bench', + 102: 'weighted_swiss_ball_plank_with_feet_on_bench', + 103: 'swiss_ball_prone_jackknife', + 104: 'weighted_swiss_ball_prone_jackknife', + 105: 'swiss_ball_side_plank', + 106: 'weighted_swiss_ball_side_plank', + 107: 'three_way_plank', + 108: 'weighted_three_way_plank', + 109: 'towel_plank_and_knee_in', + 110: 'weighted_towel_plank_and_knee_in', + 111: 't_stabilization', + 112: 'weighted_t_stabilization', + 113: 'turkish_get_up_to_side_plank', + 114: 'weighted_turkish_get_up_to_side_plank', + 115: 'two_point_plank', + 116: 'weighted_two_point_plank', + 117: 'weighted_plank', + 118: 'wide_stance_plank_with_diagonal_arm_lift', + 119: 'weighted_wide_stance_plank_with_diagonal_arm_lift', + 120: 'wide_stance_plank_with_diagonal_leg_lift', + 121: 'weighted_wide_stance_plank_with_diagonal_leg_lift', + 122: 'wide_stance_plank_with_leg_lift', + 123: 'weighted_wide_stance_plank_with_leg_lift', + 124: 'wide_stance_plank_with_opposite_arm_and_leg_lift', + 125: 'weighted_mountain_climber_with_hands_on_bench', + 126: 'weighted_swiss_ball_plank_leg_lift_and_hold', + 127: 'weighted_wide_stance_plank_with_opposite_arm_and_leg_lift', + }, + ), + 'plyo_exercise_name': FieldType( + name='plyo_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'alternating_jump_lunge', + 1: 'weighted_alternating_jump_lunge', + 2: 'barbell_jump_squat', + 3: 'body_weight_jump_squat', + 4: 'weighted_jump_squat', + 5: 'cross_knee_strike', + 6: 'weighted_cross_knee_strike', + 7: 'depth_jump', + 8: 'weighted_depth_jump', + 9: 'dumbbell_jump_squat', + 10: 'dumbbell_split_jump', + 11: 'front_knee_strike', + 12: 'weighted_front_knee_strike', + 13: 'high_box_jump', + 14: 'weighted_high_box_jump', + 15: 'isometric_explosive_body_weight_jump_squat', + 16: 'weighted_isometric_explosive_jump_squat', + 17: 'lateral_leap_and_hop', + 18: 'weighted_lateral_leap_and_hop', + 19: 'lateral_plyo_squats', + 20: 'weighted_lateral_plyo_squats', + 21: 'lateral_slide', + 22: 'weighted_lateral_slide', + 23: 'medicine_ball_overhead_throws', + 24: 'medicine_ball_side_throw', + 25: 'medicine_ball_slam', + 26: 'side_to_side_medicine_ball_throws', + 27: 'side_to_side_shuffle_jump', + 28: 'weighted_side_to_side_shuffle_jump', + 29: 'squat_jump_onto_box', + 30: 'weighted_squat_jump_onto_box', + 31: 'squat_jumps_in_and_out', + 32: 'weighted_squat_jumps_in_and_out', + }, + ), + 'power_phase_type': FieldType( + name='power_phase_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'power_phase_start_angle', + 1: 'power_phase_end_angle', + 2: 'power_phase_arc_length', + 3: 'power_phase_center', + }, + ), + 'pull_up_exercise_name': FieldType( + name='pull_up_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'banded_pull_ups', + 1: '30_degree_lat_pulldown', + 2: 'band_assisted_chin_up', + 3: 'close_grip_chin_up', + 4: 'weighted_close_grip_chin_up', + 5: 'close_grip_lat_pulldown', + 6: 'crossover_chin_up', + 7: 'weighted_crossover_chin_up', + 8: 'ez_bar_pullover', + 9: 'hanging_hurdle', + 10: 'weighted_hanging_hurdle', + 11: 'kneeling_lat_pulldown', + 12: 'kneeling_underhand_grip_lat_pulldown', + 13: 'lat_pulldown', + 14: 'mixed_grip_chin_up', + 15: 'weighted_mixed_grip_chin_up', + 16: 'mixed_grip_pull_up', + 17: 'weighted_mixed_grip_pull_up', + 18: 'reverse_grip_pulldown', + 19: 'standing_cable_pullover', + 20: 'straight_arm_pulldown', + 21: 'swiss_ball_ez_bar_pullover', + 22: 'towel_pull_up', + 23: 'weighted_towel_pull_up', + 24: 'weighted_pull_up', + 25: 'wide_grip_lat_pulldown', + 26: 'wide_grip_pull_up', + 27: 'weighted_wide_grip_pull_up', + 28: 'burpee_pull_up', + 29: 'weighted_burpee_pull_up', + 30: 'jumping_pull_ups', + 31: 'weighted_jumping_pull_ups', + 32: 'kipping_pull_up', + 33: 'weighted_kipping_pull_up', + 34: 'l_pull_up', + 35: 'weighted_l_pull_up', + 36: 'suspended_chin_up', + 37: 'weighted_suspended_chin_up', + 38: 'pull_up', + }, + ), + 'push_up_exercise_name': FieldType( + name='push_up_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'chest_press_with_band', + 1: 'alternating_staggered_push_up', + 2: 'weighted_alternating_staggered_push_up', + 3: 'alternating_hands_medicine_ball_push_up', + 4: 'weighted_alternating_hands_medicine_ball_push_up', + 5: 'bosu_ball_push_up', + 6: 'weighted_bosu_ball_push_up', + 7: 'clapping_push_up', + 8: 'weighted_clapping_push_up', + 9: 'close_grip_medicine_ball_push_up', + 10: 'weighted_close_grip_medicine_ball_push_up', + 11: 'close_hands_push_up', + 12: 'weighted_close_hands_push_up', + 13: 'decline_push_up', + 14: 'weighted_decline_push_up', + 15: 'diamond_push_up', + 16: 'weighted_diamond_push_up', + 17: 'explosive_crossover_push_up', + 18: 'weighted_explosive_crossover_push_up', + 19: 'explosive_push_up', + 20: 'weighted_explosive_push_up', + 21: 'feet_elevated_side_to_side_push_up', + 22: 'weighted_feet_elevated_side_to_side_push_up', + 23: 'hand_release_push_up', + 24: 'weighted_hand_release_push_up', + 25: 'handstand_push_up', + 26: 'weighted_handstand_push_up', + 27: 'incline_push_up', + 28: 'weighted_incline_push_up', + 29: 'isometric_explosive_push_up', + 30: 'weighted_isometric_explosive_push_up', + 31: 'judo_push_up', + 32: 'weighted_judo_push_up', + 33: 'kneeling_push_up', + 34: 'weighted_kneeling_push_up', + 35: 'medicine_ball_chest_pass', + 36: 'medicine_ball_push_up', + 37: 'weighted_medicine_ball_push_up', + 38: 'one_arm_push_up', + 39: 'weighted_one_arm_push_up', + 40: 'weighted_push_up', + 41: 'push_up_and_row', + 42: 'weighted_push_up_and_row', + 43: 'push_up_plus', + 44: 'weighted_push_up_plus', + 45: 'push_up_with_feet_on_swiss_ball', + 46: 'weighted_push_up_with_feet_on_swiss_ball', + 47: 'push_up_with_one_hand_on_medicine_ball', + 48: 'weighted_push_up_with_one_hand_on_medicine_ball', + 49: 'shoulder_push_up', + 50: 'weighted_shoulder_push_up', + 51: 'single_arm_medicine_ball_push_up', + 52: 'weighted_single_arm_medicine_ball_push_up', + 53: 'spiderman_push_up', + 54: 'weighted_spiderman_push_up', + 55: 'stacked_feet_push_up', + 56: 'weighted_stacked_feet_push_up', + 57: 'staggered_hands_push_up', + 58: 'weighted_staggered_hands_push_up', + 59: 'suspended_push_up', + 60: 'weighted_suspended_push_up', + 61: 'swiss_ball_push_up', + 62: 'weighted_swiss_ball_push_up', + 63: 'swiss_ball_push_up_plus', + 64: 'weighted_swiss_ball_push_up_plus', + 65: 't_push_up', + 66: 'weighted_t_push_up', + 67: 'triple_stop_push_up', + 68: 'weighted_triple_stop_push_up', + 69: 'wide_hands_push_up', + 70: 'weighted_wide_hands_push_up', + 71: 'parallette_handstand_push_up', + 72: 'weighted_parallette_handstand_push_up', + 73: 'ring_handstand_push_up', + 74: 'weighted_ring_handstand_push_up', + 75: 'ring_push_up', + 76: 'weighted_ring_push_up', + 77: 'push_up', + }, + ), + 'pwr_zone_calc': FieldType( + name='pwr_zone_calc', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'custom', + 1: 'percent_ftp', + }, + ), + 'rider_position_type': FieldType( + name='rider_position_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'seated', + 1: 'standing', + 2: 'transition_to_seated', + 3: 'transition_to_standing', + }, + ), + 'row_exercise_name': FieldType( + name='row_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'barbell_straight_leg_deadlift_to_row', + 1: 'cable_row_standing', + 2: 'dumbbell_row', + 3: 'elevated_feet_inverted_row', + 4: 'weighted_elevated_feet_inverted_row', + 5: 'face_pull', + 6: 'face_pull_with_external_rotation', + 7: 'inverted_row_with_feet_on_swiss_ball', + 8: 'weighted_inverted_row_with_feet_on_swiss_ball', + 9: 'kettlebell_row', + 10: 'modified_inverted_row', + 11: 'weighted_modified_inverted_row', + 12: 'neutral_grip_alternating_dumbbell_row', + 13: 'one_arm_bent_over_row', + 14: 'one_legged_dumbbell_row', + 15: 'renegade_row', + 16: 'reverse_grip_barbell_row', + 17: 'rope_handle_cable_row', + 18: 'seated_cable_row', + 19: 'seated_dumbbell_row', + 20: 'single_arm_cable_row', + 21: 'single_arm_cable_row_and_rotation', + 22: 'single_arm_inverted_row', + 23: 'weighted_single_arm_inverted_row', + 24: 'single_arm_neutral_grip_dumbbell_row', + 25: 'single_arm_neutral_grip_dumbbell_row_and_rotation', + 26: 'suspended_inverted_row', + 27: 'weighted_suspended_inverted_row', + 28: 't_bar_row', + 29: 'towel_grip_inverted_row', + 30: 'weighted_towel_grip_inverted_row', + 31: 'underhand_grip_cable_row', + 32: 'v_grip_cable_row', + 33: 'wide_grip_seated_cable_row', + }, + ), + 'run_exercise_name': FieldType( + name='run_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'run', + 1: 'walk', + 2: 'jog', + 3: 'sprint', + }, + ), + 'schedule': FieldType( + name='schedule', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'workout', + 1: 'course', + }, + ), + 'segment_delete_status': FieldType( + name='segment_delete_status', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'do_not_delete', + 1: 'delete_one', + 2: 'delete_all', + }, + ), + 'segment_lap_status': FieldType( + name='segment_lap_status', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'end', + 1: 'fail', + }, + ), + 'segment_leaderboard_type': FieldType( + name='segment_leaderboard_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'overall', + 1: 'personal_best', + 2: 'connections', + 3: 'group', + 4: 'challenger', + 5: 'kom', + 6: 'qom', + 7: 'pr', + 8: 'goal', + 9: 'rival', + 10: 'club_leader', + }, + ), + 'segment_selection_type': FieldType( + name='segment_selection_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'starred', + 1: 'suggested', + }, + ), + 'sensor_type': FieldType( + name='sensor_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'accelerometer', + 1: 'gyroscope', + 2: 'compass', # Magnetometer + 3: 'barometer', + }, + ), + 'session_trigger': FieldType( + name='session_trigger', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'activity_end', + 1: 'manual', # User changed sport. + 2: 'auto_multi_sport', # Auto multi-sport feature is enabled and user pressed lap button to advance session. + 3: 'fitness_equipment', # Auto sport change caused by user linking to fitness equipment. + }, + ), + 'set_type': FieldType( + name='set_type', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'rest', + 1: 'active', + }, + ), + 'shoulder_press_exercise_name': FieldType( + name='shoulder_press_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'alternating_dumbbell_shoulder_press', + 1: 'arnold_press', + 2: 'barbell_front_squat_to_push_press', + 3: 'barbell_push_press', + 4: 'barbell_shoulder_press', + 5: 'dead_curl_press', + 6: 'dumbbell_alternating_shoulder_press_and_twist', + 7: 'dumbbell_hammer_curl_to_lunge_to_press', + 8: 'dumbbell_push_press', + 9: 'floor_inverted_shoulder_press', + 10: 'weighted_floor_inverted_shoulder_press', + 11: 'inverted_shoulder_press', + 12: 'weighted_inverted_shoulder_press', + 13: 'one_arm_push_press', + 14: 'overhead_barbell_press', + 15: 'overhead_dumbbell_press', + 16: 'seated_barbell_shoulder_press', + 17: 'seated_dumbbell_shoulder_press', + 18: 'single_arm_dumbbell_shoulder_press', + 19: 'single_arm_step_up_and_press', + 20: 'smith_machine_overhead_press', + 21: 'split_stance_hammer_curl_to_press', + 22: 'swiss_ball_dumbbell_shoulder_press', + 23: 'weight_plate_front_raise', + }, + ), + 'shoulder_stability_exercise_name': FieldType( + name='shoulder_stability_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: '90_degree_cable_external_rotation', + 1: 'band_external_rotation', + 2: 'band_internal_rotation', + 3: 'bent_arm_lateral_raise_and_external_rotation', + 4: 'cable_external_rotation', + 5: 'dumbbell_face_pull_with_external_rotation', + 6: 'floor_i_raise', + 7: 'weighted_floor_i_raise', + 8: 'floor_t_raise', + 9: 'weighted_floor_t_raise', + 10: 'floor_y_raise', + 11: 'weighted_floor_y_raise', + 12: 'incline_i_raise', + 13: 'weighted_incline_i_raise', + 14: 'incline_l_raise', + 15: 'weighted_incline_l_raise', + 16: 'incline_t_raise', + 17: 'weighted_incline_t_raise', + 18: 'incline_w_raise', + 19: 'weighted_incline_w_raise', + 20: 'incline_y_raise', + 21: 'weighted_incline_y_raise', + 22: 'lying_external_rotation', + 23: 'seated_dumbbell_external_rotation', + 24: 'standing_l_raise', + 25: 'swiss_ball_i_raise', + 26: 'weighted_swiss_ball_i_raise', + 27: 'swiss_ball_t_raise', + 28: 'weighted_swiss_ball_t_raise', + 29: 'swiss_ball_w_raise', + 30: 'weighted_swiss_ball_w_raise', + 31: 'swiss_ball_y_raise', + 32: 'weighted_swiss_ball_y_raise', + }, + ), + 'shrug_exercise_name': FieldType( + name='shrug_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'barbell_jump_shrug', + 1: 'barbell_shrug', + 2: 'barbell_upright_row', + 3: 'behind_the_back_smith_machine_shrug', + 4: 'dumbbell_jump_shrug', + 5: 'dumbbell_shrug', + 6: 'dumbbell_upright_row', + 7: 'incline_dumbbell_shrug', + 8: 'overhead_barbell_shrug', + 9: 'overhead_dumbbell_shrug', + 10: 'scaption_and_shrug', + 11: 'scapular_retraction', + 12: 'serratus_chair_shrug', + 13: 'weighted_serratus_chair_shrug', + 14: 'serratus_shrug', + 15: 'weighted_serratus_shrug', + 16: 'wide_grip_jump_shrug', + }, + ), + 'side': FieldType( + name='side', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'right', + 1: 'left', + }, + ), + 'sit_up_exercise_name': FieldType( + name='sit_up_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'alternating_sit_up', + 1: 'weighted_alternating_sit_up', + 2: 'bent_knee_v_up', + 3: 'weighted_bent_knee_v_up', + 4: 'butterfly_sit_up', + 5: 'weighted_butterfly_situp', + 6: 'cross_punch_roll_up', + 7: 'weighted_cross_punch_roll_up', + 8: 'crossed_arms_sit_up', + 9: 'weighted_crossed_arms_sit_up', + 10: 'get_up_sit_up', + 11: 'weighted_get_up_sit_up', + 12: 'hovering_sit_up', + 13: 'weighted_hovering_sit_up', + 14: 'kettlebell_sit_up', + 15: 'medicine_ball_alternating_v_up', + 16: 'medicine_ball_sit_up', + 17: 'medicine_ball_v_up', + 18: 'modified_sit_up', + 19: 'negative_sit_up', + 20: 'one_arm_full_sit_up', + 21: 'reclining_circle', + 22: 'weighted_reclining_circle', + 23: 'reverse_curl_up', + 24: 'weighted_reverse_curl_up', + 25: 'single_leg_swiss_ball_jackknife', + 26: 'weighted_single_leg_swiss_ball_jackknife', + 27: 'the_teaser', + 28: 'the_teaser_weighted', + 29: 'three_part_roll_down', + 30: 'weighted_three_part_roll_down', + 31: 'v_up', + 32: 'weighted_v_up', + 33: 'weighted_russian_twist_on_swiss_ball', + 34: 'weighted_sit_up', + 35: 'x_abs', + 36: 'weighted_x_abs', + 37: 'sit_up', + }, + ), + 'source_type': FieldType( + name='source_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'ant', # External device connected with ANT + 1: 'antplus', # External device connected with ANT+ + 2: 'bluetooth', # External device connected with BT + 3: 'bluetooth_low_energy', # External device connected with BLE + 4: 'wifi', # External device connected with Wifi + 5: 'local', # Onboard device + }, + ), + 'sport': FieldType( + name='sport', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'generic', + 1: 'running', + 2: 'cycling', + 3: 'transition', # Mulitsport 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', # All is for goals only to include all sports. + }, + ), + 'sport_bits_0': FieldType( # Bit field corresponding to sport enum type (1 << sport). + name='sport_bits_0', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'generic', + 0x02: 'running', + 0x04: 'cycling', + 0x08: 'transition', # Mulitsport transition + 0x10: 'fitness_equipment', + 0x20: 'swimming', + 0x40: 'basketball', + 0x80: 'soccer', + }, + ), + 'sport_bits_1': FieldType( # Bit field corresponding to sport enum type (1 << (sport-8)). + name='sport_bits_1', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'tennis', + 0x02: 'american_football', + 0x04: 'training', + 0x08: 'walking', + 0x10: 'cross_country_skiing', + 0x20: 'alpine_skiing', + 0x40: 'snowboarding', + 0x80: 'rowing', + }, + ), + 'sport_bits_2': FieldType( # Bit field corresponding to sport enum type (1 << (sport-16)). + name='sport_bits_2', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'mountaineering', + 0x02: 'hiking', + 0x04: 'multisport', + 0x08: 'paddling', + 0x10: 'flying', + 0x20: 'e_biking', + 0x40: 'motorcycling', + 0x80: 'boating', + }, + ), + 'sport_bits_3': FieldType( # Bit field corresponding to sport enum type (1 << (sport-24)). + name='sport_bits_3', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'driving', + 0x02: 'golf', + 0x04: 'hang_gliding', + 0x08: 'horseback_riding', + 0x10: 'hunting', + 0x20: 'fishing', + 0x40: 'inline_skating', + 0x80: 'rock_climbing', + }, + ), + 'sport_bits_4': FieldType( # Bit field corresponding to sport enum type (1 << (sport-32)). + name='sport_bits_4', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'sailing', + 0x02: 'ice_skating', + 0x04: 'sky_diving', + 0x08: 'snowshoeing', + 0x10: 'snowmobiling', + 0x20: 'stand_up_paddleboarding', + 0x40: 'surfing', + 0x80: 'wakeboarding', + }, + ), + 'sport_bits_5': FieldType( # Bit field corresponding to sport enum type (1 << (sport-40)). + name='sport_bits_5', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'water_skiing', + 0x02: 'kayaking', + 0x04: 'rafting', + 0x08: 'windsurfing', + 0x10: 'kitesurfing', + 0x20: 'tactical', + 0x40: 'jumpmaster', + 0x80: 'boxing', + }, + ), + 'sport_bits_6': FieldType( # Bit field corresponding to sport enum type (1 << (sport-48)). + name='sport_bits_6', + base_type=BASE_TYPES[0x0A], # uint8z + values={ + 0x01: 'floor_climbing', + }, + ), + 'sport_event': FieldType( + name='sport_event', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'uncategorized', + 1: 'geocaching', + 2: 'fitness', + 3: 'recreation', + 4: 'race', + 5: 'special_event', + 6: 'training', + 7: 'transportation', + 8: 'touring', + }, + ), + 'squat_exercise_name': FieldType( + name='squat_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'leg_press', + 1: 'back_squat_with_body_bar', + 2: 'back_squats', + 3: 'weighted_back_squats', + 4: 'balancing_squat', + 5: 'weighted_balancing_squat', + 6: 'barbell_back_squat', + 7: 'barbell_box_squat', + 8: 'barbell_front_squat', + 9: 'barbell_hack_squat', + 10: 'barbell_hang_squat_snatch', + 11: 'barbell_lateral_step_up', + 12: 'barbell_quarter_squat', + 13: 'barbell_siff_squat', + 14: 'barbell_squat_snatch', + 15: 'barbell_squat_with_heels_raised', + 16: 'barbell_stepover', + 17: 'barbell_step_up', + 18: 'bench_squat_with_rotational_chop', + 19: 'weighted_bench_squat_with_rotational_chop', + 20: 'body_weight_wall_squat', + 21: 'weighted_wall_squat', + 22: 'box_step_squat', + 23: 'weighted_box_step_squat', + 24: 'braced_squat', + 25: 'crossed_arm_barbell_front_squat', + 26: 'crossover_dumbbell_step_up', + 27: 'dumbbell_front_squat', + 28: 'dumbbell_split_squat', + 29: 'dumbbell_squat', + 30: 'dumbbell_squat_clean', + 31: 'dumbbell_stepover', + 32: 'dumbbell_step_up', + 33: 'elevated_single_leg_squat', + 34: 'weighted_elevated_single_leg_squat', + 35: 'figure_four_squats', + 36: 'weighted_figure_four_squats', + 37: 'goblet_squat', + 38: 'kettlebell_squat', + 39: 'kettlebell_swing_overhead', + 40: 'kettlebell_swing_with_flip_to_squat', + 41: 'lateral_dumbbell_step_up', + 42: 'one_legged_squat', + 43: 'overhead_dumbbell_squat', + 44: 'overhead_squat', + 45: 'partial_single_leg_squat', + 46: 'weighted_partial_single_leg_squat', + 47: 'pistol_squat', + 48: 'weighted_pistol_squat', + 49: 'plie_slides', + 50: 'weighted_plie_slides', + 51: 'plie_squat', + 52: 'weighted_plie_squat', + 53: 'prisoner_squat', + 54: 'weighted_prisoner_squat', + 55: 'single_leg_bench_get_up', + 56: 'weighted_single_leg_bench_get_up', + 57: 'single_leg_bench_squat', + 58: 'weighted_single_leg_bench_squat', + 59: 'single_leg_squat_on_swiss_ball', + 60: 'weighted_single_leg_squat_on_swiss_ball', + 61: 'squat', + 62: 'weighted_squat', + 63: 'squats_with_band', + 64: 'staggered_squat', + 65: 'weighted_staggered_squat', + 66: 'step_up', + 67: 'weighted_step_up', + 68: 'suitcase_squats', + 69: 'sumo_squat', + 70: 'sumo_squat_slide_in', + 71: 'weighted_sumo_squat_slide_in', + 72: 'sumo_squat_to_high_pull', + 73: 'sumo_squat_to_stand', + 74: 'weighted_sumo_squat_to_stand', + 75: 'sumo_squat_with_rotation', + 76: 'weighted_sumo_squat_with_rotation', + 77: 'swiss_ball_body_weight_wall_squat', + 78: 'weighted_swiss_ball_wall_squat', + 79: 'thrusters', + 80: 'uneven_squat', + 81: 'weighted_uneven_squat', + 82: 'waist_slimming_squat', + 83: 'wall_ball', + 84: 'wide_stance_barbell_squat', + 85: 'wide_stance_goblet_squat', + 86: 'zercher_squat', + }, + ), + 'stroke_type': FieldType( + name='stroke_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'no_event', + 1: 'other', # stroke was detected but cannot be identified + 2: 'serve', + 3: 'forehand', + 4: 'backhand', + 5: 'smash', + }, + ), + 'sub_sport': FieldType( + name='sub_sport', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'generic', + 1: 'treadmill', # Run/Fitness Equipment + 2: 'street', # Run + 3: 'trail', # Run + 4: 'track', # Run + 5: 'spin', # Cycling + 6: 'indoor_cycling', # Cycling/Fitness Equipment + 7: 'road', # Cycling + 8: 'mountain', # Cycling + 9: 'downhill', # Cycling + 10: 'recumbent', # Cycling + 11: 'cyclocross', # Cycling + 12: 'hand_cycling', # Cycling + 13: 'track_cycling', # Cycling + 14: 'indoor_rowing', # Fitness Equipment + 15: 'elliptical', # Fitness Equipment + 16: 'stair_climbing', # Fitness Equipment + 17: 'lap_swimming', # Swimming + 18: 'open_water', # Swimming + 19: 'flexibility_training', # Training + 20: 'strength_training', # Training + 21: 'warm_up', # Tennis + 22: 'match', # Tennis + 23: 'exercise', # Tennis + 24: 'challenge', + 25: 'indoor_skiing', # Fitness Equipment + 26: 'cardio_training', # Training + 27: 'indoor_walking', # Walking/Fitness Equipment + 28: 'e_bike_fitness', # E-Biking + 29: 'bmx', # Cycling + 30: 'casual_walking', # Walking + 31: 'speed_walking', # Walking + 32: 'bike_to_run_transition', # Transition + 33: 'run_to_bike_transition', # Transition + 34: 'swim_to_bike_transition', # Transition + 35: 'atv', # Motorcycling + 36: 'motocross', # Motorcycling + 37: 'backcountry', # Alpine Skiing/Snowboarding + 38: 'resort', # Alpine Skiing/Snowboarding + 39: 'rc_drone', # Flying + 40: 'wingsuit', # Flying + 41: 'whitewater', # Kayaking/Rafting + 42: 'skate_skiing', # Cross Country Skiing + 43: 'yoga', # Training + 44: 'pilates', # Training + 45: 'indoor_running', # Run + 46: 'gravel_cycling', # Cycling + 47: 'e_bike_mountain', # Cycling + 48: 'commuting', # Cycling + 49: 'mixed_surface', # Cycling + 50: 'navigate', + 51: 'track_me', + 52: 'map', + 53: 'single_gas_diving', # Diving + 54: 'multi_gas_diving', # Diving + 55: 'gauge_diving', # Diving + 56: 'apnea_diving', # Diving + 57: 'apnea_hunting', # Diving + 58: 'virtual_activity', + 59: 'obstacle', # Used for events where participants run, crawl through mud, climb over walls, etc. + 254: 'all', + }, + ), + 'supported_exd_screen_layouts': FieldType( + name='supported_exd_screen_layouts', + base_type=BASE_TYPES[0x8C], # 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', + }, + ), + 'swim_stroke': FieldType( + name='swim_stroke', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'freestyle', + 1: 'backstroke', + 2: 'breaststroke', + 3: 'butterfly', + 4: 'drill', + 5: 'mixed', + 6: 'im', # IM is a mixed interval containing the same number of lengths for each of: Butterfly, Backstroke, Breaststroke, Freestyle, swam in that order. + }, + ), + 'switch': FieldType( + name='switch', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'off', + 1: 'on', + 2: 'auto', + }, + ), + 'time_into_day': FieldType( # number of seconds into the day since 00:00:00 UTC + name='time_into_day', + base_type=BASE_TYPES[0x86], # uint32 + ), + 'time_mode': FieldType( + name='time_mode', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'hour12', + 1: 'hour24', # Does not use a leading zero and has a colon + 2: 'military', # Uses a leading zero and does not have a colon + 3: 'hour_12_with_seconds', + 4: 'hour_24_with_seconds', + 5: 'utc', + }, + ), + 'time_zone': FieldType( + name='time_zone', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'timer_trigger': FieldType( # timer event data + name='timer_trigger', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'manual', + 1: 'auto', + 2: 'fitness_equipment', + }, + ), + 'tissue_model_type': FieldType( + name='tissue_model_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'zhl_16c', # Buhlmann's decompression algorithm, version C + }, + ), + 'tone': FieldType( + name='tone', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'off', + 1: 'tone', + 2: 'vibrate', + 3: 'tone_and_vibrate', + }, + ), + 'total_body_exercise_name': FieldType( + name='total_body_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'burpee', + 1: 'weighted_burpee', + 2: 'burpee_box_jump', + 3: 'weighted_burpee_box_jump', + 4: 'high_pull_burpee', + 5: 'man_makers', + 6: 'one_arm_burpee', + 7: 'squat_thrusts', + 8: 'weighted_squat_thrusts', + 9: 'squat_plank_push_up', + 10: 'weighted_squat_plank_push_up', + 11: 'standing_t_rotation_balance', + 12: 'weighted_standing_t_rotation_balance', + }, + ), + 'triceps_extension_exercise_name': FieldType( + name='triceps_extension_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'bench_dip', + 1: 'weighted_bench_dip', + 2: 'body_weight_dip', + 3: 'cable_kickback', + 4: 'cable_lying_triceps_extension', + 5: 'cable_overhead_triceps_extension', + 6: 'dumbbell_kickback', + 7: 'dumbbell_lying_triceps_extension', + 8: 'ez_bar_overhead_triceps_extension', + 9: 'incline_dip', + 10: 'weighted_incline_dip', + 11: 'incline_ez_bar_lying_triceps_extension', + 12: 'lying_dumbbell_pullover_to_extension', + 13: 'lying_ez_bar_triceps_extension', + 14: 'lying_triceps_extension_to_close_grip_bench_press', + 15: 'overhead_dumbbell_triceps_extension', + 16: 'reclining_triceps_press', + 17: 'reverse_grip_pressdown', + 18: 'reverse_grip_triceps_pressdown', + 19: 'rope_pressdown', + 20: 'seated_barbell_overhead_triceps_extension', + 21: 'seated_dumbbell_overhead_triceps_extension', + 22: 'seated_ez_bar_overhead_triceps_extension', + 23: 'seated_single_arm_overhead_dumbbell_extension', + 24: 'single_arm_dumbbell_overhead_triceps_extension', + 25: 'single_dumbbell_seated_overhead_triceps_extension', + 26: 'single_leg_bench_dip_and_kick', + 27: 'weighted_single_leg_bench_dip_and_kick', + 28: 'single_leg_dip', + 29: 'weighted_single_leg_dip', + 30: 'static_lying_triceps_extension', + 31: 'suspended_dip', + 32: 'weighted_suspended_dip', + 33: 'swiss_ball_dumbbell_lying_triceps_extension', + 34: 'swiss_ball_ez_bar_lying_triceps_extension', + 35: 'swiss_ball_ez_bar_overhead_triceps_extension', + 36: 'tabletop_dip', + 37: 'weighted_tabletop_dip', + 38: 'triceps_extension_on_floor', + 39: 'triceps_pressdown', + 40: 'weighted_dip', + }, + ), + 'turn_type': FieldType( + name='turn_type', + base_type=BASE_TYPES[0x00], # 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', + }, + ), + 'user_local_id': FieldType( + name='user_local_id', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0x0000: 'local_min', + 0x000F: 'local_max', + 0x0010: 'stationary_min', + 0x00FF: 'stationary_max', + 0x0100: 'portable_min', + 0xFFFE: 'portable_max', + }, + ), + 'warm_up_exercise_name': FieldType( + name='warm_up_exercise_name', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0: 'quadruped_rocking', + 1: 'neck_tilts', + 2: 'ankle_circles', + 3: 'ankle_dorsiflexion_with_band', + 4: 'ankle_internal_rotation', + 5: 'arm_circles', + 6: 'bent_over_reach_to_sky', + 7: 'cat_camel', + 8: 'elbow_to_foot_lunge', + 9: 'forward_and_backward_leg_swings', + 10: 'groiners', + 11: 'inverted_hamstring_stretch', + 12: 'lateral_duck_under', + 13: 'neck_rotations', + 14: 'opposite_arm_and_leg_balance', + 15: 'reach_roll_and_lift', + 16: 'scorpion', + 17: 'shoulder_circles', + 18: 'side_to_side_leg_swings', + 19: 'sleeper_stretch', + 20: 'slide_out', + 21: 'swiss_ball_hip_crossover', + 22: 'swiss_ball_reach_roll_and_lift', + 23: 'swiss_ball_windshield_wipers', + 24: 'thoracic_rotation', + 25: 'walking_high_kicks', + 26: 'walking_high_knees', + 27: 'walking_knee_hugs', + 28: 'walking_leg_cradles', + 29: 'walkout', + 30: 'walkout_from_push_up_position', + }, + ), + 'watchface_mode': FieldType( + name='watchface_mode', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'digital', + 1: 'analog', + 2: 'connect_iq', + 3: 'disabled', + }, + ), + 'water_type': FieldType( + name='water_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'fresh', + 1: 'salt', + 2: 'en13319', + 3: 'custom', + }, + ), + 'weather_report': FieldType( + name='weather_report', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'current', + 1: 'forecast', # Deprecated use hourly_forecast instead + 1: 'hourly_forecast', + 2: 'daily_forecast', + }, + ), + 'weather_severe_type': FieldType( + name='weather_severe_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'unspecified', + 1: 'tornado', + 2: 'tsunami', + 3: 'hurricane', + 4: 'extreme_wind', + 5: 'typhoon', + 6: 'inland_hurricane', + 7: 'hurricane_force_wind', + 8: 'waterspout', + 9: 'severe_thunderstorm', + 10: 'wreckhouse_winds', + 11: 'les_suetes_wind', + 12: 'avalanche', + 13: 'flash_flood', + 14: 'tropical_storm', + 15: 'inland_tropical_storm', + 16: 'blizzard', + 17: 'ice_storm', + 18: 'freezing_rain', + 19: 'debris_flow', + 20: 'flash_freeze', + 21: 'dust_storm', + 22: 'high_wind', + 23: 'winter_storm', + 24: 'heavy_freezing_spray', + 25: 'extreme_cold', + 26: 'wind_chill', + 27: 'cold_wave', + 28: 'heavy_snow_alert', + 29: 'lake_effect_blowing_snow', + 30: 'snow_squall', + 31: 'lake_effect_snow', + 32: 'winter_weather', + 33: 'sleet', + 34: 'snowfall', + 35: 'snow_and_blowing_snow', + 36: 'blowing_snow', + 37: 'snow_alert', + 38: 'arctic_outflow', + 39: 'freezing_drizzle', + 40: 'storm', + 41: 'storm_surge', + 42: 'rainfall', + 43: 'areal_flood', + 44: 'coastal_flood', + 45: 'lakeshore_flood', + 46: 'excessive_heat', + 47: 'heat', + 48: 'weather', + 49: 'high_heat_and_humidity', + 50: 'humidex_and_health', + 51: 'humidex', + 52: 'gale', + 53: 'freezing_spray', + 54: 'special_marine', + 55: 'squall', + 56: 'strong_wind', + 57: 'lake_wind', + 58: 'marine_weather', + 59: 'wind', + 60: 'small_craft_hazardous_seas', + 61: 'hazardous_seas', + 62: 'small_craft', + 63: 'small_craft_winds', + 64: 'small_craft_rough_bar', + 65: 'high_water_level', + 66: 'ashfall', + 67: 'freezing_fog', + 68: 'dense_fog', + 69: 'dense_smoke', + 70: 'blowing_dust', + 71: 'hard_freeze', + 72: 'freeze', + 73: 'frost', + 74: 'fire_weather', + 75: 'flood', + 76: 'rip_tide', + 77: 'high_surf', + 78: 'smog', + 79: 'air_quality', + 80: 'brisk_wind', + 81: 'air_stagnation', + 82: 'low_water', + 83: 'hydrological', + 84: 'special_weather', + }, + ), + 'weather_severity': FieldType( + name='weather_severity', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'unknown', + 1: 'warning', + 2: 'watch', + 3: 'advisory', + 4: 'statement', + }, + ), + 'weather_status': FieldType( + name='weather_status', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'clear', + 1: 'partly_cloudy', + 2: 'mostly_cloudy', + 3: 'rain', + 4: 'snow', + 5: 'windy', + 6: 'thunderstorms', + 7: 'wintry_mix', + 8: 'fog', + 11: 'hazy', + 12: 'hail', + 13: 'scattered_showers', + 14: 'scattered_thunderstorms', + 15: 'unknown_precipitation', + 16: 'light_rain', + 17: 'heavy_rain', + 18: 'light_snow', + 19: 'heavy_snow', + 20: 'light_rain_snow', + 21: 'heavy_rain_snow', + 22: 'cloudy', + }, + ), + 'weight': FieldType( + name='weight', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 0xFFFE: 'calculating', + }, + ), + 'wkt_step_duration': FieldType( + name='wkt_step_duration', + base_type=BASE_TYPES[0x00], # 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', + 16: 'training_peaks_tss', + 17: 'repeat_until_power_last_lap_less_than', + 18: 'repeat_until_max_power_last_lap_less_than', + 19: 'power_3s_less_than', + 20: 'power_10s_less_than', + 21: 'power_30s_less_than', + 22: 'power_3s_greater_than', + 23: 'power_10s_greater_than', + 24: 'power_30s_greater_than', + 25: 'power_lap_less_than', + 26: 'power_lap_greater_than', + 27: 'repeat_until_training_peaks_tss', + 28: 'repetition_time', + 29: 'reps', + }, + ), + 'wkt_step_target': FieldType( + name='wkt_step_target', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'speed', + 1: 'heart_rate', + 2: 'open', + 3: 'cadence', + 4: 'power', + 5: 'grade', + 6: 'resistance', + 7: 'power_3s', + 8: 'power_10s', + 9: 'power_30s', + 10: 'power_lap', + 11: 'swim_stroke', + 12: 'speed_lap', + 13: 'heart_rate_lap', + }, + ), + 'workout_capabilities': FieldType( + name='workout_capabilities', + base_type=BASE_TYPES[0x8C], # uint32z + values={ + 0x00000001: 'interval', + 0x00000002: 'custom', + 0x00000004: 'fitness_equipment', + 0x00000008: 'firstbeat', + 0x00000010: 'new_leaf', + 0x00000020: 'tcx', # For backwards compatibility. Watch should add missing id fields then clear flag. + 0x00000080: 'speed', # Speed source required for workout step. + 0x00000100: 'heart_rate', # Heart rate source required for workout step. + 0x00000200: 'distance', # Distance source required for workout step. + 0x00000400: 'cadence', # Cadence source required for workout step. + 0x00000800: 'power', # Power source required for workout step. + 0x00001000: 'grade', # Grade source required for workout step. + 0x00002000: 'resistance', # Resistance source required for workout step. + 0x00004000: 'protected', + }, + ), + 'workout_equipment': FieldType( + name='workout_equipment', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'none', + 1: 'swim_fins', + 2: 'swim_kickboard', + 3: 'swim_paddles', + 4: 'swim_pull_buoy', + 5: 'swim_snorkel', + }, + ), + 'workout_hr': FieldType( # 0 - 100 indicates% of max hr; >100 indicates bpm (255 max) plus 100 + name='workout_hr', + base_type=BASE_TYPES[0x86], # uint32 + values={ + 100: 'bpm_offset', + }, + ), + 'workout_power': FieldType( # 0 - 1000 indicates % of functional threshold power; >1000 indicates watts plus 1000. + name='workout_power', + base_type=BASE_TYPES[0x86], # uint32 + values={ + 1000: 'watts_offset', + }, + ), +} + + +FIELD_TYPE_TIMESTAMP = Field(name='timestamp', type=FIELD_TYPES['date_time'], def_num=253, units='s') + + +MESSAGE_TYPES = { + # **************************** Common Messages ***************************** + 0: MessageType( # Must be first message in file. + name='file_id', + mesg_num=0, + fields={ + 0: Field( + name='type', + type=FIELD_TYPES['file'], + def_num=0, + ), + 1: Field( + name='manufacturer', + type=FIELD_TYPES['manufacturer'], + def_num=1, + ), + 2: Field( + name='product', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + subfields=( + SubField( + name='garmin_product', + def_num=2, + type=FIELD_TYPES['garmin_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=1, + value='garmin', + raw_value=1, + ), + ReferenceField( + name='manufacturer', + def_num=1, + value='dynastream', + raw_value=15, + ), + ReferenceField( + name='manufacturer', + def_num=1, + value='dynastream_oem', + raw_value=13, + ), + ), + ), + ), + ), + 3: Field( + name='serial_number', + type=BASE_TYPES[0x8C], # uint32z + def_num=3, + ), + 4: Field( # Only set for files that are can be created/erased. + name='time_created', + type=FIELD_TYPES['date_time'], + def_num=4, + ), + 5: Field( # Only set for files that are not created/erased. + name='number', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + ), + 8: Field( # Optional free form string to indicate the devices name or model + name='product_name', + type=BASE_TYPES[0x07], # string + def_num=8, + ), + }, + ), + + + # ************************************ ************************************ + 1: MessageType( + name='capabilities', + mesg_num=1, + fields={ + 0: Field( # Use language_bits_x types where x is index of array. + name='languages', + type=BASE_TYPES[0x0A], # uint8z + def_num=0, + ), + 1: Field( # Use sport_bits_x types where x is index of array. + name='sports', + type=FIELD_TYPES['sport_bits_0'], + def_num=1, + ), + 21: Field( + name='workouts_supported', + type=FIELD_TYPES['workout_capabilities'], + def_num=21, + ), + 23: Field( + name='connectivity_supported', + type=FIELD_TYPES['connectivity_capabilities'], + def_num=23, + ), + }, + ), + 4: MessageType( + name='hrm_profile', + mesg_num=4, + fields={ + 0: Field( + name='enabled', + type=FIELD_TYPES['bool'], + def_num=0, + ), + 1: Field( + name='hrm_ant_id', + type=BASE_TYPES[0x8B], # uint16z + def_num=1, + ), + 2: Field( + name='log_hrv', + type=FIELD_TYPES['bool'], + def_num=2, + ), + 3: Field( + name='hrm_ant_id_trans_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=3, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 5: MessageType( + name='sdm_profile', + mesg_num=5, + fields={ + 0: Field( + name='enabled', + type=FIELD_TYPES['bool'], + def_num=0, + ), + 1: Field( + name='sdm_ant_id', + type=BASE_TYPES[0x8B], # uint16z + def_num=1, + ), + 2: Field( + name='sdm_cal_factor', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + scale=10, + units='%', + ), + 3: Field( + name='odometer', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=100, + units='m', + ), + 4: Field( # Use footpod for speed source instead of GPS + name='speed_source', + type=FIELD_TYPES['bool'], + def_num=4, + ), + 5: Field( + name='sdm_ant_id_trans_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=5, + ), + 7: Field( # Rollover counter that can be used to extend the odometer + name='odometer_rollover', + type=BASE_TYPES[0x02], # uint8 + def_num=7, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 6: MessageType( + name='bike_profile', + mesg_num=6, + fields={ + 0: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=1, + ), + 2: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=2, + ), + 3: Field( + name='odometer', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=100, + units='m', + ), + 4: Field( + name='bike_spd_ant_id', + type=BASE_TYPES[0x8B], # uint16z + def_num=4, + ), + 5: Field( + name='bike_cad_ant_id', + type=BASE_TYPES[0x8B], # uint16z + def_num=5, + ), + 6: Field( + name='bike_spdcad_ant_id', + type=BASE_TYPES[0x8B], # uint16z + def_num=6, + ), + 7: Field( + name='bike_power_ant_id', + type=BASE_TYPES[0x8B], # uint16z + def_num=7, + ), + 8: Field( + name='custom_wheelsize', + type=BASE_TYPES[0x84], # uint16 + def_num=8, + scale=1000, + units='m', + ), + 9: Field( + name='auto_wheelsize', + type=BASE_TYPES[0x84], # uint16 + def_num=9, + scale=1000, + units='m', + ), + 10: Field( + name='bike_weight', + type=BASE_TYPES[0x84], # uint16 + def_num=10, + scale=10, + units='kg', + ), + 11: Field( + name='power_cal_factor', + type=BASE_TYPES[0x84], # uint16 + def_num=11, + scale=10, + units='%', + ), + 12: Field( + name='auto_wheel_cal', + type=FIELD_TYPES['bool'], + def_num=12, + ), + 13: Field( + name='auto_power_zero', + type=FIELD_TYPES['bool'], + def_num=13, + ), + 14: Field( + name='id', + type=BASE_TYPES[0x02], # uint8 + def_num=14, + ), + 15: Field( + name='spd_enabled', + type=FIELD_TYPES['bool'], + def_num=15, + ), + 16: Field( + name='cad_enabled', + type=FIELD_TYPES['bool'], + def_num=16, + ), + 17: Field( + name='spdcad_enabled', + type=FIELD_TYPES['bool'], + def_num=17, + ), + 18: Field( + name='power_enabled', + type=FIELD_TYPES['bool'], + def_num=18, + ), + 19: Field( + name='crank_length', + type=BASE_TYPES[0x02], # uint8 + def_num=19, + scale=2, + offset=-110, + units='mm', + ), + 20: Field( + name='enabled', + type=FIELD_TYPES['bool'], + def_num=20, + ), + 21: Field( + name='bike_spd_ant_id_trans_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=21, + ), + 22: Field( + name='bike_cad_ant_id_trans_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=22, + ), + 23: Field( + name='bike_spdcad_ant_id_trans_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=23, + ), + 24: Field( + name='bike_power_ant_id_trans_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=24, + ), + 37: Field( # Rollover counter that can be used to extend the odometer + name='odometer_rollover', + type=BASE_TYPES[0x02], # uint8 + def_num=37, + ), + 38: Field( # Number of front gears + name='front_gear_num', + type=BASE_TYPES[0x0A], # uint8z + def_num=38, + ), + 39: Field( # Number of teeth on each gear 0 is innermost + name='front_gear', + type=BASE_TYPES[0x0A], # uint8z + def_num=39, + ), + 40: Field( # Number of rear gears + name='rear_gear_num', + type=BASE_TYPES[0x0A], # uint8z + def_num=40, + ), + 41: Field( # Number of teeth on each gear 0 is innermost + name='rear_gear', + type=BASE_TYPES[0x0A], # uint8z + def_num=41, + ), + 44: Field( + name='shimano_di2_enabled', + type=FIELD_TYPES['bool'], + def_num=44, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 8: MessageType( + name='hr_zone', + mesg_num=8, + fields={ + 1: Field( + name='high_bpm', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + units='bpm', + ), + 2: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=2, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 9: MessageType( + name='power_zone', + mesg_num=9, + fields={ + 1: Field( + name='high_value', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='watts', + ), + 2: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=2, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 10: MessageType( + name='met_zone', + mesg_num=10, + fields={ + 1: Field( + name='high_bpm', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + ), + 2: Field( + name='calories', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + scale=10, + units='kcal/min', + ), + 3: Field( + name='fat_calories', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + scale=10, + units='kcal/min', + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 12: MessageType( + name='sport', + mesg_num=12, + fields={ + 0: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=0, + ), + 1: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=1, + ), + 3: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=3, + ), + }, + ), + 18: MessageType( + name='session', + mesg_num=18, + fields={ + 0: Field( # session + name='event', + type=FIELD_TYPES['event'], + def_num=0, + ), + 1: Field( # stop + name='event_type', + type=FIELD_TYPES['event_type'], + def_num=1, + ), + 2: Field( + name='start_time', + type=FIELD_TYPES['date_time'], + def_num=2, + ), + 3: Field( + name='start_position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=3, + units='semicircles', + ), + 4: Field( + name='start_position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=4, + units='semicircles', + ), + 5: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=5, + ), + 6: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=6, + ), + 7: Field( # Time (includes pauses) + name='total_elapsed_time', + type=BASE_TYPES[0x86], # uint32 + def_num=7, + scale=1000, + units='s', + ), + 8: Field( # Timer Time (excludes pauses) + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=8, + scale=1000, + units='s', + ), + 9: Field( + name='total_distance', + type=BASE_TYPES[0x86], # uint32 + def_num=9, + scale=100, + units='m', + ), + 10: Field( + name='total_cycles', + type=BASE_TYPES[0x86], # uint32 + def_num=10, + units='cycles', + subfields=( + SubField( + name='total_strides', + def_num=10, + type=BASE_TYPES[0x86], # uint32 + units='strides', + ref_fields=( + ReferenceField( + name='sport', + def_num=5, + value='running', + raw_value=1, + ), + ReferenceField( + name='sport', + def_num=5, + value='walking', + raw_value=11, + ), + ), + ), + ), + ), + 11: Field( + name='total_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=11, + units='kcal', + ), + 13: Field( + name='total_fat_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=13, + units='kcal', + ), + 14: Field( # total_distance / total_timer_time + name='avg_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=14, + components=( + ComponentField( + name='enhanced_avg_speed', + def_num=124, + scale=1000, + units='m/s', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 15: Field( + name='max_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=15, + components=( + ComponentField( + name='enhanced_max_speed', + def_num=125, + scale=1000, + units='m/s', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 16: Field( # average heart rate (excludes pause time) + name='avg_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=16, + units='bpm', + ), + 17: Field( + name='max_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=17, + units='bpm', + ), + 18: Field( # total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time + name='avg_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=18, + units='rpm', + subfields=( + SubField( + name='avg_running_cadence', + def_num=18, + type=BASE_TYPES[0x02], # uint8 + units='strides/min', + ref_fields=( + ReferenceField( + name='sport', + def_num=5, + value='running', + raw_value=1, + ), + ), + ), + ), + ), + 19: Field( + name='max_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=19, + units='rpm', + subfields=( + SubField( + name='max_running_cadence', + def_num=19, + type=BASE_TYPES[0x02], # uint8 + units='strides/min', + ref_fields=( + ReferenceField( + name='sport', + def_num=5, + value='running', + raw_value=1, + ), + ), + ), + ), + ), + 20: Field( # total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time + name='avg_power', + type=BASE_TYPES[0x84], # uint16 + def_num=20, + units='watts', + ), + 21: Field( + name='max_power', + type=BASE_TYPES[0x84], # uint16 + def_num=21, + units='watts', + ), + 22: Field( + name='total_ascent', + type=BASE_TYPES[0x84], # uint16 + def_num=22, + units='m', + ), + 23: Field( + name='total_descent', + type=BASE_TYPES[0x84], # uint16 + def_num=23, + units='m', + ), + 24: Field( + name='total_training_effect', + type=BASE_TYPES[0x02], # uint8 + def_num=24, + scale=10, + ), + 25: Field( + name='first_lap_index', + type=BASE_TYPES[0x84], # uint16 + def_num=25, + ), + 26: Field( + name='num_laps', + type=BASE_TYPES[0x84], # uint16 + def_num=26, + ), + 27: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=27, + ), + 28: Field( + name='trigger', + type=FIELD_TYPES['session_trigger'], + def_num=28, + ), + 29: Field( + name='nec_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=29, + units='semicircles', + ), + 30: Field( + name='nec_long', + type=BASE_TYPES[0x85], # sint32 + def_num=30, + units='semicircles', + ), + 31: Field( + name='swc_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=31, + units='semicircles', + ), + 32: Field( + name='swc_long', + type=BASE_TYPES[0x85], # sint32 + def_num=32, + units='semicircles', + ), + 34: Field( + name='normalized_power', + type=BASE_TYPES[0x84], # uint16 + def_num=34, + units='watts', + ), + 35: Field( + name='training_stress_score', + type=BASE_TYPES[0x84], # uint16 + def_num=35, + scale=10, + units='tss', + ), + 36: Field( + name='intensity_factor', + type=BASE_TYPES[0x84], # uint16 + def_num=36, + scale=1000, + units='if', + ), + 37: Field( + name='left_right_balance', + type=FIELD_TYPES['left_right_balance_100'], + def_num=37, + ), + 41: Field( + name='avg_stroke_count', + type=BASE_TYPES[0x86], # uint32 + def_num=41, + scale=10, + units='strokes/lap', + ), + 42: Field( + name='avg_stroke_distance', + type=BASE_TYPES[0x84], # uint16 + def_num=42, + scale=100, + units='m', + ), + 43: Field( + name='swim_stroke', + type=FIELD_TYPES['swim_stroke'], + def_num=43, + units='swim_stroke', + ), + 44: Field( + name='pool_length', + type=BASE_TYPES[0x84], # uint16 + def_num=44, + scale=100, + units='m', + ), + 45: Field( + name='threshold_power', + type=BASE_TYPES[0x84], # uint16 + def_num=45, + units='watts', + ), + 46: Field( + name='pool_length_unit', + type=FIELD_TYPES['display_measure'], + def_num=46, + ), + 47: Field( # # of active lengths of swim pool + name='num_active_lengths', + type=BASE_TYPES[0x84], # uint16 + def_num=47, + units='lengths', + ), + 48: Field( + name='total_work', + type=BASE_TYPES[0x86], # uint32 + def_num=48, + units='J', + ), + 49: Field( + name='avg_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=49, + components=( + ComponentField( + name='enhanced_avg_altitude', + def_num=126, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 50: Field( + name='max_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=50, + components=( + ComponentField( + name='enhanced_max_altitude', + def_num=128, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 51: Field( + name='gps_accuracy', + type=BASE_TYPES[0x02], # uint8 + def_num=51, + units='m', + ), + 52: Field( + name='avg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=52, + scale=100, + units='%', + ), + 53: Field( + name='avg_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=53, + scale=100, + units='%', + ), + 54: Field( + name='avg_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=54, + scale=100, + units='%', + ), + 55: Field( + name='max_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=55, + scale=100, + units='%', + ), + 56: Field( + name='max_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=56, + scale=100, + units='%', + ), + 57: Field( + name='avg_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=57, + units='C', + ), + 58: Field( + name='max_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=58, + units='C', + ), + 59: Field( + name='total_moving_time', + type=BASE_TYPES[0x86], # uint32 + def_num=59, + scale=1000, + units='s', + ), + 60: Field( + name='avg_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=60, + scale=1000, + units='m/s', + ), + 61: Field( + name='avg_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=61, + scale=1000, + units='m/s', + ), + 62: Field( + name='max_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=62, + scale=1000, + units='m/s', + ), + 63: Field( + name='max_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=63, + scale=1000, + units='m/s', + ), + 64: Field( + name='min_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=64, + units='bpm', + ), + 65: Field( + name='time_in_hr_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=65, + scale=1000, + units='s', + ), + 66: Field( + name='time_in_speed_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=66, + scale=1000, + units='s', + ), + 67: Field( + name='time_in_cadence_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=67, + scale=1000, + units='s', + ), + 68: Field( + name='time_in_power_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=68, + scale=1000, + units='s', + ), + 69: Field( + name='avg_lap_time', + type=BASE_TYPES[0x86], # uint32 + def_num=69, + scale=1000, + units='s', + ), + 70: Field( + name='best_lap_index', + type=BASE_TYPES[0x84], # uint16 + def_num=70, + ), + 71: Field( + name='min_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=71, + components=( + ComponentField( + name='enhanced_min_altitude', + def_num=127, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 82: Field( + name='player_score', + type=BASE_TYPES[0x84], # uint16 + def_num=82, + ), + 83: Field( + name='opponent_score', + type=BASE_TYPES[0x84], # uint16 + def_num=83, + ), + 84: Field( + name='opponent_name', + type=BASE_TYPES[0x07], # string + def_num=84, + ), + 85: Field( # stroke_type enum used as the index + name='stroke_count', + type=BASE_TYPES[0x84], # uint16 + def_num=85, + units='counts', + ), + 86: Field( # zone number used as the index + name='zone_count', + type=BASE_TYPES[0x84], # uint16 + def_num=86, + units='counts', + ), + 87: Field( + name='max_ball_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=87, + scale=100, + units='m/s', + ), + 88: Field( + name='avg_ball_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=88, + scale=100, + units='m/s', + ), + 89: Field( + name='avg_vertical_oscillation', + type=BASE_TYPES[0x84], # uint16 + def_num=89, + scale=10, + units='mm', + ), + 90: Field( + name='avg_stance_time_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=90, + scale=100, + units='percent', + ), + 91: Field( + name='avg_stance_time', + type=BASE_TYPES[0x84], # uint16 + def_num=91, + scale=10, + units='ms', + ), + 92: Field( # fractional part of the avg_cadence + name='avg_fractional_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=92, + scale=128, + units='rpm', + ), + 93: Field( # fractional part of the max_cadence + name='max_fractional_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=93, + scale=128, + units='rpm', + ), + 94: Field( # fractional part of the total_cycles + name='total_fractional_cycles', + type=BASE_TYPES[0x02], # uint8 + def_num=94, + scale=128, + units='cycles', + ), + 95: Field( # Avg saturated and unsaturated hemoglobin + name='avg_total_hemoglobin_conc', + type=BASE_TYPES[0x84], # uint16 + def_num=95, + scale=100, + units='g/dL', + ), + 96: Field( # Min saturated and unsaturated hemoglobin + name='min_total_hemoglobin_conc', + type=BASE_TYPES[0x84], # uint16 + def_num=96, + scale=100, + units='g/dL', + ), + 97: Field( # Max saturated and unsaturated hemoglobin + name='max_total_hemoglobin_conc', + type=BASE_TYPES[0x84], # uint16 + def_num=97, + scale=100, + units='g/dL', + ), + 98: Field( # Avg percentage of hemoglobin saturated with oxygen + name='avg_saturated_hemoglobin_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=98, + scale=10, + units='%', + ), + 99: Field( # Min percentage of hemoglobin saturated with oxygen + name='min_saturated_hemoglobin_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=99, + scale=10, + units='%', + ), + 100: Field( # Max percentage of hemoglobin saturated with oxygen + name='max_saturated_hemoglobin_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=100, + scale=10, + units='%', + ), + 101: Field( + name='avg_left_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=101, + scale=2, + units='percent', + ), + 102: Field( + name='avg_right_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=102, + scale=2, + units='percent', + ), + 103: Field( + name='avg_left_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=103, + scale=2, + units='percent', + ), + 104: Field( + name='avg_right_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=104, + scale=2, + units='percent', + ), + 105: Field( + name='avg_combined_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=105, + scale=2, + units='percent', + ), + 111: Field( + name='sport_index', + type=BASE_TYPES[0x02], # uint8 + def_num=111, + ), + 112: Field( # Total time spend in the standing position + name='time_standing', + type=BASE_TYPES[0x86], # uint32 + def_num=112, + scale=1000, + units='s', + ), + 113: Field( # Number of transitions to the standing state + name='stand_count', + type=BASE_TYPES[0x84], # uint16 + def_num=113, + ), + 114: Field( # Average platform center offset Left + name='avg_left_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=114, + units='mm', + ), + 115: Field( # Average platform center offset Right + name='avg_right_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=115, + units='mm', + ), + 116: Field( # Average left power phase angles. Indexes defined by power_phase_type. + name='avg_left_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=116, + scale=0.7111111, + units='degrees', + ), + 117: Field( # Average left power phase peak angles. Data value indexes defined by power_phase_type. + name='avg_left_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=117, + scale=0.7111111, + units='degrees', + ), + 118: Field( # Average right power phase angles. Data value indexes defined by power_phase_type. + name='avg_right_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=118, + scale=0.7111111, + units='degrees', + ), + 119: Field( # Average right power phase peak angles data value indexes defined by power_phase_type. + name='avg_right_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=119, + scale=0.7111111, + units='degrees', + ), + 120: Field( # Average power by position. Data value indexes defined by rider_position_type. + name='avg_power_position', + type=BASE_TYPES[0x84], # uint16 + def_num=120, + units='watts', + ), + 121: Field( # Maximum power by position. Data value indexes defined by rider_position_type. + name='max_power_position', + type=BASE_TYPES[0x84], # uint16 + def_num=121, + units='watts', + ), + 122: Field( # Average cadence by position. Data value indexes defined by rider_position_type. + name='avg_cadence_position', + type=BASE_TYPES[0x02], # uint8 + def_num=122, + units='rpm', + ), + 123: Field( # Maximum cadence by position. Data value indexes defined by rider_position_type. + name='max_cadence_position', + type=BASE_TYPES[0x02], # uint8 + def_num=123, + units='rpm', + ), + 124: Field( # total_distance / total_timer_time + name='enhanced_avg_speed', + type=BASE_TYPES[0x86], # uint32 + def_num=124, + scale=1000, + units='m/s', + ), + 125: Field( + name='enhanced_max_speed', + type=BASE_TYPES[0x86], # uint32 + def_num=125, + scale=1000, + units='m/s', + ), + 126: Field( + name='enhanced_avg_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=126, + scale=5, + offset=500, + units='m', + ), + 127: Field( + name='enhanced_min_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=127, + scale=5, + offset=500, + units='m', + ), + 128: Field( + name='enhanced_max_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=128, + scale=5, + offset=500, + units='m', + ), + 129: Field( # lev average motor power during session + name='avg_lev_motor_power', + type=BASE_TYPES[0x84], # uint16 + def_num=129, + units='watts', + ), + 130: Field( # lev maximum motor power during session + name='max_lev_motor_power', + type=BASE_TYPES[0x84], # uint16 + def_num=130, + units='watts', + ), + 131: Field( # lev battery consumption during session + name='lev_battery_consumption', + type=BASE_TYPES[0x02], # uint8 + def_num=131, + scale=2, + units='percent', + ), + 132: Field( + name='avg_vertical_ratio', + type=BASE_TYPES[0x84], # uint16 + def_num=132, + scale=100, + units='percent', + ), + 133: Field( + name='avg_stance_time_balance', + type=BASE_TYPES[0x84], # uint16 + def_num=133, + scale=100, + units='percent', + ), + 134: Field( + name='avg_step_length', + type=BASE_TYPES[0x84], # uint16 + def_num=134, + scale=10, + units='mm', + ), + 137: Field( + name='total_anaerobic_training_effect', + type=BASE_TYPES[0x02], # uint8 + def_num=137, + scale=10, + ), + 139: Field( + name='avg_vam', + type=BASE_TYPES[0x84], # uint16 + def_num=139, + scale=1000, + units='m/s', + ), + 253: FIELD_TYPE_TIMESTAMP, # Sesson end time. + 254: Field( # Selected bit is set for the current session. + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 19: MessageType( + name='lap', + mesg_num=19, + fields={ + 0: Field( + name='event', + type=FIELD_TYPES['event'], + def_num=0, + ), + 1: Field( + name='event_type', + type=FIELD_TYPES['event_type'], + def_num=1, + ), + 2: Field( + name='start_time', + type=FIELD_TYPES['date_time'], + def_num=2, + ), + 3: Field( + name='start_position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=3, + units='semicircles', + ), + 4: Field( + name='start_position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=4, + units='semicircles', + ), + 5: Field( + name='end_position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=5, + units='semicircles', + ), + 6: Field( + name='end_position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=6, + units='semicircles', + ), + 7: Field( # Time (includes pauses) + name='total_elapsed_time', + type=BASE_TYPES[0x86], # uint32 + def_num=7, + scale=1000, + units='s', + ), + 8: Field( # Timer Time (excludes pauses) + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=8, + scale=1000, + units='s', + ), + 9: Field( + name='total_distance', + type=BASE_TYPES[0x86], # uint32 + def_num=9, + scale=100, + units='m', + ), + 10: Field( + name='total_cycles', + type=BASE_TYPES[0x86], # uint32 + def_num=10, + units='cycles', + subfields=( + SubField( + name='total_strides', + def_num=10, + type=BASE_TYPES[0x86], # uint32 + units='strides', + ref_fields=( + ReferenceField( + name='sport', + def_num=25, + value='running', + raw_value=1, + ), + ReferenceField( + name='sport', + def_num=25, + value='walking', + raw_value=11, + ), + ), + ), + ), + ), + 11: Field( + name='total_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=11, + units='kcal', + ), + 12: Field( # If New Leaf + name='total_fat_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=12, + units='kcal', + ), + 13: Field( + name='avg_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=13, + components=( + ComponentField( + name='enhanced_avg_speed', + def_num=110, + scale=1000, + units='m/s', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 14: Field( + name='max_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=14, + components=( + ComponentField( + name='enhanced_max_speed', + def_num=111, + scale=1000, + units='m/s', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 15: Field( + name='avg_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=15, + units='bpm', + ), + 16: Field( + name='max_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=16, + units='bpm', + ), + 17: Field( # total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time + name='avg_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=17, + units='rpm', + subfields=( + SubField( + name='avg_running_cadence', + def_num=17, + type=BASE_TYPES[0x02], # uint8 + units='strides/min', + ref_fields=( + ReferenceField( + name='sport', + def_num=25, + value='running', + raw_value=1, + ), + ), + ), + ), + ), + 18: Field( + name='max_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=18, + units='rpm', + subfields=( + SubField( + name='max_running_cadence', + def_num=18, + type=BASE_TYPES[0x02], # uint8 + units='strides/min', + ref_fields=( + ReferenceField( + name='sport', + def_num=25, + value='running', + raw_value=1, + ), + ), + ), + ), + ), + 19: Field( # total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time + name='avg_power', + type=BASE_TYPES[0x84], # uint16 + def_num=19, + units='watts', + ), + 20: Field( + name='max_power', + type=BASE_TYPES[0x84], # uint16 + def_num=20, + units='watts', + ), + 21: Field( + name='total_ascent', + type=BASE_TYPES[0x84], # uint16 + def_num=21, + units='m', + ), + 22: Field( + name='total_descent', + type=BASE_TYPES[0x84], # uint16 + def_num=22, + units='m', + ), + 23: Field( + name='intensity', + type=FIELD_TYPES['intensity'], + def_num=23, + ), + 24: Field( + name='lap_trigger', + type=FIELD_TYPES['lap_trigger'], + def_num=24, + ), + 25: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=25, + ), + 26: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=26, + ), + 32: Field( # # of lengths of swim pool + name='num_lengths', + type=BASE_TYPES[0x84], # uint16 + def_num=32, + units='lengths', + ), + 33: Field( + name='normalized_power', + type=BASE_TYPES[0x84], # uint16 + def_num=33, + units='watts', + ), + 34: Field( + name='left_right_balance', + type=FIELD_TYPES['left_right_balance_100'], + def_num=34, + ), + 35: Field( + name='first_length_index', + type=BASE_TYPES[0x84], # uint16 + def_num=35, + ), + 37: Field( + name='avg_stroke_distance', + type=BASE_TYPES[0x84], # uint16 + def_num=37, + scale=100, + units='m', + ), + 38: Field( + name='swim_stroke', + type=FIELD_TYPES['swim_stroke'], + def_num=38, + ), + 39: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=39, + ), + 40: Field( # # of active lengths of swim pool + name='num_active_lengths', + type=BASE_TYPES[0x84], # uint16 + def_num=40, + units='lengths', + ), + 41: Field( + name='total_work', + type=BASE_TYPES[0x86], # uint32 + def_num=41, + units='J', + ), + 42: Field( + name='avg_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=42, + components=( + ComponentField( + name='enhanced_avg_altitude', + def_num=112, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 43: Field( + name='max_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=43, + components=( + ComponentField( + name='enhanced_max_altitude', + def_num=114, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 44: Field( + name='gps_accuracy', + type=BASE_TYPES[0x02], # uint8 + def_num=44, + units='m', + ), + 45: Field( + name='avg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=45, + scale=100, + units='%', + ), + 46: Field( + name='avg_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=46, + scale=100, + units='%', + ), + 47: Field( + name='avg_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=47, + scale=100, + units='%', + ), + 48: Field( + name='max_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=48, + scale=100, + units='%', + ), + 49: Field( + name='max_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=49, + scale=100, + units='%', + ), + 50: Field( + name='avg_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=50, + units='C', + ), + 51: Field( + name='max_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=51, + units='C', + ), + 52: Field( + name='total_moving_time', + type=BASE_TYPES[0x86], # uint32 + def_num=52, + scale=1000, + units='s', + ), + 53: Field( + name='avg_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=53, + scale=1000, + units='m/s', + ), + 54: Field( + name='avg_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=54, + scale=1000, + units='m/s', + ), + 55: Field( + name='max_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=55, + scale=1000, + units='m/s', + ), + 56: Field( + name='max_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=56, + scale=1000, + units='m/s', + ), + 57: Field( + name='time_in_hr_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=57, + scale=1000, + units='s', + ), + 58: Field( + name='time_in_speed_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=58, + scale=1000, + units='s', + ), + 59: Field( + name='time_in_cadence_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=59, + scale=1000, + units='s', + ), + 60: Field( + name='time_in_power_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=60, + scale=1000, + units='s', + ), + 61: Field( + name='repetition_num', + type=BASE_TYPES[0x84], # uint16 + def_num=61, + ), + 62: Field( + name='min_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=62, + components=( + ComponentField( + name='enhanced_min_altitude', + def_num=113, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 63: Field( + name='min_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=63, + units='bpm', + ), + 71: Field( + name='wkt_step_index', + type=FIELD_TYPES['message_index'], + def_num=71, + ), + 74: Field( + name='opponent_score', + type=BASE_TYPES[0x84], # uint16 + def_num=74, + ), + 75: Field( # stroke_type enum used as the index + name='stroke_count', + type=BASE_TYPES[0x84], # uint16 + def_num=75, + units='counts', + ), + 76: Field( # zone number used as the index + name='zone_count', + type=BASE_TYPES[0x84], # uint16 + def_num=76, + units='counts', + ), + 77: Field( + name='avg_vertical_oscillation', + type=BASE_TYPES[0x84], # uint16 + def_num=77, + scale=10, + units='mm', + ), + 78: Field( + name='avg_stance_time_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=78, + scale=100, + units='percent', + ), + 79: Field( + name='avg_stance_time', + type=BASE_TYPES[0x84], # uint16 + def_num=79, + scale=10, + units='ms', + ), + 80: Field( # fractional part of the avg_cadence + name='avg_fractional_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=80, + scale=128, + units='rpm', + ), + 81: Field( # fractional part of the max_cadence + name='max_fractional_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=81, + scale=128, + units='rpm', + ), + 82: Field( # fractional part of the total_cycles + name='total_fractional_cycles', + type=BASE_TYPES[0x02], # uint8 + def_num=82, + scale=128, + units='cycles', + ), + 83: Field( + name='player_score', + type=BASE_TYPES[0x84], # uint16 + def_num=83, + ), + 84: Field( # Avg saturated and unsaturated hemoglobin + name='avg_total_hemoglobin_conc', + type=BASE_TYPES[0x84], # uint16 + def_num=84, + scale=100, + units='g/dL', + ), + 85: Field( # Min saturated and unsaturated hemoglobin + name='min_total_hemoglobin_conc', + type=BASE_TYPES[0x84], # uint16 + def_num=85, + scale=100, + units='g/dL', + ), + 86: Field( # Max saturated and unsaturated hemoglobin + name='max_total_hemoglobin_conc', + type=BASE_TYPES[0x84], # uint16 + def_num=86, + scale=100, + units='g/dL', + ), + 87: Field( # Avg percentage of hemoglobin saturated with oxygen + name='avg_saturated_hemoglobin_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=87, + scale=10, + units='%', + ), + 88: Field( # Min percentage of hemoglobin saturated with oxygen + name='min_saturated_hemoglobin_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=88, + scale=10, + units='%', + ), + 89: Field( # Max percentage of hemoglobin saturated with oxygen + name='max_saturated_hemoglobin_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=89, + scale=10, + units='%', + ), + 91: Field( + name='avg_left_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=91, + scale=2, + units='percent', + ), + 92: Field( + name='avg_right_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=92, + scale=2, + units='percent', + ), + 93: Field( + name='avg_left_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=93, + scale=2, + units='percent', + ), + 94: Field( + name='avg_right_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=94, + scale=2, + units='percent', + ), + 95: Field( + name='avg_combined_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=95, + scale=2, + units='percent', + ), + 98: Field( # Total time spent in the standing position + name='time_standing', + type=BASE_TYPES[0x86], # uint32 + def_num=98, + scale=1000, + units='s', + ), + 99: Field( # Number of transitions to the standing state + name='stand_count', + type=BASE_TYPES[0x84], # uint16 + def_num=99, + ), + 100: Field( # Average left platform center offset + name='avg_left_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=100, + units='mm', + ), + 101: Field( # Average right platform center offset + name='avg_right_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=101, + units='mm', + ), + 102: Field( # Average left power phase angles. Data value indexes defined by power_phase_type. + name='avg_left_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=102, + scale=0.7111111, + units='degrees', + ), + 103: Field( # Average left power phase peak angles. Data value indexes defined by power_phase_type. + name='avg_left_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=103, + scale=0.7111111, + units='degrees', + ), + 104: Field( # Average right power phase angles. Data value indexes defined by power_phase_type. + name='avg_right_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=104, + scale=0.7111111, + units='degrees', + ), + 105: Field( # Average right power phase peak angles. Data value indexes defined by power_phase_type. + name='avg_right_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=105, + scale=0.7111111, + units='degrees', + ), + 106: Field( # Average power by position. Data value indexes defined by rider_position_type. + name='avg_power_position', + type=BASE_TYPES[0x84], # uint16 + def_num=106, + units='watts', + ), + 107: Field( # Maximum power by position. Data value indexes defined by rider_position_type. + name='max_power_position', + type=BASE_TYPES[0x84], # uint16 + def_num=107, + units='watts', + ), + 108: Field( # Average cadence by position. Data value indexes defined by rider_position_type. + name='avg_cadence_position', + type=BASE_TYPES[0x02], # uint8 + def_num=108, + units='rpm', + ), + 109: Field( # Maximum cadence by position. Data value indexes defined by rider_position_type. + name='max_cadence_position', + type=BASE_TYPES[0x02], # uint8 + def_num=109, + units='rpm', + ), + 110: Field( + name='enhanced_avg_speed', + type=BASE_TYPES[0x86], # uint32 + def_num=110, + scale=1000, + units='m/s', + ), + 111: Field( + name='enhanced_max_speed', + type=BASE_TYPES[0x86], # uint32 + def_num=111, + scale=1000, + units='m/s', + ), + 112: Field( + name='enhanced_avg_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=112, + scale=5, + offset=500, + units='m', + ), + 113: Field( + name='enhanced_min_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=113, + scale=5, + offset=500, + units='m', + ), + 114: Field( + name='enhanced_max_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=114, + scale=5, + offset=500, + units='m', + ), + 115: Field( # lev average motor power during lap + name='avg_lev_motor_power', + type=BASE_TYPES[0x84], # uint16 + def_num=115, + units='watts', + ), + 116: Field( # lev maximum motor power during lap + name='max_lev_motor_power', + type=BASE_TYPES[0x84], # uint16 + def_num=116, + units='watts', + ), + 117: Field( # lev battery consumption during lap + name='lev_battery_consumption', + type=BASE_TYPES[0x02], # uint8 + def_num=117, + scale=2, + units='percent', + ), + 118: Field( + name='avg_vertical_ratio', + type=BASE_TYPES[0x84], # uint16 + def_num=118, + scale=100, + units='percent', + ), + 119: Field( + name='avg_stance_time_balance', + type=BASE_TYPES[0x84], # uint16 + def_num=119, + scale=100, + units='percent', + ), + 120: Field( + name='avg_step_length', + type=BASE_TYPES[0x84], # uint16 + def_num=120, + scale=10, + units='mm', + ), + 121: Field( + name='avg_vam', + type=BASE_TYPES[0x84], # uint16 + def_num=121, + scale=1000, + units='m/s', + ), + 253: FIELD_TYPE_TIMESTAMP, # Lap end time. + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 20: MessageType( + name='record', + mesg_num=20, + fields={ + 0: Field( + name='position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=0, + units='semicircles', + ), + 1: Field( + name='position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=1, + units='semicircles', + ), + 2: Field( + name='altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + components=( + ComponentField( + name='enhanced_altitude', + def_num=78, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 3: Field( + name='heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + units='bpm', + ), + 4: Field( + name='cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=4, + units='rpm', + ), + 5: Field( + name='distance', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + scale=100, + units='m', + ), + 6: Field( + name='speed', + type=BASE_TYPES[0x84], # uint16 + def_num=6, + components=( + ComponentField( + name='enhanced_speed', + def_num=73, + scale=1000, + units='m/s', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 7: Field( + name='power', + type=BASE_TYPES[0x84], # uint16 + def_num=7, + units='watts', + ), + 8: Field( + name='compressed_speed_distance', + type=BASE_TYPES[0x0D], # byte + def_num=8, + components=( + ComponentField( + name='speed', + def_num=6, + scale=100, + units='m/s', + accumulate=False, + bits=12, + bit_offset=0, + ), + ComponentField( + name='distance', + def_num=5, + scale=16, + units='m', + accumulate=True, + bits=12, + bit_offset=12, + ), + ), + ), + 9: Field( + name='grade', + type=BASE_TYPES[0x83], # sint16 + def_num=9, + scale=100, + units='%', + ), + 10: Field( # Relative. 0 is none 254 is Max. + name='resistance', + type=BASE_TYPES[0x02], # uint8 + def_num=10, + ), + 11: Field( + name='time_from_course', + type=BASE_TYPES[0x85], # sint32 + def_num=11, + scale=1000, + units='s', + ), + 12: Field( + name='cycle_length', + type=BASE_TYPES[0x02], # uint8 + def_num=12, + scale=100, + units='m', + ), + 13: Field( + name='temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=13, + units='C', + ), + 17: Field( # Speed at 1s intervals. Timestamp field indicates time of last array element. + name='speed_1s', + type=BASE_TYPES[0x02], # uint8 + def_num=17, + scale=16, + units='m/s', + ), + 18: Field( + name='cycles', + type=BASE_TYPES[0x02], # uint8 + def_num=18, + components=( + ComponentField( + name='total_cycles', + def_num=19, + units='cycles', + accumulate=True, + bits=8, + bit_offset=0, + ), + ), + ), + 19: Field( + name='total_cycles', + type=BASE_TYPES[0x86], # uint32 + def_num=19, + units='cycles', + ), + 28: Field( + name='compressed_accumulated_power', + type=BASE_TYPES[0x84], # uint16 + def_num=28, + components=( + ComponentField( + name='accumulated_power', + def_num=29, + units='watts', + accumulate=True, + bits=16, + bit_offset=0, + ), + ), + ), + 29: Field( + name='accumulated_power', + type=BASE_TYPES[0x86], # uint32 + def_num=29, + units='watts', + ), + 30: Field( + name='left_right_balance', + type=FIELD_TYPES['left_right_balance'], + def_num=30, + ), + 31: Field( + name='gps_accuracy', + type=BASE_TYPES[0x02], # uint8 + def_num=31, + units='m', + ), + 32: Field( + name='vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=32, + scale=1000, + units='m/s', + ), + 33: Field( + name='calories', + type=BASE_TYPES[0x84], # uint16 + def_num=33, + units='kcal', + ), + 39: Field( + name='vertical_oscillation', + type=BASE_TYPES[0x84], # uint16 + def_num=39, + scale=10, + units='mm', + ), + 40: Field( + name='stance_time_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=40, + scale=100, + units='percent', + ), + 41: Field( + name='stance_time', + type=BASE_TYPES[0x84], # uint16 + def_num=41, + scale=10, + units='ms', + ), + 42: Field( + name='activity_type', + type=FIELD_TYPES['activity_type'], + def_num=42, + ), + 43: Field( + name='left_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=43, + scale=2, + units='percent', + ), + 44: Field( + name='right_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=44, + scale=2, + units='percent', + ), + 45: Field( + name='left_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=45, + scale=2, + units='percent', + ), + 46: Field( + name='right_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=46, + scale=2, + units='percent', + ), + 47: Field( + name='combined_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=47, + scale=2, + units='percent', + ), + 48: Field( + name='time128', + type=BASE_TYPES[0x02], # uint8 + def_num=48, + scale=128, + units='s', + ), + 49: Field( + name='stroke_type', + type=FIELD_TYPES['stroke_type'], + def_num=49, + ), + 50: Field( + name='zone', + type=BASE_TYPES[0x02], # uint8 + def_num=50, + ), + 51: Field( + name='ball_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=51, + scale=100, + units='m/s', + ), + 52: Field( # Log cadence and fractional cadence for backwards compatability + name='cadence256', + type=BASE_TYPES[0x84], # uint16 + def_num=52, + scale=256, + units='rpm', + ), + 53: Field( + name='fractional_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=53, + scale=128, + units='rpm', + ), + 54: Field( # Total saturated and unsaturated hemoglobin + name='total_hemoglobin_conc', + type=BASE_TYPES[0x84], # uint16 + def_num=54, + scale=100, + units='g/dL', + ), + 55: Field( # Min saturated and unsaturated hemoglobin + name='total_hemoglobin_conc_min', + type=BASE_TYPES[0x84], # uint16 + def_num=55, + scale=100, + units='g/dL', + ), + 56: Field( # Max saturated and unsaturated hemoglobin + name='total_hemoglobin_conc_max', + type=BASE_TYPES[0x84], # uint16 + def_num=56, + scale=100, + units='g/dL', + ), + 57: Field( # Percentage of hemoglobin saturated with oxygen + name='saturated_hemoglobin_percent', + type=BASE_TYPES[0x84], # uint16 + def_num=57, + scale=10, + units='%', + ), + 58: Field( # Min percentage of hemoglobin saturated with oxygen + name='saturated_hemoglobin_percent_min', + type=BASE_TYPES[0x84], # uint16 + def_num=58, + scale=10, + units='%', + ), + 59: Field( # Max percentage of hemoglobin saturated with oxygen + name='saturated_hemoglobin_percent_max', + type=BASE_TYPES[0x84], # uint16 + def_num=59, + scale=10, + units='%', + ), + 62: Field( + name='device_index', + type=FIELD_TYPES['device_index'], + def_num=62, + ), + 67: Field( # Left platform center offset + name='left_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=67, + units='mm', + ), + 68: Field( # Right platform center offset + name='right_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=68, + units='mm', + ), + 69: Field( # Left power phase angles. Data value indexes defined by power_phase_type. + name='left_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=69, + scale=0.7111111, + units='degrees', + ), + 70: Field( # Left power phase peak angles. Data value indexes defined by power_phase_type. + name='left_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=70, + scale=0.7111111, + units='degrees', + ), + 71: Field( # Right power phase angles. Data value indexes defined by power_phase_type. + name='right_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=71, + scale=0.7111111, + units='degrees', + ), + 72: Field( # Right power phase peak angles. Data value indexes defined by power_phase_type. + name='right_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=72, + scale=0.7111111, + units='degrees', + ), + 73: Field( + name='enhanced_speed', + type=BASE_TYPES[0x86], # uint32 + def_num=73, + scale=1000, + units='m/s', + ), + 78: Field( + name='enhanced_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=78, + scale=5, + offset=500, + units='m', + ), + 81: Field( # lev battery state of charge + name='battery_soc', + type=BASE_TYPES[0x02], # uint8 + def_num=81, + scale=2, + units='percent', + ), + 82: Field( # lev motor power + name='motor_power', + type=BASE_TYPES[0x84], # uint16 + def_num=82, + units='watts', + ), + 83: Field( + name='vertical_ratio', + type=BASE_TYPES[0x84], # uint16 + def_num=83, + scale=100, + units='percent', + ), + 84: Field( + name='stance_time_balance', + type=BASE_TYPES[0x84], # uint16 + def_num=84, + scale=100, + units='percent', + ), + 85: Field( + name='step_length', + type=BASE_TYPES[0x84], # uint16 + def_num=85, + scale=10, + units='mm', + ), + 91: Field( # Includes atmospheric pressure + name='absolute_pressure', + type=BASE_TYPES[0x86], # uint32 + def_num=91, + units='Pa', + ), + 92: Field( # 0 if above water + name='depth', + type=BASE_TYPES[0x86], # uint32 + def_num=92, + scale=1000, + units='m', + ), + 93: Field( # 0 if above water + name='next_stop_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=93, + scale=1000, + units='m', + ), + 94: Field( + name='next_stop_time', + type=BASE_TYPES[0x86], # uint32 + def_num=94, + units='s', + ), + 95: Field( + name='time_to_surface', + type=BASE_TYPES[0x86], # uint32 + def_num=95, + units='s', + ), + 96: Field( + name='ndl_time', + type=BASE_TYPES[0x86], # uint32 + def_num=96, + units='s', + ), + 97: Field( + name='cns_load', + type=BASE_TYPES[0x02], # uint8 + def_num=97, + units='percent', + ), + 98: Field( + name='n2_load', + type=BASE_TYPES[0x84], # uint16 + def_num=98, + units='percent', + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 21: MessageType( + name='event', + mesg_num=21, + fields={ + 0: Field( + name='event', + type=FIELD_TYPES['event'], + def_num=0, + ), + 1: Field( + name='event_type', + type=FIELD_TYPES['event_type'], + def_num=1, + ), + 2: Field( + name='data16', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + components=( + ComponentField( + name='data', + def_num=3, + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 3: Field( + name='data', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + subfields=( + SubField( + name='battery_level', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + scale=1000, + units='V', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='battery', + raw_value=11, + ), + ), + ), + SubField( + name='cad_high_alert', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + units='rpm', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='cad_high_alert', + raw_value=17, + ), + ), + ), + SubField( + name='cad_low_alert', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + units='rpm', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='cad_low_alert', + raw_value=18, + ), + ), + ), + SubField( + name='calorie_duration_alert', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + units='calories', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='calorie_duration_alert', + raw_value=25, + ), + ), + ), + SubField( + name='comm_timeout', + def_num=3, + type=FIELD_TYPES['comm_timeout_type'], + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='comm_timeout', + raw_value=47, + ), + ), + ), + SubField( + name='course_point_index', + def_num=3, + type=FIELD_TYPES['message_index'], + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='course_point', + raw_value=10, + ), + ), + ), + SubField( + name='distance_duration_alert', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + scale=100, + units='m', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='distance_duration_alert', + raw_value=24, + ), + ), + ), + SubField( + name='fitness_equipment_state', + def_num=3, + type=FIELD_TYPES['fitness_equipment_state'], + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='fitness_equipment', + raw_value=27, + ), + ), + ), + SubField( + name='gear_change_data', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='front_gear_change', + raw_value=42, + ), + ReferenceField( + name='event', + def_num=0, + value='rear_gear_change', + raw_value=43, + ), + ), + components=( + ComponentField( + name='rear_gear_num', + def_num=11, + accumulate=False, + bits=8, + bit_offset=0, + ), + ComponentField( + name='rear_gear', + def_num=12, + accumulate=False, + bits=8, + bit_offset=8, + ), + ComponentField( + name='front_gear_num', + def_num=9, + accumulate=False, + bits=8, + bit_offset=16, + ), + ComponentField( + name='front_gear', + def_num=10, + accumulate=False, + bits=8, + bit_offset=24, + ), + ), + ), + SubField( + name='hr_high_alert', + def_num=3, + type=BASE_TYPES[0x02], # uint8 + units='bpm', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='hr_high_alert', + raw_value=13, + ), + ), + ), + SubField( + name='hr_low_alert', + def_num=3, + type=BASE_TYPES[0x02], # uint8 + units='bpm', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='hr_low_alert', + raw_value=14, + ), + ), + ), + SubField( + name='power_high_alert', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + units='watts', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='power_high_alert', + raw_value=19, + ), + ), + ), + SubField( + name='power_low_alert', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + units='watts', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='power_low_alert', + raw_value=20, + ), + ), + ), + SubField( # Indicates the rider position value. + name='rider_position', + def_num=3, + type=FIELD_TYPES['rider_position_type'], + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='rider_position_change', + raw_value=44, + ), + ), + ), + SubField( + name='speed_high_alert', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='m/s', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='speed_high_alert', + raw_value=15, + ), + ), + ), + SubField( + name='speed_low_alert', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='m/s', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='speed_low_alert', + raw_value=16, + ), + ), + ), + SubField( + name='sport_point', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='sport_point', + raw_value=33, + ), + ), + components=( + ComponentField( + name='score', + def_num=7, + accumulate=False, + bits=16, + bit_offset=0, + ), + ComponentField( + name='opponent_score', + def_num=8, + accumulate=False, + bits=16, + bit_offset=16, + ), + ), + ), + SubField( + name='time_duration_alert', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='s', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='time_duration_alert', + raw_value=23, + ), + ), + ), + SubField( + name='timer_trigger', + def_num=3, + type=FIELD_TYPES['timer_trigger'], + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='timer', + raw_value=0, + ), + ), + ), + SubField( + name='virtual_partner_speed', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + scale=1000, + units='m/s', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='virtual_partner_pace', + raw_value=12, + ), + ), + ), + ), + ), + 4: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=4, + ), + 7: Field( # Do not populate directly. Autogenerated by decoder for sport_point subfield components + name='score', + type=BASE_TYPES[0x84], # uint16 + def_num=7, + ), + 8: Field( # Do not populate directly. Autogenerated by decoder for sport_point subfield components + name='opponent_score', + type=BASE_TYPES[0x84], # uint16 + def_num=8, + ), + 9: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Front gear number. 1 is innermost. + name='front_gear_num', + type=BASE_TYPES[0x0A], # uint8z + def_num=9, + ), + 10: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Number of front teeth. + name='front_gear', + type=BASE_TYPES[0x0A], # uint8z + def_num=10, + ), + 11: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Rear gear number. 1 is innermost. + name='rear_gear_num', + type=BASE_TYPES[0x0A], # uint8z + def_num=11, + ), + 12: Field( # Do not populate directly. Autogenerated by decoder for gear_change subfield components. Number of rear teeth. + name='rear_gear', + type=BASE_TYPES[0x0A], # uint8z + def_num=12, + ), + 13: Field( + name='device_index', + type=FIELD_TYPES['device_index'], + def_num=13, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 23: MessageType( + name='device_info', + mesg_num=23, + fields={ + 0: Field( + name='device_index', + type=FIELD_TYPES['device_index'], + def_num=0, + ), + 1: Field( + name='device_type', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + subfields=( + SubField( + name='ant_device_type', + def_num=1, + type=BASE_TYPES[0x02], # uint8 + ref_fields=( + ReferenceField( + name='source_type', + def_num=25, + value='ant', + raw_value=0, + ), + ), + ), + SubField( + name='antplus_device_type', + def_num=1, + type=FIELD_TYPES['antplus_device_type'], + ref_fields=( + ReferenceField( + name='source_type', + def_num=25, + value='antplus', + raw_value=1, + ), + ), + ), + ), + ), + 2: Field( + name='manufacturer', + type=FIELD_TYPES['manufacturer'], + def_num=2, + ), + 3: Field( + name='serial_number', + type=BASE_TYPES[0x8C], # uint32z + def_num=3, + ), + 4: Field( + name='product', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + subfields=( + SubField( + name='garmin_product', + def_num=4, + type=FIELD_TYPES['garmin_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=2, + value='garmin', + raw_value=1, + ), + ReferenceField( + name='manufacturer', + def_num=2, + value='dynastream', + raw_value=15, + ), + ReferenceField( + name='manufacturer', + def_num=2, + value='dynastream_oem', + raw_value=13, + ), + ), + ), + ), + ), + 5: Field( + name='software_version', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + scale=100, + ), + 6: Field( + name='hardware_version', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + ), + 7: Field( # Reset by new battery or charge. + name='cum_operating_time', + type=BASE_TYPES[0x86], # uint32 + def_num=7, + units='s', + ), + 10: Field( + name='battery_voltage', + type=BASE_TYPES[0x84], # uint16 + def_num=10, + scale=256, + units='V', + ), + 11: Field( + name='battery_status', + type=FIELD_TYPES['battery_status'], + def_num=11, + ), + 18: Field( # Indicates the location of the sensor + name='sensor_position', + type=FIELD_TYPES['body_location'], + def_num=18, + ), + 19: Field( # Used to describe the sensor or location + name='descriptor', + type=BASE_TYPES[0x07], # string + def_num=19, + ), + 20: Field( + name='ant_transmission_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=20, + ), + 21: Field( + name='ant_device_number', + type=BASE_TYPES[0x8B], # uint16z + def_num=21, + ), + 22: Field( + name='ant_network', + type=FIELD_TYPES['ant_network'], + def_num=22, + ), + 25: Field( + name='source_type', + type=FIELD_TYPES['source_type'], + def_num=25, + ), + 27: Field( # Optional free form string to indicate the devices name or model + name='product_name', + type=BASE_TYPES[0x07], # string + def_num=27, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 27: MessageType( + name='workout_step', + mesg_num=27, + fields={ + 0: Field( + name='wkt_step_name', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( + name='duration_type', + type=FIELD_TYPES['wkt_step_duration'], + def_num=1, + ), + 2: Field( + name='duration_value', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + subfields=( + SubField( + name='duration_calories', + def_num=2, + type=BASE_TYPES[0x86], # uint32 + units='calories', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='calories', + raw_value=4, + ), + ), + ), + SubField( + name='duration_distance', + def_num=2, + type=BASE_TYPES[0x86], # uint32 + scale=100, + units='m', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='distance', + raw_value=1, + ), + ), + ), + SubField( + name='duration_hr', + def_num=2, + type=FIELD_TYPES['workout_hr'], + units='% or bpm', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='hr_less_than', + raw_value=2, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='hr_greater_than', + raw_value=3, + ), + ), + ), + SubField( + name='duration_power', + def_num=2, + type=FIELD_TYPES['workout_power'], + units='% or watts', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='power_less_than', + raw_value=14, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='power_greater_than', + raw_value=15, + ), + ), + ), + SubField( + name='duration_reps', + def_num=2, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='reps', + raw_value=29, + ), + ), + ), + SubField( # message_index of step to loop back to. Steps are assumed to be in the order by message_index. custom_name and intensity members are undefined for this duration type. + name='duration_step', + def_num=2, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_steps_cmplt', + raw_value=6, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_time', + raw_value=7, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_distance', + raw_value=8, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_calories', + raw_value=9, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_hr_less_than', + raw_value=10, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_hr_greater_than', + raw_value=11, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_power_less_than', + raw_value=12, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_power_greater_than', + raw_value=13, + ), + ), + ), + SubField( + name='duration_time', + def_num=2, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='s', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='time', + raw_value=0, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repetition_time', + raw_value=28, + ), + ), + ), + ), + ), + 3: Field( + name='target_type', + type=FIELD_TYPES['wkt_step_target'], + def_num=3, + ), + 4: Field( + name='target_value', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + subfields=( + SubField( + name='repeat_calories', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + units='calories', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_calories', + raw_value=9, + ), + ), + ), + SubField( + name='repeat_distance', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + scale=100, + units='m', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_distance', + raw_value=8, + ), + ), + ), + SubField( + name='repeat_hr', + def_num=4, + type=FIELD_TYPES['workout_hr'], + units='% or bpm', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_hr_less_than', + raw_value=10, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_hr_greater_than', + raw_value=11, + ), + ), + ), + SubField( + name='repeat_power', + def_num=4, + type=FIELD_TYPES['workout_power'], + units='% or watts', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_power_less_than', + raw_value=12, + ), + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_power_greater_than', + raw_value=13, + ), + ), + ), + SubField( # # of repetitions + name='repeat_steps', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_steps_cmplt', + raw_value=6, + ), + ), + ), + SubField( + name='repeat_time', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='s', + ref_fields=( + ReferenceField( + name='duration_type', + def_num=1, + value='repeat_until_time', + raw_value=7, + ), + ), + ), + SubField( # Zone (1-?); Custom = 0; + name='target_cadence_zone', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='cadence', + raw_value=3, + ), + ), + ), + SubField( # hr zone (1-5);Custom =0; + name='target_hr_zone', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='heart_rate', + raw_value=1, + ), + ), + ), + SubField( # Power Zone ( 1-7); Custom = 0; + name='target_power_zone', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='power', + raw_value=4, + ), + ), + ), + SubField( # speed zone (1-10);Custom =0; + name='target_speed_zone', + def_num=4, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='speed', + raw_value=0, + ), + ), + ), + SubField( + name='target_stroke_type', + def_num=4, + type=FIELD_TYPES['swim_stroke'], + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='swim_stroke', + raw_value=11, + ), + ), + ), + ), + ), + 5: Field( + name='custom_target_value_low', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + subfields=( + SubField( + name='custom_target_cadence_low', + def_num=5, + type=BASE_TYPES[0x86], # uint32 + units='rpm', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='cadence', + raw_value=3, + ), + ), + ), + SubField( + name='custom_target_heart_rate_low', + def_num=5, + type=FIELD_TYPES['workout_hr'], + units='% or bpm', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='heart_rate', + raw_value=1, + ), + ), + ), + SubField( + name='custom_target_power_low', + def_num=5, + type=FIELD_TYPES['workout_power'], + units='% or watts', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='power', + raw_value=4, + ), + ), + ), + SubField( + name='custom_target_speed_low', + def_num=5, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='m/s', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='speed', + raw_value=0, + ), + ), + ), + ), + ), + 6: Field( + name='custom_target_value_high', + type=BASE_TYPES[0x86], # uint32 + def_num=6, + subfields=( + SubField( + name='custom_target_cadence_high', + def_num=6, + type=BASE_TYPES[0x86], # uint32 + units='rpm', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='cadence', + raw_value=3, + ), + ), + ), + SubField( + name='custom_target_heart_rate_high', + def_num=6, + type=FIELD_TYPES['workout_hr'], + units='% or bpm', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='heart_rate', + raw_value=1, + ), + ), + ), + SubField( + name='custom_target_power_high', + def_num=6, + type=FIELD_TYPES['workout_power'], + units='% or watts', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='power', + raw_value=4, + ), + ), + ), + SubField( + name='custom_target_speed_high', + def_num=6, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='m/s', + ref_fields=( + ReferenceField( + name='target_type', + def_num=3, + value='speed', + raw_value=0, + ), + ), + ), + ), + ), + 7: Field( + name='intensity', + type=FIELD_TYPES['intensity'], + def_num=7, + ), + 8: Field( + name='notes', + type=BASE_TYPES[0x07], # string + def_num=8, + ), + 9: Field( + name='equipment', + type=FIELD_TYPES['workout_equipment'], + def_num=9, + ), + 10: Field( + name='exercise_category', + type=FIELD_TYPES['exercise_category'], + def_num=10, + ), + 11: Field( + name='exercise_name', + type=BASE_TYPES[0x84], # uint16 + def_num=11, + ), + 12: Field( + name='exercise_weight', + type=BASE_TYPES[0x84], # uint16 + def_num=12, + scale=100, + units='kg', + ), + 13: Field( + name='weight_display_unit', + type=FIELD_TYPES['fit_base_unit'], + def_num=13, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 32: MessageType( + name='course_point', + mesg_num=32, + fields={ + 1: Field( + name='timestamp', + type=FIELD_TYPES['date_time'], + def_num=1, + ), + 2: Field( + name='position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=2, + units='semicircles', + ), + 3: Field( + name='position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=3, + units='semicircles', + ), + 4: Field( + name='distance', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + scale=100, + units='m', + ), + 5: Field( + name='type', + type=FIELD_TYPES['course_point'], + def_num=5, + ), + 6: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=6, + ), + 8: Field( + name='favorite', + type=FIELD_TYPES['bool'], + def_num=8, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 37: MessageType( + name='file_capabilities', + mesg_num=37, + fields={ + 0: Field( + name='type', + type=FIELD_TYPES['file'], + def_num=0, + ), + 1: Field( + name='flags', + type=FIELD_TYPES['file_flags'], + def_num=1, + ), + 2: Field( + name='directory', + type=BASE_TYPES[0x07], # string + def_num=2, + ), + 3: Field( + name='max_count', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + ), + 4: Field( + name='max_size', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + units='bytes', + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 38: MessageType( + name='mesg_capabilities', + mesg_num=38, + fields={ + 0: Field( + name='file', + type=FIELD_TYPES['file'], + def_num=0, + ), + 1: Field( + name='mesg_num', + type=FIELD_TYPES['mesg_num'], + def_num=1, + ), + 2: Field( + name='count_type', + type=FIELD_TYPES['mesg_count'], + def_num=2, + ), + 3: Field( + name='count', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + subfields=( + SubField( + name='max_per_file', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + ref_fields=( + ReferenceField( + name='count_type', + def_num=2, + value='max_per_file', + raw_value=1, + ), + ), + ), + SubField( + name='max_per_file_type', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + ref_fields=( + ReferenceField( + name='count_type', + def_num=2, + value='max_per_file_type', + raw_value=2, + ), + ), + ), + SubField( + name='num_per_file', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + ref_fields=( + ReferenceField( + name='count_type', + def_num=2, + value='num_per_file', + raw_value=0, + ), + ), + ), + ), + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 39: MessageType( + name='field_capabilities', + mesg_num=39, + fields={ + 0: Field( + name='file', + type=FIELD_TYPES['file'], + def_num=0, + ), + 1: Field( + name='mesg_num', + type=FIELD_TYPES['mesg_num'], + def_num=1, + ), + 2: Field( + name='field_num', + type=BASE_TYPES[0x02], # uint8 + def_num=2, + ), + 3: Field( + name='count', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 49: MessageType( + name='file_creator', + mesg_num=49, + fields={ + 0: Field( + name='software_version', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + ), + 1: Field( + name='hardware_version', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + ), + }, + ), + 53: MessageType( + name='speed_zone', + mesg_num=53, + fields={ + 0: Field( + name='high_value', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + scale=1000, + units='m/s', + ), + 1: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 55: MessageType( + name='monitoring', + mesg_num=55, + fields={ + 0: Field( # Associates this data to device_info message. Not required for file with single device (sensor). + name='device_index', + type=FIELD_TYPES['device_index'], + def_num=0, + ), + 1: Field( # Accumulated total calories. Maintained by MonitoringReader for each activity_type. See SDK documentation + name='calories', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='kcal', + ), + 2: Field( # Accumulated distance. Maintained by MonitoringReader for each activity_type. See SDK documentation. + name='distance', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + scale=100, + units='m', + ), + 3: Field( # Accumulated cycles. Maintained by MonitoringReader for each activity_type. See SDK documentation. + name='cycles', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=2, + units='cycles', + subfields=( + SubField( + name='steps', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + units='steps', + ref_fields=( + ReferenceField( + name='activity_type', + def_num=5, + value='walking', + raw_value=6, + ), + ReferenceField( + name='activity_type', + def_num=5, + value='running', + raw_value=1, + ), + ), + ), + SubField( + name='strokes', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + scale=2, + units='strokes', + ref_fields=( + ReferenceField( + name='activity_type', + def_num=5, + value='cycling', + raw_value=2, + ), + ReferenceField( + name='activity_type', + def_num=5, + value='swimming', + raw_value=5, + ), + ), + ), + ), + ), + 4: Field( + name='active_time', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + scale=1000, + units='s', + ), + 5: Field( + name='activity_type', + type=FIELD_TYPES['activity_type'], + def_num=5, + ), + 6: Field( + name='activity_subtype', + type=FIELD_TYPES['activity_subtype'], + def_num=6, + ), + 7: Field( + name='activity_level', + type=FIELD_TYPES['activity_level'], + def_num=7, + ), + 8: Field( + name='distance_16', + type=BASE_TYPES[0x84], # uint16 + def_num=8, + units='100*m', + ), + 9: Field( + name='cycles_16', + type=BASE_TYPES[0x84], # uint16 + def_num=9, + units='2*cycles or steps', + ), + 10: Field( + name='active_time_16', + type=BASE_TYPES[0x84], # uint16 + def_num=10, + units='s', + ), + 11: Field( # Must align to logging interval, for example, time must be 00:00:00 for daily log. + name='local_timestamp', + type=FIELD_TYPES['local_date_time'], + def_num=11, + ), + 12: Field( # Avg temperature during the logging interval ended at timestamp + name='temperature', + type=BASE_TYPES[0x83], # sint16 + def_num=12, + scale=100, + units='C', + ), + 14: Field( # Min temperature during the logging interval ended at timestamp + name='temperature_min', + type=BASE_TYPES[0x83], # sint16 + def_num=14, + scale=100, + units='C', + ), + 15: Field( # Max temperature during the logging interval ended at timestamp + name='temperature_max', + type=BASE_TYPES[0x83], # sint16 + def_num=15, + scale=100, + units='C', + ), + 16: Field( # Indexed using minute_activity_level enum + name='activity_time', + type=BASE_TYPES[0x84], # uint16 + def_num=16, + units='minutes', + ), + 19: Field( + name='active_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=19, + units='kcal', + ), + 24: Field( # Indicates single type / intensity for duration since last monitoring message. + name='current_activity_type_intensity', + type=BASE_TYPES[0x0D], # byte + def_num=24, + components=( + ComponentField( + name='activity_type', + def_num=5, + accumulate=False, + bits=5, + bit_offset=0, + ), + ComponentField( + name='intensity', + def_num=28, + accumulate=False, + bits=3, + bit_offset=5, + ), + ), + ), + 25: Field( + name='timestamp_min_8', + type=BASE_TYPES[0x02], # uint8 + def_num=25, + units='min', + ), + 26: Field( + name='timestamp_16', + type=BASE_TYPES[0x84], # uint16 + def_num=26, + units='s', + ), + 27: Field( + name='heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=27, + units='bpm', + ), + 28: Field( + name='intensity', + type=BASE_TYPES[0x02], # uint8 + def_num=28, + scale=10, + ), + 29: Field( + name='duration_min', + type=BASE_TYPES[0x84], # uint16 + def_num=29, + units='min', + ), + 30: Field( + name='duration', + type=BASE_TYPES[0x86], # uint32 + def_num=30, + units='s', + ), + 31: Field( + name='ascent', + type=BASE_TYPES[0x86], # uint32 + def_num=31, + scale=1000, + units='m', + ), + 32: Field( + name='descent', + type=BASE_TYPES[0x86], # uint32 + def_num=32, + scale=1000, + units='m', + ), + 33: Field( + name='moderate_activity_minutes', + type=BASE_TYPES[0x84], # uint16 + def_num=33, + units='minutes', + ), + 34: Field( + name='vigorous_activity_minutes', + type=BASE_TYPES[0x84], # uint16 + def_num=34, + units='minutes', + ), + 253: FIELD_TYPE_TIMESTAMP, # Must align to logging interval, for example, time must be 00:00:00 for daily log. + }, + ), + 72: MessageType( # Corresponds to file_id of workout or course. + name='training_file', + mesg_num=72, + fields={ + 0: Field( + name='type', + type=FIELD_TYPES['file'], + def_num=0, + ), + 1: Field( + name='manufacturer', + type=FIELD_TYPES['manufacturer'], + def_num=1, + ), + 2: Field( + name='product', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + subfields=( + SubField( + name='garmin_product', + def_num=2, + type=FIELD_TYPES['garmin_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=1, + value='garmin', + raw_value=1, + ), + ReferenceField( + name='manufacturer', + def_num=1, + value='dynastream', + raw_value=15, + ), + ReferenceField( + name='manufacturer', + def_num=1, + value='dynastream_oem', + raw_value=13, + ), + ), + ), + ), + ), + 3: Field( + name='serial_number', + type=BASE_TYPES[0x8C], # uint32z + def_num=3, + ), + 4: Field( + name='time_created', + type=FIELD_TYPES['date_time'], + def_num=4, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 78: MessageType( # Heart rate variability + name='hrv', + mesg_num=78, + fields={ + 0: Field( # Time between beats + name='time', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + scale=1000, + units='s', + ), + }, + ), + 80: MessageType( + name='ant_rx', + mesg_num=80, + fields={ + 0: Field( + name='fractional_timestamp', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + scale=32768, + units='s', + ), + 1: Field( + name='mesg_id', + type=BASE_TYPES[0x0D], # byte + def_num=1, + ), + 2: Field( + name='mesg_data', + type=BASE_TYPES[0x0D], # byte + def_num=2, + components=( + ComponentField( + name='channel_number', + def_num=3, + accumulate=False, + bits=8, + bit_offset=0, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=8, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=16, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=24, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=32, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=40, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=48, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=56, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=64, + ), + ), + ), + 3: Field( + name='channel_number', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + ), + 4: Field( + name='data', + type=BASE_TYPES[0x0D], # byte + def_num=4, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 81: MessageType( + name='ant_tx', + mesg_num=81, + fields={ + 0: Field( + name='fractional_timestamp', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + scale=32768, + units='s', + ), + 1: Field( + name='mesg_id', + type=BASE_TYPES[0x0D], # byte + def_num=1, + ), + 2: Field( + name='mesg_data', + type=BASE_TYPES[0x0D], # byte + def_num=2, + components=( + ComponentField( + name='channel_number', + def_num=3, + accumulate=False, + bits=8, + bit_offset=0, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=8, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=16, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=24, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=32, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=40, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=48, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=56, + ), + ComponentField( + name='data', + def_num=4, + accumulate=False, + bits=8, + bit_offset=64, + ), + ), + ), + 3: Field( + name='channel_number', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + ), + 4: Field( + name='data', + type=BASE_TYPES[0x0D], # byte + def_num=4, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 82: MessageType( + name='ant_channel_id', + mesg_num=82, + fields={ + 0: Field( + name='channel_number', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + ), + 1: Field( + name='device_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=1, + ), + 2: Field( + name='device_number', + type=BASE_TYPES[0x8B], # uint16z + def_num=2, + ), + 3: Field( + name='transmission_type', + type=BASE_TYPES[0x0A], # uint8z + def_num=3, + ), + 4: Field( + name='device_index', + type=FIELD_TYPES['device_index'], + def_num=4, + ), + }, + ), + 101: MessageType( + name='length', + mesg_num=101, + fields={ + 0: Field( + name='event', + type=FIELD_TYPES['event'], + def_num=0, + ), + 1: Field( + name='event_type', + type=FIELD_TYPES['event_type'], + def_num=1, + ), + 2: Field( + name='start_time', + type=FIELD_TYPES['date_time'], + def_num=2, + ), + 3: Field( + name='total_elapsed_time', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=1000, + units='s', + ), + 4: Field( + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + scale=1000, + units='s', + ), + 5: Field( + name='total_strokes', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + units='strokes', + ), + 6: Field( + name='avg_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=6, + scale=1000, + units='m/s', + ), + 7: Field( + name='swim_stroke', + type=FIELD_TYPES['swim_stroke'], + def_num=7, + units='swim_stroke', + ), + 9: Field( + name='avg_swimming_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=9, + units='strokes/min', + ), + 10: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=10, + ), + 11: Field( + name='total_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=11, + units='kcal', + ), + 12: Field( + name='length_type', + type=FIELD_TYPES['length_type'], + def_num=12, + ), + 18: Field( + name='player_score', + type=BASE_TYPES[0x84], # uint16 + def_num=18, + ), + 19: Field( + name='opponent_score', + type=BASE_TYPES[0x84], # uint16 + def_num=19, + ), + 20: Field( # stroke_type enum used as the index + name='stroke_count', + type=BASE_TYPES[0x84], # uint16 + def_num=20, + units='counts', + ), + 21: Field( # zone number used as the index + name='zone_count', + type=BASE_TYPES[0x84], # uint16 + def_num=21, + units='counts', + ), + 253: FIELD_TYPE_TIMESTAMP, + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 106: MessageType( + name='slave_device', + mesg_num=106, + fields={ + 0: Field( + name='manufacturer', + type=FIELD_TYPES['manufacturer'], + def_num=0, + ), + 1: Field( + name='product', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + subfields=( + SubField( + name='garmin_product', + def_num=1, + type=FIELD_TYPES['garmin_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=0, + value='garmin', + raw_value=1, + ), + ReferenceField( + name='manufacturer', + def_num=0, + value='dynastream', + raw_value=15, + ), + ReferenceField( + name='manufacturer', + def_num=0, + value='dynastream_oem', + raw_value=13, + ), + ), + ), + ), + ), + }, + ), + 127: MessageType( + name='connectivity', + mesg_num=127, + fields={ + 0: Field( # Use Bluetooth for connectivity features + name='bluetooth_enabled', + type=FIELD_TYPES['bool'], + def_num=0, + ), + 1: Field( # Use Bluetooth Low Energy for connectivity features + name='bluetooth_le_enabled', + type=FIELD_TYPES['bool'], + def_num=1, + ), + 2: Field( # Use ANT for connectivity features + name='ant_enabled', + type=FIELD_TYPES['bool'], + def_num=2, + ), + 3: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=3, + ), + 4: Field( + name='live_tracking_enabled', + type=FIELD_TYPES['bool'], + def_num=4, + ), + 5: Field( + name='weather_conditions_enabled', + type=FIELD_TYPES['bool'], + def_num=5, + ), + 6: Field( + name='weather_alerts_enabled', + type=FIELD_TYPES['bool'], + def_num=6, + ), + 7: Field( + name='auto_activity_upload_enabled', + type=FIELD_TYPES['bool'], + def_num=7, + ), + 8: Field( + name='course_download_enabled', + type=FIELD_TYPES['bool'], + def_num=8, + ), + 9: Field( + name='workout_download_enabled', + type=FIELD_TYPES['bool'], + def_num=9, + ), + 10: Field( + name='gps_ephemeris_download_enabled', + type=FIELD_TYPES['bool'], + def_num=10, + ), + 11: Field( + name='incident_detection_enabled', + type=FIELD_TYPES['bool'], + def_num=11, + ), + 12: Field( + name='grouptrack_enabled', + type=FIELD_TYPES['bool'], + def_num=12, + ), + }, + ), + 128: MessageType( + name='weather_conditions', + mesg_num=128, + fields={ + 0: Field( # Current or forecast + name='weather_report', + type=FIELD_TYPES['weather_report'], + def_num=0, + ), + 1: Field( + name='temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=1, + units='C', + ), + 2: Field( # Corresponds to GSC Response weatherIcon field + name='condition', + type=FIELD_TYPES['weather_status'], + def_num=2, + ), + 3: Field( + name='wind_direction', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + units='degrees', + ), + 4: Field( + name='wind_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + scale=1000, + units='m/s', + ), + 5: Field( # range 0-100 + name='precipitation_probability', + type=BASE_TYPES[0x02], # uint8 + def_num=5, + ), + 6: Field( # Heat Index if GCS heatIdx above or equal to 90F or wind chill if GCS windChill below or equal to 32F + name='temperature_feels_like', + type=BASE_TYPES[0x01], # sint8 + def_num=6, + units='C', + ), + 7: Field( + name='relative_humidity', + type=BASE_TYPES[0x02], # uint8 + def_num=7, + ), + 8: Field( # string corresponding to GCS response location string + name='location', + type=BASE_TYPES[0x07], # string + def_num=8, + ), + 9: Field( + name='observed_at_time', + type=FIELD_TYPES['date_time'], + def_num=9, + ), + 10: Field( + name='observed_location_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=10, + units='semicircles', + ), + 11: Field( + name='observed_location_long', + type=BASE_TYPES[0x85], # sint32 + def_num=11, + units='semicircles', + ), + 12: Field( + name='day_of_week', + type=FIELD_TYPES['day_of_week'], + def_num=12, + ), + 13: Field( + name='high_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=13, + units='C', + ), + 14: Field( + name='low_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=14, + units='C', + ), + 253: FIELD_TYPE_TIMESTAMP, # time of update for current conditions, else forecast time + }, + ), + 129: MessageType( + name='weather_alert', + mesg_num=129, + fields={ + 0: Field( # Unique identifier from GCS report ID string, length is 12 + name='report_id', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( # Time alert was issued + name='issue_time', + type=FIELD_TYPES['date_time'], + def_num=1, + ), + 2: Field( # Time alert expires + name='expire_time', + type=FIELD_TYPES['date_time'], + def_num=2, + ), + 3: Field( # Warning, Watch, Advisory, Statement + name='severity', + type=FIELD_TYPES['weather_severity'], + def_num=3, + ), + 4: Field( # Tornado, Severe Thunderstorm, etc. + name='type', + type=FIELD_TYPES['weather_severe_type'], + def_num=4, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 131: MessageType( + name='cadence_zone', + mesg_num=131, + fields={ + 0: Field( + name='high_value', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + units='rpm', + ), + 1: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 132: MessageType( + name='hr', + mesg_num=132, + fields={ + 0: Field( + name='fractional_timestamp', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + scale=32768, + units='s', + ), + 1: Field( + name='time256', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + components=( + ComponentField( + name='fractional_timestamp', + def_num=0, + scale=256, + units='s', + accumulate=False, + bits=8, + bit_offset=0, + ), + ), + ), + 6: Field( + name='filtered_bpm', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + units='bpm', + ), + 9: Field( + name='event_timestamp', + type=BASE_TYPES[0x86], # uint32 + def_num=9, + scale=1024, + units='s', + ), + 10: Field( + name='event_timestamp_12', + type=BASE_TYPES[0x0D], # byte + def_num=10, + components=( + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=0, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=12, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=24, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=36, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=48, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=60, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=72, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=84, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=96, + ), + ComponentField( + name='event_timestamp', + def_num=9, + scale=1024, + units='s', + accumulate=True, + bits=12, + bit_offset=108, + ), + ), + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 142: MessageType( + name='segment_lap', + mesg_num=142, + fields={ + 0: Field( + name='event', + type=FIELD_TYPES['event'], + def_num=0, + ), + 1: Field( + name='event_type', + type=FIELD_TYPES['event_type'], + def_num=1, + ), + 2: Field( + name='start_time', + type=FIELD_TYPES['date_time'], + def_num=2, + ), + 3: Field( + name='start_position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=3, + units='semicircles', + ), + 4: Field( + name='start_position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=4, + units='semicircles', + ), + 5: Field( + name='end_position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=5, + units='semicircles', + ), + 6: Field( + name='end_position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=6, + units='semicircles', + ), + 7: Field( # Time (includes pauses) + name='total_elapsed_time', + type=BASE_TYPES[0x86], # uint32 + def_num=7, + scale=1000, + units='s', + ), + 8: Field( # Timer Time (excludes pauses) + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=8, + scale=1000, + units='s', + ), + 9: Field( + name='total_distance', + type=BASE_TYPES[0x86], # uint32 + def_num=9, + scale=100, + units='m', + ), + 10: Field( + name='total_cycles', + type=BASE_TYPES[0x86], # uint32 + def_num=10, + units='cycles', + subfields=( + SubField( + name='total_strokes', + def_num=10, + type=BASE_TYPES[0x86], # uint32 + units='strokes', + ref_fields=( + ReferenceField( + name='sport', + def_num=23, + value='cycling', + raw_value=2, + ), + ), + ), + ), + ), + 11: Field( + name='total_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=11, + units='kcal', + ), + 12: Field( # If New Leaf + name='total_fat_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=12, + units='kcal', + ), + 13: Field( + name='avg_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=13, + scale=1000, + units='m/s', + ), + 14: Field( + name='max_speed', + type=BASE_TYPES[0x84], # uint16 + def_num=14, + scale=1000, + units='m/s', + ), + 15: Field( + name='avg_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=15, + units='bpm', + ), + 16: Field( + name='max_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=16, + units='bpm', + ), + 17: Field( # total_cycles / total_timer_time if non_zero_avg_cadence otherwise total_cycles / total_elapsed_time + name='avg_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=17, + units='rpm', + ), + 18: Field( + name='max_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=18, + units='rpm', + ), + 19: Field( # total_power / total_timer_time if non_zero_avg_power otherwise total_power / total_elapsed_time + name='avg_power', + type=BASE_TYPES[0x84], # uint16 + def_num=19, + units='watts', + ), + 20: Field( + name='max_power', + type=BASE_TYPES[0x84], # uint16 + def_num=20, + units='watts', + ), + 21: Field( + name='total_ascent', + type=BASE_TYPES[0x84], # uint16 + def_num=21, + units='m', + ), + 22: Field( + name='total_descent', + type=BASE_TYPES[0x84], # uint16 + def_num=22, + units='m', + ), + 23: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=23, + ), + 24: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=24, + ), + 25: Field( # North east corner latitude. + name='nec_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=25, + units='semicircles', + ), + 26: Field( # North east corner longitude. + name='nec_long', + type=BASE_TYPES[0x85], # sint32 + def_num=26, + units='semicircles', + ), + 27: Field( # South west corner latitude. + name='swc_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=27, + units='semicircles', + ), + 28: Field( # South west corner latitude. + name='swc_long', + type=BASE_TYPES[0x85], # sint32 + def_num=28, + units='semicircles', + ), + 29: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=29, + ), + 30: Field( + name='normalized_power', + type=BASE_TYPES[0x84], # uint16 + def_num=30, + units='watts', + ), + 31: Field( + name='left_right_balance', + type=FIELD_TYPES['left_right_balance_100'], + def_num=31, + ), + 32: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=32, + ), + 33: Field( + name='total_work', + type=BASE_TYPES[0x86], # uint32 + def_num=33, + units='J', + ), + 34: Field( + name='avg_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=34, + scale=5, + offset=500, + units='m', + ), + 35: Field( + name='max_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=35, + scale=5, + offset=500, + units='m', + ), + 36: Field( + name='gps_accuracy', + type=BASE_TYPES[0x02], # uint8 + def_num=36, + units='m', + ), + 37: Field( + name='avg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=37, + scale=100, + units='%', + ), + 38: Field( + name='avg_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=38, + scale=100, + units='%', + ), + 39: Field( + name='avg_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=39, + scale=100, + units='%', + ), + 40: Field( + name='max_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=40, + scale=100, + units='%', + ), + 41: Field( + name='max_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=41, + scale=100, + units='%', + ), + 42: Field( + name='avg_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=42, + units='C', + ), + 43: Field( + name='max_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=43, + units='C', + ), + 44: Field( + name='total_moving_time', + type=BASE_TYPES[0x86], # uint32 + def_num=44, + scale=1000, + units='s', + ), + 45: Field( + name='avg_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=45, + scale=1000, + units='m/s', + ), + 46: Field( + name='avg_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=46, + scale=1000, + units='m/s', + ), + 47: Field( + name='max_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=47, + scale=1000, + units='m/s', + ), + 48: Field( + name='max_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=48, + scale=1000, + units='m/s', + ), + 49: Field( + name='time_in_hr_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=49, + scale=1000, + units='s', + ), + 50: Field( + name='time_in_speed_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=50, + scale=1000, + units='s', + ), + 51: Field( + name='time_in_cadence_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=51, + scale=1000, + units='s', + ), + 52: Field( + name='time_in_power_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=52, + scale=1000, + units='s', + ), + 53: Field( + name='repetition_num', + type=BASE_TYPES[0x84], # uint16 + def_num=53, + ), + 54: Field( + name='min_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=54, + scale=5, + offset=500, + units='m', + ), + 55: Field( + name='min_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=55, + units='bpm', + ), + 56: Field( + name='active_time', + type=BASE_TYPES[0x86], # uint32 + def_num=56, + scale=1000, + units='s', + ), + 57: Field( + name='wkt_step_index', + type=FIELD_TYPES['message_index'], + def_num=57, + ), + 58: Field( + name='sport_event', + type=FIELD_TYPES['sport_event'], + def_num=58, + ), + 59: Field( + name='avg_left_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=59, + scale=2, + units='percent', + ), + 60: Field( + name='avg_right_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=60, + scale=2, + units='percent', + ), + 61: Field( + name='avg_left_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=61, + scale=2, + units='percent', + ), + 62: Field( + name='avg_right_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=62, + scale=2, + units='percent', + ), + 63: Field( + name='avg_combined_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=63, + scale=2, + units='percent', + ), + 64: Field( + name='status', + type=FIELD_TYPES['segment_lap_status'], + def_num=64, + ), + 65: Field( + name='uuid', + type=BASE_TYPES[0x07], # string + def_num=65, + ), + 66: Field( # fractional part of the avg_cadence + name='avg_fractional_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=66, + scale=128, + units='rpm', + ), + 67: Field( # fractional part of the max_cadence + name='max_fractional_cadence', + type=BASE_TYPES[0x02], # uint8 + def_num=67, + scale=128, + units='rpm', + ), + 68: Field( # fractional part of the total_cycles + name='total_fractional_cycles', + type=BASE_TYPES[0x02], # uint8 + def_num=68, + scale=128, + units='cycles', + ), + 69: Field( + name='front_gear_shift_count', + type=BASE_TYPES[0x84], # uint16 + def_num=69, + ), + 70: Field( + name='rear_gear_shift_count', + type=BASE_TYPES[0x84], # uint16 + def_num=70, + ), + 71: Field( # Total time spent in the standing position + name='time_standing', + type=BASE_TYPES[0x86], # uint32 + def_num=71, + scale=1000, + units='s', + ), + 72: Field( # Number of transitions to the standing state + name='stand_count', + type=BASE_TYPES[0x84], # uint16 + def_num=72, + ), + 73: Field( # Average left platform center offset + name='avg_left_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=73, + units='mm', + ), + 74: Field( # Average right platform center offset + name='avg_right_pco', + type=BASE_TYPES[0x01], # sint8 + def_num=74, + units='mm', + ), + 75: Field( # Average left power phase angles. Data value indexes defined by power_phase_type. + name='avg_left_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=75, + scale=0.7111111, + units='degrees', + ), + 76: Field( # Average left power phase peak angles. Data value indexes defined by power_phase_type. + name='avg_left_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=76, + scale=0.7111111, + units='degrees', + ), + 77: Field( # Average right power phase angles. Data value indexes defined by power_phase_type. + name='avg_right_power_phase', + type=BASE_TYPES[0x02], # uint8 + def_num=77, + scale=0.7111111, + units='degrees', + ), + 78: Field( # Average right power phase peak angles. Data value indexes defined by power_phase_type. + name='avg_right_power_phase_peak', + type=BASE_TYPES[0x02], # uint8 + def_num=78, + scale=0.7111111, + units='degrees', + ), + 79: Field( # Average power by position. Data value indexes defined by rider_position_type. + name='avg_power_position', + type=BASE_TYPES[0x84], # uint16 + def_num=79, + units='watts', + ), + 80: Field( # Maximum power by position. Data value indexes defined by rider_position_type. + name='max_power_position', + type=BASE_TYPES[0x84], # uint16 + def_num=80, + units='watts', + ), + 81: Field( # Average cadence by position. Data value indexes defined by rider_position_type. + name='avg_cadence_position', + type=BASE_TYPES[0x02], # uint8 + def_num=81, + units='rpm', + ), + 82: Field( # Maximum cadence by position. Data value indexes defined by rider_position_type. + name='max_cadence_position', + type=BASE_TYPES[0x02], # uint8 + def_num=82, + units='rpm', + ), + 83: Field( # Manufacturer that produced the segment + name='manufacturer', + type=FIELD_TYPES['manufacturer'], + def_num=83, + ), + 253: FIELD_TYPE_TIMESTAMP, # Lap end time. + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 149: MessageType( # Unique Identification data for an individual segment leader within a segment file + name='segment_leaderboard_entry', + mesg_num=149, + fields={ + 0: Field( # Friendly name assigned to leader + name='name', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( # Leader classification + name='type', + type=FIELD_TYPES['segment_leaderboard_type'], + def_num=1, + ), + 2: Field( # Primary user ID of this leader + name='group_primary_key', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + ), + 3: Field( # ID of the activity associated with this leader time + name='activity_id', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + ), + 4: Field( # Segment Time (includes pauses) + name='segment_time', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + scale=1000, + units='s', + ), + 5: Field( # String version of the activity_id. 21 characters long, express in decimal + name='activity_id_string', + type=BASE_TYPES[0x07], # string + def_num=5, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 150: MessageType( # Navigation and race evaluation point for a segment decribing a point along the segment path and time it took each segment leader to reach that point + name='segment_point', + mesg_num=150, + fields={ + 1: Field( + name='position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=1, + units='semicircles', + ), + 2: Field( + name='position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=2, + units='semicircles', + ), + 3: Field( # Accumulated distance along the segment at the described point + name='distance', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=100, + units='m', + ), + 4: Field( # Accumulated altitude along the segment at the described point + name='altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + scale=5, + offset=500, + units='m', + ), + 5: Field( # Accumualted time each leader board member required to reach the described point. This value is zero for all leader board members at the starting point of the segment. + name='leader_time', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + scale=1000, + units='s', + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 158: MessageType( + name='workout_session', + mesg_num=158, + fields={ + 0: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=0, + ), + 1: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=1, + ), + 2: Field( + name='num_valid_steps', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + ), + 3: Field( + name='first_step_index', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + ), + 4: Field( + name='pool_length', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + scale=100, + units='m', + ), + 5: Field( + name='pool_length_unit', + type=FIELD_TYPES['display_measure'], + def_num=5, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 159: MessageType( + name='watchface_settings', + mesg_num=159, + fields={ + 0: Field( + name='mode', + type=FIELD_TYPES['watchface_mode'], + def_num=0, + ), + 1: Field( + name='layout', + type=BASE_TYPES[0x0D], # byte + def_num=1, + subfields=( + SubField( + name='analog_layout', + def_num=1, + type=FIELD_TYPES['analog_watchface_layout'], + ref_fields=( + ReferenceField( + name='mode', + def_num=0, + value='analog', + raw_value=1, + ), + ), + ), + SubField( + name='digital_layout', + def_num=1, + type=FIELD_TYPES['digital_watchface_layout'], + ref_fields=( + ReferenceField( + name='mode', + def_num=0, + value='digital', + raw_value=0, + ), + ), + ), + ), + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 160: MessageType( + name='gps_metadata', + mesg_num=160, + fields={ + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( + name='position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=1, + units='semicircles', + ), + 2: Field( + name='position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=2, + units='semicircles', + ), + 3: Field( + name='enhanced_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=5, + offset=500, + units='m', + ), + 4: Field( + name='enhanced_speed', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + scale=1000, + units='m/s', + ), + 5: Field( + name='heading', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + scale=100, + units='degrees', + ), + 6: Field( # Used to correlate UTC to system time if the timestamp of the message is in system time. This UTC time is derived from the GPS data. + name='utc_timestamp', + type=FIELD_TYPES['date_time'], + def_num=6, + units='s', + ), + 7: Field( # velocity[0] is lon velocity. Velocity[1] is lat velocity. Velocity[2] is altitude velocity. + name='velocity', + type=BASE_TYPES[0x83], # sint16 + def_num=7, + scale=100, + units='m/s', + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp. + }, + ), + 161: MessageType( + name='camera_event', + mesg_num=161, + fields={ + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( + name='camera_event_type', + type=FIELD_TYPES['camera_event_type'], + def_num=1, + ), + 2: Field( + name='camera_file_uuid', + type=BASE_TYPES[0x07], # string + def_num=2, + ), + 3: Field( + name='camera_orientation', + type=FIELD_TYPES['camera_orientation_type'], + def_num=3, + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp. + }, + ), + 162: MessageType( + name='timestamp_correlation', + mesg_num=162, + fields={ + 0: Field( # Fractional part of the UTC timestamp at the time the system timestamp was recorded. + name='fractional_timestamp', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + scale=32768, + units='s', + ), + 1: Field( # Whole second part of the system timestamp + name='system_timestamp', + type=FIELD_TYPES['date_time'], + def_num=1, + units='s', + ), + 2: Field( # Fractional part of the system timestamp + name='fractional_system_timestamp', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + scale=32768, + units='s', + ), + 3: Field( # timestamp epoch expressed in local time used to convert timestamps to local time + name='local_timestamp', + type=FIELD_TYPES['local_date_time'], + def_num=3, + units='s', + ), + 4: Field( # Millisecond part of the UTC timestamp at the time the system timestamp was recorded. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + units='ms', + ), + 5: Field( # Millisecond part of the system timestamp + name='system_timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + units='ms', + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of UTC timestamp at the time the system timestamp was recorded. + }, + ), + 164: MessageType( + name='gyroscope_data', + mesg_num=164, + fields={ + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # Each time in the array describes the time at which the gyro sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in gyro_x and gyro_y and gyro_z + name='sample_time_offset', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='ms', + ), + 2: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='gyro_x', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + units='counts', + ), + 3: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='gyro_y', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + units='counts', + ), + 4: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='gyro_z', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + units='counts', + ), + 5: Field( # Calibrated gyro reading + name='calibrated_gyro_x', + type=BASE_TYPES[0x88], # float32 + def_num=5, + units='deg/s', + ), + 6: Field( # Calibrated gyro reading + name='calibrated_gyro_y', + type=BASE_TYPES[0x88], # float32 + def_num=6, + units='deg/s', + ), + 7: Field( # Calibrated gyro reading + name='calibrated_gyro_z', + type=BASE_TYPES[0x88], # float32 + def_num=7, + units='deg/s', + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + }, + ), + 165: MessageType( + name='accelerometer_data', + mesg_num=165, + fields={ + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # Each time in the array describes the time at which the accelerometer sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in accel_x and accel_y and accel_z + name='sample_time_offset', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='ms', + ), + 2: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='accel_x', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + units='counts', + ), + 3: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='accel_y', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + units='counts', + ), + 4: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='accel_z', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + units='counts', + ), + 5: Field( # Calibrated accel reading + name='calibrated_accel_x', + type=BASE_TYPES[0x88], # float32 + def_num=5, + units='g', + ), + 6: Field( # Calibrated accel reading + name='calibrated_accel_y', + type=BASE_TYPES[0x88], # float32 + def_num=6, + units='g', + ), + 7: Field( # Calibrated accel reading + name='calibrated_accel_z', + type=BASE_TYPES[0x88], # float32 + def_num=7, + units='g', + ), + 8: Field( # Calibrated accel reading + name='compressed_calibrated_accel_x', + type=BASE_TYPES[0x83], # sint16 + def_num=8, + units='mG', + ), + 9: Field( # Calibrated accel reading + name='compressed_calibrated_accel_y', + type=BASE_TYPES[0x83], # sint16 + def_num=9, + units='mG', + ), + 10: Field( # Calibrated accel reading + name='compressed_calibrated_accel_z', + type=BASE_TYPES[0x83], # sint16 + def_num=10, + units='mG', + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + }, + ), + 167: MessageType( + name='three_d_sensor_calibration', + mesg_num=167, + fields={ + 0: Field( # Indicates which sensor the calibration is for + name='sensor_type', + type=FIELD_TYPES['sensor_type'], + def_num=0, + ), + 1: Field( # Calibration factor used to convert from raw ADC value to degrees, g, etc. + name='calibration_factor', + type=BASE_TYPES[0x86], # uint32 + def_num=1, + subfields=( + SubField( # Accelerometer calibration factor + name='accel_cal_factor', + def_num=1, + type=BASE_TYPES[0x86], # uint32 + units='g', + ref_fields=( + ReferenceField( + name='sensor_type', + def_num=0, + value='accelerometer', + raw_value=0, + ), + ), + ), + SubField( # Gyro calibration factor + name='gyro_cal_factor', + def_num=1, + type=BASE_TYPES[0x86], # uint32 + units='deg/s', + ref_fields=( + ReferenceField( + name='sensor_type', + def_num=0, + value='gyroscope', + raw_value=1, + ), + ), + ), + ), + ), + 2: Field( # Calibration factor divisor + name='calibration_divisor', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + units='counts', + ), + 3: Field( # Level shift value used to shift the ADC value back into range + name='level_shift', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + ), + 4: Field( # Internal calibration factors, one for each: xy, yx, zx + name='offset_cal', + type=BASE_TYPES[0x85], # sint32 + def_num=4, + ), + 5: Field( # 3 x 3 rotation matrix (row major) + name='orientation_matrix', + type=BASE_TYPES[0x85], # sint32 + def_num=5, + scale=65535, + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + }, + ), + 169: MessageType( + name='video_frame', + mesg_num=169, + fields={ + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # Number of the frame that the timestamp and timestamp_ms correlate to + name='frame_number', + type=BASE_TYPES[0x86], # uint32 + def_num=1, + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + }, + ), + 174: MessageType( + name='obdii_data', + mesg_num=174, + fields={ + 0: Field( # Fractional part of timestamp, added to timestamp + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # Offset of PID reading [i] from start_timestamp+start_timestamp_ms. Readings may span accross seconds. + name='time_offset', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='ms', + ), + 2: Field( # Parameter ID + name='pid', + type=BASE_TYPES[0x0D], # byte + def_num=2, + ), + 3: Field( # Raw parameter data + name='raw_data', + type=BASE_TYPES[0x0D], # byte + def_num=3, + ), + 4: Field( # Optional, data size of PID[i]. If not specified refer to SAE J1979. + name='pid_data_size', + type=BASE_TYPES[0x02], # uint8 + def_num=4, + ), + 5: Field( # System time associated with sample expressed in ms, can be used instead of time_offset. There will be a system_time value for each raw_data element. For multibyte pids the system_time is repeated. + name='system_time', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + ), + 6: Field( # Timestamp of first sample recorded in the message. Used with time_offset to generate time of each sample + name='start_timestamp', + type=FIELD_TYPES['date_time'], + def_num=6, + ), + 7: Field( # Fractional part of start_timestamp + name='start_timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=7, + units='ms', + ), + 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output + }, + ), + 177: MessageType( + name='nmea_sentence', + mesg_num=177, + fields={ + 0: Field( # Fractional part of timestamp, added to timestamp + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # NMEA sentence + name='sentence', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output + }, + ), + 178: MessageType( + name='aviation_attitude', + mesg_num=178, + fields={ + 0: Field( # Fractional part of timestamp, added to timestamp + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # System time associated with sample expressed in ms. + name='system_time', + type=BASE_TYPES[0x86], # uint32 + def_num=1, + units='ms', + ), + 2: Field( # Range -PI/2 to +PI/2 + name='pitch', + type=BASE_TYPES[0x83], # sint16 + def_num=2, + scale=10430.38, + units='radians', + ), + 3: Field( # Range -PI to +PI + name='roll', + type=BASE_TYPES[0x83], # sint16 + def_num=3, + scale=10430.38, + units='radians', + ), + 4: Field( # Range -78.4 to +78.4 (-8 Gs to 8 Gs) + name='accel_lateral', + type=BASE_TYPES[0x83], # sint16 + def_num=4, + scale=100, + units='m/s^2', + ), + 5: Field( # Range -78.4 to +78.4 (-8 Gs to 8 Gs) + name='accel_normal', + type=BASE_TYPES[0x83], # sint16 + def_num=5, + scale=100, + units='m/s^2', + ), + 6: Field( # Range -8.727 to +8.727 (-500 degs/sec to +500 degs/sec) + name='turn_rate', + type=BASE_TYPES[0x83], # sint16 + def_num=6, + scale=1024, + units='radians/second', + ), + 7: Field( + name='stage', + type=FIELD_TYPES['attitude_stage'], + def_num=7, + ), + 8: Field( # The percent complete of the current attitude stage. Set to 0 for attitude stages 0, 1 and 2 and to 100 for attitude stage 3 by AHRS modules that do not support it. Range - 100 + name='attitude_stage_complete', + type=BASE_TYPES[0x02], # uint8 + def_num=8, + units='%', + ), + 9: Field( # Track Angle/Heading Range 0 - 2pi + name='track', + type=BASE_TYPES[0x84], # uint16 + def_num=9, + scale=10430.38, + units='radians', + ), + 10: Field( + name='validity', + type=FIELD_TYPES['attitude_validity'], + def_num=10, + ), + 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output + }, + ), + 184: MessageType( + name='video', + mesg_num=184, + fields={ + 0: Field( + name='url', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( + name='hosting_provider', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 2: Field( # Playback time of video + name='duration', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + units='ms', + ), + }, + ), + 185: MessageType( + name='video_title', + mesg_num=185, + fields={ + 0: Field( # Total number of title parts + name='message_count', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + ), + 1: Field( + name='text', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 254: Field( # Long titles will be split into multiple parts + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 186: MessageType( + name='video_description', + mesg_num=186, + fields={ + 0: Field( # Total number of description parts + name='message_count', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + ), + 1: Field( + name='text', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 254: Field( # Long descriptions will be split into multiple parts + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 187: MessageType( + name='video_clip', + mesg_num=187, + fields={ + 0: Field( + name='clip_number', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + ), + 1: Field( + name='start_timestamp', + type=FIELD_TYPES['date_time'], + def_num=1, + ), + 2: Field( + name='start_timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + ), + 3: Field( + name='end_timestamp', + type=FIELD_TYPES['date_time'], + def_num=3, + ), + 4: Field( + name='end_timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + ), + 6: Field( # Start of clip in video time + name='clip_start', + type=BASE_TYPES[0x86], # uint32 + def_num=6, + units='ms', + ), + 7: Field( # End of clip in video time + name='clip_end', + type=BASE_TYPES[0x86], # uint32 + def_num=7, + units='ms', + ), + }, + ), + 188: MessageType( + name='ohr_settings', + mesg_num=188, + fields={ + 0: Field( + name='enabled', + type=FIELD_TYPES['switch'], + def_num=0, + ), + }, + ), + 200: MessageType( + name='exd_screen_configuration', + mesg_num=200, + fields={ + 0: Field( + name='screen_index', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + ), + 1: Field( # number of fields in screen + name='field_count', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + ), + 2: Field( + name='layout', + type=FIELD_TYPES['exd_layout'], + def_num=2, + ), + 3: Field( + name='screen_enabled', + type=FIELD_TYPES['bool'], + def_num=3, + ), + }, + ), + 201: MessageType( + name='exd_data_field_configuration', + mesg_num=201, + fields={ + 0: Field( + name='screen_index', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + ), + 1: Field( + name='concept_field', + type=BASE_TYPES[0x0D], # byte + def_num=1, + components=( + ComponentField( + name='field_id', + def_num=2, + accumulate=False, + bits=4, + bit_offset=0, + ), + ComponentField( + name='concept_count', + def_num=3, + accumulate=False, + bits=4, + bit_offset=4, + ), + ), + ), + 2: Field( + name='field_id', + type=BASE_TYPES[0x02], # uint8 + def_num=2, + ), + 3: Field( + name='concept_count', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + ), + 4: Field( + name='display_type', + type=FIELD_TYPES['exd_display_type'], + def_num=4, + ), + 5: Field( + name='title', + type=BASE_TYPES[0x07], # string + def_num=5, + ), + }, + ), + 202: MessageType( + name='exd_data_concept_configuration', + mesg_num=202, + fields={ + 0: Field( + name='screen_index', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + ), + 1: Field( + name='concept_field', + type=BASE_TYPES[0x0D], # byte + def_num=1, + components=( + ComponentField( + name='field_id', + def_num=2, + accumulate=False, + bits=4, + bit_offset=0, + ), + ComponentField( + name='concept_index', + def_num=3, + accumulate=False, + bits=4, + bit_offset=4, + ), + ), + ), + 2: Field( + name='field_id', + type=BASE_TYPES[0x02], # uint8 + def_num=2, + ), + 3: Field( + name='concept_index', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + ), + 4: Field( + name='data_page', + type=BASE_TYPES[0x02], # uint8 + def_num=4, + ), + 5: Field( + name='concept_key', + type=BASE_TYPES[0x02], # uint8 + def_num=5, + ), + 6: Field( + name='scaling', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + ), + 8: Field( + name='data_units', + type=FIELD_TYPES['exd_data_units'], + def_num=8, + ), + 9: Field( + name='qualifier', + type=FIELD_TYPES['exd_qualifiers'], + def_num=9, + ), + 10: Field( + name='descriptor', + type=FIELD_TYPES['exd_descriptors'], + def_num=10, + ), + 11: Field( + name='is_signed', + type=FIELD_TYPES['bool'], + def_num=11, + ), + }, + ), + 206: MessageType( # Must be logged before developer field is used + name='field_description', + mesg_num=206, + fields={ + 0: Field( + name='developer_data_index', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + ), + 1: Field( + name='field_definition_number', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + ), + 2: Field( + name='fit_base_type_id', + type=FIELD_TYPES['fit_base_type'], + def_num=2, + ), + 3: Field( + name='field_name', + type=BASE_TYPES[0x07], # string + def_num=3, + ), + 4: Field( + name='array', + type=BASE_TYPES[0x02], # uint8 + def_num=4, + ), + 5: Field( + name='components', + type=BASE_TYPES[0x07], # string + def_num=5, + ), + 6: Field( + name='scale', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + ), + 7: Field( + name='offset', + type=BASE_TYPES[0x01], # sint8 + def_num=7, + ), + 8: Field( + name='units', + type=BASE_TYPES[0x07], # string + def_num=8, + ), + 9: Field( + name='bits', + type=BASE_TYPES[0x07], # string + def_num=9, + ), + 10: Field( + name='accumulate', + type=BASE_TYPES[0x07], # string + def_num=10, + ), + 13: Field( + name='fit_base_unit_id', + type=FIELD_TYPES['fit_base_unit'], + def_num=13, + ), + 14: Field( + name='native_mesg_num', + type=FIELD_TYPES['mesg_num'], + def_num=14, + ), + 15: Field( + name='native_field_num', + type=BASE_TYPES[0x02], # uint8 + def_num=15, + ), + }, + ), + 207: MessageType( # Must be logged before field description + name='developer_data_id', + mesg_num=207, + fields={ + 0: Field( + name='developer_id', + type=BASE_TYPES[0x0D], # byte + def_num=0, + ), + 1: Field( + name='application_id', + type=BASE_TYPES[0x0D], # byte + def_num=1, + ), + 2: Field( + name='manufacturer_id', + type=FIELD_TYPES['manufacturer'], + def_num=2, + ), + 3: Field( + name='developer_data_index', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + ), + 4: Field( + name='application_version', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + ), + }, + ), + 208: MessageType( + name='magnetometer_data', + mesg_num=208, + fields={ + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # Each time in the array describes the time at which the compass sample with the corrosponding index was taken. Limited to 30 samples in each message. The samples may span across seconds. Array size must match the number of samples in cmps_x and cmps_y and cmps_z + name='sample_time_offset', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='ms', + ), + 2: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='mag_x', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + units='counts', + ), + 3: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='mag_y', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + units='counts', + ), + 4: Field( # These are the raw ADC reading. Maximum number of samples is 30 in each message. The samples may span across seconds. A conversion will need to be done on this data once read. + name='mag_z', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + units='counts', + ), + 5: Field( # Calibrated Magnetometer reading + name='calibrated_mag_x', + type=BASE_TYPES[0x88], # float32 + def_num=5, + units='G', + ), + 6: Field( # Calibrated Magnetometer reading + name='calibrated_mag_y', + type=BASE_TYPES[0x88], # float32 + def_num=6, + units='G', + ), + 7: Field( # Calibrated Magnetometer reading + name='calibrated_mag_z', + type=BASE_TYPES[0x88], # float32 + def_num=7, + units='G', + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + }, + ), + 209: MessageType( + name='barometer_data', + mesg_num=209, + fields={ + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='ms', + ), + 1: Field( # Each time in the array describes the time at which the barometer sample with the corrosponding index was taken. The samples may span across seconds. Array size must match the number of samples in baro_cal + name='sample_time_offset', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='ms', + ), + 2: Field( # These are the raw ADC reading. The samples may span across seconds. A conversion will need to be done on this data once read. + name='baro_pres', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + units='Pa', + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + }, + ), + 210: MessageType( + name='one_d_sensor_calibration', + mesg_num=210, + fields={ + 0: Field( # Indicates which sensor the calibration is for + name='sensor_type', + type=FIELD_TYPES['sensor_type'], + def_num=0, + ), + 1: Field( # Calibration factor used to convert from raw ADC value to degrees, g, etc. + name='calibration_factor', + type=BASE_TYPES[0x86], # uint32 + def_num=1, + subfields=( + SubField( # Barometer calibration factor + name='baro_cal_factor', + def_num=1, + type=BASE_TYPES[0x86], # uint32 + units='Pa', + ref_fields=( + ReferenceField( + name='sensor_type', + def_num=0, + value='barometer', + raw_value=3, + ), + ), + ), + ), + ), + 2: Field( # Calibration factor divisor + name='calibration_divisor', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + units='counts', + ), + 3: Field( # Level shift value used to shift the ADC value back into range + name='level_shift', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + ), + 4: Field( # Internal Calibration factor + name='offset_cal', + type=BASE_TYPES[0x85], # sint32 + def_num=4, + ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + }, + ), + 225: MessageType( + name='set', + mesg_num=225, + fields={ + 0: Field( + name='duration', + type=BASE_TYPES[0x86], # uint32 + def_num=0, + scale=1000, + units='s', + ), + 3: Field( # # of repitions of the movement + name='repetitions', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + ), + 4: Field( # Amount of weight applied for the set + name='weight', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + scale=16, + units='kg', + ), + 5: Field( + name='set_type', + type=FIELD_TYPES['set_type'], + def_num=5, + ), + 6: Field( # Start time of the set + name='start_time', + type=FIELD_TYPES['date_time'], + def_num=6, + ), + 7: Field( + name='category', + type=FIELD_TYPES['exercise_category'], + def_num=7, + ), + 8: Field( # Based on the associated category, see [category]_exercise_names + name='category_subtype', + type=BASE_TYPES[0x84], # uint16 + def_num=8, + ), + 9: Field( + name='weight_display_unit', + type=FIELD_TYPES['fit_base_unit'], + def_num=9, + ), + 10: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=10, + ), + 11: Field( + name='wkt_step_index', + type=FIELD_TYPES['message_index'], + def_num=11, + ), + 254: Field( # Timestamp of the set + name='timestamp', + type=FIELD_TYPES['date_time'], + def_num=254, + ), + }, + ), + 227: MessageType( # Value from 1 to 100 calculated by FirstBeat + name='stress_level', + mesg_num=227, + fields={ + 0: Field( + name='stress_level_value', + type=BASE_TYPES[0x83], # sint16 + def_num=0, + ), + 1: Field( # Time stress score was calculated + name='stress_level_time', + type=FIELD_TYPES['date_time'], + def_num=1, + units='s', + ), + }, + ), + 258: MessageType( + name='dive_settings', + mesg_num=258, + fields={ + 0: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( + name='model', + type=FIELD_TYPES['tissue_model_type'], + def_num=1, + ), + 2: Field( + name='gf_low', + type=BASE_TYPES[0x02], # uint8 + def_num=2, + units='percent', + ), + 3: Field( + name='gf_high', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + units='percent', + ), + 4: Field( + name='water_type', + type=FIELD_TYPES['water_type'], + def_num=4, + ), + 5: Field( # Fresh water is usually 1000; salt water is usually 1025 + name='water_density', + type=BASE_TYPES[0x88], # float32 + def_num=5, + units='kg/m^3', + ), + 6: Field( # Typically 1.40 + name='po2_warn', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + scale=100, + units='percent', + ), + 7: Field( # Typically 1.60 + name='po2_critical', + type=BASE_TYPES[0x02], # uint8 + def_num=7, + scale=100, + units='percent', + ), + 8: Field( + name='po2_deco', + type=BASE_TYPES[0x02], # uint8 + def_num=8, + scale=100, + units='percent', + ), + 9: Field( + name='safety_stop_enabled', + type=FIELD_TYPES['bool'], + def_num=9, + ), + 10: Field( + name='bottom_depth', + type=BASE_TYPES[0x88], # float32 + def_num=10, + ), + 11: Field( + name='bottom_time', + type=BASE_TYPES[0x86], # uint32 + def_num=11, + ), + 12: Field( + name='apnea_countdown_enabled', + type=FIELD_TYPES['bool'], + def_num=12, + ), + 13: Field( + name='apnea_countdown_time', + type=BASE_TYPES[0x86], # uint32 + def_num=13, + ), + 14: Field( + name='backlight_mode', + type=FIELD_TYPES['dive_backlight_mode'], + def_num=14, + ), + 15: Field( + name='backlight_brightness', + type=BASE_TYPES[0x02], # uint8 + def_num=15, + ), + 16: Field( + name='backlight_timeout', + type=FIELD_TYPES['backlight_timeout'], + def_num=16, + ), + 17: Field( # Time between surfacing and ending the activity + name='repeat_dive_interval', + type=BASE_TYPES[0x84], # uint16 + def_num=17, + units='s', + ), + 18: Field( # Time at safety stop (if enabled) + name='safety_stop_time', + type=BASE_TYPES[0x84], # uint16 + def_num=18, + units='s', + ), + 19: Field( + name='heart_rate_source_type', + type=FIELD_TYPES['source_type'], + def_num=19, + ), + 20: Field( + name='heart_rate_source', + type=BASE_TYPES[0x02], # uint8 + def_num=20, + subfields=( + SubField( + name='heart_rate_antplus_device_type', + def_num=20, + type=FIELD_TYPES['antplus_device_type'], + ref_fields=( + ReferenceField( + name='heart_rate_source_type', + def_num=19, + value='antplus', + raw_value=1, + ), + ), + ), + SubField( + name='heart_rate_local_device_type', + def_num=20, + type=FIELD_TYPES['local_device_type'], + ref_fields=( + ReferenceField( + name='heart_rate_source_type', + def_num=19, + value='local', + raw_value=5, + ), + ), + ), + ), + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 259: MessageType( + name='dive_gas', + mesg_num=259, + fields={ + 0: Field( + name='helium_content', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + units='percent', + ), + 1: Field( + name='oxygen_content', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + units='percent', + ), + 2: Field( + name='status', + type=FIELD_TYPES['dive_gas_status'], + def_num=2, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 262: MessageType( + name='dive_alarm', + mesg_num=262, + fields={ + 0: Field( + name='depth', + type=BASE_TYPES[0x86], # uint32 + def_num=0, + scale=1000, + units='m', + ), + 1: Field( + name='time', + type=BASE_TYPES[0x85], # sint32 + def_num=1, + units='s', + ), + 2: Field( + name='enabled', + type=FIELD_TYPES['bool'], + def_num=2, + ), + 3: Field( + name='alarm_type', + type=FIELD_TYPES['dive_alarm_type'], + def_num=3, + ), + 4: Field( + name='sound', + type=FIELD_TYPES['tone'], + def_num=4, + ), + 5: Field( + name='dive_types', + type=FIELD_TYPES['sub_sport'], + def_num=5, + ), + 254: Field( # Index of the alarm + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 264: MessageType( + name='exercise_title', + mesg_num=264, + fields={ + 0: Field( + name='exercise_category', + type=FIELD_TYPES['exercise_category'], + def_num=0, + ), + 1: Field( + name='exercise_name', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + ), + 2: Field( + name='wkt_step_name', + type=BASE_TYPES[0x07], # string + def_num=2, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 268: MessageType( + name='dive_summary', + mesg_num=268, + fields={ + 0: Field( + name='reference_mesg', + type=FIELD_TYPES['mesg_num'], + def_num=0, + ), + 1: Field( + name='reference_index', + type=FIELD_TYPES['message_index'], + def_num=1, + ), + 2: Field( # 0 if above water + name='avg_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + scale=1000, + units='m', + ), + 3: Field( # 0 if above water + name='max_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=1000, + units='m', + ), + 4: Field( # Time since end of last dive + name='surface_interval', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + units='s', + ), + 5: Field( + name='start_cns', + type=BASE_TYPES[0x02], # uint8 + def_num=5, + units='percent', + ), + 6: Field( + name='end_cns', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + units='percent', + ), + 7: Field( + name='start_n2', + type=BASE_TYPES[0x84], # uint16 + def_num=7, + units='percent', + ), + 8: Field( + name='end_n2', + type=BASE_TYPES[0x84], # uint16 + def_num=8, + units='percent', + ), + 9: Field( + name='o2_toxicity', + type=BASE_TYPES[0x84], # uint16 + def_num=9, + units='OTUs', + ), + 10: Field( + name='dive_number', + type=BASE_TYPES[0x86], # uint32 + def_num=10, + ), + 11: Field( + name='bottom_time', + type=BASE_TYPES[0x86], # uint32 + def_num=11, + scale=1000, + units='s', + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + + + # ************************* Activity File Messages ************************* + 34: MessageType( + name='activity', + mesg_num=34, + fields={ + 0: Field( # Exclude pauses + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=0, + scale=1000, + units='s', + ), + 1: Field( + name='num_sessions', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + ), + 2: Field( + name='type', + type=FIELD_TYPES['activity'], + def_num=2, + ), + 3: Field( + name='event', + type=FIELD_TYPES['event'], + def_num=3, + ), + 4: Field( + name='event_type', + type=FIELD_TYPES['event_type'], + def_num=4, + ), + 5: Field( # timestamp epoch expressed in local time, used to convert activity timestamps to local time + name='local_timestamp', + type=FIELD_TYPES['local_date_time'], + def_num=5, + ), + 6: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + + + # ********************** Blood Pressure File Messages ********************** + 51: MessageType( + name='blood_pressure', + mesg_num=51, + fields={ + 0: Field( + name='systolic_pressure', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + units='mmHg', + ), + 1: Field( + name='diastolic_pressure', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='mmHg', + ), + 2: Field( + name='mean_arterial_pressure', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + units='mmHg', + ), + 3: Field( + name='map_3_sample_mean', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + units='mmHg', + ), + 4: Field( + name='map_morning_values', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + units='mmHg', + ), + 5: Field( + name='map_evening_values', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + units='mmHg', + ), + 6: Field( + name='heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + units='bpm', + ), + 7: Field( + name='heart_rate_type', + type=FIELD_TYPES['hr_type'], + def_num=7, + ), + 8: Field( + name='status', + type=FIELD_TYPES['bp_status'], + def_num=8, + ), + 9: Field( # Associates this blood pressure message to a user. This corresponds to the index of the user profile message in the blood pressure file. + name='user_profile_index', + type=FIELD_TYPES['message_index'], + def_num=9, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + + + # ************************** Course File Messages ************************** + 31: MessageType( + name='course', + mesg_num=31, + fields={ + 4: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=4, + ), + 5: Field( + name='name', + type=BASE_TYPES[0x07], # string + def_num=5, + ), + 6: Field( + name='capabilities', + type=FIELD_TYPES['course_capabilities'], + def_num=6, + ), + 7: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=7, + ), + }, + ), + + + # ************************** Device File Messages ************************** + 35: MessageType( + name='software', + mesg_num=35, + fields={ + 3: Field( + name='version', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + scale=100, + ), + 5: Field( + name='part_number', + type=BASE_TYPES[0x07], # string + def_num=5, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + + + # ************************** Goals File Messages *************************** + 15: MessageType( + name='goal', + mesg_num=15, + fields={ + 0: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=0, + ), + 1: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=1, + ), + 2: Field( + name='start_date', + type=FIELD_TYPES['date_time'], + def_num=2, + ), + 3: Field( + name='end_date', + type=FIELD_TYPES['date_time'], + def_num=3, + ), + 4: Field( + name='type', + type=FIELD_TYPES['goal'], + def_num=4, + ), + 5: Field( + name='value', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + ), + 6: Field( + name='repeat', + type=FIELD_TYPES['bool'], + def_num=6, + ), + 7: Field( + name='target_value', + type=BASE_TYPES[0x86], # uint32 + def_num=7, + ), + 8: Field( + name='recurrence', + type=FIELD_TYPES['goal_recurrence'], + def_num=8, + ), + 9: Field( + name='recurrence_value', + type=BASE_TYPES[0x84], # uint16 + def_num=9, + ), + 10: Field( + name='enabled', + type=FIELD_TYPES['bool'], + def_num=10, + ), + 11: Field( + name='source', + type=FIELD_TYPES['goal_source'], + def_num=11, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + + + # ************************ Monitoring File Messages ************************ + 103: MessageType( + name='monitoring_info', + mesg_num=103, + fields={ + 0: Field( # Use to convert activity timestamps to local time if device does not support time zone and daylight savings time correction. + name='local_timestamp', + type=FIELD_TYPES['local_date_time'], + def_num=0, + units='s', + ), + 1: Field( + name='activity_type', + type=FIELD_TYPES['activity_type'], + def_num=1, + ), + 3: Field( # Indexed by activity_type + name='cycles_to_distance', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + scale=5000, + units='m/cycle', + ), + 4: Field( # Indexed by activity_type + name='cycles_to_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + scale=5000, + units='kcal/cycle', + ), + 5: Field( + name='resting_metabolic_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + units='kcal/day', + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + + + # ***************************** Other Messages ***************************** + 145: MessageType( + name='memo_glob', + mesg_num=145, + fields={ + 0: Field( # Block of utf8 bytes + name='memo', + type=BASE_TYPES[0x0D], # byte + def_num=0, + ), + 1: Field( # Allows relating glob to another mesg If used only required for first part of each memo_glob + name='message_number', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + ), + 2: Field( # Index of external mesg + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=2, + ), + 250: Field( # Sequence number of memo blocks + name='part_index', + type=BASE_TYPES[0x86], # uint32 + def_num=250, + ), + }, + ), + + + # ************************* Schedule File Messages ************************* + 28: MessageType( + name='schedule', + mesg_num=28, + fields={ + 0: Field( # Corresponds to file_id of scheduled workout / course. + name='manufacturer', + type=FIELD_TYPES['manufacturer'], + def_num=0, + ), + 1: Field( # Corresponds to file_id of scheduled workout / course. + name='product', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + subfields=( + SubField( + name='garmin_product', + def_num=1, + type=FIELD_TYPES['garmin_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=0, + value='garmin', + raw_value=1, + ), + ReferenceField( + name='manufacturer', + def_num=0, + value='dynastream', + raw_value=15, + ), + ReferenceField( + name='manufacturer', + def_num=0, + value='dynastream_oem', + raw_value=13, + ), + ), + ), + ), + ), + 2: Field( # Corresponds to file_id of scheduled workout / course. + name='serial_number', + type=BASE_TYPES[0x8C], # uint32z + def_num=2, + ), + 3: Field( # Corresponds to file_id of scheduled workout / course. + name='time_created', + type=FIELD_TYPES['date_time'], + def_num=3, + ), + 4: Field( # TRUE if this activity has been started + name='completed', + type=FIELD_TYPES['bool'], + def_num=4, + ), + 5: Field( + name='type', + type=FIELD_TYPES['schedule'], + def_num=5, + ), + 6: Field( + name='scheduled_time', + type=FIELD_TYPES['local_date_time'], + def_num=6, + ), + }, + ), + + + # ************************* Segment File Messages ************************** + 148: MessageType( # Unique Identification data for a segment file + name='segment_id', + mesg_num=148, + fields={ + 0: Field( # Friendly name assigned to segment + name='name', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( # UUID of the segment + name='uuid', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 2: Field( # Sport associated with the segment + name='sport', + type=FIELD_TYPES['sport'], + def_num=2, + ), + 3: Field( # Segment enabled for evaluation + name='enabled', + type=FIELD_TYPES['bool'], + def_num=3, + ), + 4: Field( # Primary key of the user that created the segment + name='user_profile_primary_key', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + ), + 5: Field( # ID of the device that created the segment + name='device_id', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + ), + 6: Field( # Index for the Leader Board entry selected as the default race participant + name='default_race_leader', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + ), + 7: Field( # Indicates if any segments should be deleted + name='delete_status', + type=FIELD_TYPES['segment_delete_status'], + def_num=7, + ), + 8: Field( # Indicates how the segment was selected to be sent to the device + name='selection_type', + type=FIELD_TYPES['segment_selection_type'], + def_num=8, + ), + }, + ), + + + # *********************** Segment List File Messages *********************** + 151: MessageType( # Summary of the unique segment and leaderboard information associated with a segment file. This message is used to compile a segment list file describing all segment files on a device. The segment list file is used when refreshing the contents of a segment file with the latest available leaderboard information. + name='segment_file', + mesg_num=151, + fields={ + 1: Field( # UUID of the segment file + name='file_uuid', + type=BASE_TYPES[0x07], # string + def_num=1, + ), + 3: Field( # Enabled state of the segment file + name='enabled', + type=FIELD_TYPES['bool'], + def_num=3, + ), + 4: Field( # Primary key of the user that created the segment file + name='user_profile_primary_key', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + ), + 7: Field( # Leader type of each leader in the segment file + name='leader_type', + type=FIELD_TYPES['segment_leaderboard_type'], + def_num=7, + ), + 8: Field( # Group primary key of each leader in the segment file + name='leader_group_primary_key', + type=BASE_TYPES[0x86], # uint32 + def_num=8, + ), + 9: Field( # Activity ID of each leader in the segment file + name='leader_activity_id', + type=BASE_TYPES[0x86], # uint32 + def_num=9, + ), + 10: Field( # String version of the activity ID of each leader in the segment file. 21 characters long for each ID, express in decimal + name='leader_activity_id_string', + type=BASE_TYPES[0x07], # string + def_num=10, + ), + 11: Field( # Index for the Leader Board entry selected as the default race participant + name='default_race_leader', + type=BASE_TYPES[0x02], # uint8 + def_num=11, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + + + # ************************* Settings File Messages ************************* + 2: MessageType( + name='device_settings', + mesg_num=2, + fields={ + 0: Field( # Index into time zone arrays. + name='active_time_zone', + type=BASE_TYPES[0x02], # uint8 + def_num=0, + ), + 1: Field( # Offset from system time. Required to convert timestamp from system time to UTC. + name='utc_offset', + type=BASE_TYPES[0x86], # uint32 + def_num=1, + ), + 2: Field( # Offset from system time. + name='time_offset', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + units='s', + ), + 4: Field( # Display mode for the time + name='time_mode', + type=FIELD_TYPES['time_mode'], + def_num=4, + ), + 5: Field( # timezone offset in 1/4 hour increments + name='time_zone_offset', + type=BASE_TYPES[0x01], # sint8 + def_num=5, + scale=4, + units='hr', + ), + 12: Field( # Mode for backlight + name='backlight_mode', + type=FIELD_TYPES['backlight_mode'], + def_num=12, + ), + 36: Field( # Enabled state of the activity tracker functionality + name='activity_tracker_enabled', + type=FIELD_TYPES['bool'], + def_num=36, + ), + 39: Field( # UTC timestamp used to set the devices clock and date + name='clock_time', + type=FIELD_TYPES['date_time'], + def_num=39, + ), + 40: Field( # Bitfield to configure enabled screens for each supported loop + name='pages_enabled', + type=BASE_TYPES[0x84], # uint16 + def_num=40, + ), + 46: Field( # Enabled state of the move alert + name='move_alert_enabled', + type=FIELD_TYPES['bool'], + def_num=46, + ), + 47: Field( # Display mode for the date + name='date_mode', + type=FIELD_TYPES['date_mode'], + def_num=47, + ), + 55: Field( + name='display_orientation', + type=FIELD_TYPES['display_orientation'], + def_num=55, + ), + 56: Field( + name='mounting_side', + type=FIELD_TYPES['side'], + def_num=56, + ), + 57: Field( # Bitfield to indicate one page as default for each supported loop + name='default_page', + type=BASE_TYPES[0x84], # uint16 + def_num=57, + ), + 58: Field( # Minimum steps before an autosync can occur + name='autosync_min_steps', + type=BASE_TYPES[0x84], # uint16 + def_num=58, + units='steps', + ), + 59: Field( # Minimum minutes before an autosync can occur + name='autosync_min_time', + type=BASE_TYPES[0x84], # uint16 + def_num=59, + units='minutes', + ), + 80: Field( # Enable auto-detect setting for the lactate threshold feature. + name='lactate_threshold_autodetect_enabled', + type=FIELD_TYPES['bool'], + def_num=80, + ), + 86: Field( # Automatically upload using BLE + name='ble_auto_upload_enabled', + type=FIELD_TYPES['bool'], + def_num=86, + ), + 89: Field( # Helps to conserve battery by changing modes + name='auto_sync_frequency', + type=FIELD_TYPES['auto_sync_frequency'], + def_num=89, + ), + 90: Field( # Allows setting specific activities auto-activity detect enabled/disabled settings + name='auto_activity_detect', + type=FIELD_TYPES['auto_activity_detect'], + def_num=90, + ), + 94: Field( # Number of screens configured to display + name='number_of_screens', + type=BASE_TYPES[0x02], # uint8 + def_num=94, + ), + 95: Field( # Smart Notification display orientation + name='smart_notification_display_orientation', + type=FIELD_TYPES['display_orientation'], + def_num=95, + ), + 134: Field( + name='tap_interface', + type=FIELD_TYPES['switch'], + def_num=134, + ), + }, + ), + 3: MessageType( + name='user_profile', + mesg_num=3, + fields={ + 0: Field( + name='friendly_name', + type=BASE_TYPES[0x07], # string + def_num=0, + ), + 1: Field( + name='gender', + type=FIELD_TYPES['gender'], + def_num=1, + ), + 2: Field( + name='age', + type=BASE_TYPES[0x02], # uint8 + def_num=2, + units='years', + ), + 3: Field( + name='height', + type=BASE_TYPES[0x02], # uint8 + def_num=3, + scale=100, + units='m', + ), + 4: Field( + name='weight', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + scale=10, + units='kg', + ), + 5: Field( + name='language', + type=FIELD_TYPES['language'], + def_num=5, + ), + 6: Field( + name='elev_setting', + type=FIELD_TYPES['display_measure'], + def_num=6, + ), + 7: Field( + name='weight_setting', + type=FIELD_TYPES['display_measure'], + def_num=7, + ), + 8: Field( + name='resting_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=8, + units='bpm', + ), + 9: Field( + name='default_max_running_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=9, + units='bpm', + ), + 10: Field( + name='default_max_biking_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=10, + units='bpm', + ), + 11: Field( + name='default_max_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=11, + units='bpm', + ), + 12: Field( + name='hr_setting', + type=FIELD_TYPES['display_heart'], + def_num=12, + ), + 13: Field( + name='speed_setting', + type=FIELD_TYPES['display_measure'], + def_num=13, + ), + 14: Field( + name='dist_setting', + type=FIELD_TYPES['display_measure'], + def_num=14, + ), + 16: Field( + name='power_setting', + type=FIELD_TYPES['display_power'], + def_num=16, + ), + 17: Field( + name='activity_class', + type=FIELD_TYPES['activity_class'], + def_num=17, + ), + 18: Field( + name='position_setting', + type=FIELD_TYPES['display_position'], + def_num=18, + ), + 21: Field( + name='temperature_setting', + type=FIELD_TYPES['display_measure'], + def_num=21, + ), + 22: Field( + name='local_id', + type=FIELD_TYPES['user_local_id'], + def_num=22, + ), + 23: Field( + name='global_id', + type=BASE_TYPES[0x0D], # byte + def_num=23, + ), + 28: Field( # Typical wake time + name='wake_time', + type=FIELD_TYPES['localtime_into_day'], + def_num=28, + ), + 29: Field( # Typical bed time + name='sleep_time', + type=FIELD_TYPES['localtime_into_day'], + def_num=29, + ), + 30: Field( + name='height_setting', + type=FIELD_TYPES['display_measure'], + def_num=30, + ), + 31: Field( # User defined running step length set to 0 for auto length + name='user_running_step_length', + type=BASE_TYPES[0x84], # uint16 + def_num=31, + scale=1000, + units='m', + ), + 32: Field( # User defined walking step length set to 0 for auto length + name='user_walking_step_length', + type=BASE_TYPES[0x84], # uint16 + def_num=32, + scale=1000, + units='m', + ), + 47: Field( + name='depth_setting', + type=FIELD_TYPES['display_measure'], + def_num=47, + ), + 49: Field( + name='dive_count', + type=BASE_TYPES[0x86], # uint32 + def_num=49, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + + + # ********************** Sport Settings File Messages ********************** + 7: MessageType( + name='zones_target', + mesg_num=7, + fields={ + 1: Field( + name='max_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=1, + ), + 2: Field( + name='threshold_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=2, + ), + 3: Field( + name='functional_threshold_power', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + ), + 5: Field( + name='hr_calc_type', + type=FIELD_TYPES['hr_zone_calc'], + def_num=5, + ), + 7: Field( + name='pwr_calc_type', + type=FIELD_TYPES['pwr_zone_calc'], + def_num=7, + ), + }, + ), + + + # ************************** Totals File Messages ************************** + 33: MessageType( + name='totals', + mesg_num=33, + fields={ + 0: Field( # Excludes pauses + name='timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=0, + units='s', + ), + 1: Field( + name='distance', + type=BASE_TYPES[0x86], # uint32 + def_num=1, + units='m', + ), + 2: Field( + name='calories', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + units='kcal', + ), + 3: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=3, + ), + 4: Field( # Includes pauses + name='elapsed_time', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + units='s', + ), + 5: Field( + name='sessions', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + ), + 6: Field( + name='active_time', + type=BASE_TYPES[0x86], # uint32 + def_num=6, + units='s', + ), + 9: Field( + name='sport_index', + type=BASE_TYPES[0x02], # uint8 + def_num=9, + ), + 253: FIELD_TYPE_TIMESTAMP, + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + + + # *********************** Weight Scale File Messages *********************** + 30: MessageType( + name='weight_scale', + mesg_num=30, + fields={ + 0: Field( + name='weight', + type=FIELD_TYPES['weight'], + def_num=0, + scale=100, + units='kg', + ), + 1: Field( + name='percent_fat', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + scale=100, + units='%', + ), + 2: Field( + name='percent_hydration', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + scale=100, + units='%', + ), + 3: Field( + name='visceral_fat_mass', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + scale=100, + units='kg', + ), + 4: Field( + name='bone_mass', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + scale=100, + units='kg', + ), + 5: Field( + name='muscle_mass', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + scale=100, + units='kg', + ), + 7: Field( + name='basal_met', + type=BASE_TYPES[0x84], # uint16 + def_num=7, + scale=4, + units='kcal/day', + ), + 8: Field( + name='physique_rating', + type=BASE_TYPES[0x02], # uint8 + def_num=8, + ), + 9: Field( # ~4kJ per kcal, 0.25 allows max 16384 kcal + name='active_met', + type=BASE_TYPES[0x84], # uint16 + def_num=9, + scale=4, + units='kcal/day', + ), + 10: Field( + name='metabolic_age', + type=BASE_TYPES[0x02], # uint8 + def_num=10, + units='years', + ), + 11: Field( + name='visceral_fat_rating', + type=BASE_TYPES[0x02], # uint8 + def_num=11, + ), + 12: Field( # Associates this weight scale message to a user. This corresponds to the index of the user profile message in the weight scale file. + name='user_profile_index', + type=FIELD_TYPES['message_index'], + def_num=12, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + + + # ************************* Workout File Messages ************************** + 26: MessageType( + name='workout', + mesg_num=26, + fields={ + 4: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=4, + ), + 5: Field( + name='capabilities', + type=FIELD_TYPES['workout_capabilities'], + def_num=5, + ), + 6: Field( # number of valid steps + name='num_valid_steps', + type=BASE_TYPES[0x84], # uint16 + def_num=6, + ), + 8: Field( + name='wkt_name', + type=BASE_TYPES[0x07], # string + def_num=8, + ), + 11: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=11, + ), + 14: Field( + name='pool_length', + type=BASE_TYPES[0x84], # uint16 + def_num=14, + scale=100, + units='m', + ), + 15: Field( + name='pool_length_unit', + type=FIELD_TYPES['display_measure'], + def_num=15, + ), + }, + ), +} diff --git a/fitparse/records.py b/fitparse/records.py index 71edc93..d007f0a 100644 --- a/fitparse/records.py +++ b/fitparse/records.py @@ -299,7 +299,7 @@ class SubField(FieldAndSubFieldBase): class DevField(FieldAndSubFieldBase): __slots__ = ('dev_data_index', 'def_num', 'type', 'name', 'units', 'native_field_num', # The rest of these are just to be compatible with Field objects. They're always None - 'scale', 'offset', 'components', 'subfields') + 'scale', 'offset', 'components', 'subfields') field_type = 'devfield' @@ -318,6 +318,14 @@ def render(self, raw_value): # If it's a tuple, then it's a byte array and unpack it as such # (only type that uses this is compressed speed/distance) if isinstance(raw_value, tuple): + # Profile.xls sometimes contains more components than the read raw + # value is able to hold (typically the *event_timestamp_12* field in + # *hr* messages). + # This test allows to ensure *unpacked_num* is not right-shifted + # more than necessary. + if self.bit_offset and self.bit_offset >= len(raw_value) << 3: + raise ValueError() + unpacked_num = 0 # Unpack byte array as little endian @@ -381,11 +389,23 @@ def calculate(cls, byte_arr, crc=0): def parse_string(string): try: - end = string.index(0x00) - except TypeError: # Python 2 compat - end = string.index('\x00') - - return string[:end].decode('utf-8', errors='replace') or None + try: + s = string[:string.index(0x00)] + except TypeError: # Python 2 compat + s = string[:string.index('\x00')] + except ValueError: + # FIT specification defines the 'string' type as follows: "Null + # terminated string encoded in UTF-8 format". + # + # However 'string' values are not always null-terminated when encoded, + # according to FIT files created by Garmin devices (e.g. DEVICE.FIT file + # from a fenix3). + # + # So in order to be more flexible, in case index() could not find any + # null byte, we just decode the whole bytes-like object. + s = string + + return s.decode(encoding='utf-8', errors='replace') or None # The default base type BASE_TYPE_BYTE = BaseType(name='byte', identifier=0x0D, fmt='B', parse=lambda x: None if all(b == 0xFF for b in x) else x) @@ -405,6 +425,9 @@ def parse_string(string): 0x8B: BaseType(name='uint16z', identifier=0x8B, fmt='H', parse=lambda x: None if x == 0x0 else x), 0x8C: BaseType(name='uint32z', identifier=0x8C, fmt='I', parse=lambda x: None if x == 0x0 else x), 0x0D: BASE_TYPE_BYTE, + 0x8E: BaseType(name='sint64', identifier=0x8E, fmt='q', parse=lambda x: None if x == 0x7FFFFFFFFFFFFFFF else x), + 0x8F: BaseType(name='uint64', identifier=0x8F, fmt='Q', parse=lambda x: None if x == 0xFFFFFFFFFFFFFFFF else x), + 0x90: BaseType(name='uint64z', identifier=0x90, fmt='Q', parse=lambda x: None if x == 0 else x), } diff --git a/scripts/generate_profile.py b/scripts/generate_profile.py index 52e5c00..d4f72be 100755 --- a/scripts/generate_profile.py +++ b/scripts/generate_profile.py @@ -20,11 +20,19 @@ import xlrd # Dev requirement for parsing Excel spreadsheet +FIELD_NUM_TIMESTAMP = 253 + XLS_HEADER_MAGIC = b'\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1' +SYMBOL_NAME_SCRUBBER = re.compile(r'\W|^(?=\d)') + def header(header, indent=0): - return '%s%s' % (' ' * indent, (' %s ' % header).center(78 - indent, '#')) + return '%s# %s' % (' ' * indent, (' %s ' % header).center(78 - indent, '*')) + + +def scrub_symbol_name(symbol_name): + return SYMBOL_NAME_SCRUBBER.sub('_', symbol_name) PROFILE_HEADER_FIRST_PART = "%s\n%s" % ( @@ -42,7 +50,17 @@ def header(header, indent=0): BASE_TYPES, )''' -SPECIAL_FIELD_DECLARTIONS = "FIELD_TYPE_TIMESTAMP = Field(name='timestamp', type=FIELD_TYPES['date_time'], def_num=253, units='s')" +# This allows to prepend the declaration of some message numbers to the +# generated file. +# E.g. 'hr' -> MESG_NUM_HR = 132 +MESSAGE_NUM_DECLARATIONS = () + +# This allows to prepend the declaration of some field numbers of specific +# messages to the generated file. +# E.g. 'hr.event_timestamp' -> FIELD_NUM_HR_EVENT_TIMESTAMP = 9 +FIELD_NUM_DECLARATIONS = () + +SPECIAL_FIELD_DECLARATIONS = "FIELD_TYPE_TIMESTAMP = Field(name='timestamp', type=FIELD_TYPES['date_time'], def_num=" + str(FIELD_NUM_TIMESTAMP) + ", units='s')" IGNORE_TYPE_VALUES = ( # of the form 'type_name:value_name' @@ -52,10 +70,23 @@ def header(header, indent=0): ) BASE_TYPES = { - 'enum': '0x00', 'sint8': '0x01', 'uint8': '0x02', 'sint16': '0x83', - 'uint16': '0x84', 'sint32': '0x85', 'uint32': '0x86', 'string': '0x07', - 'float32': '0x88', 'float64': '0x89', 'uint8z': '0x0A', 'uint16z': '0x8B', - 'uint32z': '0x8C', 'byte': '0x0D', + 'enum': '0x00', + 'sint8': '0x01', + 'uint8': '0x02', + 'sint16': '0x83', + 'uint16': '0x84', + 'sint32': '0x85', + 'uint32': '0x86', + 'string': '0x07', + 'float32': '0x88', + 'float64': '0x89', + 'uint8z': '0x0A', + 'uint16z': '0x8B', + 'uint32z': '0x8C', + 'byte': '0x0D', + 'sint64': '0x8E', + 'uint64': '0x8F', + 'uint64z': '0x90', } @@ -143,6 +174,22 @@ def __str__(self): s += '}' return s + def get_by_name(self, mesg_name): + for mesg in self.messages: + if mesg.name == mesg_name: + return mesg + + raise ValueError('message "%s" not found' % mesg_name) + + def get_field_by_name(self, mesg_name, field_name): + mesg = self.get_by_name(mesg_name) + + for field in mesg.fields: + if field.name == field_name: + return mesg, field + + raise ValueError('field "%s" not found in message "%s"' % (field_name, mesg_name)) + class MessageInfo(namedtuple('MessageInfo', ('name', 'num', 'group_name', 'fields', 'comment'))): def get(self, field_name): @@ -166,7 +213,7 @@ def __str__(self): class FieldInfo(namedtuple('FieldInfo', ('name', 'type', 'num', 'scale', 'offset', 'units', 'components', 'subfields', 'comment'))): def __str__(self): - if self.num == 253: + if self.num == FIELD_NUM_TIMESTAMP: # Add trailing comma here because of comment assert not self.components and not self.subfields return 'FIELD_TYPE_TIMESTAMP,%s' % render_comment(self.comment) @@ -359,6 +406,7 @@ def maybe_decode(o): return o.decode() return o + def parse_messages(messages_rows, type_list): message_list = MessageList([]) @@ -389,10 +437,10 @@ def parse_messages(messages_rows, type_list): ) for cmp_name, cmp_scale, cmp_offset, cmp_units, cmp_bits, cmp_accumulate in zip( component_names, # name - parse_csv_fields(maybe_decode(row[6]), num_components), # scale - parse_csv_fields(maybe_decode(row[7]), num_components), # offset - parse_csv_fields(maybe_decode(row[8]), num_components), # units - parse_csv_fields(maybe_decode(row[9]), num_components), # bits + parse_csv_fields(maybe_decode(row[6]), num_components), # scale + parse_csv_fields(maybe_decode(row[7]), num_components), # offset + parse_csv_fields(maybe_decode(row[8]), num_components), # units + parse_csv_fields(maybe_decode(row[9]), num_components), # bits parse_csv_fields(maybe_decode(row[10]), num_components), # accumulate ) ] @@ -402,12 +450,12 @@ def parse_messages(messages_rows, type_list): assert component.name assert component.bits - # Otherwise a field + # Otherwise a field # Not a subfield if first row has definition num if row[1] is not None and row[1] != b'': field = FieldInfo( name=row[2].decode(), type=row[3].decode(), num=maybe_decode(row[1]), scale=fix_scale(row[6]), - offset=row[7], units=fix_units(row[8].decode()), components=[], + offset=maybe_decode(row[7]), units=fix_units(row[8].decode()), components=[], subfields=[], comment=row[13].decode(), ) @@ -425,7 +473,7 @@ def parse_messages(messages_rows, type_list): # Sub fields subfield = SubFieldInfo( name=row[2].decode(), num=field.num, type=row[3].decode(), scale=fix_scale(row[6]), - offset=row[7], units=fix_units(row[8].decode()), ref_fields=[], + offset=maybe_decode(row[7]), units=fix_units(row[8].decode()), ref_fields=[], components=[], comment=row[13].decode(), ) @@ -447,7 +495,7 @@ def parse_messages(messages_rows, type_list): ) assert len(subfield.ref_fields) == len(ref_field_names) - if not "alert_type" in ref_field_names: + if "alert_type" not in ref_field_names: field.subfields.append(subfield) # Resolve reference fields for subfields and components @@ -509,19 +557,48 @@ def main(input_xls_or_zip, output_py_path=None): type_list = parse_types(types_rows) message_list = parse_messages(messages_rows, type_list) + mesg_num_declarations = [] + for mesg_name in MESSAGE_NUM_DECLARATIONS: + mesg_info = message_list.get_by_name(mesg_name) + + mesg_num_declarations.append('MESG_NUM_%s = %s' % ( + scrub_symbol_name(mesg_name).upper(), + str(mesg_info.num) if mesg_info else 'None')) + + field_num_declarations = [ + 'FIELD_NUM_TIMESTAMP = ' + str(FIELD_NUM_TIMESTAMP)] + for field_fqn in FIELD_NUM_DECLARATIONS: + mesg_name, field_name = field_fqn.split('.', maxsplit=1) + mesg_info, field_info = message_list.get_field_by_name(mesg_name, field_name) + + field_decl = 'FIELD_NUM_%s_%s = %s' % ( + scrub_symbol_name(mesg_name).upper(), + scrub_symbol_name(field_name).upper(), + str(field_info.num)) + + field_num_declarations.append(field_decl) + output = '\n'.join([ "\n%s" % PROFILE_HEADER_FIRST_PART, - header('EXPORTED PROFILE FROM %s AT %s' % ( + header('EXPORTED PROFILE FROM %s ON %s' % ( ('SDK VERSION %s' % profile_version) if profile_version else 'SPREADSHEET', - datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + datetime.datetime.now().strftime('%Y-%m-%d'), )), header('PARSED %d TYPES (%d VALUES), %d MESSAGES (%d FIELDS)' % ( len(type_list.types), sum(len(ti.values) for ti in type_list.types), len(message_list.messages), sum(len(mi.fields) for mi in message_list.messages), )), - '', IMPORT_HEADER, '\n', + '', IMPORT_HEADER + ]) + '\n' + + if mesg_num_declarations: + output += '\n\n' + '\n'.join(mesg_num_declarations) + '\n' + if field_num_declarations: + output += '\n\n' + '\n'.join(field_num_declarations) + '\n' + + output += '\n\n' + '\n'.join([ str(type_list), '\n', - SPECIAL_FIELD_DECLARTIONS, '\n', + SPECIAL_FIELD_DECLARATIONS, '\n', str(message_list), '' ]) @@ -530,17 +607,16 @@ def main(input_xls_or_zip, output_py_path=None): if output_py_path: open(output_py_path, 'w').write(output) - print("Profile%s written to %s", - ' version %s' % profile_version if profile_version else '', - output_py_path - ) + print('Profile version %s written to %s' % ( + profile_version if profile_version else '', + output_py_path)) else: print(output.strip()) if __name__ == '__main__': if len(sys.argv) < 2: - print("Usage: %s [profile.py]", os.path.basename(__file__)) + print("Usage: %s [profile.py]" % os.path.basename(__file__)) sys.exit(0) xls = sys.argv[1]