Пример #1
0
class BikeProfile(Message):
    msg_type = 6

    message_index = MessageIndex(254)
    name = String(0)
    sport = Sport(1)
    sub_sport = SubSport(2)
    odometer = UInt32(3, units="m") * 100
    bike_spd_ant_id = UInt16Z(4)
    bike_cad_ant_id = UInt16Z(5)
    bike_spdcad_ant_id = UInt16Z(6)
    bike_power_ant_id = UInt16Z(7)
    custom_wheelsize = UInt16(8)
    auto_wheelsize = UInt16(9)
    bike_wieght = UInt16(10)
    power_cal_factor = UInt16(11)
    auto_wheel_cal = Bool(12)
    auto_power_zero = Bool(13)
    id = UInt8(14)
    spd_enabled = Bool(15)
    cad_enabled = Bool(16)
    spdcad_enabled = Bool(17)
    power_enabled = Bool(18)
    crank_length = UInt8(19)
    enabled = Bool(20)
    bike_spd_ant_id_trans_type = UInt8Z(21)
    bike_cad_ant_id_trans_type = UInt8Z(22)
    bike_spdcad_ant_id_trans_type = UInt8Z(23)
    bike_power_ant_id_trans_type = UInt8Z(24)
    odometer_rollover = UInt8(37)
    front_gear_num = UInt8Z(38)
    front_gear = UInt8Z(39)
    rear_gear_num = UInt8Z(40)
    read_gear = UInt8Z(41)
Пример #2
0
class FileId(Message):
    msg_type = 0

    type = File(0)
    manufacturer = Manufacturer(1)
    product = DynamicField(UInt16(2),
                           manufacturer={
                               ("garmin", "dynastream", "dynastream_oem"):
                               SubField("garmin_product", GarminProduct),
                           })
    serial_number = UInt32Z(3)
    time_created = DateTime(4)
    number = UInt16(5)

    @property
    def filetype(self):
        return self._meta.model[0]._save(self.type)

    @classmethod
    def create(cls, file_type, **data):
        attributes = {
            'serial_number': 0xDEADBEAF,
            'time_created': datetime.now(),
            'manufacturer': Manufacturer.known[1],
            'product': GarminProduct.known[65534],
            'type': File.variants[file_type]
        }
        attributes.update(data)

        return cls(**attributes)
Пример #3
0
class DeviceInfo(Message):
    msg_type = 23

    timestamp = DateTime(253)
    device_index = DeviceIndex(0)
    device_type = DynamicField(
        UInt8(1),
        source_type={
            "antplus": SubField("antplus_device_type", AntplusDeviceType),
            "ant": SubField("ant_device_type")
        }
    )
    manufacturer = Manufacturer(2)
    serial_number = UInt32Z(3)
    product = UInt16(4)  # Maybe DynamicField?
    software_version = UInt16(5) * 100
    hardware_version = UInt8(6)
    cum_operating_time = UInt32(7) * "s"
    battery_voltage = UInt16(10, units="V") * 256
    battery_status = BatteryStatus(11)
    sensor_position = BodyLocation(18)
    descriptor = String(19)
    ant_transmission_type = UInt8Z(20)
    ant_device_number = UInt16Z(21)
    ant_network = AntNetwork(22)
    source_type = SourceType(25)
Пример #4
0
class MonitoringInfo(Message):
    msg_type = 103

    timestamp = DateTime(253)
    local_timestamp = LocalDateTime(0)
    activity_type = ActivityType(1)  # array
    cycles_to_distance = UInt16(3, units="m/cycle") * 5000  # array
    cycles_to_calories = UInt16(4, units="kcal/cycle") * 5000  # array
    resting_metabolic_rate = UInt16(5) * "kcal/day"
Пример #5
0
class Workout(Message):
    msg_type = 26

    sport = Sport(4)
    capabilities = WorkoutCapabilities(5)
    num_valid_steps = UInt16(6)
    wkt_name = String(8)
Пример #6
0
class UserProfile(Message):
    msg_type = 3

    message_index = MessageIndex(254)
    friendly_name = String(0)
    gender = Gender(1)
    age = UInt8(2) * "years"
    height = UInt8(3)
    weight = UInt16(4)
    language = Language(5)
    elev_setting = DisplayMeasure(6)
    weight_settings = DisplayMeasure(7)
    resting_heart_rate = UInt8(8) * "bpm"
    default_max_running_heart_rate = UInt8(9) * "bpm"
    default_max_biking_heart_rate = UInt8(10) * "bpm"
    default_max_heart_rate = UInt8(11) * "bpm"
    hr_setting = DisplayHeart(12)
    speed_setting = DisplayMeasure(13)
    dist_setting = DisplayMeasure(14)
    power_settings = DisplayPower(16)
    activity_class = ActivityClass(17)
    position_setting = DisplayPosition(18)
    temperature_setting = DisplayMeasure(21)
    local_id = UserLocalId(22)
    global_id = Byte(23)  # array
    height_setting = DisplayMeasure(30)
Пример #7
0
class MetZone(Message):
    msg_type = 10

    message_index = MessageIndex(254)
    high_bpm = UInt8(1)
    calories = UInt16(2, units="kcal/min") * 10
    fat_calories = UInt8(2, units="kcal/min") * 10
Пример #8
0
class MemoGlob(Message):
    msg_type = 145

    part_index = UInt32(250)
    memo = Byte(0)
    message_number = UInt16(1)
    message_index = MessageIndex(2)
Пример #9
0
class FieldCapabilities(Message):
    msg_type = 39

    message_index = MessageIndex(254)
    file = File(0)
    mesg_num = MesgNum(1)
    field_num = UInt8(2)
    count = UInt16(3)
Пример #10
0
class ZonesTarget(Message):
    msg_type = 7

    max_heart_rate = UInt8(1)
    threshold_heart_rate = UInt8(2)
    functional_threshold_power = UInt16(3)
    hr_calc_type = HrZoneCalc(5)
    pwr_calc_type = PwrZoneCalc(7)
Пример #11
0
class MesgCapabilities(Message):
    msg_type = 38

    message_index = MessageIndex(254)
    file = File(0)
    mesg_num = MesgNum(1)
    count_type = MesgCount(2)
    count = UInt16(3)
Пример #12
0
class FileCapabilities(Message):
    msg_type = 37

    message_index = MessageIndex(254)
    type = File(0)
    flags = FileFlags(1)
    directory = String(2)
    max_count = UInt16(3)
    max_size = UInt32(4)
Пример #13
0
class SdmProfile(Message):
    msg_type = 5

    message_index = MessageIndex(254)
    enabled = Bool(0)
    sdm_ant_id = UInt16Z(1)
    sdm_cal_factor = UInt16(2)
    odometer = UInt32(3, units="m") * 100
    speed_source = Bool(4)
    sdm_ant_id_trans_byte = UInt8Z(5)
    odometer_rollover = UInt8(7)
Пример #14
0
class Activity(Message):
    msg_type = 34

    timestamp = DateTime(253)
    total_timer_time = UInt32(0, units="s") * 1000
    num_sessions = UInt16(1)
    type = ActivityField(2)
    event = EventField(3)
    event_type = EventType(4)
    local_timestamp = LocalDateTime(5)
    event_group = UInt8(6)
Пример #15
0
class Totals(Message):
    msg_type = 33

    message_index = MessageIndex(254)
    timestamp = DateTime(253) * "s"
    timer_time = UInt32(0) * "s"
    distance = UInt32(1) * "m"
    calories = UInt32(2) * "kcal"
    sport = Sport(3)
    elapsed_time = UInt32(4) * "s"
    sessions = UInt16(5)
    active_time = UInt32(6) * "s"
Пример #16
0
class Event(Message):
    msg_type = 21

    timestamp = DateTime(253)
    event = EventField(0)
    event_type = EventType(1)
    data16 = UInt16(2)  # components
    data = DynamicField(
        UInt32(3),
        event={
            "timer": SubField("timer_trigger", TimerTrigger),
            "course_point": SubField("course_point_index", MessageIndex),
            "battery": SubField(
                "battery_level",
                lambda number: UInt16(number, units="V") * 1000),
            "virtual_partner_pace": SubField(
                "virtual_partner_speed",
                lambda number: UInt16(number, units="m/s") * 1000),
            "hr_high_alert": SubField("hr_high_alert", UInt8, units="bpm"),
            "hr_low_alert": SubField("hr_low_alert", UInt8, units="bpm"),
            "speed_high_alert": SubField(
                "speed_high_alert",
                lambda number: UInt16(number, units="m/s") * 1000),
            "speed_low_alert": SubField(
                "speed_low_alert",
                lambda number: UInt16(number, units="m/s") * 1000),
            "cad_high_alert": SubField("cad_high_alert", UInt16, units="rpm"),
            "cad_low_alert": SubField("cad_low_alert", UInt16, units="rpm"),
            "power_high_alert": SubField(
                "power_high_alert", UInt16, units="watts"),
            "power_low_alert": SubField(
                "power_low_alert", UInt16, units="watts"),
            "time_duration_alert": SubField(
                "time_duration_alert",
                lambda number: UInt32(number, units="s") * 1000),
            "distance_duration_alert": SubField(
                "distance_duration_alert",
                lambda number: UInt32(number, units="m") * 100),
            "calorie_duration_alert": SubField(
                "calorie_duration_alert", units="calories"),
            "fitness_equipment": SubField(
                "fitness_equipment_state", FitnessEquipmentState),
            "sport_point": SubField("sport_point"),  # components
            ("front_gear_change", "rear_gear_change"): SubField(
                "gear_change_data")  # components
        }
    )
    event_group = UInt8(4)
    score = UInt16(7)
    opponent_score = UInt16(8)
    front_gear_num = UInt8Z(9)
    front_gear = UInt8Z(10)
    rear_gear_num = UInt8Z(11)
    rear_gear = UInt8Z(12)
Пример #17
0
class Goal(Message):
    msg_type = 15

    message_index = MessageIndex(254)
    sport = Sport(0)
    sub_sport = SubSport(1)
    start_date = DateTime(2)
    end_date = DateTime(3)
    type = GoalField(4)
    value = UInt32(5)
    repeat = Bool(6)
    target_value = UInt32(7)
    recurrence = GoalRecurrence(8)
    recurrence_value = UInt16(9)
    enabled = Bool(10)
Пример #18
0
class WeightScale(Message):
    msg_type = 30

    timestamp = DateTime(253)
    weight = Weight(0, units="kg") * 100
    percent_fat = UInt16(1, units="%") * 100
    percent_hydration = UInt16(2, units="%") * 100
    visceral_fat_mass = UInt16(3, units="kg") * 100
    bone_mass = UInt16(4, units="kg") * 100
    muscle_mass = UInt16(5, units="kg") * 100
    basal_met = UInt16(7, units="kcal/day") * 4
    physical_rating = UInt8(8)
    active_met = UInt16(9, units="kcal/day") * 4
    metabolic_age = UInt8(10) * "years"
    visceral_fat_rating = UInt8(11)
    user_profile_index = MessageIndex(12)
Пример #19
0
class BloodPressure(Message):
    msg_type = 51

    timestamp = DateTime(253)
    systolic_pressure = UInt16(0) * "mmHg"
    diastolic_pressure = UInt16(1) * "mmHg"
    mean_arterial_pressure = UInt16(2) * "mmHg"
    map_3_sample_mean = UInt16(3) * "mmHg"
    map_morning_values = UInt16(4) * "mmHg"
    map_evening_values = UInt16(5) * "mmHg"
    heart_rate = UInt8(6) * "bpm"
    heart_rate_type = HrType(7)
    status = BpStatus(8)
    user_profile_index = MessageIndex(9)
Пример #20
0
class Monitoring(Message):
    msg_type = 55

    timestamp = DateTime(253)
    device_index = DeviceIndex(0)
    calories = UInt16(1) * "kcal"
    distance = UInt32(2, units="m") * 100
    cycles = Dynamic(
        UInt32(3, units="cycles") * 2,
        referred_to="activity_type",
        walking=SubField("steps", units="steps"),
        running=SubField("steps", units="steps"),
        cycling=SubField(
            "strokes", lambda number: UInt32(number, units="strokes") * 2),
        swimming=SubField(
            "strokes", lambda number: UInt32(number, units="strokes") * 2)
    )
    active_time = UInt32(4, units="s") * 1000
    activity_type = ActivityType(5)
    activity_subtime = ActivitySubType(6)
    activity_level = ActivityLevel(7)
    distance_16 = UInt16(8)
    cycles_16 = UInt16(9)
    active_time_16 = UInt16(10)
    local_timestamp = LocalDateTime(11)
    temperature = SInt16(12, units="°C") * 100
    temperature_min = SInt16(14, units="°C") * 100
    temperature_max = SInt16(15, units="°C") * 100
    activity_time = UInt16(16) * "minutes"  # array
    active_calories = UInt16(19) * "kcal"
    current_activity_type_intensity = Byte(24)  # components
    timestamp_min_8 = UInt8(25) * "min"
    timestamp_16 = UInt16(26) * "s"
    heart_rate = UInt8(27) * "bpm"
    intensity = Intensity(28)
    duration_min = UInt16(29) * "min"
    duration = UInt32(30) * "s"
Пример #21
0
class Length(Message):
    msg_type = 101

    message_index = MessageIndex(254)
    timestamp = DateTime(253)
    event = EventField(0)
    event_type = EventType(1)
    start_time = DateTime(2)
    total_elapsed_time = UInt32(3, units="s") * 1000
    total_timer_time = UInt32(4, units="s") * 1000
    total_strokes = UInt16(5) * "strokes"
    avg_speed = UInt16(6, units="m/s") * 1000
    swim_stroke = SwimStroke(7)
    avg_swimming_cadence = UInt8(9) * "strokes/min"
    event_group = UInt8(10)
    total_calories = UInt16(11) * "kcal"
    length_type = LengthType(12)
    player_score = UInt16(18)
    opponent_score = UInt16(19)
    stroke_count = Array(UInt16(20))
    zone_count = Array(UInt16(21))
Пример #22
0
class Software(Message):
    msg_type = 35

    message_index = MessageIndex(254)
    version = UInt16(3) * 100
    part_number = String(5)
Пример #23
0
class SpeedZone(Message):
    msg_type = 53

    message_index = MessageIndex(254)
    high_value = UInt16(0, units="m/s") * 1000
    name = String(1)
Пример #24
0
class PowerZone(Message):
    msg_type = 9

    message_index = MessageIndex(254)
    high_value = UInt16(1) * "watts"
    name = String(2)
Пример #25
0
class FileCreator(Message):
    msg_type = 49

    software_version = UInt16(0)
    hardware_version = UInt8(1)
Пример #26
0
class Hrv(Message):
    msg_type = 78

    time = Array(UInt16(0, units="s") * 1000)
Пример #27
0
class Session(Message):
    msg_type = 18

    message_index = MessageIndex(254)
    timestamp = DateTime(253)
    event = EventField(0)
    event_type = EventType(1)
    start_time = DateTime(2)
    start_position_lat = degrees(3)
    start_position_long = degrees(4)
    sport = Sport(5)
    sub_sport = SubSport(6)
    total_elapsed_time = UInt32(7, units="s") * 1000
    total_timer_time = UInt32(8, units="s") * 1000
    total_distance = UInt32(9, units="m") * 100
    total_cycles = Dynamic(UInt32(10, units="cycles"),
                           referred_to="sport",
                           running=SubField("total_strides", units="strides"))
    total_calories = UInt16(11) * "kcal"
    total_fat_calories = UInt16(13) * "kcal"
    avg_speed = UInt16(14, units="m/s") * 1000
    max_speed = UInt16(15, units="m/s") * 1000
    avg_heart_rate = UInt8(16) * "bpm"
    max_heart_rate = UInt8(17) * "bpm"
    avg_cadence = Dynamic(UInt8(18, units="rpm"),
                          referred_to="sport",
                          running=SubField("avg_running_cadence",
                                           units="strides/min"))
    max_cadence = Dynamic(UInt8(19, units="rpm"),
                          referred_to="sport",
                          running=SubField("max_running_cadence",
                                           units="strides/min"))
    avg_power = UInt16(20) * "watts"
    max_power = UInt16(21) * "watts"
    total_ascent = UInt16(22) * "m"
    total_descent = UInt16(23) * "m"
    total_training_effect = UInt8(24) * 10
    first_lap_index = UInt16(25)
    num_laps = UInt16(26)
    event_group = UInt8(27)
    trigger = SessionTrigger(28)
    nec_lat = degrees(29)
    nec_long = degrees(30)
    swc_lat = degrees(31)
    swc_long = degrees(32)
    normalized_power = UInt16(34) * "watts"
    training_stress_score = UInt16(35, units="tss") * 10
    intensity_factor = UInt16(36, units="if") * 1000
    left_right_balance = LeftRightBalance100(37)
    avg_stroke_count = UInt32(41, units="strokes/lap") * 10
    avg_stroke_distance = UInt16(42, units="m") * 100
    swim_stroke = SwimStroke(43)
    pool_length = UInt16(44, units="m") * 100
    pool_length_unit = DisplayMeasure(46)
    num_active_lengths = UInt16(47)
    total_work = UInt32(48) * "J"
    avg_altitude = UInt16(49, units="m") * 5 + 500
    max_altitude = UInt16(50, units="m") * 5 + 500
    gps_accuracy = UInt8(51) * "m"
    avg_grade = SInt16(52, units="%") * 100
    avg_pos_grade = SInt16(53, units="%") * 100
    avg_neg_grade = SInt16(54, units="%") * 100
    max_pos_grade = SInt16(55, units="%") * 100
    max_neg_grade = SInt16(56, units="%") * 100
    avg_temperature = SInt8(57) * "°C"
    max_temperature = SInt8(58) * "°C"
    total_moving_time = UInt32(59, units="s") * 1000
    avg_pos_vertical_speed = SInt16(60, units="m/s") * 1000
    avg_neg_vertical_speed = SInt16(61, units="m/s") * 1000
    max_pos_vertical_speed = SInt16(62, units="m/s") * 1000
    max_neg_vertical_speed = SInt16(63, units="m/s") * 1000
    min_heart_rate = UInt8(64) * "bpm"
    time_in_hr_zone = Array(UInt32(65, units="s") * 1000)
    time_in_speed_zone = Array(UInt32(66, units="s") * 1000)
    time_in_cadence_zone = Array(UInt32(67, units="s") * 1000)
    time_in_power_zone = Array(UInt32(68, units="s") * 1000)
    avg_lap_time = UInt32(69, units="s") * 1000
    best_lap_index = UInt16(70)
    min_altitude = UInt16(71, units="m") * 5 + 500
    player_score = UInt16(82)
    opponent_score = UInt16(83)
    opponent_name = String(84)
    stroke_count = Array(UInt16(85))
    zone_count = Array(UInt16(86))
    max_ball_speed = UInt16(87, units="m/s") * 100
    avg_ball_speed = UInt16(88, units="m/s") * 100
    avg_vertical_oscillation = UInt16(89, units="mm") * 10
    avg_stance_time_percent = UInt16(90, units="%") * 100
    avg_stance_time = UInt16(91, units="ms") * 10
    avg_fractional_cadence = UInt8(92, units="rpm") * 128
    max_fractional_cadence = UInt8(93, units="rpm") * 128
    total_fractional_cycles = UInt8(94, units="cycles") * 128
    avg_total_hemoglobin_conc = Array(UInt16(95, units="g/dL") * 100)
    min_total_hemoglobin_conc = Array(UInt16(96, units="g/dL") * 100)
    max_total_hemoglobin_conc = Array(UInt16(97, units="g/dL") * 100)
    avg_saturated_hemoglobin_percent = Array(UInt16(98, units="%") * 10)
    min_saturated_hemoglobin_percent = Array(UInt16(99, units="%") * 10)
    max_saturated_hemoglobin_percent = Array(UInt16(100, units="%") * 10)
    avg_left_torque_effectiveness = UInt8(101, units="%") * 2
    avg_right_torque_effectiveness = UInt8(102, units="%") * 2
    avg_left_pedal_smoothness = UInt8(103, units="%") * 2
    avg_right_pedal_smoothness = UInt8(104, units="%") * 2
    avg_combined_pedal_smoothness = UInt8(105, units="%") * 2
Пример #28
0
class Record(Message):
    msg_type = 20

    timestamp = DateTime(253)
    position_lat = degrees(0)
    position_long = degrees(1)
    altitude = UInt16(2, units="m") * 5 + 500
    heart_rate = UInt8(3) * "bpm"
    cadence = UInt8(4) * "rpm"
    distance = UInt32(5, units="m") * 100
    speed = UInt16(6, units="m/s") * 1000
    power = UInt16(7) * "watts"
    compressed_speed_distance = Composite(
        Array(Byte(8), size=3),
        speed=ComponentField(bits=12) * 100,
        distance=ComponentField(bits=12, offset=12) * 16)
    grade = SInt16(9, units="%") * 100
    resistance = UInt8(10)
    time_from_course = SInt32(11, units="s") * 1000
    cycle_length = UInt8(12, units="m") * 100
    temperature = SInt8(13) * "°C"
    speed_1s = Array(UInt8(17, units="m/s") * 16)
    cycles = UInt8(18) * "cycles"  # components
    total_cycles = UInt32(19) * "cycles"
    compressed_accumulated_power = UInt16(28) * "watts"  # components
    accumulated_power = UInt32(29) * "watts"
    left_right_balance = LeftRightBalance(30)
    gps_accuracy = UInt8(31) * "m"
    vertical_speed = SInt16(32, units="m/s") * 1000
    calories = UInt16(33) * "kcal"
    vertical_oscillation = UInt16(39, units="mm") * 10
    stance_time_percent = UInt16(40, units="%") * 100
    stance_time = UInt16(41, units="ms") * 10
    activity_type = ActivityType(42)
    left_torque_effectiveness = UInt8(43, units="%") * 2
    right_torque_effectiveness = UInt8(44, units="%") * 2
    left_pedal_smoothness = UInt8(45, units="%") * 2
    right_pedal_smoothness = UInt8(46, units="%") * 2
    combined_pedal_smoothness = UInt8(47, units="%") * 2
    time128 = UInt8(48, units="s") * 128
    stroke_type = StrokeType(49)
    zone = UInt8(50)
    ball_speed = UInt16(51, units="m/s") * 100
    cadence256 = UInt16(52, units="rpm") * 256
    total_hemoglobin_conc = UInt16(54, units="g/dL") * 100
    total_hemoglobin_conc_min = UInt16(55, units="g/dL") * 100
    total_hemoglobin_conc_max = UInt16(56, units="g/dL") * 100
    saturated_hemoglobin_percent = UInt16(57, units="%") * 10
    saturated_hemoglobin_percent_min = UInt16(58, units="%") * 10
    saturated_hemoglobin_percent_max = UInt16(59, units="%") * 10
    device_index = DeviceIndex(62)
Пример #29
0
class Lap(Message):
    msg_type = 19

    message_index = MessageIndex(254)
    timestamp = DateTime(253)
    event = EventField(0)
    event_type = EventType(1)
    start_time = DateTime(2)
    start_position_lat = degrees(3)
    start_position_long = degrees(4)
    end_position_lat = degrees(5)
    end_position_long = degrees(6)
    total_elapsed_time = UInt32(7, units="s") * 1000
    total_timer_time = UInt32(8, units="s") * 1000
    total_distance = UInt32(9, units="m") * 100
    total_cycles = Dynamic(UInt32(10, units="cycles"),
                           referred_to="sport",
                           running=SubField("total_strides", units="strides"))
    total_calories = UInt16(11) * "kcal"
    total_fat_calories = UInt16(12) * "kcal"
    avg_speed = UInt16(13, units="m/s") * 1000
    max_speed = UInt16(14, units="m/s") * 1000
    avg_heart_rate = UInt8(15) * "bpm"
    max_heart_rate = UInt8(16) * "bpm"
    avg_cadence = Dynamic(UInt8(17, units="rpm"),
                          referred_to="sport",
                          running=SubField("avg_running_cadence",
                                           units="strides/min"))
    max_cadence = Dynamic(UInt8(18, units="rpc"),
                          referred_to="sport",
                          running=SubField("max_running_cadence",
                                           units="strides/min"))
    avg_power = UInt16(19) * "watts"
    max_power = UInt16(20) * "watts"
    total_ascent = UInt16(21) * "m"
    total_descent = UInt16(22) * "m"
    intensity = Intensity(23)
    lap_trigger = LapTrigger(24)
    sport = Sport(25)
    event_group = UInt8(26)
    num_lengths = UInt16(32)
    normalized_power = UInt16(33) * "watts"
    left_right_balance = LeftRightBalance100(34)
    first_length_index = UInt16(35)
    avg_stroke_distance = UInt16(37, units="m") * 100
    swim_stroke = SwimStroke(38)
    sub_sport = SubSport(39)
    num_active_lengths = UInt16(40)
    total_work = UInt32(41) * "J"
    avg_altitude = UInt16(42, units="m") * 5 + 500
    max_altitude = UInt16(43, units="m") * 5 + 500
    gps_accuracy = UInt8(44) * "m"
    avg_grade = SInt16(45, units="%") * 100
    avg_pos_grade = SInt16(46, units="%") * 100
    avg_neg_grade = SInt16(47, units="%") * 100
    max_pos_grade = SInt16(48, units="%") * 100
    max_neg_grade = SInt16(49, units="%") * 100
    avg_temperature = SInt8(50) * "°C"
    max_temperature = SInt8(51) * "°C"
    total_moving_time = UInt32(52, units="s") * 1000
    avg_pos_vertical_speed = SInt16(53, units="m/s") * 1000
    avg_neg_vertical_speed = SInt16(54, units="m/s") * 1000
    max_pos_vertical_speed = SInt16(55, units="m/s") * 1000
    max_neg_vertical_speed = SInt16(56, units="m/s") * 1000
    time_in_hr_zone = Array(UInt32(57, units="s") * 1000)
    time_in_speed_zone = Array(UInt32(58, units="s") * 1000)
    time_in_cadence_zone = Array(UInt32(59, units="s") * 1000)
    time_in_power_zone = Array(UInt32(60, units="s") * 1000)
    repetition_num = UInt16(61)
    min_altitude = UInt16(62, units="m") * 5 + 500
    min_heart_rate = UInt8(63) * "bpm"
    wkt_step_index = MessageIndex(71)
    opponent_score = UInt16(74)
    stroke_count = Array(UInt16(75))
    zone_count = Array(UInt16(76))
    avg_vertical_oscillation = UInt16(77, units="mm") * 10
    avg_stance_time_percent = UInt16(78, units="%") * 100
    avg_stance_time = UInt16(79, units="ms") * 10
    avg_fractional_cadence = UInt8(80, units="rpm") * 128
    max_fractional_cadence = UInt8(81, units="rpm") * 128
    total_fractional_cycles = UInt8(82, units="cycles") * 128
    player_score = UInt16(83)
    avg_total_hemoglobin_conc = Array(UInt16(84, units="g/dL") * 100)
    min_total_hemoglobin_conc = Array(UInt16(85, units="g/dL") * 100)
    max_total_hemoglobin_conc = Array(UInt16(86, units="g/dL") * 100)
    avg_saturated_hemoglobin_percent = Array(UInt16(87, units="%") * 10)
    min_saturated_hemoglobin_percent = Array(UInt16(88, units="%") * 10)
    max_saturated_hemoglobin_percent = Array(UInt16(89, units="%") * 10)
    avg_left_torque_effectiveness = UInt8(91, units="%") * 2
    avg_right_torque_effectiveness = UInt8(92, units="%") * 2
    avg_left_pedal_smoothness = UInt8(93, units="%") * 2
    avg_right_pedal_smoothness = UInt8(94, units="%") * 2
    avg_combined_pedal_smoothness = UInt8(95, units="%") * 2