diff --git a/fitparse/profile.py b/fitparse/profile.py index daaf579..6c64bab 100644 --- a/fitparse/profile.py +++ b/fitparse/profile.py @@ -1,7 +1,8 @@ + # ***************** BEGIN AUTOMATICALLY GENERATED FIT PROFILE ****************** # *************************** DO NOT EDIT THIS FILE **************************** -# ************ EXPORTED PROFILE FROM SDK VERSION 20.8 ON 2019-03-05 ************ -# ********* PARSED 161 TYPES (2985 VALUES), 85 MESSAGES (1038 FIELDS) ********** +# *********** EXPORTED PROFILE FROM SDK VERSION 21.126 ON 2023-12-29 *********** +# ********* PARSED 179 TYPES (3590 VALUES), 103 MESSAGES (1307 FIELDS) ********* from fitparse.records import ( ComponentField, @@ -94,6 +95,16 @@ 2: 'modern', }, ), + 'ant_channel_id': FieldType( + name='ant_channel_id', + base_type=BASE_TYPES[0x8C], # uint32z + values={ + 0x0000FFFF: 'ant_device_number', + 0x00FF0000: 'ant_device_type', + 0x0F000000: 'ant_transmission_type_lower_nibble', + 0xF0000000: 'ant_extended_device_number_upper_nibble', + }, + ), 'ant_network': FieldType( name='ant_network', base_type=BASE_TYPES[0x00], # enum @@ -121,10 +132,12 @@ 26: 'racquet', 27: 'control_hub', 31: 'muscle_oxygen', + 34: 'shifting', 35: 'bike_light_main', 36: 'bike_light_shared', 38: 'exd', 40: 'bike_radar', + 46: 'bike_aero', 119: 'weight_scale', 120: 'heart_rate', 121: 'bike_speed_cadence', @@ -293,6 +306,20 @@ 6: 'trail', }, ), + 'ble_device_type': FieldType( + name='ble_device_type', + base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'connected_gps', # GPS that is provided over a proprietary bluetooth service + 1: 'heart_rate', + 2: 'bike_power', + 3: 'bike_speed_cadence', + 4: 'bike_speed', + 5: 'bike_cadence', + 6: 'footpod', + 7: 'bike_trainer', # Indoor-Bike FTMS protocol + }, + ), 'body_location': FieldType( name='body_location', base_type=BASE_TYPES[0x00], # enum @@ -449,12 +476,20 @@ 4: 'overhead_carry', }, ), + 'ccr_setpoint_switch_mode': FieldType( + name='ccr_setpoint_switch_mode', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'manual', # User switches setpoints manually + 1: 'automatic', # Switch automatically based on depth + }, + ), '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. + 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( @@ -486,6 +521,15 @@ 22: 'standing_stability_reverse_chop', }, ), + 'climb_pro_event': FieldType( + name='climb_pro_event', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'approach', + 1: 'start', + 2: 'complete', + }, + ), 'comm_timeout_type': FieldType( name='comm_timeout_type', base_type=BASE_TYPES[0x84], # uint16 @@ -584,6 +628,33 @@ 43: 'overhead_walk', 44: 'inchworm', 45: 'weighted_modified_front_lever', + 46: 'russian_twist', + 47: 'abdominal_leg_rotations', # Deprecated do not use + 48: 'arm_and_leg_extension_on_knees', + 49: 'bicycle', + 50: 'bicep_curl_with_leg_extension', + 51: 'cat_cow', + 52: 'corkscrew', + 53: 'criss_cross', + 54: 'criss_cross_with_ball', # Deprecated do not use + 55: 'double_leg_stretch', + 56: 'knee_folds', + 57: 'lower_lift', + 58: 'neck_pull', + 59: 'pelvic_clocks', + 60: 'roll_over', + 61: 'roll_up', + 62: 'rolling', + 63: 'rowing_1', + 64: 'rowing_2', + 65: 'scissors', + 66: 'single_leg_circles', + 67: 'single_leg_stretch', + 68: 'snake_twist_1_and_2', # Deprecated do not use + 69: 'swan', + 70: 'swimming', + 71: 'teaser', + 72: 'the_hundred', }, ), 'course_capabilities': FieldType( @@ -601,6 +672,7 @@ 0x00000100: 'training', 0x00000200: 'navigation', 0x00000400: 'bikeway', + 0x00001000: 'aviation', # Denote course files to be used as flight plans }, ), 'course_point': FieldType( @@ -633,6 +705,33 @@ 23: 'u_turn', 24: 'segment_start', 25: 'segment_end', + 27: 'campsite', + 28: 'aid_station', + 29: 'rest_area', + 30: 'general_distance', # Used with UpAhead + 31: 'service', + 32: 'energy_gel', + 33: 'sports_drink', + 34: 'mile_marker', + 35: 'checkpoint', + 36: 'shelter', + 37: 'meeting_spot', + 38: 'overlook', + 39: 'toilet', + 40: 'shower', + 41: 'gear', + 42: 'sharp_curve', + 43: 'steep_incline', + 44: 'tunnel', + 45: 'bridge', + 46: 'obstacle', + 47: 'crossing', + 48: 'store', + 49: 'transition', + 50: 'navaid', + 51: 'transport', + 52: 'alert', + 53: 'info', }, ), 'crunch_exercise_name': FieldType( @@ -723,6 +822,7 @@ 81: 'toes_to_bar', 82: 'weighted_toes_to_bar', 83: 'crunch', + 84: 'straight_leg_crunch_with_ball', }, ), 'curl_exercise_name': FieldType( @@ -930,8 +1030,54 @@ name='dive_alarm_type', base_type=BASE_TYPES[0x00], # enum values={ - 0: 'depth', - 1: 'time', + 0: 'depth', # Alarm when a certain depth is crossed + 1: 'time', # Alarm when a certain time has transpired + 2: 'speed', # Alarm when a certain ascent or descent rate is exceeded + }, + ), + 'dive_alert': FieldType( + name='dive_alert', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'ndl_reached', + 1: 'gas_switch_prompted', + 2: 'near_surface', + 3: 'approaching_ndl', + 4: 'po2_warn', + 5: 'po2_crit_high', + 6: 'po2_crit_low', + 7: 'time_alert', + 8: 'depth_alert', + 9: 'deco_ceiling_broken', + 10: 'deco_complete', + 11: 'safety_stop_broken', + 12: 'safety_stop_complete', + 13: 'cns_warning', + 14: 'cns_critical', + 15: 'otu_warning', + 16: 'otu_critical', + 17: 'ascent_critical', + 18: 'alert_dismissed_by_key', + 19: 'alert_dismissed_by_timeout', + 20: 'battery_low', + 21: 'battery_critical', + 22: 'safety_stop_started', + 23: 'approaching_first_deco_stop', + 24: 'setpoint_switch_auto_low', + 25: 'setpoint_switch_auto_high', + 26: 'setpoint_switch_manual_low', + 27: 'setpoint_switch_manual_high', + 28: 'auto_setpoint_switch_ignored', + 29: 'switched_to_open_circuit', + 30: 'switched_to_closed_circuit', + 32: 'tank_battery_low', + 33: 'po2_ccr_dil_low', # ccr diluent has low po2 + 34: 'deco_stop_cleared', # a deco stop has been cleared + 35: 'apnea_neutral_buoyancy', # Target Depth Apnea Alarm triggered + 36: 'apnea_target_depth', # Neutral Buoyance Apnea Alarm triggered + 37: 'apnea_surface', # Surface Apnea Alarm triggered + 38: 'apnea_high_speed', # High Speed Apnea Alarm triggered + 39: 'apnea_low_speed', # Low Speed Apnea Alarm triggered }, ), 'dive_backlight_mode': FieldType( @@ -942,6 +1088,14 @@ 1: 'always_on', }, ), + 'dive_gas_mode': FieldType( + name='dive_gas_mode', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'open_circuit', + 1: 'closed_circuit_diluent', + }, + ), 'dive_gas_status': FieldType( name='dive_gas_status', base_type=BASE_TYPES[0x00], # enum @@ -955,9 +1109,9 @@ name='event', base_type=BASE_TYPES[0x00], # enum values={ - 0: 'timer', # Group 0. Start / stop_all + 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. + 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 @@ -965,21 +1119,21 @@ 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. + 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. + 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 @@ -988,9 +1142,19 @@ 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. + 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 + 54: 'auto_activity_detect', # marker + 56: 'dive_alert', # marker + 57: 'dive_gas_switched', # marker + 71: 'tank_pressure_reserve', # marker + 72: 'tank_pressure_critical', # marker + 73: 'tank_lost', # marker + 75: 'radar_threat_alert', # start/stop/marker + 76: 'tank_battery_low', # marker + 81: 'tank_pod_connected', # marker - tank pod has connected + 82: 'tank_pod_disconnected', # marker - tank pod has lost connection }, ), 'event_type': FieldType( @@ -1197,6 +1361,7 @@ 5: 'full_quarter_split', 6: 'half_vertical_left_split', 7: 'half_horizontal_top_split', + 8: 'dynamic', # The EXD may display the configured concepts in any layout it sees fit. }, ), 'exd_qualifiers': FieldType( @@ -1289,6 +1454,14 @@ 65534: 'unknown', }, ), + 'favero_product': FieldType( + name='favero_product', + base_type=BASE_TYPES[0x84], # uint16 + values={ + 10: 'assioma_uno', + 12: 'assioma_duo', + }, + ), 'file': FieldType( name='file', base_type=BASE_TYPES[0x00], # enum @@ -1308,8 +1481,8 @@ 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 + 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 @@ -1378,16 +1551,10 @@ 5: 'kneeling_rear_flye', 6: 'single_arm_standing_cable_reverse_flye', 7: 'swiss_ball_dumbbell_flye', + 8: 'arm_rotations', + 9: 'hug_a_tree', }, ), - 'strava_product': FieldType( - name='strava_product', - base_type=BASE_TYPES[0x84], # uint16 - values={ - 101: 'Strava iPhone App', # recent versions of Strava iPhone app - 102: 'Strava Android App', # recent versions of Strava Android app - } - ), 'garmin_product': FieldType( name='garmin_product', base_type=BASE_TYPES[0x84], # uint16 @@ -1404,7 +1571,11 @@ 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 + 13: 'hrm4_run_single_byte_product_id', # hrm4 run model for HRM ANT+ messaging 14: 'fr225_single_byte_product_id', # fr225 model for HRM ANT+ messaging + 15: 'gen3_bsm_single_byte_product_id', # gen3_bsm model for Bike Speed ANT+ messaging + 16: 'gen3_bcm_single_byte_product_id', # gen3_bcm model for Bike Cadence ANT+ messaging + 255: 'OHR', # Garmin Wearable Optical Heart Rate Sensor for ANT+ HR Profile Broadcasting 473: 'fr301_china', 474: 'fr301_japan', 475: 'fr301_korea', @@ -1433,6 +1604,7 @@ 1381: 'vector_cp', 1386: 'edge800_china', 1387: 'edge500_china', + 1405: 'approach_g10', 1410: 'fr610_japan', 1422: 'edge500_korea', 1436: 'fr70', @@ -1456,7 +1628,7 @@ 1735: 'virb_elite', 1736: 'edge_touring', # Also Edge Touring Plus 1742: 'edge510_japan', - 1743: 'hrm_tri', + 1743: 'hrm_tri', # Also HRM-Swim 1752: 'hrm_run', 1765: 'fr920xt', 1821: 'edge510_asia', @@ -1499,6 +1671,7 @@ 2153: 'fr225', 2156: 'fr630', 2157: 'fr230', + 2158: 'fr735xt', 2160: 'vivo_active_apac', 2161: 'vector_2', 2162: 'vector_2s', @@ -1506,6 +1679,7 @@ 2173: 'fr620_taiwan', 2174: 'fr220_taiwan', 2175: 'truswing', + 2187: 'd2airvenu', 2188: 'fenix3_china', 2189: 'fenix3_twn', 2192: 'varia_headlight', @@ -1515,16 +1689,37 @@ 2225: 'varia_radar_taillight', 2226: 'varia_radar_display', 2238: 'edge20', + 2260: 'edge520_asia', + 2261: 'edge520_japan', 2262: 'd2_bravo', 2266: 'approach_s20', + 2271: 'vivo_smart2', + 2274: 'edge1000_thai', 2276: 'varia_remote', + 2288: 'edge25_asia', + 2289: 'edge25_jpn', + 2290: 'edge20_asia', + 2292: 'approach_x40', + 2293: 'fenix3_japan', + 2294: 'vivo_smart_emea', + 2310: 'fr630_asia', + 2311: 'fr630_jpn', + 2313: 'fr230_jpn', 2327: 'hrm4_run', + 2332: 'epix_japan', 2337: 'vivo_active_hr', 2347: 'vivo_smart_gps_hr', 2348: 'vivo_smart_hr', + 2361: 'vivo_smart_hr_asia', + 2362: 'vivo_smart_gps_hr_asia', 2368: 'vivo_move', + 2379: 'varia_taillight', + 2396: 'fr235_asia', + 2397: 'fr235_japan', 2398: 'varia_vision', 2406: 'vivo_fit3', + 2407: 'fenix3_korea', + 2408: 'fenix3_sea', 2413: 'fenix3_hr', 2417: 'virb_ultra_30', 2429: 'index_smart_scale', @@ -1532,25 +1727,276 @@ 2432: 'fenix3_chronos', 2441: 'oregon7xx', 2444: 'rino7xx', + 2457: 'epix_korea', + 2473: 'fenix3_hr_chn', + 2474: 'fenix3_hr_twn', + 2475: 'fenix3_hr_jpn', + 2476: 'fenix3_hr_sea', + 2477: 'fenix3_hr_kor', 2496: 'nautix', + 2497: 'vivo_active_hr_apac', + 2503: 'fr35', + 2512: 'oregon7xx_ww', 2530: 'edge_820', 2531: 'edge_explore_820', + 2533: 'fr735xt_apac', + 2534: 'fr735xt_japan', 2544: 'fenix5s', 2547: 'd2_bravo_titanium', 2567: 'varia_ut800', # Varia UT 800 SW 2593: 'running_dynamics_pod', + 2599: 'edge_820_china', + 2600: 'edge_820_japan', 2604: 'fenix5x', 2606: 'vivo_fit_jr', + 2622: 'vivo_smart3', + 2623: 'vivo_sport', + 2628: 'edge_820_taiwan', + 2629: 'edge_820_korea', + 2630: 'edge_820_sea', + 2650: 'fr35_hebrew', + 2656: 'approach_s60', + 2667: 'fr35_apac', + 2668: 'fr35_japan', + 2675: 'fenix3_chronos_asia', + 2687: 'virb_360', 2691: 'fr935', 2697: 'fenix5', + 2700: 'vivoactive3', + 2713: 'edge_1030', + 2727: 'fr35_sea', + 2733: 'fr235_china_nfc', + 2769: 'foretrex_601_701', + 2772: 'vivo_move_hr', + 2787: 'vector_3', + 2796: 'fenix5_asia', + 2797: 'fenix5s_asia', + 2798: 'fenix5x_asia', + 2806: 'approach_z80', + 2814: 'fr35_korea', + 2819: 'd2charlie', + 2831: 'vivo_smart3_apac', + 2832: 'vivo_sport_apac', + 2833: 'fr935_asia', + 2859: 'descent', + 2878: 'vivo_fit4', + 2886: 'fr645', + 2888: 'fr645m', + 2891: 'fr30', + 2900: 'fenix5s_plus', + 2909: 'Edge_130', + 2924: 'edge_1030_asia', + 2927: 'vivosmart_4', + 2945: 'vivo_move_hr_asia', + 2962: 'approach_x10', + 2977: 'fr30_asia', + 2988: 'vivoactive3m_w', + 3003: 'fr645_asia', + 3004: 'fr645m_asia', + 3011: 'edge_explore', + 3028: 'gpsmap66', + 3049: 'approach_s10', + 3066: 'vivoactive3m_l', + 3085: 'approach_g80', + 3092: 'edge_130_asia', + 3095: 'edge_1030_bontrager', + 3110: 'fenix5_plus', + 3111: 'fenix5x_plus', + 3112: 'edge_520_plus', + 3113: 'fr945', + 3121: 'edge_530', + 3122: 'edge_830', + 3126: 'instinct_esports', + 3134: 'fenix5s_plus_apac', + 3135: 'fenix5x_plus_apac', + 3142: 'edge_520_plus_apac', + 3143: 'descent_t1', + 3144: 'fr235l_asia', + 3145: 'fr245_asia', + 3163: 'vivo_active3m_apac', + 3192: 'gen3_bsm', # gen3 bike speed sensor + 3193: 'gen3_bcm', # gen3 bike cadence sensor + 3218: 'vivo_smart4_asia', + 3224: 'vivoactive4_small', + 3225: 'vivoactive4_large', + 3226: 'venu', + 3246: 'marq_driver', + 3247: 'marq_aviator', + 3248: 'marq_captain', + 3249: 'marq_commander', + 3250: 'marq_expedition', + 3251: 'marq_athlete', + 3258: 'descent_mk2', + 3284: 'gpsmap66i', + 3287: 'fenix6S_sport', + 3288: 'fenix6S', + 3289: 'fenix6_sport', + 3290: 'fenix6', + 3291: 'fenix6x', + 3299: 'hrm_dual', # HRM-Dual + 3300: 'hrm_pro', # HRM-Pro + 3308: 'vivo_move3_premium', + 3314: 'approach_s40', + 3321: 'fr245m_asia', + 3349: 'edge_530_apac', + 3350: 'edge_830_apac', + 3378: 'vivo_move3', + 3387: 'vivo_active4_small_asia', + 3388: 'vivo_active4_large_asia', + 3389: 'vivo_active4_oled_asia', + 3405: 'swim2', + 3420: 'marq_driver_asia', + 3421: 'marq_aviator_asia', + 3422: 'vivo_move3_asia', + 3441: 'fr945_asia', + 3446: 'vivo_active3t_chn', + 3448: 'marq_captain_asia', + 3449: 'marq_commander_asia', + 3450: 'marq_expedition_asia', + 3451: 'marq_athlete_asia', + 3466: 'instinct_solar', + 3469: 'fr45_asia', + 3473: 'vivoactive3_daimler', + 3498: 'legacy_rey', + 3499: 'legacy_darth_vader', + 3500: 'legacy_captain_marvel', + 3501: 'legacy_first_avenger', + 3512: 'fenix6s_sport_asia', + 3513: 'fenix6s_asia', + 3514: 'fenix6_sport_asia', + 3515: 'fenix6_asia', + 3516: 'fenix6x_asia', + 3535: 'legacy_captain_marvel_asia', + 3536: 'legacy_first_avenger_asia', + 3537: 'legacy_rey_asia', + 3538: 'legacy_darth_vader_asia', + 3542: 'descent_mk2s', + 3558: 'edge_130_plus', + 3570: 'edge_1030_plus', + 3578: 'rally_200', # Rally 100/200 Power Meter Series + 3589: 'fr745', + 3600: 'venusq', + 3615: 'lily', + 3624: 'marq_adventurer', + 3638: 'enduro', + 3639: 'swim2_apac', + 3648: 'marq_adventurer_asia', + 3652: 'fr945_lte', + 3702: 'descent_mk2_asia', # Mk2 and Mk2i + 3703: 'venu2', + 3704: 'venu2s', + 3737: 'venu_daimler_asia', + 3739: 'marq_golfer', + 3740: 'venu_daimler', + 3794: 'fr745_asia', + 3808: 'varia_rct715', + 3809: 'lily_asia', + 3812: 'edge_1030_plus_asia', + 3813: 'edge_130_plus_asia', + 3823: 'approach_s12', + 3837: 'venusq_asia', + 3843: 'edge_1040', + 3850: 'marq_golfer_asia', + 3851: 'venu2_plus', + 3865: 'gnss', + 3869: 'fr55', + 3872: 'enduro_asia', + 3888: 'instinct_2', + 3905: 'fenix7s', + 3906: 'fenix7', + 3907: 'fenix7x', + 3908: 'fenix7s_apac', + 3909: 'fenix7_apac', + 3910: 'fenix7x_apac', + 3930: 'descent_mk2s_asia', + 3934: 'approach_s42', + 3943: 'epix_gen2', + 3944: 'epix_gen2_apac', + 3949: 'venu2s_asia', + 3950: 'venu2_asia', + 3978: 'fr945_lte_asia', + 3982: 'vivo_move_sport', + 3983: 'vivomove_trend', + 3986: 'approach_S12_asia', + 3990: 'fr255_music', + 3991: 'fr255_small_music', + 3992: 'fr255', + 3993: 'fr255_small', + 4002: 'approach_s42_asia', + 4005: 'descent_g1', + 4017: 'venu2_plus_asia', + 4024: 'fr955', + 4033: 'fr55_asia', + 4061: 'edge_540', + 4062: 'edge_840', + 4063: 'vivosmart_5', + 4071: 'instinct_2_asia', + 4105: 'marq_gen2', # Adventurer, Athlete, Captain, Golfer + 4115: 'venusq2', + 4116: 'venusq2music', + 4124: 'marq_gen2_aviator', + 4125: 'd2_air_x10', + 4130: 'hrm_pro_plus', + 4132: 'descent_g1_asia', + 4135: 'tactix7', + 4155: 'instinct_crossover', + 4169: 'edge_explore2', + 4233: 'approach_s70', + 4257: 'fr265_large', + 4258: 'fr265_small', + 4260: 'venu3', + 4261: 'venu3s', + 4265: 'tacx_neo_smart', # Neo Smart, Tacx + 4266: 'tacx_neo2_smart', # Neo 2 Smart, Tacx + 4267: 'tacx_neo2_t_smart', # Neo 2T Smart, Tacx + 4268: 'tacx_neo_smart_bike', # Neo Smart Bike, Tacx + 4269: 'tacx_satori_smart', # Satori Smart, Tacx + 4270: 'tacx_flow_smart', # Flow Smart, Tacx + 4271: 'tacx_vortex_smart', # Vortex Smart, Tacx + 4272: 'tacx_bushido_smart', # Bushido Smart, Tacx + 4273: 'tacx_genius_smart', # Genius Smart, Tacx + 4274: 'tacx_flux_flux_s_smart', # Flux/Flux S Smart, Tacx + 4275: 'tacx_flux2_smart', # Flux 2 Smart, Tacx + 4276: 'tacx_magnum', # Magnum, Tacx + 4305: 'edge_1040_asia', + 4312: 'epix_gen2_pro_42', + 4313: 'epix_gen2_pro_47', + 4314: 'epix_gen2_pro_51', + 4315: 'fr965', + 4341: 'enduro2', + 4374: 'fenix7s_pro_solar', + 4375: 'fenix7_pro_solar', + 4376: 'fenix7x_pro_solar', + 4394: 'instinct_2x', + 4426: 'vivoactive5', + 4442: 'descent_t2', + 4472: 'marq_gen2_commander', + 4556: 'd2_mach1_pro', 10007: 'sdm4', # SDM4 footpod 10014: 'edge_remote', + 3927: 'approach_g12', + 4001: 'approach_g12_asia', 20119: 'training_center', + 20533: 'tacx_training_app_win', + 20534: 'tacx_training_app_mac', + 20565: 'tacx_training_app_mac_catalyst', + 30045: 'tacx_training_app_android', + 30046: 'tacx_training_app_ios', + 30047: 'tacx_training_app_legacy', 65531: 'connectiq_simulator', 65532: 'android_antplus_plugin', 65534: 'connect', # Garmin Connect website }, ), + 'gas_consumption_rate_type': FieldType( + name='gas_consumption_rate_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'pressure_sac', # Pressure-based Surface Air Consumption + 1: 'volume_sac', # Volumetric Surface Air Consumption + 2: 'rmv', # Respiratory Minute Volume + }, + ), 'gender': FieldType( name='gender', base_type=BASE_TYPES[0x00], # enum @@ -1640,6 +2086,13 @@ 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', + 43: 'single_leg_swiss_ball_hip_raise_and_leg_curl', + 44: 'clams', + 45: 'inner_thigh_circles', # Deprecated do not use + 46: 'inner_thigh_side_lift', # Deprecated do not use + 47: 'leg_circles', + 48: 'leg_lift', + 49: 'leg_lift_in_external_rotation', }, ), 'hip_stability_exercise_name': FieldType( @@ -1706,6 +2159,18 @@ 0: 'custom', 1: 'percent_max_hr', 2: 'percent_hrr', + 3: 'percent_lthr', + }, + ), + 'hrv_status': FieldType( + name='hrv_status', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'none', + 1: 'poor', + 2: 'low', + 3: 'unbalanced', + 4: 'balanced', }, ), 'hyperextension_exercise_name': FieldType( @@ -1749,6 +2214,9 @@ 34: 'weighted_swiss_ball_hyperextension', 35: 'swiss_ball_opposite_arm_and_leg_lift', 36: 'weighted_swiss_ball_opposite_arm_and_leg_lift', + 37: 'superman_on_swiss_ball', + 38: 'cobra', + 39: 'supine_floor_barre', # Deprecated do not use }, ), 'intensity': FieldType( @@ -1759,6 +2227,9 @@ 1: 'rest', 2: 'warmup', 3: 'cooldown', + 4: 'recovery', + 5: 'interval', + 6: 'other', }, ), 'language': FieldType( @@ -1925,6 +2396,8 @@ 29: 'underhand_grip_rear_lateral_raise', 30: 'wall_slide', 31: 'weighted_wall_slide', + 32: 'arm_circles', + 33: 'shaving_the_head', }, ), 'left_right_balance': FieldType( @@ -2007,6 +2480,16 @@ 'local_device_type': FieldType( name='local_device_type', base_type=BASE_TYPES[0x02], # uint8 + values={ + 0: 'gps', # Onboard gps receiver + 1: 'glonass', # Onboard glonass receiver + 2: 'gps_glonass', # Onboard gps glonass receiver + 3: 'accelerometer', # Onboard sensor + 4: 'barometer', # Onboard sensor + 5: 'temperature', # Onboard sensor + 10: 'whr', # Onboard wrist HR sensor + 12: 'sensor_hub', # Onboard software package + }, ), 'localtime_into_day': FieldType( # number of seconds into the day since local 00:00:00 name='localtime_into_day', @@ -2104,7 +2587,7 @@ base_type=BASE_TYPES[0x84], # uint16 values={ 1: 'garmin', - 2: 'garmin_fr405_antfs', # Do not use. Used by FR405 for ANTFS man id. + 2: 'garmin_fr405_antfs', # Do not use. Used by FR405 for ANTFS man id. 3: 'zephyr', 4: 'dayton', 5: 'idt', @@ -2143,6 +2626,7 @@ 38: 'osynce', 39: 'holux', 40: 'concept2', + 41: 'shimano', 42: 'one_giant_leap', 43: 'ace_sensor', 44: 'brim_brothers', @@ -2224,6 +2708,32 @@ 122: 'johnson_health_tech', 123: 'polar_electro', 124: 'seesense', + 125: 'nci_technology', + 126: 'iqsquare', + 127: 'leomo', + 128: 'ifit_com', + 129: 'coros_byte', + 130: 'versa_design', + 131: 'chileaf', + 132: 'cycplus', + 133: 'gravaa_byte', + 134: 'sigeyi', + 135: 'coospo', + 136: 'geoid', + 137: 'bosch', + 138: 'kyto', + 139: 'kinetic_sports', + 140: 'decathlon_byte', + 141: 'tq_systems', + 142: 'tag_heuer', + 143: 'keiser_fitness', + 144: 'zwift_byte', + 145: 'porsche_ep', + 146: 'blackbird', + 147: 'meilan_byte', + 148: 'ezon', + 149: 'laisi', + 150: 'myzone', 255: 'development', 257: 'healthandlife', 258: 'lezyne', @@ -2262,9 +2772,68 @@ 291: 'shapelog', 292: 'dabuziduo', 293: 'jetblack', + 294: 'coros', + 295: 'virtugo', + 296: 'velosense', + 297: 'cycligentinc', + 298: 'trailforks', + 299: 'mahle_ebikemotion', + 300: 'nurvv', + 301: 'microprogram', + 302: 'zone5cloud', + 303: 'greenteg', + 304: 'yamaha_motors', + 305: 'whoop', + 306: 'gravaa', + 307: 'onelap', + 308: 'monark_exercise', + 309: 'form', + 310: 'decathlon', + 311: 'syncros', + 312: 'heatup', + 313: 'cannondale', + 314: 'true_fitness', + 315: 'RGT_cycling', + 316: 'vasa', + 317: 'race_republic', + 318: 'fazua', + 319: 'oreka_training', + 320: 'lsec', # Lishun Electric & Communication + 321: 'lululemon_studio', + 322: 'shanyue', + 323: 'spinning_mda', + 324: 'hilldating', + 325: 'aero_sensor', + 326: 'nike', + 327: 'magicshine', 5759: 'actigraphcorp', }, ), + 'max_met_category': FieldType( + name='max_met_category', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'generic', + 1: 'cycling', + }, + ), + 'max_met_heart_rate_source': FieldType( + name='max_met_heart_rate_source', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'whr', # Wrist Heart Rate Monitor + 1: 'hrm', # Chest Strap Heart Rate Monitor + }, + ), + 'max_met_speed_source': FieldType( + name='max_met_speed_source', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'onboard_gps', + 1: 'connected_gps', + 2: 'cadence', + }, + ), 'mesg_count': FieldType( name='mesg_count', base_type=BASE_TYPES[0x00], # enum @@ -2357,13 +2926,31 @@ 208: 'magnetometer_data', 209: 'barometer_data', 210: 'one_d_sensor_calibration', + 211: 'monitoring_hr_data', + 216: 'time_in_zone', 225: 'set', 227: 'stress_level', + 229: 'max_met_data', 258: 'dive_settings', 259: 'dive_gas', 262: 'dive_alarm', 264: 'exercise_title', 268: 'dive_summary', + 269: 'spo2_data', + 275: 'sleep_level', + 285: 'jump', + 290: 'beat_intervals', + 297: 'respiration_rate', + 312: 'split', + 313: 'split_summary', + 317: 'climb_pro', + 319: 'tank_update', + 323: 'tank_summary', + 346: 'sleep_assessment', + 370: 'hrv_status_summary', + 371: 'hrv_value', + 375: 'device_aux_battery_info', + 393: 'dive_apnea_alarm', }, ), 'message_index': FieldType( @@ -2375,6 +2962,14 @@ 0x8000: 'selected', # message is selected if set }, ), + 'no_fly_time_mode': FieldType( + name='no_fly_time_mode', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'standard', # Standard Diver Alert Network no-fly guidance + 1: 'flat_24_hours', # Flat 24 hour no-fly guidance + }, + ), 'olympic_lift_exercise_name': FieldType( name='olympic_lift_exercise_name', base_type=BASE_TYPES[0x84], # uint16 @@ -2534,6 +3129,13 @@ 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', + 128: 'plank_with_feet_on_swiss_ball', + 129: 'side_plank_to_plank_with_reach_under', + 130: 'bridge_with_glute_lower_lift', + 131: 'bridge_one_leg_bridge', + 132: 'plank_with_arm_variations', + 133: 'plank_with_leg_lift', + 134: 'reverse_plank_with_leg_pull', }, ), 'plyo_exercise_name': FieldType( @@ -2712,6 +3314,7 @@ 75: 'ring_push_up', 76: 'weighted_ring_push_up', 77: 'push_up', + 78: 'pilates_pushup', }, ), 'pwr_zone_calc': FieldType( @@ -2722,6 +3325,16 @@ 1: 'percent_ftp', }, ), + 'radar_threat_level_type': FieldType( + name='radar_threat_level_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'threat_unknown', + 1: 'threat_none', + 2: 'threat_approaching', + 3: 'threat_approaching_fast', + }, + ), 'rider_position_type': FieldType( name='rider_position_type', base_type=BASE_TYPES[0x00], # enum @@ -3004,6 +3617,17 @@ 37: 'sit_up', }, ), + 'sleep_level': FieldType( + name='sleep_level', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'unmeasurable', + 1: 'awake', + 2: 'light', + 3: 'deep', + 4: 'rem', + }, + ), 'source_type': FieldType( name='source_type', base_type=BASE_TYPES[0x00], # enum @@ -3016,6 +3640,43 @@ 5: 'local', # Onboard device }, ), + 'split_type': FieldType( + name='split_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 1: 'ascent_split', + 2: 'descent_split', + 3: 'interval_active', + 4: 'interval_rest', + 5: 'interval_warmup', + 6: 'interval_cooldown', + 7: 'interval_recovery', + 8: 'interval_other', + 9: 'climb_active', + 10: 'climb_rest', + 11: 'surf_active', + 12: 'run_active', + 13: 'run_rest', + 14: 'workout_round', + 17: 'rwd_run', # run/walk detection running + 18: 'rwd_walk', # run/walk detection walking + 21: 'windsurf_active', + 22: 'rwd_stand', # run/walk detection standing + 23: 'transition', # Marks the time going from ascent_split to descent_split/used in backcountry ski + 28: 'ski_lift_split', + 29: 'ski_run_split', + }, + ), + 'spo2_measurement_type': FieldType( + name='spo2_measurement_type', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'off_wrist', + 1: 'spot_check', + 2: 'continuous_check', + 3: 'periodic', + }, + ), 'sport': FieldType( name='sport', base_type=BASE_TYPES[0x00], # enum @@ -3069,6 +3730,14 @@ 46: 'jumpmaster', 47: 'boxing', 48: 'floor_climbing', + 53: 'diving', + 62: 'hiit', + 64: 'racket', + 65: 'wheelchair_push_walk', + 66: 'wheelchair_push_run', + 67: 'meditation', + 76: 'water_tubing', + 77: 'wakesurfing', 254: 'all', # All is for goals only to include all sports. }, ), @@ -3269,6 +3938,11 @@ 84: 'wide_stance_barbell_squat', 85: 'wide_stance_goblet_squat', 86: 'zercher_squat', + 87: 'kbs_overhead', # Deprecated do not use + 88: 'squat_and_side_kick', + 89: 'squat_jumps_in_n_out', + 90: 'pilates_plie_squats_parallel_turned_out_flat_and_heels', + 91: 'releve_straight_leg_and_knee_bent_with_one_leg_variation', }, ), 'stroke_type': FieldType( @@ -3331,7 +4005,7 @@ 41: 'whitewater', # Kayaking/Rafting 42: 'skate_skiing', # Cross Country Skiing 43: 'yoga', # Training - 44: 'pilates', # Training + 44: 'pilates', # Fitness Equipment 45: 'indoor_running', # Run 46: 'gravel_cycling', # Cycling 47: 'e_bike_mountain', # Cycling @@ -3347,6 +4021,30 @@ 57: 'apnea_hunting', # Diving 58: 'virtual_activity', 59: 'obstacle', # Used for events where participants run, crawl through mud, climb over walls, etc. + 62: 'breathing', + 65: 'sail_race', # Sailing + 67: 'ultra', # Ultramarathon + 68: 'indoor_climbing', # Climbing + 69: 'bouldering', # Climbing + 70: 'hiit', # High Intensity Interval Training + 73: 'amrap', # HIIT + 74: 'emom', # HIIT + 75: 'tabata', # HIIT + 84: 'pickleball', # Racket + 85: 'padel', # Racket + 86: 'indoor_wheelchair_walk', + 87: 'indoor_wheelchair_run', + 88: 'indoor_hand_cycling', + 110: 'fly_canopy', # Flying + 111: 'fly_paraglide', # Flying + 112: 'fly_paramotor', # Flying + 113: 'fly_pressurized', # Flying + 114: 'fly_navigate', # Flying + 115: 'fly_timer', # Flying + 116: 'fly_altimeter', # Flying + 117: 'fly_wx', # Flying + 118: 'fly_vfr', # Flying + 119: 'fly_ifr', # Flying 254: 'all', }, ), @@ -3386,6 +4084,15 @@ 2: 'auto', }, ), + 'tap_sensitivity': FieldType( + name='tap_sensitivity', + base_type=BASE_TYPES[0x00], # enum + values={ + 0: 'high', + 1: 'medium', + 2: 'low', + }, + ), '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 @@ -3682,7 +4389,7 @@ 13: 'neck_rotations', 14: 'opposite_arm_and_leg_balance', 15: 'reach_roll_and_lift', - 16: 'scorpion', + 16: 'scorpion', # Deprecated do not use 17: 'shoulder_circles', 18: 'side_to_side_leg_swings', 19: 'sleeper_stretch', @@ -3899,6 +4606,7 @@ 27: 'repeat_until_training_peaks_tss', 28: 'repetition_time', 29: 'reps', + 31: 'time_only', }, ), 'wkt_step_target': FieldType( @@ -3930,7 +4638,7 @@ 0x00000004: 'fitness_equipment', 0x00000008: 'firstbeat', 0x00000010: 'new_leaf', - 0x00000020: 'tcx', # For backwards compatibility. Watch should add missing id fields then clear flag. + 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. @@ -3974,7 +4682,7 @@ MESSAGE_TYPES = { - # **************************** Common Messages ***************************** + # ************************************ ************************************ 0: MessageType( # Must be first message in file. name='file_id', mesg_num=0, @@ -3994,6 +4702,19 @@ type=BASE_TYPES[0x84], # uint16 def_num=2, subfields=( + SubField( + name='favero_product', + def_num=2, + type=FIELD_TYPES['favero_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=1, + value='favero_electronics', + raw_value=263, + ), + ), + ), SubField( name='garmin_product', def_num=2, @@ -4017,18 +4738,11 @@ value='dynastream_oem', raw_value=13, ), - ) - ), - SubField( - name='strava_product', - def_num=2, - type=FIELD_TYPES['strava_product'], - ref_fields=( ReferenceField( name='manufacturer', def_num=1, - value='strava', - raw_value=265, + value='tacx', + raw_value=89, ), ), ), @@ -4056,715 +4770,445 @@ ), }, ), - - - # ************************************ ************************************ - 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, + 49: MessageType( + name='file_creator', + mesg_num=49, fields={ 0: Field( - name='enabled', - type=FIELD_TYPES['bool'], + name='software_version', + type=BASE_TYPES[0x84], # uint16 def_num=0, ), 1: Field( - name='hrm_ant_id', - type=BASE_TYPES[0x8B], # uint16z + name='hardware_version', + type=BASE_TYPES[0x02], # uint8 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, + 162: MessageType( + name='timestamp_correlation', + mesg_num=162, fields={ - 0: Field( - name='enabled', - type=FIELD_TYPES['bool'], + 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( - name='sdm_ant_id', - type=BASE_TYPES[0x8B], # uint16z + 1: Field( # Whole second part of the system timestamp + name='system_timestamp', + type=FIELD_TYPES['date_time'], def_num=1, + units='s', ), - 2: Field( - name='sdm_cal_factor', + 2: Field( # Fractional part of the system timestamp + name='fractional_system_timestamp', type=BASE_TYPES[0x84], # uint16 def_num=2, - scale=10, - units='%', + scale=32768, + units='s', ), - 3: Field( - name='odometer', - type=BASE_TYPES[0x86], # uint32 + 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, - scale=100, - units='m', + units='s', ), - 4: Field( # Use footpod for speed source instead of GPS - name='speed_source', - type=FIELD_TYPES['bool'], + 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( - name='sdm_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z + 5: Field( # Millisecond part of the system timestamp + name='system_timestamp_ms', + type=BASE_TYPES[0x84], # uint16 def_num=5, + units='ms', ), - 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, - ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of UTC timestamp at the time the system timestamp was recorded. }, ), - 6: MessageType( - name='bike_profile', - mesg_num=6, + + + # ************************* Activity File Messages ************************* + 18: MessageType( + name='session', + mesg_num=18, fields={ - 0: Field( - name='name', - type=BASE_TYPES[0x07], # string + 0: Field( # session + name='event', + type=FIELD_TYPES['event'], def_num=0, ), - 1: Field( - name='sport', - type=FIELD_TYPES['sport'], + 1: Field( # stop + name='event_type', + type=FIELD_TYPES['event_type'], def_num=1, ), 2: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], + name='start_time', + type=FIELD_TYPES['date_time'], def_num=2, ), 3: Field( - name='odometer', - type=BASE_TYPES[0x86], # uint32 + name='start_position_lat', + type=BASE_TYPES[0x85], # sint32 def_num=3, - scale=100, - units='m', + units='semicircles', ), 4: Field( - name='bike_spd_ant_id', - type=BASE_TYPES[0x8B], # uint16z + name='start_position_long', + type=BASE_TYPES[0x85], # sint32 def_num=4, + units='semicircles', ), 5: Field( - name='bike_cad_ant_id', - type=BASE_TYPES[0x8B], # uint16z + name='sport', + type=FIELD_TYPES['sport'], def_num=5, ), 6: Field( - name='bike_spdcad_ant_id', - type=BASE_TYPES[0x8B], # uint16z + name='sub_sport', + type=FIELD_TYPES['sub_sport'], def_num=6, ), - 7: Field( - name='bike_power_ant_id', - type=BASE_TYPES[0x8B], # uint16z + 7: Field( # Time (includes pauses) + name='total_elapsed_time', + type=BASE_TYPES[0x86], # uint32 def_num=7, + scale=1000, + units='s', ), - 8: Field( - name='custom_wheelsize', - type=BASE_TYPES[0x84], # uint16 + 8: Field( # Timer Time (excludes pauses) + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 def_num=8, scale=1000, - units='m', + units='s', ), 9: Field( - name='auto_wheelsize', - type=BASE_TYPES[0x84], # uint16 + name='total_distance', + type=BASE_TYPES[0x86], # uint32 def_num=9, - scale=1000, + scale=100, units='m', ), 10: Field( - name='bike_weight', - type=BASE_TYPES[0x84], # uint16 + name='total_cycles', + type=BASE_TYPES[0x86], # uint32 def_num=10, - scale=10, - units='kg', + 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, + ), + ), + ), + SubField( + name='total_strokes', + def_num=10, + type=BASE_TYPES[0x86], # uint32 + units='strokes', + ref_fields=( + ReferenceField( + name='sport', + def_num=5, + value='cycling', + raw_value=2, + ), + ReferenceField( + name='sport', + def_num=5, + value='swimming', + raw_value=5, + ), + ReferenceField( + name='sport', + def_num=5, + value='rowing', + raw_value=15, + ), + ReferenceField( + name='sport', + def_num=5, + value='stand_up_paddleboarding', + raw_value=37, + ), + ), + ), + ), ), 11: Field( - name='power_cal_factor', + name='total_calories', type=BASE_TYPES[0x84], # uint16 def_num=11, - scale=10, - units='%', - ), - 12: Field( - name='auto_wheel_cal', - type=FIELD_TYPES['bool'], - def_num=12, + units='kcal', ), 13: Field( - name='auto_power_zero', - type=FIELD_TYPES['bool'], + name='total_fat_calories', + type=BASE_TYPES[0x84], # uint16 def_num=13, + units='kcal', ), - 14: Field( - name='id', - type=BASE_TYPES[0x02], # uint8 + 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='spd_enabled', - type=FIELD_TYPES['bool'], + 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( - name='cad_enabled', - type=FIELD_TYPES['bool'], + 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='spdcad_enabled', - type=FIELD_TYPES['bool'], + name='max_heart_rate', + type=BASE_TYPES[0x02], # uint8 def_num=17, + units='bpm', ), - 18: Field( - name='power_enabled', - type=FIELD_TYPES['bool'], + 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='crank_length', + name='max_cadence', type=BASE_TYPES[0x02], # uint8 def_num=19, - scale=2, - offset=-110, - units='mm', + 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( - name='enabled', - type=FIELD_TYPES['bool'], + 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='bike_spd_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z + name='max_power', + type=BASE_TYPES[0x84], # uint16 def_num=21, + units='watts', ), 22: Field( - name='bike_cad_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z + name='total_ascent', + type=BASE_TYPES[0x84], # uint16 def_num=22, + units='m', ), 23: Field( - name='bike_spdcad_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z + name='total_descent', + type=BASE_TYPES[0x84], # uint16 def_num=23, + units='m', ), 24: Field( - name='bike_power_ant_id_trans_type', - type=BASE_TYPES[0x0A], # uint8z + name='total_training_effect', + type=BASE_TYPES[0x02], # uint8 def_num=24, + scale=10, ), - 37: Field( # Rollover counter that can be used to extend the odometer - name='odometer_rollover', - type=BASE_TYPES[0x02], # uint8 - def_num=37, + 25: Field( + name='first_lap_index', + type=BASE_TYPES[0x84], # uint16 + def_num=25, ), - 38: Field( # Number of front gears - name='front_gear_num', - type=BASE_TYPES[0x0A], # uint8z - def_num=38, + 26: Field( + name='num_laps', + type=BASE_TYPES[0x84], # uint16 + def_num=26, ), - 39: Field( # Number of teeth on each gear 0 is innermost - name='front_gear', - type=BASE_TYPES[0x0A], # uint8z - def_num=39, + 27: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=27, ), - 40: Field( # Number of rear gears - name='rear_gear_num', - type=BASE_TYPES[0x0A], # uint8z - def_num=40, + 28: Field( + name='trigger', + type=FIELD_TYPES['session_trigger'], + def_num=28, ), - 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, + 29: Field( # North east corner latitude + name='nec_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=29, + units='semicircles', ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 30: Field( # North east corner longitude + name='nec_long', + type=BASE_TYPES[0x85], # sint32 + def_num=30, + units='semicircles', ), - }, - ), - 8: MessageType( - name='hr_zone', - mesg_num=8, - fields={ - 1: Field( - name='high_bpm', - type=BASE_TYPES[0x02], # uint8 - def_num=1, - units='bpm', + 31: Field( # South west corner latitude + name='swc_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=31, + units='semicircles', ), - 2: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=2, + 32: Field( # South west corner longitude + name='swc_long', + type=BASE_TYPES[0x85], # sint32 + def_num=32, + units='semicircles', ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 33: Field( # # of lengths of swim pool + name='num_lengths', + type=BASE_TYPES[0x84], # uint16 + def_num=33, + units='lengths', ), - }, - ), - 9: MessageType( - name='power_zone', - mesg_num=9, - fields={ - 1: Field( - name='high_value', + 34: Field( + name='normalized_power', type=BASE_TYPES[0x84], # uint16 - def_num=1, + def_num=34, 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', + 35: Field( + name='training_stress_score', 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, + def_num=35, 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, + units='tss', ), - 1: Field( # stop - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=1, + 36: Field( + name='intensity_factor', + type=BASE_TYPES[0x84], # uint16 + def_num=36, + scale=1000, + units='if', ), - 2: Field( - name='start_time', - type=FIELD_TYPES['date_time'], - def_num=2, + 37: Field( + name='left_right_balance', + type=FIELD_TYPES['left_right_balance_100'], + def_num=37, ), - 3: Field( - name='start_position_lat', + 38: Field( + name='end_position_lat', type=BASE_TYPES[0x85], # sint32 - def_num=3, + def_num=38, units='semicircles', ), - 4: Field( - name='start_position_long', + 39: Field( + name='end_position_long', type=BASE_TYPES[0x85], # sint32 - def_num=4, + def_num=39, 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', + 41: Field( + name='avg_stroke_count', type=BASE_TYPES[0x86], # uint32 - def_num=8, - scale=1000, - units='s', + def_num=41, + scale=10, + units='strokes/lap', ), - 9: Field( - name='total_distance', - type=BASE_TYPES[0x86], # uint32 - def_num=9, + 42: Field( + name='avg_stroke_distance', + type=BASE_TYPES[0x84], # uint16 + def_num=42, 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, - ), - ), - ), - ), + 43: Field( + name='swim_stroke', + type=FIELD_TYPES['swim_stroke'], + def_num=43, + units='swim_stroke', ), - 11: Field( - name='total_calories', + 44: Field( + name='pool_length', type=BASE_TYPES[0x84], # uint16 - def_num=11, - units='kcal', + def_num=44, + scale=100, + units='m', ), - 13: Field( - name='total_fat_calories', + 45: Field( + name='threshold_power', 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', + def_num=45, + units='watts', ), 46: Field( name='pool_length_unit', @@ -5137,6 +5581,11 @@ scale=2, units='percent', ), + 110: Field( # Sport name from associated sport mesg + name='sport_profile_name', + type=BASE_TYPES[0x07], # string + def_num=110, + ), 111: Field( name='sport_index', type=BASE_TYPES[0x02], # uint8 @@ -5187,7 +5636,7 @@ scale=0.7111111, units='degrees', ), - 119: Field( # Average right power phase peak angles data value indexes defined by power_phase_type. + 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, @@ -5309,32 +5758,249 @@ 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, + 140: Field( # 0 if above water + name='avg_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=140, + scale=1000, + units='m', ), - }, - ), - 19: MessageType( - name='lap', - mesg_num=19, - fields={ - 0: Field( - name='event', - type=FIELD_TYPES['event'], - def_num=0, + 141: Field( # 0 if above water + name='max_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=141, + scale=1000, + units='m', ), - 1: Field( - name='event_type', - type=FIELD_TYPES['event_type'], - def_num=1, + 142: Field( # Time since end of last dive + name='surface_interval', + type=BASE_TYPES[0x86], # uint32 + def_num=142, + units='s', ), - 2: Field( - name='start_time', - type=FIELD_TYPES['date_time'], - def_num=2, + 143: Field( + name='start_cns', + type=BASE_TYPES[0x02], # uint8 + def_num=143, + units='percent', + ), + 144: Field( + name='end_cns', + type=BASE_TYPES[0x02], # uint8 + def_num=144, + units='percent', + ), + 145: Field( + name='start_n2', + type=BASE_TYPES[0x84], # uint16 + def_num=145, + units='percent', + ), + 146: Field( + name='end_n2', + type=BASE_TYPES[0x84], # uint16 + def_num=146, + units='percent', + ), + 147: Field( + name='avg_respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=147, + components=( + ComponentField( + name='enhanced_avg_respiration_rate', + def_num=169, + accumulate=False, + bits=8, + bit_offset=0, + ), + ), + ), + 148: Field( + name='max_respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=148, + components=( + ComponentField( + name='enhanced_max_respiration_rate', + def_num=170, + accumulate=False, + bits=8, + bit_offset=0, + ), + ), + ), + 149: Field( + name='min_respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=149, + components=( + ComponentField( + name='enhanced_min_respiration_rate', + def_num=180, + accumulate=False, + bits=8, + bit_offset=0, + ), + ), + ), + 150: Field( + name='min_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=150, + units='C', + ), + 155: Field( + name='o2_toxicity', + type=BASE_TYPES[0x84], # uint16 + def_num=155, + units='OTUs', + ), + 156: Field( + name='dive_number', + type=BASE_TYPES[0x86], # uint32 + def_num=156, + ), + 168: Field( + name='training_load_peak', + type=BASE_TYPES[0x85], # sint32 + def_num=168, + scale=65536, + ), + 169: Field( + name='enhanced_avg_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=169, + scale=100, + units='Breaths/min', + ), + 170: Field( + name='enhanced_max_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=170, + scale=100, + units='Breaths/min', + ), + 180: Field( + name='enhanced_min_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=180, + scale=100, + ), + 181: Field( # The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. + name='total_grit', + type=BASE_TYPES[0x88], # float32 + def_num=181, + units='kGrit', + ), + 182: Field( # The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. + name='total_flow', + type=BASE_TYPES[0x88], # float32 + def_num=182, + units='Flow', + ), + 183: Field( + name='jump_count', + type=BASE_TYPES[0x84], # uint16 + def_num=183, + ), + 186: Field( # The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. + name='avg_grit', + type=BASE_TYPES[0x88], # float32 + def_num=186, + units='kGrit', + ), + 187: Field( # The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. + name='avg_flow', + type=BASE_TYPES[0x88], # float32 + def_num=187, + units='Flow', + ), + 194: Field( # Average SPO2 for the monitoring session + name='avg_spo2', + type=BASE_TYPES[0x02], # uint8 + def_num=194, + units='percent', + ), + 195: Field( # Average stress for the monitoring session + name='avg_stress', + type=BASE_TYPES[0x02], # uint8 + def_num=195, + units='percent', + ), + 197: Field( # Standard deviation of R-R interval (SDRR) - Heart rate variability measure most useful for wellness users. + name='sdrr_hrv', + type=BASE_TYPES[0x02], # uint8 + def_num=197, + units='mS', + ), + 198: Field( # Root mean square successive difference (RMSSD) - Heart rate variability measure most useful for athletes + name='rmssd_hrv', + type=BASE_TYPES[0x02], # uint8 + def_num=198, + units='mS', + ), + 199: Field( # fractional part of total_ascent + name='total_fractional_ascent', + type=BASE_TYPES[0x02], # uint8 + def_num=199, + scale=100, + units='m', + ), + 200: Field( # fractional part of total_descent + name='total_fractional_descent', + type=BASE_TYPES[0x02], # uint8 + def_num=200, + scale=100, + units='m', + ), + 208: Field( + name='avg_core_temperature', + type=BASE_TYPES[0x84], # uint16 + def_num=208, + scale=100, + units='C', + ), + 209: Field( + name='min_core_temperature', + type=BASE_TYPES[0x84], # uint16 + def_num=209, + scale=100, + units='C', + ), + 210: Field( + name='max_core_temperature', + type=BASE_TYPES[0x84], # uint16 + def_num=210, + scale=100, + units='C', + ), + 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', @@ -5407,6 +6073,38 @@ ), ), ), + SubField( + name='total_strokes', + def_num=10, + type=BASE_TYPES[0x86], # uint32 + units='strokes', + ref_fields=( + ReferenceField( + name='sport', + def_num=25, + value='cycling', + raw_value=2, + ), + ReferenceField( + name='sport', + def_num=25, + value='swimming', + raw_value=5, + ), + ReferenceField( + name='sport', + def_num=25, + value='rowing', + raw_value=15, + ), + ReferenceField( + name='sport', + def_num=25, + value='stand_up_paddleboarding', + raw_value=37, + ), + ), + ), ), ), 11: Field( @@ -5972,7 +6670,7 @@ scale=0.7111111, units='degrees', ), - 103: Field( # Average left power phase peak angles. Data value indexes defined by power_phase_type. + 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, @@ -5986,7 +6684,7 @@ scale=0.7111111, units='degrees', ), - 105: Field( # Average right power phase peak angles. Data value indexes defined by power_phase_type. + 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, @@ -6102,6 +6800,132 @@ scale=1000, units='m/s', ), + 122: Field( # 0 if above water + name='avg_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=122, + scale=1000, + units='m', + ), + 123: Field( # 0 if above water + name='max_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=123, + scale=1000, + units='m', + ), + 124: Field( + name='min_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=124, + units='C', + ), + 136: Field( + name='enhanced_avg_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=136, + scale=100, + units='Breaths/min', + ), + 137: Field( + name='enhanced_max_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=137, + scale=100, + units='Breaths/min', + ), + 147: Field( + name='avg_respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=147, + components=( + ComponentField( + name='enhanced_avg_respiration_rate', + def_num=136, + accumulate=False, + bits=8, + bit_offset=0, + ), + ), + ), + 148: Field( + name='max_respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=148, + components=( + ComponentField( + name='enhanced_max_respiration_rate', + def_num=137, + accumulate=False, + bits=8, + bit_offset=0, + ), + ), + ), + 149: Field( # The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. + name='total_grit', + type=BASE_TYPES[0x88], # float32 + def_num=149, + units='kGrit', + ), + 150: Field( # The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. + name='total_flow', + type=BASE_TYPES[0x88], # float32 + def_num=150, + units='Flow', + ), + 151: Field( + name='jump_count', + type=BASE_TYPES[0x84], # uint16 + def_num=151, + ), + 153: Field( # The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. + name='avg_grit', + type=BASE_TYPES[0x88], # float32 + def_num=153, + units='kGrit', + ), + 154: Field( # The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. + name='avg_flow', + type=BASE_TYPES[0x88], # float32 + def_num=154, + units='Flow', + ), + 156: Field( # fractional part of total_ascent + name='total_fractional_ascent', + type=BASE_TYPES[0x02], # uint8 + def_num=156, + scale=100, + units='m', + ), + 157: Field( # fractional part of total_descent + name='total_fractional_descent', + type=BASE_TYPES[0x02], # uint8 + def_num=157, + scale=100, + units='m', + ), + 158: Field( + name='avg_core_temperature', + type=BASE_TYPES[0x84], # uint16 + def_num=158, + scale=100, + units='C', + ), + 159: Field( + name='min_core_temperature', + type=BASE_TYPES[0x84], # uint16 + def_num=159, + scale=100, + units='C', + ), + 160: Field( + name='max_core_temperature', + type=BASE_TYPES[0x84], # uint16 + def_num=160, + scale=100, + units='C', + ), 253: FIELD_TYPE_TIMESTAMP, # Lap end time. 254: Field( name='message_index', @@ -6221,7 +7045,7 @@ scale=100, units='%', ), - 10: Field( # Relative. 0 is none 254 is Max. + 10: Field( # Relative. 0 is none 254 is Max. name='resistance', type=BASE_TYPES[0x02], # uint8 def_num=10, @@ -6246,7 +7070,7 @@ def_num=13, units='C', ), - 17: Field( # Speed at 1s intervals. Timestamp field indicates time of last array element. + 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, @@ -6554,6 +7378,13 @@ scale=10, units='mm', ), + 87: Field( # Supports larger cycle sizes needed for paddlesports. Max cycle size: 655.35 + name='cycle_length16', + type=BASE_TYPES[0x84], # uint16 + def_num=87, + scale=100, + units='m', + ), 91: Field( # Includes atmospheric pressure name='absolute_pressure', type=BASE_TYPES[0x86], # uint32 @@ -6604,19 +7435,130 @@ 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, + 99: Field( + name='respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=99, + units='s', + components=( + ComponentField( + name='enhanced_respiration_rate', + def_num=108, + units='s', + accumulate=False, + bits=8, + bit_offset=0, + ), + ), ), - 1: Field( + 108: Field( + name='enhanced_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=108, + scale=100, + units='Breaths/min', + ), + 114: Field( # The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. + name='grit', + type=BASE_TYPES[0x88], # float32 + def_num=114, + ), + 115: Field( # The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. + name='flow', + type=BASE_TYPES[0x88], # float32 + def_num=115, + ), + 116: Field( # Current Stress value + name='current_stress', + type=BASE_TYPES[0x84], # uint16 + def_num=116, + scale=100, + ), + 117: Field( + name='ebike_travel_range', + type=BASE_TYPES[0x84], # uint16 + def_num=117, + units='km', + ), + 118: Field( + name='ebike_battery_level', + type=BASE_TYPES[0x02], # uint8 + def_num=118, + units='percent', + ), + 119: Field( + name='ebike_assist_mode', + type=BASE_TYPES[0x02], # uint8 + def_num=119, + units='depends on sensor', + ), + 120: Field( + name='ebike_assist_level_percent', + type=BASE_TYPES[0x02], # uint8 + def_num=120, + units='percent', + ), + 123: Field( + name='air_time_remaining', + type=BASE_TYPES[0x86], # uint32 + def_num=123, + units='s', + ), + 124: Field( # Pressure-based surface air consumption + name='pressure_sac', + type=BASE_TYPES[0x84], # uint16 + def_num=124, + scale=100, + units='bar/min', + ), + 125: Field( # Volumetric surface air consumption + name='volume_sac', + type=BASE_TYPES[0x84], # uint16 + def_num=125, + scale=100, + units='L/min', + ), + 126: Field( # Respiratory minute volume + name='rmv', + type=BASE_TYPES[0x84], # uint16 + def_num=126, + scale=100, + units='L/min', + ), + 127: Field( + name='ascent_rate', + type=BASE_TYPES[0x85], # sint32 + def_num=127, + scale=1000, + units='m/s', + ), + 129: Field( # Current partial pressure of oxygen + name='po2', + type=BASE_TYPES[0x02], # uint8 + def_num=129, + scale=100, + units='percent', + ), + 139: Field( + name='core_temperature', + type=BASE_TYPES[0x84], # uint16 + def_num=139, + scale=100, + units='C', + ), + 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, @@ -6640,6 +7582,20 @@ type=BASE_TYPES[0x86], # uint32 def_num=3, subfields=( + SubField( + name='auto_activity_detect_duration', + def_num=3, + type=BASE_TYPES[0x84], # uint16 + units='min', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='auto_activity_detect', + raw_value=54, + ), + ), + ), SubField( name='battery_level', def_num=3, @@ -6738,6 +7694,19 @@ ), ), ), + SubField( + name='dive_alert', + def_num=3, + type=FIELD_TYPES['dive_alert'], + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='dive_alert', + raw_value=56, + ), + ), + ), SubField( name='fitness_equipment_state', def_num=3, @@ -6856,6 +7825,51 @@ ), ), ), + SubField( # The first byte is the radar_threat_level_max, the second byte is the radar_threat_count, third bytes is the average approach speed, and the 4th byte is the max approach speed + name='radar_threat_alert', + def_num=3, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='radar_threat_alert', + raw_value=75, + ), + ), + components=( + ComponentField( + name='radar_threat_level_max', + def_num=21, + accumulate=False, + bits=8, + bit_offset=0, + ), + ComponentField( + name='radar_threat_count', + def_num=22, + accumulate=False, + bits=8, + bit_offset=8, + ), + ComponentField( + name='radar_threat_avg_approach_speed', + def_num=23, + scale=10, + accumulate=False, + bits=8, + bit_offset=16, + ), + ComponentField( + name='radar_threat_max_approach_speed', + def_num=24, + scale=10, + accumulate=False, + bits=8, + bit_offset=24, + ), + ), + ), SubField( # Indicates the rider position value. name='rider_position', def_num=3, @@ -6978,32 +7992,32 @@ type=BASE_TYPES[0x02], # uint8 def_num=4, ), - 7: Field( # Do not populate directly. Autogenerated by decoder for sport_point subfield components + 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 + 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. + 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. + 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. + 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. + 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, @@ -7013,6 +8027,57 @@ type=FIELD_TYPES['device_index'], def_num=13, ), + 14: Field( # Activity Type associated with an auto_activity_detect event + name='activity_type', + type=FIELD_TYPES['activity_type'], + def_num=14, + ), + 15: Field( # Timestamp of when the event started + name='start_timestamp', + type=FIELD_TYPES['date_time'], + def_num=15, + units='s', + subfields=( + SubField( # Auto Activity Detect Start Timestamp. + name='auto_activity_detect_start_timestamp', + def_num=15, + type=FIELD_TYPES['date_time'], + units='s', + ref_fields=( + ReferenceField( + name='event', + def_num=0, + value='auto_activity_detect', + raw_value=54, + ), + ), + ), + ), + ), + 21: Field( # Do not populate directly. Autogenerated by decoder for threat_alert subfield components. + name='radar_threat_level_max', + type=FIELD_TYPES['radar_threat_level_type'], + def_num=21, + ), + 22: Field( # Do not populate directly. Autogenerated by decoder for threat_alert subfield components. + name='radar_threat_count', + type=BASE_TYPES[0x02], # uint8 + def_num=22, + ), + 23: Field( # Do not populate directly. Autogenerated by decoder for radar_threat_alert subfield components + name='radar_threat_avg_approach_speed', + type=BASE_TYPES[0x02], # uint8 + def_num=23, + scale=10, + units='m/s', + ), + 24: Field( # Do not populate directly. Autogenerated by decoder for radar_threat_alert subfield components + name='radar_threat_max_approach_speed', + type=BASE_TYPES[0x02], # uint8 + def_num=24, + scale=10, + units='m/s', + ), 253: FIELD_TYPE_TIMESTAMP, }, ), @@ -7056,6 +8121,32 @@ ), ), ), + SubField( + name='ble_device_type', + def_num=1, + type=FIELD_TYPES['ble_device_type'], + ref_fields=( + ReferenceField( + name='source_type', + def_num=25, + value='bluetooth_low_energy', + raw_value=3, + ), + ), + ), + SubField( + name='local_device_type', + def_num=1, + type=FIELD_TYPES['local_device_type'], + ref_fields=( + ReferenceField( + name='source_type', + def_num=25, + value='local', + raw_value=5, + ), + ), + ), ), ), 2: Field( @@ -7073,6 +8164,19 @@ type=BASE_TYPES[0x84], # uint16 def_num=4, subfields=( + SubField( + name='favero_product', + def_num=4, + type=FIELD_TYPES['favero_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=2, + value='favero_electronics', + raw_value=263, + ), + ), + ), SubField( name='garmin_product', def_num=4, @@ -7096,18 +8200,11 @@ value='dynastream_oem', raw_value=13, ), - ), - ), - SubField( - name='strava_product', - def_num=4, - type=FIELD_TYPES['strava_product'], - ref_fields=( ReferenceField( name='manufacturer', def_num=2, - value='strava', - raw_value=265, + value='tacx', + raw_value=89, ), ), ), @@ -7177,527 +8274,276 @@ type=BASE_TYPES[0x07], # string def_num=27, ), + 32: Field( + name='battery_level', + type=BASE_TYPES[0x02], # uint8 + def_num=32, + units='%', + ), 253: FIELD_TYPE_TIMESTAMP, }, ), - 27: MessageType( - name='workout_step', - mesg_num=27, + 34: MessageType( + name='activity', + mesg_num=34, fields={ - 0: Field( - name='wkt_step_name', - type=BASE_TYPES[0x07], # string + 0: Field( # Exclude pauses + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 def_num=0, + scale=1000, + units='s', ), 1: Field( - name='duration_type', - type=FIELD_TYPES['wkt_step_duration'], + name='num_sessions', + type=BASE_TYPES[0x84], # uint16 def_num=1, ), 2: Field( - name='duration_value', - type=BASE_TYPES[0x86], # uint32 + name='type', + type=FIELD_TYPES['activity'], 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, - ), - ), - ), + ), + 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, + }, + ), + 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='duration_power', + name='favero_product', def_num=2, - type=FIELD_TYPES['workout_power'], - units='% or watts', + type=FIELD_TYPES['favero_product'], ref_fields=( ReferenceField( - name='duration_type', - def_num=1, - value='power_less_than', - raw_value=14, - ), - ReferenceField( - name='duration_type', + name='manufacturer', def_num=1, - value='power_greater_than', - raw_value=15, + value='favero_electronics', + raw_value=263, ), ), ), 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', + name='garmin_product', def_num=2, - type=BASE_TYPES[0x86], # uint32 + type=FIELD_TYPES['garmin_product'], 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', + name='manufacturer', def_num=1, - value='repeat_until_hr_greater_than', - raw_value=11, + value='garmin', + raw_value=1, ), ReferenceField( - name='duration_type', + name='manufacturer', def_num=1, - value='repeat_until_power_less_than', - raw_value=12, + value='dynastream', + raw_value=15, ), ReferenceField( - name='duration_type', + name='manufacturer', def_num=1, - value='repeat_until_power_greater_than', + value='dynastream_oem', 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', + name='manufacturer', def_num=1, - value='repetition_time', - raw_value=28, + value='tacx', + raw_value=89, ), ), ), ), ), 3: Field( - name='target_type', - type=FIELD_TYPES['wkt_step_target'], + name='serial_number', + type=BASE_TYPES[0x8C], # uint32z def_num=3, ), 4: Field( - name='target_value', + name='time_created', + type=FIELD_TYPES['date_time'], + def_num=4, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 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, - 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, - ), - ), - ), - ), + scale=1000, + units='s', ), 5: Field( - name='custom_target_value_low', - type=BASE_TYPES[0x86], # uint32 + name='total_strokes', + type=BASE_TYPES[0x84], # uint16 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, - ), - ), - ), - ), + units='strokes', ), 6: Field( - name='custom_target_value_high', - type=BASE_TYPES[0x86], # uint32 + name='avg_speed', + type=BASE_TYPES[0x84], # uint16 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, - ), - ), - ), - ), + scale=1000, + units='m/s', ), 7: Field( - name='intensity', - type=FIELD_TYPES['intensity'], + name='swim_stroke', + type=FIELD_TYPES['swim_stroke'], def_num=7, - ), - 8: Field( - name='notes', - type=BASE_TYPES[0x07], # string - def_num=8, + units='swim_stroke', ), 9: Field( - name='equipment', - type=FIELD_TYPES['workout_equipment'], + name='avg_swimming_cadence', + type=BASE_TYPES[0x02], # uint8 def_num=9, + units='strokes/min', ), 10: Field( - name='exercise_category', - type=FIELD_TYPES['exercise_category'], + name='event_group', + type=BASE_TYPES[0x02], # uint8 def_num=10, ), 11: Field( - name='exercise_name', + name='total_calories', type=BASE_TYPES[0x84], # uint16 def_num=11, + units='kcal', ), 12: Field( - name='exercise_weight', - type=BASE_TYPES[0x84], # uint16 + 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', + ), + 22: Field( + name='enhanced_avg_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=22, scale=100, - units='kg', + units='Breaths/min', ), - 13: Field( - name='weight_display_unit', - type=FIELD_TYPES['fit_base_unit'], - def_num=13, + 23: Field( + name='enhanced_max_respiration_rate', + type=BASE_TYPES[0x84], # uint16 + def_num=23, + scale=100, + units='Breaths/min', + ), + 24: Field( + name='avg_respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=24, + components=( + ComponentField( + name='enhanced_avg_respiration_rate', + def_num=22, + accumulate=False, + bits=8, + bit_offset=0, + ), + ), + ), + 25: Field( + name='max_respiration_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=25, + components=( + ComponentField( + name='enhanced_max_respiration_rate', + def_num=23, + accumulate=False, + bits=8, + bit_offset=0, + ), + ), ), + 253: FIELD_TYPE_TIMESTAMP, 254: Field( name='message_index', type=FIELD_TYPES['message_index'], @@ -7705,1924 +8551,1482 @@ ), }, ), - 32: MessageType( - name='course_point', - mesg_num=32, + 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='timestamp', - type=FIELD_TYPES['date_time'], + name='temperature', + type=BASE_TYPES[0x01], # sint8 def_num=1, + units='C', ), - 2: Field( - name='position_lat', - type=BASE_TYPES[0x85], # sint32 + 2: Field( # Corresponds to GSC Response weatherIcon field + name='condition', + type=FIELD_TYPES['weather_status'], def_num=2, - units='semicircles', ), 3: Field( - name='position_long', - type=BASE_TYPES[0x85], # sint32 + name='wind_direction', + type=BASE_TYPES[0x84], # uint16 def_num=3, - units='semicircles', + units='degrees', ), 4: Field( - name='distance', - type=BASE_TYPES[0x86], # uint32 + name='wind_speed', + type=BASE_TYPES[0x84], # uint16 def_num=4, - scale=100, - units='m', + scale=1000, + units='m/s', ), - 5: Field( - name='type', - type=FIELD_TYPES['course_point'], + 5: Field( # range 0-100 + name='precipitation_probability', + type=BASE_TYPES[0x02], # uint8 def_num=5, ), - 6: Field( - name='name', - type=BASE_TYPES[0x07], # string + 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', ), - 8: Field( - name='favorite', - type=FIELD_TYPES['bool'], + 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, ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 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 }, ), - 37: MessageType( - name='file_capabilities', - mesg_num=37, + 129: MessageType( + name='weather_alert', + mesg_num=129, fields={ - 0: Field( - name='type', - type=FIELD_TYPES['file'], + 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( - name='flags', - type=FIELD_TYPES['file_flags'], + 1: Field( # Time alert was issued + name='issue_time', + type=FIELD_TYPES['date_time'], def_num=1, ), - 2: Field( - name='directory', - type=BASE_TYPES[0x07], # string + 2: Field( # Time alert expires + name='expire_time', + type=FIELD_TYPES['date_time'], def_num=2, ), - 3: Field( - name='max_count', - type=BASE_TYPES[0x84], # uint16 + 3: Field( # Warning, Watch, Advisory, Statement + name='severity', + type=FIELD_TYPES['weather_severity'], def_num=3, ), - 4: Field( - name='max_size', - type=BASE_TYPES[0x86], # uint32 + 4: Field( # Tornado, Severe Thunderstorm, etc. + name='type', + type=FIELD_TYPES['weather_severe_type'], def_num=4, - units='bytes', - ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 38: MessageType( - name='mesg_capabilities', - mesg_num=38, + 160: MessageType( + name='gps_metadata', + mesg_num=160, fields={ - 0: Field( - name='file', - type=FIELD_TYPES['file'], + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 def_num=0, + units='ms', ), 1: Field( - name='mesg_num', - type=FIELD_TYPES['mesg_num'], + name='position_lat', + type=BASE_TYPES[0x85], # sint32 def_num=1, + units='semicircles', ), 2: Field( - name='count_type', - type=FIELD_TYPES['mesg_count'], + name='position_long', + type=BASE_TYPES[0x85], # sint32 def_num=2, + units='semicircles', ), 3: Field( - name='count', - type=BASE_TYPES[0x84], # uint16 + name='enhanced_altitude', + type=BASE_TYPES[0x86], # uint32 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, - ), - ), - ), - ), + scale=5, + offset=500, + units='m', ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 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. }, ), - 39: MessageType( - name='field_capabilities', - mesg_num=39, + 161: MessageType( + name='camera_event', + mesg_num=161, fields={ - 0: Field( - name='file', - type=FIELD_TYPES['file'], + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 def_num=0, + units='ms', ), 1: Field( - name='mesg_num', - type=FIELD_TYPES['mesg_num'], + name='camera_event_type', + type=FIELD_TYPES['camera_event_type'], def_num=1, ), 2: Field( - name='field_num', - type=BASE_TYPES[0x02], # uint8 + name='camera_file_uuid', + type=BASE_TYPES[0x07], # string def_num=2, ), 3: Field( - name='count', - type=BASE_TYPES[0x84], # uint16 + name='camera_orientation', + type=FIELD_TYPES['camera_orientation_type'], def_num=3, ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, - ), + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp. }, ), - 49: MessageType( - name='file_creator', - mesg_num=49, + 164: MessageType( + name='gyroscope_data', + mesg_num=164, fields={ - 0: Field( - name='software_version', + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', type=BASE_TYPES[0x84], # uint16 def_num=0, + units='ms', ), - 1: Field( - name='hardware_version', - type=BASE_TYPES[0x02], # uint8 + 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', ), - }, - ), - 53: MessageType( - name='speed_zone', - mesg_num=53, - fields={ - 0: Field( - name='high_value', + 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=0, - scale=1000, - units='m/s', + def_num=2, + units='counts', ), - 1: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=1, + 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', ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 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 }, ), - 55: MessageType( - name='monitoring', - mesg_num=55, + 165: MessageType( + name='accelerometer_data', + mesg_num=165, 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'], + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 def_num=0, + units='ms', ), - 1: Field( # Accumulated total calories. Maintained by MonitoringReader for each activity_type. See SDK documentation - name='calories', + 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='kcal', + units='ms', ), - 2: Field( # Accumulated distance. Maintained by MonitoringReader for each activity_type. See SDK documentation. - name='distance', - type=BASE_TYPES[0x86], # uint32 + 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, - scale=100, - units='m', + units='counts', ), - 3: Field( # Accumulated cycles. Maintained by MonitoringReader for each activity_type. See SDK documentation. - name='cycles', - type=BASE_TYPES[0x86], # uint32 + 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, - 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, - ), - ), - ), - ), + units='counts', ), - 4: Field( - name='active_time', - type=BASE_TYPES[0x86], # uint32 + 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, - scale=1000, - units='s', + units='counts', ), - 5: Field( - name='activity_type', - type=FIELD_TYPES['activity_type'], + 5: Field( # Calibrated accel reading + name='calibrated_accel_x', + type=BASE_TYPES[0x88], # float32 def_num=5, + units='g', ), - 6: Field( - name='activity_subtype', - type=FIELD_TYPES['activity_subtype'], + 6: Field( # Calibrated accel reading + name='calibrated_accel_y', + type=BASE_TYPES[0x88], # float32 def_num=6, + units='g', ), - 7: Field( - name='activity_level', - type=FIELD_TYPES['activity_level'], + 7: Field( # Calibrated accel reading + name='calibrated_accel_z', + type=BASE_TYPES[0x88], # float32 def_num=7, + units='g', ), - 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', + 8: Field( # Calibrated accel reading + name='compressed_calibrated_accel_x', type=BASE_TYPES[0x83], # sint16 - def_num=12, - scale=100, - units='C', + def_num=8, + units='mG', ), - 14: Field( # Min temperature during the logging interval ended at timestamp - name='temperature_min', + 9: Field( # Calibrated accel reading + name='compressed_calibrated_accel_y', type=BASE_TYPES[0x83], # sint16 - def_num=14, - scale=100, - units='C', + def_num=9, + units='mG', ), - 15: Field( # Max temperature during the logging interval ended at timestamp - name='temperature_max', + 10: Field( # Calibrated accel reading + name='compressed_calibrated_accel_z', 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', + def_num=10, + units='mG', ), - 253: FIELD_TYPE_TIMESTAMP, # Must align to logging interval, for example, time must be 00:00:00 for daily log. + 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp }, ), - 72: MessageType( # Corresponds to file_id of workout or course. - name='training_file', - mesg_num=72, + 167: MessageType( + name='three_d_sensor_calibration', + mesg_num=167, fields={ - 0: Field( - name='type', - type=FIELD_TYPES['file'], + 0: Field( # Indicates which sensor the calibration is for + name='sensor_type', + type=FIELD_TYPES['sensor_type'], def_num=0, ), - 1: Field( - name='manufacturer', - type=FIELD_TYPES['manufacturer'], + 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, - ), - 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'], + SubField( # Accelerometer calibration factor + name='accel_cal_factor', + def_num=1, + type=BASE_TYPES[0x86], # uint32 + units='g', ref_fields=( ReferenceField( - name='manufacturer', - def_num=1, - value='garmin', - raw_value=1, - ), - ReferenceField( - name='manufacturer', - def_num=1, - value='dynastream', - raw_value=15, + 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='manufacturer', - def_num=1, - value='dynastream_oem', - raw_value=13, + name='sensor_type', + def_num=0, + value='gyroscope', + raw_value=1, ), ), ), ), ), - 3: Field( - name='serial_number', - type=BASE_TYPES[0x8C], # uint32z + 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( - name='time_created', - type=FIELD_TYPES['date_time'], + 4: Field( # Internal calibration factors, one for each: xy, yx, zx + name='offset_cal', + type=BASE_TYPES[0x85], # sint32 def_num=4, ), - 253: FIELD_TYPE_TIMESTAMP, + 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 }, ), - 78: MessageType( # Heart rate variability - name='hrv', - mesg_num=78, + 169: MessageType( + name='video_frame', + mesg_num=169, fields={ - 0: Field( # Time between beats - name='time', + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', type=BASE_TYPES[0x84], # uint16 def_num=0, - scale=1000, - units='s', + 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 }, ), - 80: MessageType( - name='ant_rx', - mesg_num=80, + 174: MessageType( + name='obdii_data', + mesg_num=174, fields={ - 0: Field( - name='fractional_timestamp', + 0: Field( # Fractional part of timestamp, added to timestamp + name='timestamp_ms', type=BASE_TYPES[0x84], # uint16 def_num=0, - scale=32768, - units='s', + units='ms', ), - 1: Field( - name='mesg_id', - type=BASE_TYPES[0x0D], # byte + 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( - name='mesg_data', + 2: Field( # Parameter ID + name='pid', 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 + 3: Field( # Raw parameter data + name='raw_data', + type=BASE_TYPES[0x0D], # byte def_num=3, ), - 4: Field( - name='data', - type=BASE_TYPES[0x0D], # byte + 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, ), - 253: FIELD_TYPE_TIMESTAMP, + 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 }, ), - 81: MessageType( - name='ant_tx', - mesg_num=81, + 177: MessageType( + name='nmea_sentence', + mesg_num=177, fields={ - 0: Field( - name='fractional_timestamp', + 0: Field( # Fractional part of timestamp, added to timestamp + name='timestamp_ms', type=BASE_TYPES[0x84], # uint16 def_num=0, - scale=32768, - units='s', + units='ms', ), - 1: Field( - name='mesg_id', - type=BASE_TYPES[0x0D], # byte + 1: Field( # NMEA sentence + name='sentence', + type=BASE_TYPES[0x07], # string 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, + 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output }, ), - 82: MessageType( - name='ant_channel_id', - mesg_num=82, + 178: MessageType( + name='aviation_attitude', + mesg_num=178, fields={ - 0: Field( - name='channel_number', - type=BASE_TYPES[0x02], # uint8 + 0: Field( # Fractional part of timestamp, added to timestamp + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 def_num=0, + units='ms', ), - 1: Field( - name='device_type', - type=BASE_TYPES[0x0A], # uint8z + 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( - name='device_number', - type=BASE_TYPES[0x8B], # uint16z + 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( - name='transmission_type', - type=BASE_TYPES[0x0A], # uint8z + 3: Field( # Range -PI to +PI + name='roll', + type=BASE_TYPES[0x83], # sint16 def_num=3, + scale=10430.38, + units='radians', ), - 4: Field( - name='device_index', - type=FIELD_TYPES['device_index'], + 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', ), - }, - ), - 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 + 5: Field( # Range -78.4 to +78.4 (-8 Gs to 8 Gs) + name='accel_normal', + type=BASE_TYPES[0x83], # sint16 def_num=5, - units='strokes', + scale=100, + units='m/s^2', ), - 6: Field( - name='avg_speed', - type=BASE_TYPES[0x84], # uint16 + 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=1000, - units='m/s', + scale=1024, + units='radians/second', ), 7: Field( - name='swim_stroke', - type=FIELD_TYPES['swim_stroke'], + name='stage', + type=FIELD_TYPES['attitude_stage'], def_num=7, - units='swim_stroke', ), - 9: Field( - name='avg_swimming_cadence', + 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, - units='strokes/min', + scale=10430.38, + units='radians', ), 10: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 + name='validity', + type=FIELD_TYPES['attitude_validity'], 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, + 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, ), - 18: Field( - name='player_score', - type=BASE_TYPES[0x84], # uint16 - def_num=18, + 1: Field( + name='hosting_provider', + type=BASE_TYPES[0x07], # string + def_num=1, ), - 19: Field( - name='opponent_score', - type=BASE_TYPES[0x84], # uint16 - def_num=19, + 2: Field( # Playback time of video + name='duration', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + units='ms', ), - 20: Field( # stroke_type enum used as the index - name='stroke_count', + }, + ), + 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=20, - units='counts', + def_num=0, ), - 21: Field( # zone number used as the index - name='zone_count', - type=BASE_TYPES[0x84], # uint16 - def_num=21, - units='counts', + 1: Field( + name='text', + type=BASE_TYPES[0x07], # string + def_num=1, ), - 253: FIELD_TYPE_TIMESTAMP, - 254: Field( + 254: Field( # Long titles will be split into multiple parts name='message_index', type=FIELD_TYPES['message_index'], def_num=254, ), }, ), - 106: MessageType( - name='slave_device', - mesg_num=106, + 186: MessageType( + name='video_description', + mesg_num=186, fields={ - 0: Field( - name='manufacturer', - type=FIELD_TYPES['manufacturer'], + 0: Field( # Total number of description parts + name='message_count', + type=BASE_TYPES[0x84], # uint16 def_num=0, ), 1: Field( - name='product', - type=BASE_TYPES[0x84], # uint16 + name='text', + type=BASE_TYPES[0x07], # string 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, - ), - ), - ), - SubField( - name='strava_product', - def_num=1, - type=FIELD_TYPES['strava_product'], - ref_fields=( - ReferenceField( - name='manufacturer', - def_num=0, - value='strava', - raw_value=265, - ), - ), - ), - ), + ), + 254: Field( # Long descriptions will be split into multiple parts + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, ), }, ), - 127: MessageType( - name='connectivity', - mesg_num=127, + 187: MessageType( + name='video_clip', + mesg_num=187, fields={ - 0: Field( # Use Bluetooth for connectivity features - name='bluetooth_enabled', - type=FIELD_TYPES['bool'], + 0: Field( + name='clip_number', + type=BASE_TYPES[0x84], # uint16 def_num=0, ), - 1: Field( # Use Bluetooth Low Energy for connectivity features - name='bluetooth_le_enabled', - type=FIELD_TYPES['bool'], + 1: Field( + name='start_timestamp', + type=FIELD_TYPES['date_time'], def_num=1, ), - 2: Field( # Use ANT for connectivity features - name='ant_enabled', - type=FIELD_TYPES['bool'], + 2: Field( + name='start_timestamp_ms', + type=BASE_TYPES[0x84], # uint16 def_num=2, ), 3: Field( - name='name', - type=BASE_TYPES[0x07], # string + name='end_timestamp', + type=FIELD_TYPES['date_time'], def_num=3, ), 4: Field( - name='live_tracking_enabled', - type=FIELD_TYPES['bool'], + name='end_timestamp_ms', + type=BASE_TYPES[0x84], # uint16 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'], + 6: Field( # Start of clip in video time + name='clip_start', + type=BASE_TYPES[0x86], # uint32 def_num=6, + units='ms', ), - 7: Field( - name='auto_activity_upload_enabled', - type=FIELD_TYPES['bool'], + 7: Field( # End of clip in video time + name='clip_end', + type=BASE_TYPES[0x86], # uint32 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, + units='ms', ), }, ), - 128: MessageType( - name='weather_conditions', - mesg_num=128, + 206: MessageType( # Must be logged before developer field is used + name='field_description', + mesg_num=206, fields={ - 0: Field( # Current or forecast - name='weather_report', - type=FIELD_TYPES['weather_report'], + 0: Field( + name='developer_data_index', + type=BASE_TYPES[0x02], # uint8 def_num=0, ), 1: Field( - name='temperature', - type=BASE_TYPES[0x01], # sint8 + name='field_definition_number', + type=BASE_TYPES[0x02], # uint8 def_num=1, - units='C', ), - 2: Field( # Corresponds to GSC Response weatherIcon field - name='condition', - type=FIELD_TYPES['weather_status'], + 2: Field( + name='fit_base_type_id', + type=FIELD_TYPES['fit_base_type'], def_num=2, ), 3: Field( - name='wind_direction', - type=BASE_TYPES[0x84], # uint16 + name='field_name', + type=BASE_TYPES[0x07], # string def_num=3, - units='degrees', ), 4: Field( - name='wind_speed', - type=BASE_TYPES[0x84], # uint16 + name='array', + type=BASE_TYPES[0x02], # uint8 def_num=4, - scale=1000, - units='m/s', ), - 5: Field( # range 0-100 - name='precipitation_probability', - type=BASE_TYPES[0x02], # uint8 + 5: Field( + name='components', + type=BASE_TYPES[0x07], # string 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 + 6: Field( + name='scale', + type=BASE_TYPES[0x02], # uint8 def_num=6, - units='C', ), 7: Field( - name='relative_humidity', - type=BASE_TYPES[0x02], # uint8 + name='offset', + type=BASE_TYPES[0x01], # sint8 def_num=7, ), - 8: Field( # string corresponding to GCS response location string - name='location', + 8: Field( + name='units', type=BASE_TYPES[0x07], # string def_num=8, ), 9: Field( - name='observed_at_time', - type=FIELD_TYPES['date_time'], + name='bits', + type=BASE_TYPES[0x07], # string def_num=9, ), 10: Field( - name='observed_location_lat', - type=BASE_TYPES[0x85], # sint32 + name='accumulate', + type=BASE_TYPES[0x07], # string 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 + name='fit_base_unit_id', + type=FIELD_TYPES['fit_base_unit'], def_num=13, - units='C', ), 14: Field( - name='low_temperature', - type=BASE_TYPES[0x01], # sint8 + name='native_mesg_num', + type=FIELD_TYPES['mesg_num'], def_num=14, - units='C', ), - 253: FIELD_TYPE_TIMESTAMP, # time of update for current conditions, else forecast time + 15: Field( + name='native_field_num', + type=BASE_TYPES[0x02], # uint8 + def_num=15, + ), }, ), - 129: MessageType( - name='weather_alert', - mesg_num=129, + 207: MessageType( # Must be logged before field description + name='developer_data_id', + mesg_num=207, fields={ - 0: Field( # Unique identifier from GCS report ID string, length is 12 - name='report_id', - type=BASE_TYPES[0x07], # string + 0: Field( + name='developer_id', + type=BASE_TYPES[0x0D], # byte def_num=0, ), - 1: Field( # Time alert was issued - name='issue_time', - type=FIELD_TYPES['date_time'], + 1: Field( + name='application_id', + type=BASE_TYPES[0x0D], # byte def_num=1, ), - 2: Field( # Time alert expires - name='expire_time', - type=FIELD_TYPES['date_time'], + 2: Field( + name='manufacturer_id', + type=FIELD_TYPES['manufacturer'], def_num=2, ), - 3: Field( # Warning, Watch, Advisory, Statement - name='severity', - type=FIELD_TYPES['weather_severity'], + 3: Field( + name='developer_data_index', + type=BASE_TYPES[0x02], # uint8 def_num=3, ), - 4: Field( # Tornado, Severe Thunderstorm, etc. - name='type', - type=FIELD_TYPES['weather_severe_type'], + 4: Field( + name='application_version', + type=BASE_TYPES[0x86], # uint32 def_num=4, ), - 253: FIELD_TYPE_TIMESTAMP, }, ), - 131: MessageType( - name='cadence_zone', - mesg_num=131, + 208: MessageType( + name='magnetometer_data', + mesg_num=208, fields={ - 0: Field( - name='high_value', - type=BASE_TYPES[0x02], # uint8 + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', + type=BASE_TYPES[0x84], # uint16 def_num=0, - units='rpm', + units='ms', ), - 1: Field( - name='name', - type=BASE_TYPES[0x07], # string + 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', ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 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 }, ), - 132: MessageType( - name='hr', - mesg_num=132, + 209: MessageType( + name='barometer_data', + mesg_num=209, fields={ - 0: Field( - name='fractional_timestamp', + 0: Field( # Millisecond part of the timestamp. + name='timestamp_ms', type=BASE_TYPES[0x84], # uint16 def_num=0, - scale=32768, - units='s', + units='ms', ), - 1: Field( - name='time256', - type=BASE_TYPES[0x02], # uint8 + 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, - scale=256, - units='s', - 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', + units='ms', ), - 9: Field( - name='event_timestamp', + 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=9, - scale=1024, - units='s', + def_num=2, + units='Pa', ), - 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, # 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, + ), + ), ), ), ), - 253: FIELD_TYPE_TIMESTAMP, + 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 }, ), - 142: MessageType( - name='segment_lap', - mesg_num=142, + 225: MessageType( + name='set', + mesg_num=225, fields={ 0: Field( - name='event', - type=FIELD_TYPES['event'], + 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, + ), + }, + ), + 285: MessageType( + name='jump', + mesg_num=285, + fields={ + 0: Field( + name='distance', + type=BASE_TYPES[0x88], # float32 def_num=0, + units='m', ), 1: Field( - name='event_type', - type=FIELD_TYPES['event_type'], + name='height', + type=BASE_TYPES[0x88], # float32 def_num=1, + units='m', ), 2: Field( - name='start_time', - type=FIELD_TYPES['date_time'], + name='rotations', + type=BASE_TYPES[0x02], # uint8 def_num=2, ), 3: Field( - name='start_position_lat', - type=BASE_TYPES[0x85], # sint32 + name='hang_time', + type=BASE_TYPES[0x88], # float32 def_num=3, - units='semicircles', + units='s', ), - 4: Field( - name='start_position_long', - type=BASE_TYPES[0x85], # sint32 + 4: Field( # A score for a jump calculated based on hang time, rotations, and distance. + name='score', + type=BASE_TYPES[0x88], # float32 def_num=4, - units='semicircles', ), 5: Field( - name='end_position_lat', + name='position_lat', type=BASE_TYPES[0x85], # sint32 def_num=5, units='semicircles', ), 6: Field( - name='end_position_long', + name='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 + 7: Field( + name='speed', + type=BASE_TYPES[0x84], # uint16 def_num=7, scale=1000, - units='s', + units='m/s', + components=( + ComponentField( + name='enhanced_speed', + def_num=8, + scale=1000, + units='m/s', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), ), - 8: Field( # Timer Time (excludes pauses) - name='total_timer_time', + 8: Field( + name='enhanced_speed', type=BASE_TYPES[0x86], # uint32 def_num=8, scale=1000, + units='m/s', + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 312: MessageType( + name='split', + mesg_num=312, + fields={ + 0: Field( + name='split_type', + type=FIELD_TYPES['split_type'], + def_num=0, + ), + 1: Field( + name='total_elapsed_time', + type=BASE_TYPES[0x86], # uint32 + def_num=1, + scale=1000, units='s', ), - 9: Field( + 2: Field( + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + scale=1000, + units='s', + ), + 3: Field( name='total_distance', type=BASE_TYPES[0x86], # uint32 - def_num=9, + def_num=3, scale=100, units='m', ), - 10: Field( - name='total_cycles', + 4: Field( + name='avg_speed', 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', + def_num=4, + scale=1000, + units='m/s', ), - 12: Field( # If New Leaf - name='total_fat_calories', - type=BASE_TYPES[0x84], # uint16 - def_num=12, - units='kcal', + 9: Field( + name='start_time', + type=FIELD_TYPES['date_time'], + def_num=9, ), 13: Field( - name='avg_speed', + name='total_ascent', type=BASE_TYPES[0x84], # uint16 def_num=13, - scale=1000, - units='m/s', + units='m', ), 14: Field( - name='max_speed', + name='total_descent', 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', + units='m', ), 21: Field( - name='total_ascent', - type=BASE_TYPES[0x84], # uint16 + name='start_position_lat', + type=BASE_TYPES[0x85], # sint32 def_num=21, - units='m', + units='semicircles', ), 22: Field( - name='total_descent', - type=BASE_TYPES[0x84], # uint16 + name='start_position_long', + type=BASE_TYPES[0x85], # sint32 def_num=22, - units='m', + units='semicircles', ), 23: Field( - name='sport', - type=FIELD_TYPES['sport'], + name='end_position_lat', + type=BASE_TYPES[0x85], # sint32 def_num=23, + units='semicircles', ), 24: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 + name='end_position_long', + type=BASE_TYPES[0x85], # sint32 def_num=24, + units='semicircles', ), - 25: Field( # North east corner latitude. - name='nec_lat', - type=BASE_TYPES[0x85], # sint32 + 25: Field( + name='max_speed', + type=BASE_TYPES[0x86], # uint32 def_num=25, - units='semicircles', + scale=1000, + units='m/s', ), - 26: Field( # North east corner longitude. - name='nec_long', + 26: Field( + name='avg_vert_speed', type=BASE_TYPES[0x85], # sint32 def_num=26, - units='semicircles', + scale=1000, + units='m/s', ), - 27: Field( # South west corner latitude. - name='swc_lat', - type=BASE_TYPES[0x85], # sint32 + 27: Field( + name='end_time', + type=FIELD_TYPES['date_time'], def_num=27, - units='semicircles', ), - 28: Field( # South west corner latitude. - name='swc_long', - type=BASE_TYPES[0x85], # sint32 + 28: Field( + name='total_calories', + type=BASE_TYPES[0x86], # uint32 def_num=28, - units='semicircles', + units='kcal', ), - 29: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=29, + 74: Field( + name='start_elevation', + type=BASE_TYPES[0x86], # uint32 + def_num=74, + scale=5, + offset=500, + units='m', ), - 30: Field( - name='normalized_power', + 110: Field( + name='total_moving_time', + type=BASE_TYPES[0x86], # uint32 + def_num=110, + scale=1000, + units='s', + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 313: MessageType( + name='split_summary', + mesg_num=313, + fields={ + 0: Field( + name='split_type', + type=FIELD_TYPES['split_type'], + def_num=0, + ), + 3: Field( + name='num_splits', type=BASE_TYPES[0x84], # uint16 - def_num=30, - units='watts', + def_num=3, ), - 31: Field( - name='left_right_balance', - type=FIELD_TYPES['left_right_balance_100'], - def_num=31, + 4: Field( + name='total_timer_time', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + scale=1000, + units='s', ), - 32: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], - def_num=32, + 5: Field( + name='total_distance', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + scale=100, + units='m', ), - 33: Field( - name='total_work', + 6: Field( + name='avg_speed', type=BASE_TYPES[0x86], # uint32 - def_num=33, - units='J', + def_num=6, + scale=1000, + units='m/s', ), - 34: Field( - name='avg_altitude', + 7: Field( + name='max_speed', + type=BASE_TYPES[0x86], # uint32 + def_num=7, + scale=1000, + units='m/s', + ), + 8: Field( + name='total_ascent', type=BASE_TYPES[0x84], # uint16 - def_num=34, - scale=5, - offset=500, + def_num=8, units='m', ), - 35: Field( - name='max_altitude', + 9: Field( + name='total_descent', type=BASE_TYPES[0x84], # uint16 - def_num=35, - scale=5, - offset=500, + def_num=9, units='m', ), - 36: Field( - name='gps_accuracy', + 10: Field( + name='avg_heart_rate', type=BASE_TYPES[0x02], # uint8 - def_num=36, - units='m', + def_num=10, + units='bpm', ), - 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='%', + 11: Field( + name='max_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=11, + units='bpm', ), - 42: Field( - name='avg_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=42, - units='C', + 12: Field( + name='avg_vert_speed', + type=BASE_TYPES[0x85], # sint32 + def_num=12, + scale=1000, + units='m/s', ), - 43: Field( - name='max_temperature', - type=BASE_TYPES[0x01], # sint8 - def_num=43, - units='C', + 13: Field( + name='total_calories', + type=BASE_TYPES[0x86], # uint32 + def_num=13, + units='kcal', ), - 44: Field( + 77: Field( name='total_moving_time', type=BASE_TYPES[0x86], # uint32 - def_num=44, + def_num=77, scale=1000, units='s', ), - 45: Field( - name='avg_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=45, - scale=1000, - units='m/s', + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, ), - 46: Field( - name='avg_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=46, - scale=1000, - units='m/s', + }, + ), + 317: MessageType( + name='climb_pro', + mesg_num=317, + fields={ + 0: Field( + name='position_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=0, + units='semicircles', ), - 47: Field( - name='max_pos_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=47, - scale=1000, - units='m/s', + 1: Field( + name='position_long', + type=BASE_TYPES[0x85], # sint32 + def_num=1, + units='semicircles', ), - 48: Field( - name='max_neg_vertical_speed', - type=BASE_TYPES[0x83], # sint16 - def_num=48, - scale=1000, - units='m/s', + 2: Field( + name='climb_pro_event', + type=FIELD_TYPES['climb_pro_event'], + def_num=2, ), - 49: Field( - name='time_in_hr_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=49, - scale=1000, - units='s', + 3: Field( + name='climb_number', + type=BASE_TYPES[0x84], # uint16 + def_num=3, ), - 50: Field( - name='time_in_speed_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=50, - scale=1000, - units='s', + 4: Field( + name='climb_category', + type=BASE_TYPES[0x02], # uint8 + def_num=4, ), - 51: Field( - name='time_in_cadence_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=51, - scale=1000, - units='s', + 5: Field( + name='current_dist', + type=BASE_TYPES[0x88], # float32 + def_num=5, + units='m', ), - 52: Field( - name='time_in_power_zone', - type=BASE_TYPES[0x86], # uint32 - def_num=52, - scale=1000, - units='s', + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 375: MessageType( + name='device_aux_battery_info', + mesg_num=375, + fields={ + 0: Field( + name='device_index', + type=FIELD_TYPES['device_index'], + def_num=0, ), - 53: Field( - name='repetition_num', + 1: Field( + name='battery_voltage', type=BASE_TYPES[0x84], # uint16 - def_num=53, + def_num=1, + scale=256, + units='V', ), - 54: Field( - name='min_altitude', - type=BASE_TYPES[0x84], # uint16 - def_num=54, - scale=5, - offset=500, - units='m', + 2: Field( + name='battery_status', + type=FIELD_TYPES['battery_status'], + def_num=2, ), - 55: Field( - name='min_heart_rate', + 3: Field( + name='battery_identifier', type=BASE_TYPES[0x02], # uint8 - def_num=55, - units='bpm', + def_num=3, ), - 56: Field( - name='active_time', - type=BASE_TYPES[0x86], # uint32 - def_num=56, - scale=1000, - units='s', + 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', ), - 57: Field( - name='wkt_step_index', - type=FIELD_TYPES['message_index'], - def_num=57, + 1: Field( + name='diastolic_pressure', + type=BASE_TYPES[0x84], # uint16 + def_num=1, + units='mmHg', ), - 58: Field( - name='sport_event', - type=FIELD_TYPES['sport_event'], - def_num=58, + 2: Field( + name='mean_arterial_pressure', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + units='mmHg', ), - 59: Field( - name='avg_left_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=59, - scale=2, - units='percent', + 3: Field( + name='map_3_sample_mean', + type=BASE_TYPES[0x84], # uint16 + def_num=3, + units='mmHg', ), - 60: Field( - name='avg_right_torque_effectiveness', - type=BASE_TYPES[0x02], # uint8 - def_num=60, - scale=2, - units='percent', + 4: Field( + name='map_morning_values', + type=BASE_TYPES[0x84], # uint16 + def_num=4, + units='mmHg', ), - 61: Field( - name='avg_left_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=61, - scale=2, - units='percent', + 5: Field( + name='map_evening_values', + type=BASE_TYPES[0x84], # uint16 + def_num=5, + units='mmHg', ), - 62: Field( - name='avg_right_pedal_smoothness', + 6: Field( + name='heart_rate', type=BASE_TYPES[0x02], # uint8 - def_num=62, - scale=2, - units='percent', + def_num=6, + units='bpm', ), - 63: Field( - name='avg_combined_pedal_smoothness', - type=BASE_TYPES[0x02], # uint8 - def_num=63, - scale=2, - units='percent', + 7: Field( + name='heart_rate_type', + type=FIELD_TYPES['hr_type'], + def_num=7, ), - 64: Field( + 8: 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, + type=FIELD_TYPES['bp_status'], + def_num=8, ), - 253: FIELD_TYPE_TIMESTAMP, # Lap end time. - 254: Field( - name='message_index', + 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=254, + def_num=9, ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 149: MessageType( # Unique Identification data for an individual segment leader within a segment file - name='segment_leaderboard_entry', - mesg_num=149, + + + # ************************** Course File Messages ************************** + 31: MessageType( + name='course', + mesg_num=31, 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 + 4: Field( + name='sport', + type=FIELD_TYPES['sport'], 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', + 5: Field( + name='name', type=BASE_TYPES[0x07], # string def_num=5, ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 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, ), }, ), - 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, + 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=1, + def_num=2, units='semicircles', ), - 2: Field( + 3: Field( name='position_long', type=BASE_TYPES[0x85], # sint32 - def_num=2, + def_num=3, units='semicircles', ), - 3: Field( # Accumulated distance along the segment at the described point + 4: Field( 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, + scale=100, 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 + 5: Field( + name='type', + type=FIELD_TYPES['course_point'], def_num=5, - scale=1000, - units='s', + ), + 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', @@ -9631,41 +10035,86 @@ ), }, ), - 158: MessageType( - name='workout_session', - mesg_num=158, + + + # ************************** Device File Messages ************************** + 1: MessageType( + name='capabilities', + mesg_num=1, fields={ - 0: Field( - name='sport', - type=FIELD_TYPES['sport'], + 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( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], + 1: Field( # Use sport_bits_x types where x is index of array. + name='sports', + type=FIELD_TYPES['sport_bits_0'], def_num=1, ), - 2: Field( - name='num_valid_steps', + 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, + ), + }, + ), + 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, + ), + }, + ), + 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='first_step_index', + name='max_count', type=BASE_TYPES[0x84], # uint16 def_num=3, ), 4: Field( - name='pool_length', - type=BASE_TYPES[0x84], # uint16 + name='max_size', + type=BASE_TYPES[0x86], # uint32 def_num=4, - scale=100, - units='m', - ), - 5: Field( - name='pool_length_unit', - type=FIELD_TYPES['display_measure'], - def_num=5, + units='bytes', ), 254: Field( name='message_index', @@ -9674,42 +10123,65 @@ ), }, ), - 159: MessageType( - name='watchface_settings', - mesg_num=159, + 38: MessageType( + name='mesg_capabilities', + mesg_num=38, fields={ 0: Field( - name='mode', - type=FIELD_TYPES['watchface_mode'], + name='file', + type=FIELD_TYPES['file'], def_num=0, ), 1: Field( - name='layout', - type=BASE_TYPES[0x0D], # byte + 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='analog_layout', - def_num=1, - type=FIELD_TYPES['analog_watchface_layout'], + name='max_per_file', + def_num=3, + type=BASE_TYPES[0x84], # uint16 ref_fields=( ReferenceField( - name='mode', - def_num=0, - value='analog', + name='count_type', + def_num=2, + value='max_per_file', raw_value=1, ), ), ), SubField( - name='digital_layout', - def_num=1, - type=FIELD_TYPES['digital_watchface_layout'], + name='max_per_file_type', + def_num=3, + type=BASE_TYPES[0x84], # uint16 ref_fields=( ReferenceField( - name='mode', - def_num=0, - value='digital', + 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, ), ), @@ -9723,2306 +10195,4786 @@ ), }, ), - 160: MessageType( - name='gps_metadata', - mesg_num=160, + 39: MessageType( + name='field_capabilities', + mesg_num=39, fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 + 0: Field( + name='file', + type=FIELD_TYPES['file'], def_num=0, - units='ms', ), 1: Field( - name='position_lat', - type=BASE_TYPES[0x85], # sint32 + name='mesg_num', + type=FIELD_TYPES['mesg_num'], def_num=1, - units='semicircles', ), 2: Field( - name='position_long', - type=BASE_TYPES[0x85], # sint32 + name='field_num', + type=BASE_TYPES[0x02], # uint8 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', + name='count', 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', + def_num=3, ), - 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', + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp. }, ), - 161: MessageType( - name='camera_event', - mesg_num=161, + 106: MessageType( + name='slave_device', + mesg_num=106, fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 + 0: Field( + name='manufacturer', + type=FIELD_TYPES['manufacturer'], 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', + name='product', 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', + subfields=( + SubField( + name='favero_product', + def_num=1, + type=FIELD_TYPES['favero_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=0, + value='favero_electronics', + raw_value=263, + ), + ), + ), + 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, + ), + ReferenceField( + name='manufacturer', + def_num=0, + value='tacx', + raw_value=89, + ), + ), + ), + ), ), - 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, + + + # ************************** Goals File Messages *************************** + 15: MessageType( + name='goal', + mesg_num=15, fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 + 0: Field( + name='sport', + type=FIELD_TYPES['sport'], 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 + 1: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], 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 + 2: Field( + name='start_date', + type=FIELD_TYPES['date_time'], 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 + 3: Field( + name='end_date', + type=FIELD_TYPES['date_time'], 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 + 4: Field( + name='type', + type=FIELD_TYPES['goal'], def_num=4, - units='counts', ), - 5: Field( # Calibrated gyro reading - name='calibrated_gyro_x', - type=BASE_TYPES[0x88], # float32 + 5: Field( + name='value', + type=BASE_TYPES[0x86], # uint32 def_num=5, - units='deg/s', ), - 6: Field( # Calibrated gyro reading - name='calibrated_gyro_y', - type=BASE_TYPES[0x88], # float32 + 6: Field( + name='repeat', + type=FIELD_TYPES['bool'], def_num=6, - units='deg/s', ), - 7: Field( # Calibrated gyro reading - name='calibrated_gyro_z', - type=BASE_TYPES[0x88], # float32 + 7: Field( + name='target_value', + type=BASE_TYPES[0x86], # uint32 def_num=7, - units='deg/s', ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + 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, + ), }, ), - 165: MessageType( - name='accelerometer_data', - mesg_num=165, + + + # ************************ Monitoring File Messages ************************ + 55: MessageType( + name='monitoring', + mesg_num=55, fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 + 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, - 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', + 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='ms', + units='kcal', ), - 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 + 2: Field( # Accumulated distance. Maintained by MonitoringReader for each activity_type. See SDK documentation. + name='distance', + type=BASE_TYPES[0x86], # uint32 def_num=2, - units='counts', + scale=100, + units='m', ), - 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 + 3: Field( # Accumulated cycles. Maintained by MonitoringReader for each activity_type. See SDK documentation. + name='cycles', + type=BASE_TYPES[0x86], # uint32 def_num=3, - units='counts', + 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( # 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 + 4: Field( + name='active_time', + type=BASE_TYPES[0x86], # uint32 def_num=4, - units='counts', + scale=1000, + units='s', ), - 5: Field( # Calibrated accel reading - name='calibrated_accel_x', - type=BASE_TYPES[0x88], # float32 + 5: Field( + name='activity_type', + type=FIELD_TYPES['activity_type'], def_num=5, - units='g', ), - 6: Field( # Calibrated accel reading - name='calibrated_accel_y', - type=BASE_TYPES[0x88], # float32 + 6: Field( + name='activity_subtype', + type=FIELD_TYPES['activity_subtype'], def_num=6, - units='g', ), - 7: Field( # Calibrated accel reading - name='calibrated_accel_z', - type=BASE_TYPES[0x88], # float32 + 7: Field( + name='activity_level', + type=FIELD_TYPES['activity_level'], def_num=7, - units='g', ), - 8: Field( # Calibrated accel reading - name='compressed_calibrated_accel_x', - type=BASE_TYPES[0x83], # sint16 + 8: Field( + name='distance_16', + type=BASE_TYPES[0x84], # uint16 def_num=8, - units='mG', + units='100*m', ), - 9: Field( # Calibrated accel reading - name='compressed_calibrated_accel_y', - type=BASE_TYPES[0x83], # sint16 + 9: Field( + name='cycles_16', + type=BASE_TYPES[0x84], # uint16 def_num=9, - units='mG', + units='2*cycles or steps', ), - 10: Field( # Calibrated accel reading - name='compressed_calibrated_accel_z', - type=BASE_TYPES[0x83], # sint16 + 10: Field( + name='active_time_16', + type=BASE_TYPES[0x84], # uint16 def_num=10, - units='mG', + units='s', ), - 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, + 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, ), - 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, - ), - ), + 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, ), - 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, - ), - ), + ComponentField( + name='intensity', + def_num=28, + accumulate=False, + bits=3, + bit_offset=5, ), ), ), - 2: Field( # Calibration factor divisor - name='calibration_divisor', - type=BASE_TYPES[0x86], # uint32 - def_num=2, - units='counts', + 25: Field( + name='timestamp_min_8', + type=BASE_TYPES[0x02], # uint8 + def_num=25, + units='min', ), - 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, + 26: Field( + name='timestamp_16', + type=BASE_TYPES[0x84], # uint16 + def_num=26, + units='s', ), - 4: Field( # Internal calibration factors, one for each: xy, yx, zx - name='offset_cal', - type=BASE_TYPES[0x85], # sint32 - def_num=4, + 27: Field( + name='heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=27, + units='bpm', ), - 5: Field( # 3 x 3 rotation matrix (row major) - name='orientation_matrix', - type=BASE_TYPES[0x85], # sint32 - def_num=5, - scale=65535, + 28: Field( + name='intensity', + type=BASE_TYPES[0x02], # uint8 + def_num=28, + scale=10, ), - 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', + 29: Field( + name='duration_min', type=BASE_TYPES[0x84], # uint16 - def_num=0, - units='ms', + def_num=29, + units='min', ), - 1: Field( # Number of the frame that the timestamp and timestamp_ms correlate to - name='frame_number', + 30: Field( + name='duration', type=BASE_TYPES[0x86], # uint32 - def_num=1, + def_num=30, + units='s', ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp + 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. }, ), - 174: MessageType( - name='obdii_data', - mesg_num=174, + 103: MessageType( + name='monitoring_info', + mesg_num=103, fields={ - 0: Field( # Fractional part of timestamp, added to timestamp - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 + 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='ms', + units='s', ), - 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 + 1: Field( + name='activity_type', + type=FIELD_TYPES['activity_type'], 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 + 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( # Optional, data size of PID[i]. If not specified refer to SAE J1979. - name='pid_data_size', - type=BASE_TYPES[0x02], # uint8 + 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( # 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', + 5: Field( + name='resting_metabolic_rate', type=BASE_TYPES[0x84], # uint16 - def_num=7, - units='ms', + def_num=5, + units='kcal/day', ), - 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output + 253: FIELD_TYPE_TIMESTAMP, }, ), - 177: MessageType( - name='nmea_sentence', - mesg_num=177, + 132: MessageType( + name='hr', + mesg_num=132, fields={ - 0: Field( # Fractional part of timestamp, added to timestamp - name='timestamp_ms', + 0: Field( + name='fractional_timestamp', type=BASE_TYPES[0x84], # uint16 def_num=0, - units='ms', + scale=32768, + units='s', ), - 1: Field( # NMEA sentence - name='sentence', - type=BASE_TYPES[0x07], # string + 1: Field( + name='time256', + type=BASE_TYPES[0x02], # uint8 def_num=1, + scale=256, + units='s', + components=( + ComponentField( + name='fractional_timestamp', + def_num=0, + scale=256, + units='s', + accumulate=False, + bits=8, + bit_offset=0, + ), + ), ), - 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output + 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, }, ), - 178: MessageType( - name='aviation_attitude', - mesg_num=178, + 211: MessageType( + name='monitoring_hr_data', + mesg_num=211, fields={ - 0: Field( # Fractional part of timestamp, added to timestamp - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 + 0: Field( # 7-day rolling average + name='resting_heart_rate', + type=BASE_TYPES[0x02], # uint8 def_num=0, - units='ms', + units='bpm', ), - 1: Field( # System time associated with sample expressed in ms. - name='system_time', - type=BASE_TYPES[0x86], # uint32 + 1: Field( # RHR for today only. (Feeds into 7-day average) + name='current_day_resting_heart_rate', + type=BASE_TYPES[0x02], # uint8 def_num=1, - units='ms', + units='bpm', ), - 2: Field( # Range -PI/2 to +PI/2 - name='pitch', + 253: FIELD_TYPE_TIMESTAMP, # Must align to logging interval, for example, time must be 00:00:00 for daily log. + }, + ), + 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=2, - scale=10430.38, - units='radians', + def_num=0, ), - 3: Field( # Range -PI to +PI - name='roll', - type=BASE_TYPES[0x83], # sint16 - def_num=3, - scale=10430.38, - units='radians', + 1: Field( # Time stress score was calculated + name='stress_level_time', + type=FIELD_TYPES['date_time'], + def_num=1, + units='s', ), - 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', + }, + ), + 229: MessageType( + name='max_met_data', + mesg_num=229, + fields={ + 0: Field( # Time maxMET and vo2 were calculated + name='update_time', + type=FIELD_TYPES['date_time'], + def_num=0, ), - 5: Field( # Range -78.4 to +78.4 (-8 Gs to 8 Gs) - name='accel_normal', - type=BASE_TYPES[0x83], # sint16 + 2: Field( + name='vo2_max', + type=BASE_TYPES[0x84], # uint16 + def_num=2, + scale=10, + units='mL/kg/min', + ), + 5: Field( + name='sport', + type=FIELD_TYPES['sport'], 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 + 6: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], 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 + 8: Field( + name='max_met_category', + type=FIELD_TYPES['max_met_category'], def_num=8, - units='%', ), - 9: Field( # Track Angle/Heading Range 0 - 2pi - name='track', - type=BASE_TYPES[0x84], # uint16 + 9: Field( # Indicates if calibrated data was used in the calculation + name='calibrated_data', + type=FIELD_TYPES['bool'], def_num=9, - scale=10430.38, - units='radians', ), - 10: Field( - name='validity', - type=FIELD_TYPES['attitude_validity'], - def_num=10, + 12: Field( # Indicates if the estimate was obtained using a chest strap or wrist heart rate + name='hr_source', + type=FIELD_TYPES['max_met_heart_rate_source'], + def_num=12, + ), + 13: Field( # Indidcates if the estimate was obtained using onboard GPS or connected GPS + name='speed_source', + type=FIELD_TYPES['max_met_speed_source'], + def_num=13, ), - 253: FIELD_TYPE_TIMESTAMP, # Timestamp message was output }, ), - 184: MessageType( - name='video', - mesg_num=184, + 269: MessageType( + name='spo2_data', + mesg_num=269, fields={ 0: Field( - name='url', - type=BASE_TYPES[0x07], # string + name='reading_spo2', + type=BASE_TYPES[0x02], # uint8 def_num=0, + units='percent', ), 1: Field( - name='hosting_provider', - type=BASE_TYPES[0x07], # string + name='reading_confidence', + type=BASE_TYPES[0x02], # uint8 def_num=1, ), - 2: Field( # Playback time of video - name='duration', - type=BASE_TYPES[0x86], # uint32 + 2: Field( # Mode when data was captured + name='mode', + type=FIELD_TYPES['spo2_measurement_type'], 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, ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 186: MessageType( - name='video_description', - mesg_num=186, + + + # ***************************** Other Messages ***************************** + 78: MessageType( # Heart rate variability + name='hrv', + mesg_num=78, fields={ - 0: Field( # Total number of description parts - name='message_count', + 0: Field( # Time between beats + name='time', 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, + scale=1000, + units='s', ), }, ), - 187: MessageType( - name='video_clip', - mesg_num=187, + 80: MessageType( + name='ant_rx', + mesg_num=80, fields={ 0: Field( - name='clip_number', + name='fractional_timestamp', type=BASE_TYPES[0x84], # uint16 def_num=0, + scale=32768, + units='s', ), 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 + name='mesg_id', + type=BASE_TYPES[0x0D], # byte 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', + name='mesg_data', type=BASE_TYPES[0x0D], # byte - def_num=1, + def_num=2, components=( ComponentField( - name='field_id', - def_num=2, + name='channel_number', + def_num=3, accumulate=False, - bits=4, + bits=8, bit_offset=0, ), ComponentField( - name='concept_count', - def_num=3, + name='data', + def_num=4, accumulate=False, - bits=4, - bit_offset=4, + 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, ), ), ), - 2: Field( - name='field_id', - type=BASE_TYPES[0x02], # uint8 - def_num=2, - ), 3: Field( - name='concept_count', + name='channel_number', type=BASE_TYPES[0x02], # uint8 def_num=3, ), 4: Field( - name='display_type', - type=FIELD_TYPES['exd_display_type'], + name='data', + type=BASE_TYPES[0x0D], # byte def_num=4, ), - 5: Field( - name='title', - type=BASE_TYPES[0x07], # string - def_num=5, - ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 202: MessageType( - name='exd_data_concept_configuration', - mesg_num=202, + 81: MessageType( + name='ant_tx', + mesg_num=81, fields={ 0: Field( - name='screen_index', - type=BASE_TYPES[0x02], # uint8 + name='fractional_timestamp', + type=BASE_TYPES[0x84], # uint16 def_num=0, + scale=32768, + units='s', ), 1: Field( - name='concept_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='field_id', - def_num=2, + name='channel_number', + def_num=3, accumulate=False, - bits=4, + bits=8, bit_offset=0, ), ComponentField( - name='concept_index', - def_num=3, + name='data', + def_num=4, accumulate=False, - bits=4, - bit_offset=4, + bits=8, + bit_offset=8, ), - ), - ), - 2: Field( - name='field_id', - type=BASE_TYPES[0x02], # uint8 - def_num=2, + 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='concept_index', + name='channel_number', type=BASE_TYPES[0x02], # uint8 def_num=3, ), 4: Field( - name='data_page', - type=BASE_TYPES[0x02], # uint8 + name='data', + type=BASE_TYPES[0x0D], # byte 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, - ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 206: MessageType( # Must be logged before developer field is used - name='field_description', - mesg_num=206, + 82: MessageType( + name='ant_channel_id', + mesg_num=82, fields={ 0: Field( - name='developer_data_index', + name='channel_number', type=BASE_TYPES[0x02], # uint8 def_num=0, ), 1: Field( - name='field_definition_number', - type=BASE_TYPES[0x02], # uint8 + name='device_type', + type=BASE_TYPES[0x0A], # uint8z def_num=1, ), 2: Field( - name='fit_base_type_id', - type=FIELD_TYPES['fit_base_type'], + name='device_number', + type=BASE_TYPES[0x8B], # uint16z def_num=2, ), 3: Field( - name='field_name', - type=BASE_TYPES[0x07], # string + name='transmission_type', + type=BASE_TYPES[0x0A], # uint8z def_num=3, ), 4: Field( - name='array', - type=BASE_TYPES[0x02], # uint8 + name='device_index', + type=FIELD_TYPES['device_index'], 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, + }, + ), + 145: MessageType( + name='memo_glob', + mesg_num=145, + fields={ + 0: Field( # Deprecated. Use data field. + name='memo', + type=BASE_TYPES[0x0D], # byte + def_num=0, ), - 7: Field( - name='offset', - type=BASE_TYPES[0x01], # sint8 - def_num=7, + 1: Field( # Message Number of the parent message + name='mesg_num', + type=FIELD_TYPES['mesg_num'], + def_num=1, ), - 8: Field( - name='units', - type=BASE_TYPES[0x07], # string - def_num=8, + 2: Field( # Index of mesg that this glob is associated with. + name='parent_index', + type=FIELD_TYPES['message_index'], + def_num=2, ), - 9: Field( - name='bits', - type=BASE_TYPES[0x07], # string - def_num=9, + 3: Field( # Field within the parent that this glob is associated with + name='field_num', + type=BASE_TYPES[0x02], # uint8 + def_num=3, ), - 10: Field( - name='accumulate', - type=BASE_TYPES[0x07], # string - def_num=10, + 4: Field( # Block of utf8 bytes. Note, mutltibyte characters may be split across adjoining memo_glob messages. + name='data', + type=BASE_TYPES[0x0A], # uint8z + def_num=4, ), - 13: Field( - name='fit_base_unit_id', - type=FIELD_TYPES['fit_base_unit'], - def_num=13, + 250: Field( # Sequence number of memo blocks + name='part_index', + type=BASE_TYPES[0x86], # uint32 + def_num=250, ), - 14: Field( - name='native_mesg_num', - type=FIELD_TYPES['mesg_num'], - def_num=14, + }, + ), + 200: MessageType( + name='exd_screen_configuration', + mesg_num=200, + fields={ + 0: Field( + name='screen_index', + type=BASE_TYPES[0x02], # uint8 + def_num=0, ), - 15: Field( - name='native_field_num', + 1: Field( # number of fields in screen + name='field_count', type=BASE_TYPES[0x02], # uint8 - def_num=15, + 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, ), }, ), - 207: MessageType( # Must be logged before field description - name='developer_data_id', - mesg_num=207, + 201: MessageType( + name='exd_data_field_configuration', + mesg_num=201, fields={ 0: Field( - name='developer_id', - type=BASE_TYPES[0x0D], # byte + name='screen_index', + type=BASE_TYPES[0x02], # uint8 def_num=0, ), 1: Field( - name='application_id', + 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='manufacturer_id', - type=FIELD_TYPES['manufacturer'], + name='field_id', + type=BASE_TYPES[0x02], # uint8 def_num=2, ), 3: Field( - name='developer_data_index', + name='concept_count', type=BASE_TYPES[0x02], # uint8 def_num=3, ), 4: Field( - name='application_version', - type=BASE_TYPES[0x86], # uint32 + name='display_type', + type=FIELD_TYPES['exd_display_type'], def_num=4, ), + 5: Field( + name='title', + type=BASE_TYPES[0x07], # string + def_num=5, + ), }, ), - 208: MessageType( - name='magnetometer_data', - mesg_num=208, + 202: MessageType( + name='exd_data_concept_configuration', + mesg_num=202, fields={ - 0: Field( # Millisecond part of the timestamp. - name='timestamp_ms', - type=BASE_TYPES[0x84], # uint16 + 0: Field( + name='screen_index', + type=BASE_TYPES[0x02], # uint8 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 + 1: Field( + name='concept_field', + type=BASE_TYPES[0x0D], # byte def_num=1, - units='ms', + 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( # 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 + 2: Field( + name='field_id', + type=BASE_TYPES[0x02], # uint8 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 + 3: Field( + name='concept_index', + type=BASE_TYPES[0x02], # uint8 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 + 4: Field( + name='data_page', + type=BASE_TYPES[0x02], # uint8 def_num=4, - units='counts', ), - 5: Field( # Calibrated Magnetometer reading - name='calibrated_mag_x', - type=BASE_TYPES[0x88], # float32 + 5: Field( + name='concept_key', + type=BASE_TYPES[0x02], # uint8 def_num=5, - units='G', ), - 6: Field( # Calibrated Magnetometer reading - name='calibrated_mag_y', - type=BASE_TYPES[0x88], # float32 + 6: Field( + name='scaling', + type=BASE_TYPES[0x02], # uint8 def_num=6, - units='G', ), - 7: Field( # Calibrated Magnetometer reading - name='calibrated_mag_z', - type=BASE_TYPES[0x88], # float32 - def_num=7, - units='G', + 8: Field( + name='data_units', + type=FIELD_TYPES['exd_data_units'], + def_num=8, ), - 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', + 9: Field( + name='qualifier', + type=FIELD_TYPES['exd_qualifiers'], + def_num=9, ), - 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', + 10: Field( + name='descriptor', + type=FIELD_TYPES['exd_descriptors'], + def_num=10, ), - 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', + 11: Field( + name='is_signed', + type=FIELD_TYPES['bool'], + def_num=11, ), - 253: FIELD_TYPE_TIMESTAMP, # Whole second part of the timestamp }, ), - 210: MessageType( - name='one_d_sensor_calibration', - mesg_num=210, + 268: MessageType( + name='dive_summary', + mesg_num=268, fields={ - 0: Field( # Indicates which sensor the calibration is for - name='sensor_type', - type=FIELD_TYPES['sensor_type'], + 0: Field( + name='reference_mesg', + type=FIELD_TYPES['mesg_num'], 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 + 1: Field( + name='reference_index', + type=FIELD_TYPES['message_index'], 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', + 2: Field( # 0 if above water + name='avg_depth', type=BASE_TYPES[0x86], # uint32 def_num=2, - units='counts', + scale=1000, + units='m', ), - 3: Field( # Level shift value used to shift the ADC value back into range - name='level_shift', + 3: Field( # 0 if above water + name='max_depth', 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, + units='m', ), - 4: Field( # Amount of weight applied for the set - name='weight', - type=BASE_TYPES[0x84], # uint16 + 4: Field( # Time since end of last dive + name='surface_interval', + type=BASE_TYPES[0x86], # uint32 def_num=4, - scale=16, - units='kg', + units='s', ), 5: Field( - name='set_type', - type=FIELD_TYPES['set_type'], + name='start_cns', + type=BASE_TYPES[0x02], # uint8 def_num=5, + units='percent', ), - 6: Field( # Start time of the set - name='start_time', - type=FIELD_TYPES['date_time'], + 6: Field( + name='end_cns', + type=BASE_TYPES[0x02], # uint8 def_num=6, + units='percent', ), 7: Field( - name='category', - type=FIELD_TYPES['exercise_category'], + name='start_n2', + type=BASE_TYPES[0x84], # uint16 def_num=7, + units='percent', ), - 8: Field( # Based on the associated category, see [category]_exercise_names - name='category_subtype', + 8: Field( + name='end_n2', type=BASE_TYPES[0x84], # uint16 def_num=8, + units='percent', ), 9: Field( - name='weight_display_unit', - type=FIELD_TYPES['fit_base_unit'], + name='o2_toxicity', + type=BASE_TYPES[0x84], # uint16 def_num=9, + units='OTUs', ), 10: Field( - name='message_index', - type=FIELD_TYPES['message_index'], + name='dive_number', + type=BASE_TYPES[0x86], # uint32 def_num=10, ), 11: Field( - name='wkt_step_index', - type=FIELD_TYPES['message_index'], + name='bottom_time', + type=BASE_TYPES[0x86], # uint32 def_num=11, + scale=1000, + units='s', ), - 254: Field( # Timestamp of the set - name='timestamp', - type=FIELD_TYPES['date_time'], - def_num=254, + 12: Field( # Average pressure-based surface air consumption + name='avg_pressure_sac', + type=BASE_TYPES[0x84], # uint16 + def_num=12, + scale=100, + units='bar/min', ), - }, - ), - 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, + 13: Field( # Average volumetric surface air consumption + name='avg_volume_sac', + type=BASE_TYPES[0x84], # uint16 + def_num=13, + scale=100, + units='L/min', ), - 1: Field( # Time stress score was calculated - name='stress_level_time', - type=FIELD_TYPES['date_time'], - def_num=1, - units='s', + 14: Field( # Average respiratory minute volume + name='avg_rmv', + type=BASE_TYPES[0x84], # uint16 + def_num=14, + scale=100, + units='L/min', ), - }, - ), - 258: MessageType( - name='dive_settings', - mesg_num=258, - fields={ - 0: Field( - name='name', - type=BASE_TYPES[0x07], # string - def_num=0, + 15: Field( # Time to reach deepest level stop + name='descent_time', + type=BASE_TYPES[0x86], # uint32 + def_num=15, + scale=1000, + units='s', ), - 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, + 16: Field( # Time after leaving bottom until reaching surface + name='ascent_time', + type=BASE_TYPES[0x86], # uint32 + def_num=16, + scale=1000, + units='s', ), - 10: Field( - name='bottom_depth', - type=BASE_TYPES[0x88], # float32 - def_num=10, + 17: Field( # Average ascent rate, not including descents or stops + name='avg_ascent_rate', + type=BASE_TYPES[0x85], # sint32 + def_num=17, + scale=1000, + units='m/s', ), - 11: Field( - name='bottom_time', + 22: Field( # Average descent rate, not including ascents or stops + name='avg_descent_rate', type=BASE_TYPES[0x86], # uint32 - def_num=11, - ), - 12: Field( - name='apnea_countdown_enabled', - type=FIELD_TYPES['bool'], - def_num=12, + def_num=22, + scale=1000, + units='m/s', ), - 13: Field( - name='apnea_countdown_time', + 23: Field( # Maximum ascent rate + name='max_ascent_rate', type=BASE_TYPES[0x86], # uint32 - def_num=13, + def_num=23, + scale=1000, + units='m/s', ), - 14: Field( - name='backlight_mode', - type=FIELD_TYPES['dive_backlight_mode'], - def_num=14, + 24: Field( # Maximum descent rate + name='max_descent_rate', + type=BASE_TYPES[0x86], # uint32 + def_num=24, + scale=1000, + units='m/s', ), - 15: Field( - name='backlight_brightness', - type=BASE_TYPES[0x02], # uint8 - def_num=15, + 25: Field( # Time spent neither ascending nor descending + name='hang_time', + type=BASE_TYPES[0x86], # uint32 + def_num=25, + scale=1000, + units='s', ), - 16: Field( - name='backlight_timeout', - type=FIELD_TYPES['backlight_timeout'], - def_num=16, + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 275: MessageType( + name='sleep_level', + mesg_num=275, + fields={ + 0: Field( + name='sleep_level', + type=FIELD_TYPES['sleep_level'], + def_num=0, ), - 17: Field( # Time between surfacing and ending the activity - name='repeat_dive_interval', + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 290: MessageType( # Array of heart beat intervals + name='beat_intervals', + mesg_num=290, + fields={ + 0: Field( # Milliseconds past date_time + name='timestamp_ms', type=BASE_TYPES[0x84], # uint16 - def_num=17, - units='s', + def_num=0, + units='ms', ), - 18: Field( # Time at safety stop (if enabled) - name='safety_stop_time', + 1: Field( # Array of millisecond times between beats + name='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, - ), - ), - ), - ), + def_num=1, + units='ms', ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 297: MessageType( + name='respiration_rate', + mesg_num=297, + fields={ + 0: Field( # Breaths * 100 /min, -300 indicates invalid, -200 indicates large motion, -100 indicates off wrist + name='respiration_rate', + type=BASE_TYPES[0x83], # sint16 + def_num=0, + scale=100, + units='breaths/min', ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 259: MessageType( - name='dive_gas', - mesg_num=259, + 319: MessageType( + name='tank_update', + mesg_num=319, fields={ 0: Field( - name='helium_content', - type=BASE_TYPES[0x02], # uint8 + name='sensor', + type=FIELD_TYPES['ant_channel_id'], def_num=0, - units='percent', ), 1: Field( - name='oxygen_content', - type=BASE_TYPES[0x02], # uint8 + name='pressure', + type=BASE_TYPES[0x84], # uint16 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, + scale=100, + units='bar', ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 262: MessageType( - name='dive_alarm', - mesg_num=262, + 323: MessageType( + name='tank_summary', + mesg_num=323, fields={ 0: Field( - name='depth', - type=BASE_TYPES[0x86], # uint32 + name='sensor', + type=FIELD_TYPES['ant_channel_id'], def_num=0, - scale=1000, - units='m', ), 1: Field( - name='time', - type=BASE_TYPES[0x85], # sint32 + name='start_pressure', + type=BASE_TYPES[0x84], # uint16 def_num=1, - units='s', + scale=100, + units='bar', ), 2: Field( - name='enabled', - type=FIELD_TYPES['bool'], + name='end_pressure', + type=BASE_TYPES[0x84], # uint16 def_num=2, + scale=100, + units='bar', ), 3: Field( - name='alarm_type', - type=FIELD_TYPES['dive_alarm_type'], + name='volume_used', + type=BASE_TYPES[0x86], # uint32 def_num=3, + scale=100, + units='L', ), - 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, - ), + 253: FIELD_TYPE_TIMESTAMP, }, ), - 264: MessageType( - name='exercise_title', - mesg_num=264, + 346: MessageType( + name='sleep_assessment', + mesg_num=346, fields={ - 0: Field( - name='exercise_category', - type=FIELD_TYPES['exercise_category'], + 0: Field( # Average of awake_time_score and awakenings_count_score. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='combined_awake_score', + type=BASE_TYPES[0x02], # uint8 def_num=0, ), - 1: Field( - name='exercise_name', - type=BASE_TYPES[0x84], # uint16 + 1: Field( # Score that evaluates the total time spent awake between sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='awake_time_score', + type=BASE_TYPES[0x02], # uint8 def_num=1, ), - 2: Field( - name='wkt_step_name', - type=BASE_TYPES[0x07], # string + 2: Field( # Score that evaluates the number of awakenings that interrupt sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='awakenings_count_score', + type=BASE_TYPES[0x02], # uint8 def_num=2, ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 3: Field( # Score that evaluates the amount of deep sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='deep_sleep_score', + type=BASE_TYPES[0x02], # uint8 + def_num=3, ), - }, - ), - 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 + 4: Field( # Score that evaluates the quality of sleep based on sleep stages, heart-rate variability and possible awakenings during the night. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='sleep_duration_score', + type=BASE_TYPES[0x02], # uint8 def_num=4, - units='s', ), - 5: Field( - name='start_cns', + 5: Field( # Score that evaluates the amount of light sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='light_sleep_score', type=BASE_TYPES[0x02], # uint8 def_num=5, - units='percent', ), - 6: Field( - name='end_cns', + 6: Field( # Total score that summarizes the overall quality of sleep, combining sleep duration and quality. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='overall_sleep_score', type=BASE_TYPES[0x02], # uint8 def_num=6, - units='percent', ), - 7: Field( - name='start_n2', - type=BASE_TYPES[0x84], # uint16 + 7: Field( # Score that evaluates the quality of sleep based on sleep stages, heart-rate variability and possible awakenings during the night. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='sleep_quality_score', + type=BASE_TYPES[0x02], # uint8 def_num=7, - units='percent', ), - 8: Field( - name='end_n2', - type=BASE_TYPES[0x84], # uint16 + 8: Field( # Score that evaluates stress and recovery during sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='sleep_recovery_score', + type=BASE_TYPES[0x02], # uint8 def_num=8, - units='percent', ), - 9: Field( - name='o2_toxicity', - type=BASE_TYPES[0x84], # uint16 + 9: Field( # Score that evaluates the amount of REM sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='rem_sleep_score', + type=BASE_TYPES[0x02], # uint8 def_num=9, - units='OTUs', ), - 10: Field( - name='dive_number', - type=BASE_TYPES[0x86], # uint32 + 10: Field( # Score that evaluates the amount of restlessness during sleep. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='sleep_restlessness_score', + type=BASE_TYPES[0x02], # uint8 def_num=10, ), - 11: Field( - name='bottom_time', - type=BASE_TYPES[0x86], # uint32 + 11: Field( # The number of awakenings during sleep. + name='awakenings_count', + type=BASE_TYPES[0x02], # uint8 def_num=11, - scale=1000, - units='s', ), - 253: FIELD_TYPE_TIMESTAMP, + 14: Field( # Score that evaluates the sleep interruptions. If valid: 0 (worst) to 100 (best). If unknown: FIT_UINT8_INVALID. + name='interruptions_score', + type=BASE_TYPES[0x02], # uint8 + def_num=14, + ), + 15: Field( # Excludes stress during awake periods in the sleep window + name='average_stress_during_sleep', + type=BASE_TYPES[0x84], # uint16 + def_num=15, + scale=100, + ), }, ), - - - # ************************* Activity File Messages ************************* - 34: MessageType( - name='activity', - mesg_num=34, + 370: MessageType( + name='hrv_status_summary', + mesg_num=370, fields={ - 0: Field( # Exclude pauses - name='total_timer_time', - type=BASE_TYPES[0x86], # uint32 + 0: Field( # 7 day RMSSD average over sleep + name='weekly_average', + type=BASE_TYPES[0x84], # uint16 def_num=0, - scale=1000, - units='s', + scale=128, + units='ms', ), - 1: Field( - name='num_sessions', + 1: Field( # Last night RMSSD average over sleep + name='last_night_average', type=BASE_TYPES[0x84], # uint16 def_num=1, + scale=128, + units='ms', ), - 2: Field( - name='type', - type=FIELD_TYPES['activity'], + 2: Field( # 5 minute high RMSSD value over sleep + name='last_night_5_min_high', + type=BASE_TYPES[0x84], # uint16 def_num=2, + scale=128, + units='ms', ), - 3: Field( - name='event', - type=FIELD_TYPES['event'], + 3: Field( # 3 week baseline, upper boundary of low HRV status + name='baseline_low_upper', + type=BASE_TYPES[0x84], # uint16 def_num=3, + scale=128, + units='ms', ), - 4: Field( - name='event_type', - type=FIELD_TYPES['event_type'], + 4: Field( # 3 week baseline, lower boundary of balanced HRV status + name='baseline_balanced_lower', + type=BASE_TYPES[0x84], # uint16 def_num=4, + scale=128, + units='ms', ), - 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'], + 5: Field( # 3 week baseline, upper boundary of balanced HRV status + name='baseline_balanced_upper', + type=BASE_TYPES[0x84], # uint16 def_num=5, + scale=128, + units='ms', ), 6: Field( - name='event_group', - type=BASE_TYPES[0x02], # uint8 + name='status', + type=FIELD_TYPES['hrv_status'], def_num=6, ), 253: FIELD_TYPE_TIMESTAMP, }, ), + 371: MessageType( + name='hrv_value', + mesg_num=371, + fields={ + 0: Field( # 5 minute RMSSD + name='value', + type=BASE_TYPES[0x84], # uint16 + def_num=0, + scale=128, + units='ms', + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), - # ********************** Blood Pressure File Messages ********************** - 51: MessageType( - name='blood_pressure', - mesg_num=51, + # ************************* Schedule File Messages ************************* + 28: MessageType( + name='schedule', + mesg_num=28, fields={ - 0: Field( - name='systolic_pressure', - type=BASE_TYPES[0x84], # uint16 + 0: Field( # Corresponds to file_id of scheduled workout / course. + name='manufacturer', + type=FIELD_TYPES['manufacturer'], def_num=0, - units='mmHg', ), - 1: Field( - name='diastolic_pressure', + 1: Field( # Corresponds to file_id of scheduled workout / course. + name='product', type=BASE_TYPES[0x84], # uint16 def_num=1, - units='mmHg', + subfields=( + SubField( + name='favero_product', + def_num=1, + type=FIELD_TYPES['favero_product'], + ref_fields=( + ReferenceField( + name='manufacturer', + def_num=0, + value='favero_electronics', + raw_value=263, + ), + ), + ), + 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, + ), + ReferenceField( + name='manufacturer', + def_num=0, + value='tacx', + raw_value=89, + ), + ), + ), + ), ), - 2: Field( - name='mean_arterial_pressure', - type=BASE_TYPES[0x84], # uint16 + 2: Field( # Corresponds to file_id of scheduled workout / course. + name='serial_number', + type=BASE_TYPES[0x8C], # uint32z def_num=2, - units='mmHg', ), - 3: Field( - name='map_3_sample_mean', - type=BASE_TYPES[0x84], # uint16 + 3: Field( # Corresponds to file_id of scheduled workout / course. + name='time_created', + type=FIELD_TYPES['date_time'], def_num=3, - units='mmHg', ), - 4: Field( - name='map_morning_values', - type=BASE_TYPES[0x84], # uint16 + 4: Field( # TRUE if this activity has been started + name='completed', + type=FIELD_TYPES['bool'], def_num=4, - units='mmHg', ), 5: Field( - name='map_evening_values', - type=BASE_TYPES[0x84], # uint16 + name='type', + type=FIELD_TYPES['schedule'], def_num=5, - units='mmHg', ), 6: Field( - name='heart_rate', - type=BASE_TYPES[0x02], # uint8 + name='scheduled_time', + type=FIELD_TYPES['local_date_time'], 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, + # ************************* Segment File Messages ************************** + 142: MessageType( + name='segment_lap', + mesg_num=142, 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, + 0: Field( + name='event', + type=FIELD_TYPES['event'], + def_num=0, ), 1: Field( - name='sub_sport', - type=FIELD_TYPES['sub_sport'], + name='event_type', + type=FIELD_TYPES['event_type'], def_num=1, ), 2: Field( - name='start_date', + name='start_time', type=FIELD_TYPES['date_time'], def_num=2, ), 3: Field( - name='end_date', - type=FIELD_TYPES['date_time'], + name='start_position_lat', + type=BASE_TYPES[0x85], # sint32 def_num=3, + units='semicircles', ), 4: Field( - name='type', - type=FIELD_TYPES['goal'], + name='start_position_long', + type=BASE_TYPES[0x85], # sint32 def_num=4, + units='semicircles', ), 5: Field( - name='value', - type=BASE_TYPES[0x86], # uint32 + name='end_position_lat', + type=BASE_TYPES[0x85], # sint32 def_num=5, + units='semicircles', ), 6: Field( - name='repeat', - type=FIELD_TYPES['bool'], + name='end_position_long', + type=BASE_TYPES[0x85], # sint32 def_num=6, + units='semicircles', ), - 7: Field( - name='target_value', + 7: Field( # Time (includes pauses) + name='total_elapsed_time', type=BASE_TYPES[0x86], # uint32 def_num=7, + scale=1000, + units='s', ), - 8: Field( - name='recurrence', - type=FIELD_TYPES['goal_recurrence'], + 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='recurrence_value', - type=BASE_TYPES[0x84], # uint16 + name='total_distance', + type=BASE_TYPES[0x86], # uint32 def_num=9, + scale=100, + units='m', ), 10: Field( - name='enabled', - type=FIELD_TYPES['bool'], + 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='source', - type=FIELD_TYPES['goal_source'], + name='total_calories', + type=BASE_TYPES[0x84], # uint16 def_num=11, + units='kcal', ), - 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, + 12: Field( # If New Leaf + name='total_fat_calories', + type=BASE_TYPES[0x84], # uint16 + def_num=12, + units='kcal', ), - 3: Field( # Indexed by activity_type - name='cycles_to_distance', + 13: Field( + name='avg_speed', type=BASE_TYPES[0x84], # uint16 - def_num=3, - scale=5000, - units='m/cycle', + def_num=13, + scale=1000, + units='m/s', ), - 4: Field( # Indexed by activity_type - name='cycles_to_calories', + 14: Field( + name='max_speed', type=BASE_TYPES[0x84], # uint16 - def_num=4, - scale=5000, - units='kcal/cycle', + def_num=14, + scale=1000, + units='m/s', ), - 5: Field( - name='resting_metabolic_rate', + 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=5, - units='kcal/day', + def_num=19, + units='watts', ), - 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, + 20: Field( + name='max_power', + type=BASE_TYPES[0x84], # uint16 + def_num=20, + units='watts', ), - 1: Field( # Allows relating glob to another mesg If used only required for first part of each memo_glob - name='message_number', + 21: Field( + name='total_ascent', type=BASE_TYPES[0x84], # uint16 - def_num=1, + def_num=21, + units='m', ), - 2: Field( # Index of external mesg - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=2, + 22: Field( + name='total_descent', + type=BASE_TYPES[0x84], # uint16 + def_num=22, + units='m', ), - 250: Field( # Sequence number of memo blocks - name='part_index', - type=BASE_TYPES[0x86], # uint32 - def_num=250, + 23: Field( + name='sport', + type=FIELD_TYPES['sport'], + def_num=23, ), - }, - ), - - - # ************************* 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, + 24: Field( + name='event_group', + type=BASE_TYPES[0x02], # uint8 + def_num=24, ), - 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, - ), - ), - ), - SubField( - name='strava_product', - def_num=1, - type=FIELD_TYPES['strava_product'], - ref_fields=( - ReferenceField( - name='manufacturer', - def_num=0, - value='strava', - raw_value=265, - ), - ), - ), - ), - ), - 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, + 25: Field( # North east corner latitude. + name='nec_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=25, + units='semicircles', ), - 4: Field( # TRUE if this activity has been started - name='completed', - type=FIELD_TYPES['bool'], - def_num=4, + 26: Field( # North east corner longitude. + name='nec_long', + type=BASE_TYPES[0x85], # sint32 + def_num=26, + units='semicircles', ), - 5: Field( - name='type', - type=FIELD_TYPES['schedule'], - def_num=5, + 27: Field( # South west corner latitude. + name='swc_lat', + type=BASE_TYPES[0x85], # sint32 + def_num=27, + units='semicircles', ), - 6: Field( - name='scheduled_time', - type=FIELD_TYPES['local_date_time'], - def_num=6, + 28: Field( # South west corner latitude. + name='swc_long', + type=BASE_TYPES[0x85], # sint32 + def_num=28, + units='semicircles', ), - }, - ), - - - # ************************* 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 + 29: Field( name='name', type=BASE_TYPES[0x07], # string - def_num=0, + def_num=29, ), - 1: Field( # UUID of the segment - name='uuid', - type=BASE_TYPES[0x07], # string - def_num=1, + 30: Field( + name='normalized_power', + type=BASE_TYPES[0x84], # uint16 + def_num=30, + units='watts', ), - 2: Field( # Sport associated with the segment - name='sport', - type=FIELD_TYPES['sport'], - def_num=2, + 31: Field( + name='left_right_balance', + type=FIELD_TYPES['left_right_balance_100'], + def_num=31, ), - 3: Field( # Segment enabled for evaluation - name='enabled', - type=FIELD_TYPES['bool'], - def_num=3, + 32: Field( + name='sub_sport', + type=FIELD_TYPES['sub_sport'], + def_num=32, ), - 4: Field( # Primary key of the user that created the segment - name='user_profile_primary_key', + 33: Field( + name='total_work', type=BASE_TYPES[0x86], # uint32 - def_num=4, + def_num=33, + units='J', ), - 5: Field( # ID of the device that created the segment - name='device_id', - type=BASE_TYPES[0x86], # uint32 - def_num=5, + 34: Field( + name='avg_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=34, + scale=5, + offset=500, + units='m', + components=( + ComponentField( + name='enhanced_avg_altitude', + def_num=91, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), ), - 6: Field( # Index for the Leader Board entry selected as the default race participant - name='default_race_leader', + 35: Field( + name='max_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=35, + scale=5, + offset=500, + units='m', + components=( + ComponentField( + name='enhanced_max_altitude', + def_num=92, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 36: Field( + name='gps_accuracy', type=BASE_TYPES[0x02], # uint8 - def_num=6, + def_num=36, + units='m', ), - 7: Field( # Indicates if any segments should be deleted - name='delete_status', - type=FIELD_TYPES['segment_delete_status'], - def_num=7, + 37: Field( + name='avg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=37, + scale=100, + units='%', ), - 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, + 38: Field( + name='avg_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=38, + scale=100, + units='%', ), - }, - ), - - - # *********************** 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, + 39: Field( + name='avg_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=39, + scale=100, + units='%', ), - 3: Field( # Enabled state of the segment file - name='enabled', - type=FIELD_TYPES['bool'], - def_num=3, + 40: Field( + name='max_pos_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=40, + scale=100, + units='%', ), - 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, + 41: Field( + name='max_neg_grade', + type=BASE_TYPES[0x83], # sint16 + def_num=41, + scale=100, + units='%', ), - 7: Field( # Leader type of each leader in the segment file - name='leader_type', - type=FIELD_TYPES['segment_leaderboard_type'], - def_num=7, + 42: Field( + name='avg_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=42, + units='C', ), - 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, + 43: Field( + name='max_temperature', + type=BASE_TYPES[0x01], # sint8 + def_num=43, + units='C', ), - 9: Field( # Activity ID of each leader in the segment file - name='leader_activity_id', + 44: Field( + name='total_moving_time', type=BASE_TYPES[0x86], # uint32 - def_num=9, + def_num=44, + scale=1000, + units='s', ), - 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, + 45: Field( + name='avg_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=45, + scale=1000, + units='m/s', ), - 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, + 46: Field( + name='avg_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=46, + scale=1000, + units='m/s', ), - 254: Field( - name='message_index', - type=FIELD_TYPES['message_index'], - def_num=254, + 47: Field( + name='max_pos_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=47, + scale=1000, + units='m/s', ), - }, - ), - - - # ************************* 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, + 48: Field( + name='max_neg_vertical_speed', + type=BASE_TYPES[0x83], # sint16 + def_num=48, + scale=1000, + units='m/s', ), - 1: Field( # Offset from system time. Required to convert timestamp from system time to UTC. - name='utc_offset', + 49: Field( + name='time_in_hr_zone', type=BASE_TYPES[0x86], # uint32 - def_num=1, + def_num=49, + scale=1000, + units='s', ), - 2: Field( # Offset from system time. - name='time_offset', + 50: Field( + name='time_in_speed_zone', type=BASE_TYPES[0x86], # uint32 - def_num=2, + def_num=50, + scale=1000, 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, + 51: Field( + name='time_in_cadence_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=51, + scale=1000, + units='s', ), - 39: Field( # UTC timestamp used to set the devices clock and date - name='clock_time', - type=FIELD_TYPES['date_time'], - def_num=39, + 52: Field( + name='time_in_power_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=52, + scale=1000, + units='s', ), - 40: Field( # Bitfield to configure enabled screens for each supported loop - name='pages_enabled', + 53: Field( + name='repetition_num', 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, + def_num=53, ), - 47: Field( # Display mode for the date - name='date_mode', - type=FIELD_TYPES['date_mode'], - def_num=47, + 54: Field( + name='min_altitude', + type=BASE_TYPES[0x84], # uint16 + def_num=54, + scale=5, + offset=500, + units='m', + components=( + ComponentField( + name='enhanced_min_altitude', + def_num=93, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), ), 55: Field( - name='display_orientation', - type=FIELD_TYPES['display_orientation'], + name='min_heart_rate', + type=BASE_TYPES[0x02], # uint8 def_num=55, + units='bpm', ), 56: Field( - name='mounting_side', - type=FIELD_TYPES['side'], + name='active_time', + type=BASE_TYPES[0x86], # uint32 def_num=56, + scale=1000, + units='s', ), - 57: Field( # Bitfield to indicate one page as default for each supported loop - name='default_page', - type=BASE_TYPES[0x84], # uint16 + 57: Field( + name='wkt_step_index', + type=FIELD_TYPES['message_index'], def_num=57, ), - 58: Field( # Minimum steps before an autosync can occur - name='autosync_min_steps', - type=BASE_TYPES[0x84], # uint16 + 58: Field( + name='sport_event', + type=FIELD_TYPES['sport_event'], def_num=58, - units='steps', ), - 59: Field( # Minimum minutes before an autosync can occur - name='autosync_min_time', - type=BASE_TYPES[0x84], # uint16 + 59: Field( + name='avg_left_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 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, + scale=2, + units='percent', ), - 89: Field( # Helps to conserve battery by changing modes - name='auto_sync_frequency', - type=FIELD_TYPES['auto_sync_frequency'], - def_num=89, + 60: Field( + name='avg_right_torque_effectiveness', + type=BASE_TYPES[0x02], # uint8 + def_num=60, + scale=2, + units='percent', ), - 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, + 61: Field( + name='avg_left_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=61, + scale=2, + units='percent', ), - 94: Field( # Number of screens configured to display - name='number_of_screens', + 62: Field( + name='avg_right_pedal_smoothness', type=BASE_TYPES[0x02], # uint8 - def_num=94, + def_num=62, + scale=2, + units='percent', ), - 95: Field( # Smart Notification display orientation - name='smart_notification_display_orientation', - type=FIELD_TYPES['display_orientation'], - def_num=95, + 63: Field( + name='avg_combined_pedal_smoothness', + type=BASE_TYPES[0x02], # uint8 + def_num=63, + scale=2, + units='percent', ), - 134: Field( - name='tap_interface', - type=FIELD_TYPES['switch'], - def_num=134, + 64: Field( + name='status', + type=FIELD_TYPES['segment_lap_status'], + def_num=64, ), - }, - ), - 3: MessageType( - name='user_profile', - mesg_num=3, - fields={ - 0: Field( - name='friendly_name', + 65: Field( + name='uuid', type=BASE_TYPES[0x07], # string - def_num=0, - ), - 1: Field( - name='gender', - type=FIELD_TYPES['gender'], - def_num=1, + def_num=65, ), - 2: Field( - name='age', + 66: Field( # fractional part of the avg_cadence + name='avg_fractional_cadence', type=BASE_TYPES[0x02], # uint8 - def_num=2, - units='years', + def_num=66, + scale=128, + units='rpm', ), - 3: Field( - name='height', + 67: Field( # fractional part of the max_cadence + name='max_fractional_cadence', type=BASE_TYPES[0x02], # uint8 - def_num=3, + 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, + ), + 84: Field( # The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. + name='total_grit', + type=BASE_TYPES[0x88], # float32 + def_num=84, + units='kGrit', + ), + 85: Field( # The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. + name='total_flow', + type=BASE_TYPES[0x88], # float32 + def_num=85, + units='Flow', + ), + 86: Field( # The grit score estimates how challenging a route could be for a cyclist in terms of time spent going over sharp turns or large grade slopes. + name='avg_grit', + type=BASE_TYPES[0x88], # float32 + def_num=86, + units='kGrit', + ), + 87: Field( # The flow score estimates how long distance wise a cyclist deaccelerates over intervals where deacceleration is unnecessary such as smooth turns or small grade angle intervals. + name='avg_flow', + type=BASE_TYPES[0x88], # float32 + def_num=87, + units='Flow', + ), + 89: Field( # fractional part of total_ascent + name='total_fractional_ascent', + type=BASE_TYPES[0x02], # uint8 + def_num=89, scale=100, units='m', ), - 4: Field( - name='weight', - type=BASE_TYPES[0x84], # uint16 + 90: Field( # fractional part of total_descent + name='total_fractional_descent', + type=BASE_TYPES[0x02], # uint8 + def_num=90, + scale=100, + units='m', + ), + 91: Field( + name='enhanced_avg_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=91, + scale=5, + offset=500, + units='m', + ), + 92: Field( + name='enhanced_max_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=92, + scale=5, + offset=500, + units='m', + ), + 93: Field( + name='enhanced_min_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=93, + scale=5, + offset=500, + units='m', + ), + 253: FIELD_TYPE_TIMESTAMP, # Lap end time. + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 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, - scale=10, - units='kg', ), - 5: Field( - name='language', - type=FIELD_TYPES['language'], + 5: Field( # ID of the device that created the segment + name='device_id', + type=BASE_TYPES[0x86], # uint32 def_num=5, ), - 6: Field( - name='elev_setting', - type=FIELD_TYPES['display_measure'], + 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, + ), + }, + ), + 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', + components=( + ComponentField( + name='enhanced_altitude', + def_num=6, + scale=5, + offset=500, + units='m', + accumulate=False, + bits=16, + bit_offset=0, + ), + ), + ), + 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', + ), + 6: Field( # Accumulated altitude along the segment at the described point + name='enhanced_altitude', + type=BASE_TYPES[0x86], # uint32 + def_num=6, + scale=5, + offset=500, + units='m', + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + + + # *********************** 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, + ), + 174: Field( # Used to hold the tap threshold setting + name='tap_sensitivity', + type=FIELD_TYPES['tap_sensitivity'], + def_num=174, + ), + }, + ), + 3: MessageType( + name='user_profile', + mesg_num=3, + fields={ + 0: Field( # Used for Morning Report greeting + 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, + ), + }, + ), + 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, + ), + }, + ), + 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, + ), + }, + ), + 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, + ), + }, + ), + 188: MessageType( + name='ohr_settings', + mesg_num=188, + fields={ + 0: Field( + name='enabled', + type=FIELD_TYPES['switch'], + def_num=0, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + 216: MessageType( + name='time_in_zone', + mesg_num=216, + 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( + name='time_in_hr_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=2, + scale=1000, + units='s', + ), + 3: Field( + name='time_in_speed_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=3, + scale=1000, + units='s', + ), + 4: Field( + name='time_in_cadence_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=4, + scale=1000, + units='s', + ), + 5: Field( + name='time_in_power_zone', + type=BASE_TYPES[0x86], # uint32 + def_num=5, + scale=1000, + units='s', + ), + 6: Field( + name='hr_zone_high_boundary', + type=BASE_TYPES[0x02], # uint8 + def_num=6, + units='bpm', + ), + 7: Field( + name='speed_zone_high_boundary', + type=BASE_TYPES[0x84], # uint16 + def_num=7, + scale=1000, + units='m/s', + ), + 8: Field( + name='cadence_zone_high_bondary', + type=BASE_TYPES[0x02], # uint8 + def_num=8, + units='rpm', + ), + 9: Field( + name='power_zone_high_boundary', + type=BASE_TYPES[0x84], # uint16 + def_num=9, + units='watts', + ), + 10: Field( + name='hr_calc_type', + type=FIELD_TYPES['hr_zone_calc'], + def_num=10, + ), + 11: Field( + name='max_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=11, + ), + 12: Field( + name='resting_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=12, + ), + 13: Field( + name='threshold_heart_rate', + type=BASE_TYPES[0x02], # uint8 + def_num=13, + ), + 14: Field( + name='pwr_calc_type', + type=FIELD_TYPES['pwr_zone_calc'], + def_num=14, + ), + 15: Field( + name='functional_threshold_power', + type=BASE_TYPES[0x84], # uint16 + def_num=15, + ), + 253: FIELD_TYPE_TIMESTAMP, + }, + ), + + + # ********************** 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, + ), + }, + ), + 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, + ), + }, + ), + 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, + ), + }, + ), + 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, + ), + }, + ), + 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, + ), + ), + ), + ), + ), + 21: Field( # Index of travel dive_gas message + name='travel_gas', + type=FIELD_TYPES['message_index'], + def_num=21, + ), + 22: Field( # If low PO2 should be switched to automatically + name='ccr_low_setpoint_switch_mode', + type=FIELD_TYPES['ccr_setpoint_switch_mode'], + def_num=22, + ), + 23: Field( # Target PO2 when using low setpoint + name='ccr_low_setpoint', + type=BASE_TYPES[0x02], # uint8 + def_num=23, + scale=100, + units='percent', + ), + 24: Field( # Depth to switch to low setpoint in automatic mode + name='ccr_low_setpoint_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=24, + scale=1000, + units='m', + ), + 25: Field( # If high PO2 should be switched to automatically + name='ccr_high_setpoint_switch_mode', + type=FIELD_TYPES['ccr_setpoint_switch_mode'], + def_num=25, + ), + 26: Field( # Target PO2 when using high setpoint + name='ccr_high_setpoint', + type=BASE_TYPES[0x02], # uint8 + def_num=26, + scale=100, + units='percent', + ), + 27: Field( # Depth to switch to high setpoint in automatic mode + name='ccr_high_setpoint_depth', + type=BASE_TYPES[0x86], # uint32 + def_num=27, + scale=1000, + units='m', + ), + 29: Field( # Type of gas consumption rate to display. Some values are only valid if tank volume is known. + name='gas_consumption_display', + type=FIELD_TYPES['gas_consumption_rate_type'], + def_num=29, + ), + 30: Field( # Indicates whether the up key is enabled during dives + name='up_key_enabled', + type=FIELD_TYPES['bool'], + def_num=30, + ), + 35: Field( # Sounds and vibration enabled or disabled in-dive + name='dive_sounds', + type=FIELD_TYPES['tone'], + def_num=35, + ), + 36: Field( # Usually 1.0/1.5/2.0 representing 3/4.5/6m or 10/15/20ft + name='last_stop_multiple', + type=BASE_TYPES[0x02], # uint8 + def_num=36, + scale=10, + ), + 37: Field( # Indicates which guidelines to use for no-fly surface interval. + name='no_fly_time_mode', + type=FIELD_TYPES['no_fly_time_mode'], + def_num=37, + ), + 253: FIELD_TYPE_TIMESTAMP, + 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, + ), + 3: Field( + name='mode', + type=FIELD_TYPES['dive_gas_mode'], + def_num=3, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 262: MessageType( + name='dive_alarm', + mesg_num=262, + fields={ + 0: Field( # Depth setting (m) for depth type alarms + name='depth', + type=BASE_TYPES[0x86], # uint32 + def_num=0, + scale=1000, + units='m', + ), + 1: Field( # Time setting (s) for time type alarms + name='time', + type=BASE_TYPES[0x85], # sint32 + def_num=1, + units='s', + ), + 2: Field( # Enablement flag + name='enabled', + type=FIELD_TYPES['bool'], + def_num=2, + ), + 3: Field( # Alarm type setting + name='alarm_type', + type=FIELD_TYPES['dive_alarm_type'], + def_num=3, + ), + 4: Field( # Tone and Vibe setting for the alarm + name='sound', + type=FIELD_TYPES['tone'], + def_num=4, + ), + 5: Field( # Dive types the alarm will trigger on + name='dive_types', + type=FIELD_TYPES['sub_sport'], + def_num=5, + ), + 6: Field( # Alarm ID + name='id', + type=BASE_TYPES[0x86], # uint32 + def_num=6, + ), + 7: Field( # Show a visible pop-up for this alarm + name='popup_enabled', + type=FIELD_TYPES['bool'], + def_num=7, + ), + 8: Field( # Trigger the alarm on descent + name='trigger_on_descent', + type=FIELD_TYPES['bool'], + def_num=8, + ), + 9: Field( # Trigger the alarm on ascent + name='trigger_on_ascent', + type=FIELD_TYPES['bool'], + def_num=9, + ), + 10: Field( # Repeat alarm each time threshold is crossed? + name='repeating', + type=FIELD_TYPES['bool'], + def_num=10, + ), + 11: Field( # Ascent/descent rate (mps) setting for speed type alarms + name='speed', + type=BASE_TYPES[0x85], # sint32 + def_num=11, + scale=1000, + units='mps', + ), + 254: Field( # Index of the alarm + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 393: MessageType( + name='dive_apnea_alarm', + mesg_num=393, + fields={ + 0: Field( # Depth setting (m) for depth type alarms + name='depth', + type=BASE_TYPES[0x86], # uint32 + def_num=0, + scale=1000, + units='m', + ), + 1: Field( # Time setting (s) for time type alarms + name='time', + type=BASE_TYPES[0x85], # sint32 + def_num=1, + units='s', + ), + 2: Field( # Enablement flag + name='enabled', + type=FIELD_TYPES['bool'], + def_num=2, + ), + 3: Field( # Alarm type setting + name='alarm_type', + type=FIELD_TYPES['dive_alarm_type'], + def_num=3, + ), + 4: Field( # Tone and Vibe setting for the alarm. + name='sound', + type=FIELD_TYPES['tone'], + def_num=4, + ), + 5: Field( # Dive types the alarm will trigger on + name='dive_types', + type=FIELD_TYPES['sub_sport'], + def_num=5, + ), + 6: Field( # Alarm ID + name='id', + type=BASE_TYPES[0x86], # uint32 + def_num=6, + ), + 7: Field( # Show a visible pop-up for this alarm + name='popup_enabled', + type=FIELD_TYPES['bool'], + def_num=7, + ), + 8: Field( # Trigger the alarm on descent + name='trigger_on_descent', + type=FIELD_TYPES['bool'], + def_num=8, + ), + 9: Field( # Trigger the alarm on ascent + name='trigger_on_ascent', + type=FIELD_TYPES['bool'], + def_num=9, + ), + 10: Field( # Repeat alarm each time threshold is crossed? + name='repeating', + type=FIELD_TYPES['bool'], + def_num=10, + ), + 11: Field( # Ascent/descent rate (mps) setting for speed type alarms + name='speed', + type=BASE_TYPES[0x85], # sint32 + def_num=11, + scale=1000, + units='mps', + ), + 254: Field( # Index of the alarm + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + + + # ************************** 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, + ), + 13: Field( + name='bmi', + type=BASE_TYPES[0x84], # uint16 + def_num=13, + scale=10, + units='kg/m^2', + ), + 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, + ), + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, + ), + }, + ), + 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='weight_setting', - type=FIELD_TYPES['display_measure'], + name='intensity', + type=FIELD_TYPES['intensity'], def_num=7, ), 8: Field( - name='resting_heart_rate', - type=BASE_TYPES[0x02], # uint8 + name='notes', + type=BASE_TYPES[0x07], # string def_num=8, - units='bpm', ), 9: Field( - name='default_max_running_heart_rate', - type=BASE_TYPES[0x02], # uint8 + name='equipment', + type=FIELD_TYPES['workout_equipment'], def_num=9, - units='bpm', ), 10: Field( - name='default_max_biking_heart_rate', - type=BASE_TYPES[0x02], # uint8 + name='exercise_category', + type=FIELD_TYPES['exercise_category'], def_num=10, - units='bpm', ), 11: Field( - name='default_max_heart_rate', - type=BASE_TYPES[0x02], # uint8 + name='exercise_name', + type=BASE_TYPES[0x84], # uint16 def_num=11, - units='bpm', ), 12: Field( - name='hr_setting', - type=FIELD_TYPES['display_heart'], + name='exercise_weight', + type=BASE_TYPES[0x84], # uint16 def_num=12, + scale=100, + units='kg', ), 13: Field( - name='speed_setting', - type=FIELD_TYPES['display_measure'], + name='weight_display_unit', + type=FIELD_TYPES['fit_base_unit'], 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', + 19: Field( + name='secondary_target_type', + type=FIELD_TYPES['wkt_step_target'], + def_num=19, ), - 2: Field( - name='calories', + 20: Field( + name='secondary_target_value', type=BASE_TYPES[0x86], # uint32 - def_num=2, - units='kcal', - ), - 3: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=3, + def_num=20, + subfields=( + SubField( # Zone (1-?); Custom = 0; + name='secondary_target_cadence_zone', + def_num=20, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='cadence', + raw_value=3, + ), + ), + ), + SubField( # hr zone (1-5);Custom =0; + name='secondary_target_hr_zone', + def_num=20, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='heart_rate', + raw_value=1, + ), + ), + ), + SubField( # Power Zone ( 1-7); Custom = 0; + name='secondary_target_power_zone', + def_num=20, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='power', + raw_value=4, + ), + ), + ), + SubField( # speed zone (1-10);Custom =0; + name='secondary_target_speed_zone', + def_num=20, + type=BASE_TYPES[0x86], # uint32 + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='speed', + raw_value=0, + ), + ), + ), + SubField( + name='secondary_target_stroke_type', + def_num=20, + type=FIELD_TYPES['swim_stroke'], + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='swim_stroke', + raw_value=11, + ), + ), + ), + ), ), - 4: Field( # Includes pauses - name='elapsed_time', + 21: Field( + name='secondary_custom_target_value_low', type=BASE_TYPES[0x86], # uint32 - def_num=4, - units='s', - ), - 5: Field( - name='sessions', - type=BASE_TYPES[0x84], # uint16 - def_num=5, + def_num=21, + subfields=( + SubField( + name='secondary_custom_target_cadence_low', + def_num=21, + type=BASE_TYPES[0x86], # uint32 + units='rpm', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='cadence', + raw_value=3, + ), + ), + ), + SubField( + name='secondary_custom_target_heart_rate_low', + def_num=21, + type=FIELD_TYPES['workout_hr'], + units='% or bpm', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='heart_rate', + raw_value=1, + ), + ), + ), + SubField( + name='secondary_custom_target_power_low', + def_num=21, + type=FIELD_TYPES['workout_power'], + units='% or watts', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='power', + raw_value=4, + ), + ), + ), + SubField( + name='secondary_custom_target_speed_low', + def_num=21, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='m/s', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='speed', + raw_value=0, + ), + ), + ), + ), ), - 6: Field( - name='active_time', + 22: Field( + name='secondary_custom_target_value_high', type=BASE_TYPES[0x86], # uint32 - def_num=6, - units='s', - ), - 9: Field( - name='sport_index', - type=BASE_TYPES[0x02], # uint8 - def_num=9, + def_num=22, + subfields=( + SubField( + name='secondary_custom_target_cadence_high', + def_num=22, + type=BASE_TYPES[0x86], # uint32 + units='rpm', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='cadence', + raw_value=3, + ), + ), + ), + SubField( + name='secondary_custom_target_heart_rate_high', + def_num=22, + type=FIELD_TYPES['workout_hr'], + units='% or bpm', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='heart_rate', + raw_value=1, + ), + ), + ), + SubField( + name='secondary_custom_target_power_high', + def_num=22, + type=FIELD_TYPES['workout_power'], + units='% or watts', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='power', + raw_value=4, + ), + ), + ), + SubField( + name='secondary_custom_target_speed_high', + def_num=22, + type=BASE_TYPES[0x86], # uint32 + scale=1000, + units='m/s', + ref_fields=( + ReferenceField( + name='secondary_target_type', + def_num=19, + value='speed', + raw_value=0, + ), + ), + ), + ), ), - 253: FIELD_TYPE_TIMESTAMP, 254: Field( name='message_index', type=FIELD_TYPES['message_index'], @@ -12030,136 +14982,72 @@ ), }, ), - - - # *********************** Weight Scale File Messages *********************** - 30: MessageType( - name='weight_scale', - mesg_num=30, + 158: MessageType( + name='workout_session', + mesg_num=158, fields={ 0: Field( - name='weight', - type=FIELD_TYPES['weight'], + name='sport', + type=FIELD_TYPES['sport'], def_num=0, - scale=100, - units='kg', ), 1: Field( - name='percent_fat', - type=BASE_TYPES[0x84], # uint16 + name='sub_sport', + type=FIELD_TYPES['sub_sport'], def_num=1, - scale=100, - units='%', ), 2: Field( - name='percent_hydration', + name='num_valid_steps', type=BASE_TYPES[0x84], # uint16 def_num=2, - scale=100, - units='%', ), 3: Field( - name='visceral_fat_mass', + name='first_step_index', type=BASE_TYPES[0x84], # uint16 def_num=3, - scale=100, - units='kg', ), 4: Field( - name='bone_mass', + name='pool_length', type=BASE_TYPES[0x84], # uint16 def_num=4, scale=100, - units='kg', + units='m', ), 5: Field( - name='muscle_mass', - type=BASE_TYPES[0x84], # uint16 + name='pool_length_unit', + type=FIELD_TYPES['display_measure'], 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', + 254: Field( + name='message_index', type=FIELD_TYPES['message_index'], - def_num=12, + def_num=254, ), - 253: FIELD_TYPE_TIMESTAMP, }, ), - - - # ************************* Workout File Messages ************************** - 26: MessageType( - name='workout', - mesg_num=26, + 264: MessageType( + name='exercise_title', + mesg_num=264, fields={ - 4: Field( - name='sport', - type=FIELD_TYPES['sport'], - def_num=4, - ), - 5: Field( - name='capabilities', - type=FIELD_TYPES['workout_capabilities'], - def_num=5, + 0: Field( + name='exercise_category', + type=FIELD_TYPES['exercise_category'], + def_num=0, ), - 6: Field( # number of valid steps - name='num_valid_steps', + 1: Field( + name='exercise_name', type=BASE_TYPES[0x84], # uint16 - def_num=6, + def_num=1, ), - 8: Field( - name='wkt_name', + 2: Field( + name='wkt_step_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', + def_num=2, ), - 15: Field( - name='pool_length_unit', - type=FIELD_TYPES['display_measure'], - def_num=15, + 254: Field( + name='message_index', + type=FIELD_TYPES['message_index'], + def_num=254, ), }, ),