diff --git a/README.md b/README.md
index 90a6c45..8a1b571 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ encode policies): [`docs/CAPABILITY_BOUNDARY.md`](docs/CAPABILITY_BOUNDARY.md).
Long-term strict-conformance **roadmap** (target architecture, not current
guarantees): [`docs/FIT_CONFORMANCE_DESIGN.md`](docs/FIT_CONFORMANCE_DESIGN.md).
-Profile in use: `21.218.0` (`fit_tool.SDK_VERSION`).
+Profile in use: `21.221.0` (`fit_tool.SDK_VERSION`).
## Installation
diff --git a/docs/CAPABILITY_BOUNDARY.md b/docs/CAPABILITY_BOUNDARY.md
index 0c40931..f0c3428 100644
--- a/docs/CAPABILITY_BOUNDARY.md
+++ b/docs/CAPABILITY_BOUNDARY.md
@@ -7,7 +7,7 @@ strict-conformance **target** architecture remains
[`FIT_CONFORMANCE_DESIGN.md`](FIT_CONFORMANCE_DESIGN.md) (not a guarantee of
what the installed package already does).
-Bundled Profile version: **`21.218.0`** (`fit_tool.SDK_VERSION` / `fit_tool/gen/`).
+Bundled Profile version: **`21.221.0`** (`fit_tool.SDK_VERSION` / `fit_tool/gen/`).
Wire protocol version: **`2.0`** (`fit_tool.PROTOCOL_VERSION`, the SDK's
`FIT_PROTOCOL_VERSION_20`). The FIT *protocol document* revision is **2.4**
(March 2019); that number is a documentation revision, not the value stored in
@@ -61,7 +61,7 @@ this package against the matrix above, not against full protocol conformance.
| Level | What it checks | Status in code |
| --- | --- | --- |
| `ConformanceLevel.WIRE` | Local IDs, definition field layout/sizes, data records vs active definition | Implemented |
-| `ConformanceLevel.PROFILE` | Scoped Profile semantics via `profile_scope=` / `ProfileScope` | **CORE (default):** developer-field declarations + **ambiguous native subfields** as ERROR. **DOMAIN (opt-in):** CORE + native base-type and closed-enum checks on high-frequency Activity/Workout messages. **FULL (opt-in):** same native rules for the gen-exported catalog from Profile.xlsx `21.218.0`. FULL is never default `strict` (§3.1 O1). Open/ranged enums (e.g. `activity_class`) are excluded from closed-enum checks |
+| `ConformanceLevel.PROFILE` | Scoped Profile semantics via `profile_scope=` / `ProfileScope` | **CORE (default):** developer-field declarations + **ambiguous native subfields** as ERROR. **DOMAIN (opt-in):** CORE + native base-type and closed-enum checks on high-frequency Activity/Workout messages. **FULL (opt-in):** same native rules for the gen-exported catalog from Profile.xlsx `21.221.0`. FULL is never default `strict` (§3.1 O1). Open/ranged enums (e.g. `activity_class`) are excluded from closed-enum checks |
| `ConformanceLevel.FILE_TYPE` | `file_id` first/unique + required fields; Activity, Workout, and Course rules | **`IMPLEMENTED_FILE_TYPES`** = Activity, Workout, Course; other `file_id.type` values **fail closed** |
| `ConformanceLevel.PRESERVATION` | Post-edit rewrite loss (e.g. `UnknownField.raw_bytes` cleared) | **Opt-in** — not in `DEFAULT_LEVELS` / Builder `strict=True` |
diff --git a/docs/EPIC_SHA12_RELEASE_NOTES.md b/docs/EPIC_SHA12_RELEASE_NOTES.md
index 0048540..87f4508 100644
--- a/docs/EPIC_SHA12_RELEASE_NOTES.md
+++ b/docs/EPIC_SHA12_RELEASE_NOTES.md
@@ -15,7 +15,7 @@ subfields, unknown fields, post-edit PRESERVATION, encode policies, PROFILE
scopes CORE/DOMAIN/FULL, Workout + Course FILE_TYPE). Stage 5 (**L**) publishes
honest Supported/Partial/Not-supported claims.
-Profile / SDK version: **`21.218.0`** (`SDK_VERSION`, `fit_tool/gen/`).
+Profile / SDK version: **`21.221.0`** (`SDK_VERSION`, `fit_tool/gen/`).
## User-visible capabilities (rollup)
diff --git a/docs/FIT_CONFORMANCE_DESIGN.md b/docs/FIT_CONFORMANCE_DESIGN.md
index ff470d2..e324e3d 100644
--- a/docs/FIT_CONFORMANCE_DESIGN.md
+++ b/docs/FIT_CONFORMANCE_DESIGN.md
@@ -49,7 +49,7 @@ public-claims pass that keeps this table and `docs/CAPABILITY_BOUNDARY.md` hones
| Unknown field ids on known messages (decode retain + raw bytes) | Phase 3 | **E** SHA-17 | **Done** `UnknownField` + `raw_bytes` on main path |
| Post-edit PRESERVATION (edited files, dirty records) | Phase 4 / PRESERVATION level | **F** SHA-18 | **Done** per-record dirty + mixed encode; opt-in PRESERVATION findings |
| Encode policies (canonical vs preserve, strict vs repair) | Phase 4 §6 | **G** SHA-19 | **Done** `EncodeMode` + policy matrix; no silent invalid clamp; `repair()` still future |
-| PROFILE scopes from bundled Profile.xlsx `21.218.0` | Phase 3 PROFILE / §3.1 | **H** SHA-20 | **Done** CORE/DOMAIN/FULL + gen `field_catalog`; default remains CORE; native required fields / units still residual |
+| PROFILE scopes from bundled Profile.xlsx `21.221.0` | Phase 3 PROFILE / §3.1 | **H** SHA-20 | **Done** CORE/DOMAIN/FULL + gen `field_catalog`; default remains CORE; native required fields / units still residual |
| Workout FILE_TYPE rules | Phase 4 §7 | **I** SHA-21 | **Done** required messages/fields; SDK Workout*.fit pass FILE_TYPE |
| Course FILE_TYPE rules | Phase 4 §7 | **J** SHA-22 | **Done** Course required messages/fields; Activity + Workout unchanged |
| Public capability matrix / release-note pass | Phase 5 | **L** SHA-23 | **This pass** — README + this section + §11 residual checklist + Towncrier epic notes |
@@ -82,7 +82,7 @@ Passing one dimension must not be reported as passing all four.
The conformance target is the Garmin FIT Protocol documentation and the exact
`Profile.xlsx` version committed under `fit_tool/gen/`. The current repository
-uses Profile `21.218.0`.
+uses Profile `21.221.0`.
Official references:
@@ -791,7 +791,7 @@ Honest status vs the bullets above. **None** of these residuals re-open C–J as
| Garmin cross-validation | **Incomplete** | SDK samples used as smokes/fixtures; not a release gate for full interop |
| Non-`xfail` tests for listed constructs | **Partial** | Strong constructive coverage for C–J; expand goldens / remove any remaining known-gap xfails as follow-up |
| Strict mode no silent repair | **Met** | `strict=True` / DEFAULT_LEVELS never clamp or auto-repair; no `repair()` on strict path |
-| Published SDK/Profile version | **Met** | Profile / SDK `21.218.0` (`fit_tool/gen/`, `SDK_VERSION`) |
+| Published SDK/Profile version | **Met** | Profile / SDK `21.221.0` (`fit_tool/gen/`, `SDK_VERSION`) |
**Bottom line:** SHA-12 may move to `done` / `in_review` with the residuals
above explicit. Do **not** flip public marketing to “full Garmin FIT
diff --git a/fit_tool/__init__.py b/fit_tool/__init__.py
index 288448f..189d58d 100755
--- a/fit_tool/__init__.py
+++ b/fit_tool/__init__.py
@@ -17,7 +17,7 @@
# limitation"), but the value defined by the SDK for the header is 2.0
# (FIT_PROTOCOL_VERSION_20); developer fields require 2.0.
PROTOCOL_VERSION = '2.0'
-SDK_VERSION = '21.218.0'
+SDK_VERSION = '21.221.0'
FIT_DATA_TYPE = b'.FIT'
from fit_tool.api import ( # noqa: E402
diff --git a/fit_tool/gen/Profile_21.218.0.xlsx b/fit_tool/gen/Profile_21.218.0.xlsx
deleted file mode 100644
index 63c1310..0000000
Binary files a/fit_tool/gen/Profile_21.218.0.xlsx and /dev/null differ
diff --git a/fit_tool/gen/Profile_21.221.0.xlsx b/fit_tool/gen/Profile_21.221.0.xlsx
new file mode 100644
index 0000000..16e50ec
Binary files /dev/null and b/fit_tool/gen/Profile_21.221.0.xlsx differ
diff --git a/fit_tool/profile/component_registry.py b/fit_tool/profile/component_registry.py
index fd924bd..26d9dd1 100644
--- a/fit_tool/profile/component_registry.py
+++ b/fit_tool/profile/component_registry.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
# Main-field components only (subfield-gated components omitted — see Stage 2 D).
"""Profile component registry for decode-time expansion.
diff --git a/fit_tool/profile/field_catalog.py b/fit_tool/profile/field_catalog.py
index eb4d841..353c58e 100644
--- a/fit_tool/profile/field_catalog.py
+++ b/fit_tool/profile/field_catalog.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
"""Native field and closed-enum catalog for PROFILE validation.
Generated from the bundled Garmin Profile spreadsheet by ``gen-profile``.
@@ -16,10 +16,10 @@
from fit_tool.base_type import BaseType
-PROFILE_SDK_VERSION = '21.218.0'
-PROFILE_MESSAGE_COUNT = 124
-PROFILE_FIELD_COUNT = 1566
-PROFILE_ENUM_TYPE_COUNT = 115
+PROFILE_SDK_VERSION = '21.221.0'
+PROFILE_MESSAGE_COUNT = 127
+PROFILE_FIELD_COUNT = 1593
+PROFILE_ENUM_TYPE_COUNT = 119
# (global_message_number, field_id) → (name, BaseType, type_name, units, scale, offset)
PROFILE_FIELDS: dict[tuple[int, int], tuple[str, BaseType, str, str, float, float]] = {
@@ -1511,6 +1511,33 @@
(346, 11): ('awakenings_count', BaseType.UINT8, 'uint8', '', 1.0, 0.0), # sleep_assessment
(346, 14): ('interruptions_score', BaseType.UINT8, 'uint8', '', 1.0, 0.0), # sleep_assessment
(346, 15): ('average_stress_during_sleep', BaseType.UINT16, 'uint16', '', 100.0, 0.0), # sleep_assessment
+ (364, 0): ('sonar_packet_id', BaseType.ENUM, 'sonar_packet_id', '', 1.0, 0.0), # tsb_sonar_message_event
+ (364, 21): ('diver_location_accuracy', BaseType.UINT16, 'uint16', 'degrees', 1.0, 0.0), # tsb_sonar_message_event
+ (364, 22): ('message_type', BaseType.ENUM, 'sonar_message_type', '', 1.0, 0.0), # tsb_sonar_message_event
+ (364, 23): ('message_source', BaseType.ENUM, 'sonar_message_source', '', 1.0, 0.0), # tsb_sonar_message_event
+ (365, 0): ('tx_enable', BaseType.UINT8, 'bool', '', 1.0, 0.0), # tsb_settings
+ (365, 1): ('proportional_gain', BaseType.FLOAT32, 'float32', 'dB', 1.0, 0.0), # tsb_settings
+ (365, 2): ('integral_gain', BaseType.FLOAT32, 'float32', 'dB', 1.0, 0.0), # tsb_settings
+ (365, 3): ('fixed_gain', BaseType.UINT8, 'uint8', 'dB', 1.0, 0.0), # tsb_settings
+ (365, 4): ('rssi_setpoint', BaseType.UINT32, 'uint32', '', 1.0, 0.0), # tsb_settings
+ (365, 5): ('plt_thresh_mult', BaseType.FLOAT32, 'float32', '', 1.0, 0.0), # tsb_settings
+ (365, 6): ('plt_thresh', BaseType.UINT32, 'uint32', '', 1.0, 0.0), # tsb_settings
+ (365, 7): ('transducer_spacing', BaseType.FLOAT32, 'float32', 'm', 1.0, 0.0), # tsb_settings
+ (365, 8): ('calib_accel', BaseType.FLOAT32, 'float32', '', 1.0, 0.0), # tsb_settings
+ (365, 9): ('calib_gyro', BaseType.FLOAT32, 'float32', '', 1.0, 0.0), # tsb_settings
+ (365, 10): ('calib_mag', BaseType.FLOAT32, 'float32', '', 1.0, 0.0), # tsb_settings
+ (365, 11): ('calib_mag_soft_x', BaseType.FLOAT32, 'float32', '', 1.0, 0.0), # tsb_settings
+ (365, 12): ('calib_mag_soft_y', BaseType.FLOAT32, 'float32', '', 1.0, 0.0), # tsb_settings
+ (365, 13): ('calib_mag_soft_z', BaseType.FLOAT32, 'float32', '', 1.0, 0.0), # tsb_settings
+ (365, 14): ('max_tx_duty_cycle', BaseType.UINT8, 'uint8', '', 1.0, 0.0), # tsb_settings
+ (365, 15): ('tx_chan', BaseType.UINT8, 'uint8', '', 1.0, 0.0), # tsb_settings
+ (365, 16): ('search_gain', BaseType.UINT8, 'uint8', 'dB', 1.0, 0.0), # tsb_settings
+ (366, 0): ('ant_id', BaseType.UINT32Z, 'uint32z', '', 1.0, 0.0), # tsb_diver_config
+ (366, 1): ('diver_name', BaseType.STRING, 'string', '', 1.0, 0.0), # tsb_diver_config
+ (366, 2): ('t1_tankpod_sw_ver', BaseType.UINT16, 'uint16', '', 100.0, 0.0), # tsb_diver_config
+ (366, 3): ('location_enabled', BaseType.UINT8, 'bool', '', 1.0, 0.0), # tsb_diver_config
+ (366, 4): ('messaging_enabled', BaseType.UINT8, 'bool', '', 1.0, 0.0), # tsb_diver_config
+ (366, 5): ('t1_owner_ant_id', BaseType.UINT32Z, 'uint32z', '', 1.0, 0.0), # tsb_diver_config
(370, 0): ('weekly_average', BaseType.UINT16, 'uint16', 'ms', 128.0, 0.0), # hrv_status_summary
(370, 1): ('last_night_average', BaseType.UINT16, 'uint16', 'ms', 128.0, 0.0), # hrv_status_summary
(370, 2): ('last_night_5_min_high', BaseType.UINT16, 'uint16', 'ms', 128.0, 0.0), # hrv_status_summary
@@ -1642,7 +1669,7 @@
'exd_display_type': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}),
'exd_layout': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8}),
'exd_qualifiers': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 242, 243, 244, 245, 246, 247, 248, 249, 250}),
- 'file': frozenset({1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 14, 15, 20, 28, 32, 34, 35, 40, 247, 254}),
+ 'file': frozenset({1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 14, 15, 20, 28, 32, 34, 35, 40, 66, 67, 247, 254}),
'fitness_equipment_state': frozenset({0, 1, 2, 3}),
'font_grading_scale': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}),
'french_grading_scale': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}),
@@ -1681,6 +1708,10 @@
'side': frozenset({0, 1}),
'sleep_disruption_severity': frozenset({0, 1, 2, 3}),
'sleep_level': frozenset({0, 1, 2, 3, 4}),
+ 'sonar_heading': frozenset({0, 1, 2, 3, 4, 5, 6, 7}),
+ 'sonar_message_source': frozenset({0, 1}),
+ 'sonar_message_type': frozenset({0, 1}),
+ 'sonar_packet_id': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}),
'source_type': frozenset({0, 1, 2, 3, 4, 5}),
'split_status': frozenset({0, 1, 2, 3}),
'split_type': frozenset({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 21, 22, 23, 28, 29}),
@@ -1712,5 +1743,5 @@
'yds_grading_scale': frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68}),
}
-PROFILE_ENUM_FIELD_COUNT = 164
+PROFILE_ENUM_FIELD_COUNT = 167
diff --git a/fit_tool/profile/messages/aad_accel_features_message.py b/fit_tool/profile/messages/aad_accel_features_message.py
index 0ff9d0c..4d823f0 100644
--- a/fit_tool/profile/messages/aad_accel_features_message.py
+++ b/fit_tool/profile/messages/aad_accel_features_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/accelerometer_data_message.py b/fit_tool/profile/messages/accelerometer_data_message.py
index e6f3882..b16e6d1 100644
--- a/fit_tool/profile/messages/accelerometer_data_message.py
+++ b/fit_tool/profile/messages/accelerometer_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/activity_message.py b/fit_tool/profile/messages/activity_message.py
index 6f061cd..156c705 100644
--- a/fit_tool/profile/messages/activity_message.py
+++ b/fit_tool/profile/messages/activity_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/ant_channel_id_message.py b/fit_tool/profile/messages/ant_channel_id_message.py
index 662cdf7..1bd07db 100644
--- a/fit_tool/profile/messages/ant_channel_id_message.py
+++ b/fit_tool/profile/messages/ant_channel_id_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/ant_rx_message.py b/fit_tool/profile/messages/ant_rx_message.py
index d1de07e..d94e3e5 100644
--- a/fit_tool/profile/messages/ant_rx_message.py
+++ b/fit_tool/profile/messages/ant_rx_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/ant_tx_message.py b/fit_tool/profile/messages/ant_tx_message.py
index 4549b27..bf9baf7 100644
--- a/fit_tool/profile/messages/ant_tx_message.py
+++ b/fit_tool/profile/messages/ant_tx_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/aviation_attitude_message.py b/fit_tool/profile/messages/aviation_attitude_message.py
index 4316c1e..22a066d 100644
--- a/fit_tool/profile/messages/aviation_attitude_message.py
+++ b/fit_tool/profile/messages/aviation_attitude_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/barometer_data_message.py b/fit_tool/profile/messages/barometer_data_message.py
index 610d68d..5ca147f 100644
--- a/fit_tool/profile/messages/barometer_data_message.py
+++ b/fit_tool/profile/messages/barometer_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/battery_message.py b/fit_tool/profile/messages/battery_message.py
index 08510c9..c5d3d2d 100644
--- a/fit_tool/profile/messages/battery_message.py
+++ b/fit_tool/profile/messages/battery_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/beat_intervals_message.py b/fit_tool/profile/messages/beat_intervals_message.py
index 50309aa..97fa069 100644
--- a/fit_tool/profile/messages/beat_intervals_message.py
+++ b/fit_tool/profile/messages/beat_intervals_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/bike_profile_message.py b/fit_tool/profile/messages/bike_profile_message.py
index ae419e5..efc08f3 100644
--- a/fit_tool/profile/messages/bike_profile_message.py
+++ b/fit_tool/profile/messages/bike_profile_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/blood_pressure_message.py b/fit_tool/profile/messages/blood_pressure_message.py
index eecc319..b16af87 100644
--- a/fit_tool/profile/messages/blood_pressure_message.py
+++ b/fit_tool/profile/messages/blood_pressure_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/cadence_zone_message.py b/fit_tool/profile/messages/cadence_zone_message.py
index 6f2bb3c..427ca08 100644
--- a/fit_tool/profile/messages/cadence_zone_message.py
+++ b/fit_tool/profile/messages/cadence_zone_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/camera_event_message.py b/fit_tool/profile/messages/camera_event_message.py
index ed7d70e..408f961 100644
--- a/fit_tool/profile/messages/camera_event_message.py
+++ b/fit_tool/profile/messages/camera_event_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/capabilities_message.py b/fit_tool/profile/messages/capabilities_message.py
index f5ea8b3..7f4a39c 100644
--- a/fit_tool/profile/messages/capabilities_message.py
+++ b/fit_tool/profile/messages/capabilities_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/chrono_shot_data_message.py b/fit_tool/profile/messages/chrono_shot_data_message.py
index 1a7dabb..156a53d 100644
--- a/fit_tool/profile/messages/chrono_shot_data_message.py
+++ b/fit_tool/profile/messages/chrono_shot_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/chrono_shot_session_message.py b/fit_tool/profile/messages/chrono_shot_session_message.py
index 60ee191..b0d67a3 100644
--- a/fit_tool/profile/messages/chrono_shot_session_message.py
+++ b/fit_tool/profile/messages/chrono_shot_session_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/climb_pro_message.py b/fit_tool/profile/messages/climb_pro_message.py
index 4c48a3b..4013cba 100644
--- a/fit_tool/profile/messages/climb_pro_message.py
+++ b/fit_tool/profile/messages/climb_pro_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/common_fields.py b/fit_tool/profile/messages/common_fields.py
index 05fc6e2..6113896 100644
--- a/fit_tool/profile/messages/common_fields.py
+++ b/fit_tool/profile/messages/common_fields.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from fit_tool.base_type import BaseType
from fit_tool.field import Field
diff --git a/fit_tool/profile/messages/connectivity_message.py b/fit_tool/profile/messages/connectivity_message.py
index 294be3f..4aa08e7 100644
--- a/fit_tool/profile/messages/connectivity_message.py
+++ b/fit_tool/profile/messages/connectivity_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/course_message.py b/fit_tool/profile/messages/course_message.py
index 80856e7..8466e30 100644
--- a/fit_tool/profile/messages/course_message.py
+++ b/fit_tool/profile/messages/course_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/course_point_message.py b/fit_tool/profile/messages/course_point_message.py
index 761b836..c016aa8 100644
--- a/fit_tool/profile/messages/course_point_message.py
+++ b/fit_tool/profile/messages/course_point_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/developer_data_id_message.py b/fit_tool/profile/messages/developer_data_id_message.py
index 26614a0..b82efe4 100644
--- a/fit_tool/profile/messages/developer_data_id_message.py
+++ b/fit_tool/profile/messages/developer_data_id_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/device_aux_battery_info_message.py b/fit_tool/profile/messages/device_aux_battery_info_message.py
index 3fa5a3b..7d60500 100644
--- a/fit_tool/profile/messages/device_aux_battery_info_message.py
+++ b/fit_tool/profile/messages/device_aux_battery_info_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/device_info_message.py b/fit_tool/profile/messages/device_info_message.py
index eca5075..e7c7ca6 100644
--- a/fit_tool/profile/messages/device_info_message.py
+++ b/fit_tool/profile/messages/device_info_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/device_settings_message.py b/fit_tool/profile/messages/device_settings_message.py
index 2a8917c..a7756a3 100644
--- a/fit_tool/profile/messages/device_settings_message.py
+++ b/fit_tool/profile/messages/device_settings_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/dive_alarm_message.py b/fit_tool/profile/messages/dive_alarm_message.py
index f487c82..48a2149 100644
--- a/fit_tool/profile/messages/dive_alarm_message.py
+++ b/fit_tool/profile/messages/dive_alarm_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/dive_apnea_alarm_message.py b/fit_tool/profile/messages/dive_apnea_alarm_message.py
index 33c9f59..fd359bb 100644
--- a/fit_tool/profile/messages/dive_apnea_alarm_message.py
+++ b/fit_tool/profile/messages/dive_apnea_alarm_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/dive_gas_message.py b/fit_tool/profile/messages/dive_gas_message.py
index bade433..6534eea 100644
--- a/fit_tool/profile/messages/dive_gas_message.py
+++ b/fit_tool/profile/messages/dive_gas_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/dive_settings_message.py b/fit_tool/profile/messages/dive_settings_message.py
index 999d59d..0c937b7 100644
--- a/fit_tool/profile/messages/dive_settings_message.py
+++ b/fit_tool/profile/messages/dive_settings_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/dive_summary_message.py b/fit_tool/profile/messages/dive_summary_message.py
index b784213..938261d 100644
--- a/fit_tool/profile/messages/dive_summary_message.py
+++ b/fit_tool/profile/messages/dive_summary_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/event_message.py b/fit_tool/profile/messages/event_message.py
index 0648fea..797ede8 100644
--- a/fit_tool/profile/messages/event_message.py
+++ b/fit_tool/profile/messages/event_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/exd_data_concept_configuration_message.py b/fit_tool/profile/messages/exd_data_concept_configuration_message.py
index 503ae1a..f9dd36e 100644
--- a/fit_tool/profile/messages/exd_data_concept_configuration_message.py
+++ b/fit_tool/profile/messages/exd_data_concept_configuration_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/exd_data_field_configuration_message.py b/fit_tool/profile/messages/exd_data_field_configuration_message.py
index acd2bc8..057d059 100644
--- a/fit_tool/profile/messages/exd_data_field_configuration_message.py
+++ b/fit_tool/profile/messages/exd_data_field_configuration_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/exd_screen_configuration_message.py b/fit_tool/profile/messages/exd_screen_configuration_message.py
index d8c618b..3bd7cb1 100644
--- a/fit_tool/profile/messages/exd_screen_configuration_message.py
+++ b/fit_tool/profile/messages/exd_screen_configuration_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/exercise_title_message.py b/fit_tool/profile/messages/exercise_title_message.py
index ca4fdd9..c3d39c5 100644
--- a/fit_tool/profile/messages/exercise_title_message.py
+++ b/fit_tool/profile/messages/exercise_title_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/field_capabilities_message.py b/fit_tool/profile/messages/field_capabilities_message.py
index b6aa6d4..23f9356 100644
--- a/fit_tool/profile/messages/field_capabilities_message.py
+++ b/fit_tool/profile/messages/field_capabilities_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/field_description_message.py b/fit_tool/profile/messages/field_description_message.py
index 70031c0..da196ea 100644
--- a/fit_tool/profile/messages/field_description_message.py
+++ b/fit_tool/profile/messages/field_description_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/file_capabilities_message.py b/fit_tool/profile/messages/file_capabilities_message.py
index 7b8118f..4b216b7 100644
--- a/fit_tool/profile/messages/file_capabilities_message.py
+++ b/fit_tool/profile/messages/file_capabilities_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/file_creator_message.py b/fit_tool/profile/messages/file_creator_message.py
index 796b3d1..cf4ae70 100644
--- a/fit_tool/profile/messages/file_creator_message.py
+++ b/fit_tool/profile/messages/file_creator_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/file_id_message.py b/fit_tool/profile/messages/file_id_message.py
index 8c35a69..905f062 100644
--- a/fit_tool/profile/messages/file_id_message.py
+++ b/fit_tool/profile/messages/file_id_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/goal_message.py b/fit_tool/profile/messages/goal_message.py
index a4756a4..e335b92 100644
--- a/fit_tool/profile/messages/goal_message.py
+++ b/fit_tool/profile/messages/goal_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/gps_metadata_message.py b/fit_tool/profile/messages/gps_metadata_message.py
index ee1ad75..5b99da3 100644
--- a/fit_tool/profile/messages/gps_metadata_message.py
+++ b/fit_tool/profile/messages/gps_metadata_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/gyroscope_data_message.py b/fit_tool/profile/messages/gyroscope_data_message.py
index f56b4a3..2837cc1 100644
--- a/fit_tool/profile/messages/gyroscope_data_message.py
+++ b/fit_tool/profile/messages/gyroscope_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hr_message.py b/fit_tool/profile/messages/hr_message.py
index 4e6b0f4..3c2502f 100644
--- a/fit_tool/profile/messages/hr_message.py
+++ b/fit_tool/profile/messages/hr_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hr_zone_message.py b/fit_tool/profile/messages/hr_zone_message.py
index 670e01b..0479b0f 100644
--- a/fit_tool/profile/messages/hr_zone_message.py
+++ b/fit_tool/profile/messages/hr_zone_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hrm_profile_message.py b/fit_tool/profile/messages/hrm_profile_message.py
index 949d7ee..9942e99 100644
--- a/fit_tool/profile/messages/hrm_profile_message.py
+++ b/fit_tool/profile/messages/hrm_profile_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hrv_message.py b/fit_tool/profile/messages/hrv_message.py
index 351563c..3981d89 100644
--- a/fit_tool/profile/messages/hrv_message.py
+++ b/fit_tool/profile/messages/hrv_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hrv_status_summary_message.py b/fit_tool/profile/messages/hrv_status_summary_message.py
index 053dca7..23b3a2f 100644
--- a/fit_tool/profile/messages/hrv_status_summary_message.py
+++ b/fit_tool/profile/messages/hrv_status_summary_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hrv_value_message.py b/fit_tool/profile/messages/hrv_value_message.py
index 352a31c..e908d2a 100644
--- a/fit_tool/profile/messages/hrv_value_message.py
+++ b/fit_tool/profile/messages/hrv_value_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_accelerometer_data_message.py b/fit_tool/profile/messages/hsa_accelerometer_data_message.py
index f6e6987..2b6a4f5 100644
--- a/fit_tool/profile/messages/hsa_accelerometer_data_message.py
+++ b/fit_tool/profile/messages/hsa_accelerometer_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_body_battery_data_message.py b/fit_tool/profile/messages/hsa_body_battery_data_message.py
index 61c249b..baf6f07 100644
--- a/fit_tool/profile/messages/hsa_body_battery_data_message.py
+++ b/fit_tool/profile/messages/hsa_body_battery_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_configuration_data_message.py b/fit_tool/profile/messages/hsa_configuration_data_message.py
index 4529f9f..86ca0f3 100644
--- a/fit_tool/profile/messages/hsa_configuration_data_message.py
+++ b/fit_tool/profile/messages/hsa_configuration_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_event_message.py b/fit_tool/profile/messages/hsa_event_message.py
index b8339e2..093155d 100644
--- a/fit_tool/profile/messages/hsa_event_message.py
+++ b/fit_tool/profile/messages/hsa_event_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_gyroscope_data_message.py b/fit_tool/profile/messages/hsa_gyroscope_data_message.py
index 4a4d176..0f34246 100644
--- a/fit_tool/profile/messages/hsa_gyroscope_data_message.py
+++ b/fit_tool/profile/messages/hsa_gyroscope_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_heart_rate_data_message.py b/fit_tool/profile/messages/hsa_heart_rate_data_message.py
index c8ada2a..5b00145 100644
--- a/fit_tool/profile/messages/hsa_heart_rate_data_message.py
+++ b/fit_tool/profile/messages/hsa_heart_rate_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_respiration_data_message.py b/fit_tool/profile/messages/hsa_respiration_data_message.py
index f6aeb19..e1f72fc 100644
--- a/fit_tool/profile/messages/hsa_respiration_data_message.py
+++ b/fit_tool/profile/messages/hsa_respiration_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_spo2_data_message.py b/fit_tool/profile/messages/hsa_spo2_data_message.py
index 452a1db..ffba867 100644
--- a/fit_tool/profile/messages/hsa_spo2_data_message.py
+++ b/fit_tool/profile/messages/hsa_spo2_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_step_data_message.py b/fit_tool/profile/messages/hsa_step_data_message.py
index ceacdd5..c028eca 100644
--- a/fit_tool/profile/messages/hsa_step_data_message.py
+++ b/fit_tool/profile/messages/hsa_step_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_stress_data_message.py b/fit_tool/profile/messages/hsa_stress_data_message.py
index 90600dc..69ac529 100644
--- a/fit_tool/profile/messages/hsa_stress_data_message.py
+++ b/fit_tool/profile/messages/hsa_stress_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/hsa_wrist_temperature_data_message.py b/fit_tool/profile/messages/hsa_wrist_temperature_data_message.py
index 530ea92..e25dba4 100644
--- a/fit_tool/profile/messages/hsa_wrist_temperature_data_message.py
+++ b/fit_tool/profile/messages/hsa_wrist_temperature_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/jump_message.py b/fit_tool/profile/messages/jump_message.py
index bd4342b..0451f44 100644
--- a/fit_tool/profile/messages/jump_message.py
+++ b/fit_tool/profile/messages/jump_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/lap_message.py b/fit_tool/profile/messages/lap_message.py
index 604b792..11380c7 100644
--- a/fit_tool/profile/messages/lap_message.py
+++ b/fit_tool/profile/messages/lap_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/length_message.py b/fit_tool/profile/messages/length_message.py
index f78f29f..3496544 100644
--- a/fit_tool/profile/messages/length_message.py
+++ b/fit_tool/profile/messages/length_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/magnetometer_data_message.py b/fit_tool/profile/messages/magnetometer_data_message.py
index efc1fc7..9f59d1e 100644
--- a/fit_tool/profile/messages/magnetometer_data_message.py
+++ b/fit_tool/profile/messages/magnetometer_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/max_met_data_message.py b/fit_tool/profile/messages/max_met_data_message.py
index 4584d4f..307ca38 100644
--- a/fit_tool/profile/messages/max_met_data_message.py
+++ b/fit_tool/profile/messages/max_met_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/memo_glob_message.py b/fit_tool/profile/messages/memo_glob_message.py
index e177f16..0082be7 100644
--- a/fit_tool/profile/messages/memo_glob_message.py
+++ b/fit_tool/profile/messages/memo_glob_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/mesg_capabilities_message.py b/fit_tool/profile/messages/mesg_capabilities_message.py
index d7fbeda..19e75f3 100644
--- a/fit_tool/profile/messages/mesg_capabilities_message.py
+++ b/fit_tool/profile/messages/mesg_capabilities_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/message_factory.py b/fit_tool/profile/messages/message_factory.py
index 10eda67..4b4bd17 100644
--- a/fit_tool/profile/messages/message_factory.py
+++ b/fit_tool/profile/messages/message_factory.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from functools import lru_cache
from importlib import import_module
from typing import List, Optional, Type
@@ -135,6 +135,9 @@
470: ('fit_tool.profile.messages.sleep_disruption_severity_period_message', 'SleepDisruptionSeverityPeriodMessage'),
471: ('fit_tool.profile.messages.sleep_disruption_overnight_severity_message', 'SleepDisruptionOvernightSeverityMessage'),
412: ('fit_tool.profile.messages.nap_event_message', 'NapEventMessage'),
+ 364: ('fit_tool.profile.messages.tsb_sonar_message_event_message', 'TsbSonarMessageEventMessage'),
+ 365: ('fit_tool.profile.messages.tsb_settings_message', 'TsbSettingsMessage'),
+ 366: ('fit_tool.profile.messages.tsb_diver_config_message', 'TsbDiverConfigMessage'),
398: ('fit_tool.profile.messages.skin_temp_overnight_message', 'SkinTempOvernightMessage'),
}
diff --git a/fit_tool/profile/messages/met_zone_message.py b/fit_tool/profile/messages/met_zone_message.py
index c945bca..40718ce 100644
--- a/fit_tool/profile/messages/met_zone_message.py
+++ b/fit_tool/profile/messages/met_zone_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/monitoring_hr_data_message.py b/fit_tool/profile/messages/monitoring_hr_data_message.py
index 207ad76..44270bf 100644
--- a/fit_tool/profile/messages/monitoring_hr_data_message.py
+++ b/fit_tool/profile/messages/monitoring_hr_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/monitoring_info_message.py b/fit_tool/profile/messages/monitoring_info_message.py
index 3c4421e..09820a8 100644
--- a/fit_tool/profile/messages/monitoring_info_message.py
+++ b/fit_tool/profile/messages/monitoring_info_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/monitoring_message.py b/fit_tool/profile/messages/monitoring_message.py
index b1f8411..b0d4690 100644
--- a/fit_tool/profile/messages/monitoring_message.py
+++ b/fit_tool/profile/messages/monitoring_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/nap_event_message.py b/fit_tool/profile/messages/nap_event_message.py
index a0d6c56..7332e8f 100644
--- a/fit_tool/profile/messages/nap_event_message.py
+++ b/fit_tool/profile/messages/nap_event_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/nmea_sentence_message.py b/fit_tool/profile/messages/nmea_sentence_message.py
index 875bac4..fa40cfa 100644
--- a/fit_tool/profile/messages/nmea_sentence_message.py
+++ b/fit_tool/profile/messages/nmea_sentence_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/obdii_data_message.py b/fit_tool/profile/messages/obdii_data_message.py
index 607bd82..8438414 100644
--- a/fit_tool/profile/messages/obdii_data_message.py
+++ b/fit_tool/profile/messages/obdii_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/ohr_settings_message.py b/fit_tool/profile/messages/ohr_settings_message.py
index 4ff7989..21f007f 100644
--- a/fit_tool/profile/messages/ohr_settings_message.py
+++ b/fit_tool/profile/messages/ohr_settings_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/one_d_sensor_calibration_message.py b/fit_tool/profile/messages/one_d_sensor_calibration_message.py
index 0ca89f4..e84229e 100644
--- a/fit_tool/profile/messages/one_d_sensor_calibration_message.py
+++ b/fit_tool/profile/messages/one_d_sensor_calibration_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/power_zone_message.py b/fit_tool/profile/messages/power_zone_message.py
index 115539a..6f5b044 100644
--- a/fit_tool/profile/messages/power_zone_message.py
+++ b/fit_tool/profile/messages/power_zone_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/raw_bbi_message.py b/fit_tool/profile/messages/raw_bbi_message.py
index e86becc..d2cff8e 100644
--- a/fit_tool/profile/messages/raw_bbi_message.py
+++ b/fit_tool/profile/messages/raw_bbi_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/record_message.py b/fit_tool/profile/messages/record_message.py
index e639283..364cc49 100644
--- a/fit_tool/profile/messages/record_message.py
+++ b/fit_tool/profile/messages/record_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/respiration_rate_message.py b/fit_tool/profile/messages/respiration_rate_message.py
index 07008d6..27ac7d0 100644
--- a/fit_tool/profile/messages/respiration_rate_message.py
+++ b/fit_tool/profile/messages/respiration_rate_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/schedule_message.py b/fit_tool/profile/messages/schedule_message.py
index 56fad03..d036538 100644
--- a/fit_tool/profile/messages/schedule_message.py
+++ b/fit_tool/profile/messages/schedule_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/sdm_profile_message.py b/fit_tool/profile/messages/sdm_profile_message.py
index fab111e..e8d77b8 100644
--- a/fit_tool/profile/messages/sdm_profile_message.py
+++ b/fit_tool/profile/messages/sdm_profile_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/segment_file_message.py b/fit_tool/profile/messages/segment_file_message.py
index 95eefc2..4fce30d 100644
--- a/fit_tool/profile/messages/segment_file_message.py
+++ b/fit_tool/profile/messages/segment_file_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/segment_id_message.py b/fit_tool/profile/messages/segment_id_message.py
index 0760a20..cc14773 100644
--- a/fit_tool/profile/messages/segment_id_message.py
+++ b/fit_tool/profile/messages/segment_id_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/segment_lap_message.py b/fit_tool/profile/messages/segment_lap_message.py
index f2b943d..3deea5f 100644
--- a/fit_tool/profile/messages/segment_lap_message.py
+++ b/fit_tool/profile/messages/segment_lap_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/segment_leaderboard_entry_message.py b/fit_tool/profile/messages/segment_leaderboard_entry_message.py
index 67bbb13..161840d 100644
--- a/fit_tool/profile/messages/segment_leaderboard_entry_message.py
+++ b/fit_tool/profile/messages/segment_leaderboard_entry_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/segment_point_message.py b/fit_tool/profile/messages/segment_point_message.py
index f7d1eb8..2b7eac4 100644
--- a/fit_tool/profile/messages/segment_point_message.py
+++ b/fit_tool/profile/messages/segment_point_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/session_message.py b/fit_tool/profile/messages/session_message.py
index d040641..66aa0b5 100644
--- a/fit_tool/profile/messages/session_message.py
+++ b/fit_tool/profile/messages/session_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/set_message.py b/fit_tool/profile/messages/set_message.py
index eb8b838..2e9e362 100644
--- a/fit_tool/profile/messages/set_message.py
+++ b/fit_tool/profile/messages/set_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/skin_temp_overnight_message.py b/fit_tool/profile/messages/skin_temp_overnight_message.py
index 51b05cb..6476eed 100644
--- a/fit_tool/profile/messages/skin_temp_overnight_message.py
+++ b/fit_tool/profile/messages/skin_temp_overnight_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/slave_device_message.py b/fit_tool/profile/messages/slave_device_message.py
index 7f0295d..89171f9 100644
--- a/fit_tool/profile/messages/slave_device_message.py
+++ b/fit_tool/profile/messages/slave_device_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/sleep_assessment_message.py b/fit_tool/profile/messages/sleep_assessment_message.py
index 8e1fc7a..3634523 100644
--- a/fit_tool/profile/messages/sleep_assessment_message.py
+++ b/fit_tool/profile/messages/sleep_assessment_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/sleep_disruption_overnight_severity_message.py b/fit_tool/profile/messages/sleep_disruption_overnight_severity_message.py
index a9e5a2f..f13fa59 100644
--- a/fit_tool/profile/messages/sleep_disruption_overnight_severity_message.py
+++ b/fit_tool/profile/messages/sleep_disruption_overnight_severity_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/sleep_disruption_severity_period_message.py b/fit_tool/profile/messages/sleep_disruption_severity_period_message.py
index 76cad7c..663041a 100644
--- a/fit_tool/profile/messages/sleep_disruption_severity_period_message.py
+++ b/fit_tool/profile/messages/sleep_disruption_severity_period_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/sleep_level_message.py b/fit_tool/profile/messages/sleep_level_message.py
index 530d91a..39eca40 100644
--- a/fit_tool/profile/messages/sleep_level_message.py
+++ b/fit_tool/profile/messages/sleep_level_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/software_message.py b/fit_tool/profile/messages/software_message.py
index 66ed359..8572bb2 100644
--- a/fit_tool/profile/messages/software_message.py
+++ b/fit_tool/profile/messages/software_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/speed_zone_message.py b/fit_tool/profile/messages/speed_zone_message.py
index 0b433b6..4427052 100644
--- a/fit_tool/profile/messages/speed_zone_message.py
+++ b/fit_tool/profile/messages/speed_zone_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/split_message.py b/fit_tool/profile/messages/split_message.py
index 1c424d2..1cf81dd 100644
--- a/fit_tool/profile/messages/split_message.py
+++ b/fit_tool/profile/messages/split_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/split_summary_message.py b/fit_tool/profile/messages/split_summary_message.py
index e20fe48..e1349fc 100644
--- a/fit_tool/profile/messages/split_summary_message.py
+++ b/fit_tool/profile/messages/split_summary_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/spo2_data_message.py b/fit_tool/profile/messages/spo2_data_message.py
index 524c686..36aa7c4 100644
--- a/fit_tool/profile/messages/spo2_data_message.py
+++ b/fit_tool/profile/messages/spo2_data_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/sport_message.py b/fit_tool/profile/messages/sport_message.py
index 449f456..3f06209 100644
--- a/fit_tool/profile/messages/sport_message.py
+++ b/fit_tool/profile/messages/sport_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/stress_level_message.py b/fit_tool/profile/messages/stress_level_message.py
index afde619..9029144 100644
--- a/fit_tool/profile/messages/stress_level_message.py
+++ b/fit_tool/profile/messages/stress_level_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/tank_summary_message.py b/fit_tool/profile/messages/tank_summary_message.py
index 56de9ff..53fee10 100644
--- a/fit_tool/profile/messages/tank_summary_message.py
+++ b/fit_tool/profile/messages/tank_summary_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/tank_update_message.py b/fit_tool/profile/messages/tank_update_message.py
index 06d9d66..8a25b07 100644
--- a/fit_tool/profile/messages/tank_update_message.py
+++ b/fit_tool/profile/messages/tank_update_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/three_d_sensor_calibration_message.py b/fit_tool/profile/messages/three_d_sensor_calibration_message.py
index d073963..ec89c7a 100644
--- a/fit_tool/profile/messages/three_d_sensor_calibration_message.py
+++ b/fit_tool/profile/messages/three_d_sensor_calibration_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/time_in_zone_message.py b/fit_tool/profile/messages/time_in_zone_message.py
index 6e29a99..f742afd 100644
--- a/fit_tool/profile/messages/time_in_zone_message.py
+++ b/fit_tool/profile/messages/time_in_zone_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/timestamp_correlation_message.py b/fit_tool/profile/messages/timestamp_correlation_message.py
index 3eed5e2..a483bd5 100644
--- a/fit_tool/profile/messages/timestamp_correlation_message.py
+++ b/fit_tool/profile/messages/timestamp_correlation_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/totals_message.py b/fit_tool/profile/messages/totals_message.py
index d671c34..f1732a9 100644
--- a/fit_tool/profile/messages/totals_message.py
+++ b/fit_tool/profile/messages/totals_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/training_file_message.py b/fit_tool/profile/messages/training_file_message.py
index a592b48..e981e26 100644
--- a/fit_tool/profile/messages/training_file_message.py
+++ b/fit_tool/profile/messages/training_file_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/training_settings_message.py b/fit_tool/profile/messages/training_settings_message.py
index bf061c7..eb2198f 100644
--- a/fit_tool/profile/messages/training_settings_message.py
+++ b/fit_tool/profile/messages/training_settings_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/tsb_diver_config_message.py b/fit_tool/profile/messages/tsb_diver_config_message.py
new file mode 100644
index 0000000..e4962eb
--- /dev/null
+++ b/fit_tool/profile/messages/tsb_diver_config_message.py
@@ -0,0 +1,380 @@
+# Autogenerated. Do not modify.
+#
+# Profile: 21.221.0
+from typing import Optional
+
+from fit_tool.base_type import BaseType
+from fit_tool.data_message import DataMessage
+from fit_tool.definition_message import DefinitionMessage
+from fit_tool.developer_field import DeveloperField
+from fit_tool.endian import Endian
+from fit_tool.field import Field
+from fit_tool.sub_field import SubField
+from fit_tool.profile.messages.common_fields import MessageIndexField, TimestampField
+from fit_tool.profile.profile_type import *
+from typing import List as list
+from typing import Dict as dict
+
+
+class TsbDiverConfigMessage(DataMessage):
+ """TsbDiverConfigMessage — use blank construct for authoring, ``from_definition`` for decode.
+
+ * ``TsbDiverConfigMessage()`` — create path: growable fields, no wire definition.
+ * ``TsbDiverConfigMessage.from_definition(definition, developer_fields=...)`` —
+ project a local definition onto this type (decode / MessageFactory path).
+ """
+
+ ID = 366
+ NAME = 'tsb_diver_config'
+
+ @staticmethod
+ def _field_size_from_definition(definition_message: DefinitionMessage, field_id: int) -> int:
+ field_definition = definition_message.get_field_definition(field_id)
+ if field_definition:
+ return field_definition.size
+ return 0
+
+ def __init__(self, developer_fields=None, local_id: int = 0,
+ endian: Endian = Endian.LITTLE):
+ """Create a blank message for authoring (growable fields, no definition)."""
+ super().__init__(name=TsbDiverConfigMessage.NAME,
+ global_id=TsbDiverConfigMessage.ID,
+ local_id=local_id,
+ endian=endian,
+ definition_message=None,
+ developer_fields=developer_fields,
+ fields=[
+ TsbDiverConfigAntIdField(
+ size=0,
+ growable=True),
+ TsbDiverConfigDiverNameField(
+ size=0,
+ growable=True),
+ TsbDiverConfigT1TankpodSwVerField(
+ size=0,
+ growable=True),
+ TsbDiverConfigLocationEnabledField(
+ size=0,
+ growable=True),
+ TsbDiverConfigMessagingEnabledField(
+ size=0,
+ growable=True),
+ TsbDiverConfigT1OwnerAntIdField(
+ size=0,
+ growable=True)
+ ])
+
+ self.growable = True
+
+ @classmethod
+ def from_definition(cls, definition_message: DefinitionMessage,
+ developer_fields: list[DeveloperField] = None):
+ """Project a wire definition onto this message type (decode path).
+
+ Field sizes come from the definition; fields are not growable. Prefer this
+ over passing a definition into ``__init__``.
+ """
+ message = cls.__new__(cls)
+ DataMessage.__init__(
+ message,
+ name=cls.NAME,
+ global_id=cls.ID,
+ local_id=definition_message.local_id,
+ endian=definition_message.endian,
+ definition_message=definition_message,
+ developer_fields=developer_fields,
+ fields=[
+ TsbDiverConfigAntIdField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbDiverConfigAntIdField.ID),
+ growable=False),
+ TsbDiverConfigDiverNameField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbDiverConfigDiverNameField.ID),
+ growable=False),
+ TsbDiverConfigT1TankpodSwVerField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbDiverConfigT1TankpodSwVerField.ID),
+ growable=False),
+ TsbDiverConfigLocationEnabledField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbDiverConfigLocationEnabledField.ID),
+ growable=False),
+ TsbDiverConfigMessagingEnabledField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbDiverConfigMessagingEnabledField.ID),
+ growable=False),
+ TsbDiverConfigT1OwnerAntIdField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbDiverConfigT1OwnerAntIdField.ID),
+ growable=False)
+ ])
+ message.growable = False
+ # Keep definition field ids not present in the Profile schema (Stage 2 E).
+ message.retain_unknown_fields()
+ return message
+
+ @classmethod
+ def from_bytes(cls, definition_message: DefinitionMessage, developer_fields: list[DeveloperField],
+ bytes_buffer: bytes, offset: int = 0):
+ message = cls.from_definition(definition_message, developer_fields=developer_fields)
+ message.read_from_bytes(bytes_buffer, offset)
+ return message
+
+
+
+
+ @property
+ def ant_id(self) -> Optional[int]:
+ field = self.get_field(TsbDiverConfigAntIdField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @ant_id.setter
+ def ant_id(self, value: int):
+ field = self.get_field(TsbDiverConfigAntIdField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def diver_name(self) -> Optional[str]:
+ field = self.get_field(TsbDiverConfigDiverNameField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @diver_name.setter
+ def diver_name(self, value: str):
+ field = self.get_field(TsbDiverConfigDiverNameField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def t1_tankpod_sw_ver(self) -> Optional[float]:
+ field = self.get_field(TsbDiverConfigT1TankpodSwVerField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @t1_tankpod_sw_ver.setter
+ def t1_tankpod_sw_ver(self, value: float):
+ field = self.get_field(TsbDiverConfigT1TankpodSwVerField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def location_enabled(self) -> Optional[bool]:
+ field = self.get_field(TsbDiverConfigLocationEnabledField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @location_enabled.setter
+ def location_enabled(self, value: bool):
+ field = self.get_field(TsbDiverConfigLocationEnabledField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def messaging_enabled(self) -> Optional[bool]:
+ field = self.get_field(TsbDiverConfigMessagingEnabledField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @messaging_enabled.setter
+ def messaging_enabled(self, value: bool):
+ field = self.get_field(TsbDiverConfigMessagingEnabledField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def t1_owner_ant_id(self) -> Optional[int]:
+ field = self.get_field(TsbDiverConfigT1OwnerAntIdField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @t1_owner_ant_id.setter
+ def t1_owner_ant_id(self, value: int):
+ field = self.get_field(TsbDiverConfigT1OwnerAntIdField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+
+
+
+
+class TsbDiverConfigAntIdField(Field):
+ ID = 0
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='ant_id',
+ field_id=self.ID,
+ base_type=BaseType.UINT32Z,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'uint32z',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbDiverConfigDiverNameField(Field):
+ ID = 1
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='diver_name',
+ field_id=self.ID,
+ base_type=BaseType.STRING,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'string',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbDiverConfigT1TankpodSwVerField(Field):
+ ID = 2
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='t1_tankpod_sw_ver',
+ field_id=self.ID,
+ base_type=BaseType.UINT16,
+ offset = 0,
+ scale = 100,
+ size = size,
+ type_name = 'uint16',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbDiverConfigLocationEnabledField(Field):
+ ID = 3
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='location_enabled',
+ field_id=self.ID,
+ base_type=BaseType.UINT8,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'bool',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbDiverConfigMessagingEnabledField(Field):
+ ID = 4
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='messaging_enabled',
+ field_id=self.ID,
+ base_type=BaseType.UINT8,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'bool',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbDiverConfigT1OwnerAntIdField(Field):
+ ID = 5
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='t1_owner_ant_id',
+ field_id=self.ID,
+ base_type=BaseType.UINT32Z,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'uint32z',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
\ No newline at end of file
diff --git a/fit_tool/profile/messages/tsb_settings_message.py b/fit_tool/profile/messages/tsb_settings_message.py
new file mode 100644
index 0000000..6e81575
--- /dev/null
+++ b/fit_tool/profile/messages/tsb_settings_message.py
@@ -0,0 +1,912 @@
+# Autogenerated. Do not modify.
+#
+# Profile: 21.221.0
+from typing import Optional
+
+from fit_tool.base_type import BaseType
+from fit_tool.data_message import DataMessage
+from fit_tool.definition_message import DefinitionMessage
+from fit_tool.developer_field import DeveloperField
+from fit_tool.endian import Endian
+from fit_tool.field import Field
+from fit_tool.sub_field import SubField
+from fit_tool.profile.messages.common_fields import MessageIndexField, TimestampField
+from fit_tool.profile.profile_type import *
+from typing import List as list
+from typing import Dict as dict
+
+
+class TsbSettingsMessage(DataMessage):
+ """TsbSettingsMessage — use blank construct for authoring, ``from_definition`` for decode.
+
+ * ``TsbSettingsMessage()`` — create path: growable fields, no wire definition.
+ * ``TsbSettingsMessage.from_definition(definition, developer_fields=...)`` —
+ project a local definition onto this type (decode / MessageFactory path).
+ """
+
+ ID = 365
+ NAME = 'tsb_settings'
+
+ @staticmethod
+ def _field_size_from_definition(definition_message: DefinitionMessage, field_id: int) -> int:
+ field_definition = definition_message.get_field_definition(field_id)
+ if field_definition:
+ return field_definition.size
+ return 0
+
+ def __init__(self, developer_fields=None, local_id: int = 0,
+ endian: Endian = Endian.LITTLE):
+ """Create a blank message for authoring (growable fields, no definition)."""
+ super().__init__(name=TsbSettingsMessage.NAME,
+ global_id=TsbSettingsMessage.ID,
+ local_id=local_id,
+ endian=endian,
+ definition_message=None,
+ developer_fields=developer_fields,
+ fields=[
+ TsbSettingsTxEnableField(
+ size=0,
+ growable=True),
+ TsbSettingsProportionalGainField(
+ size=0,
+ growable=True),
+ TsbSettingsIntegralGainField(
+ size=0,
+ growable=True),
+ TsbSettingsFixedGainField(
+ size=0,
+ growable=True),
+ TsbSettingsRssiSetpointField(
+ size=0,
+ growable=True),
+ TsbSettingsPltThreshMultField(
+ size=0,
+ growable=True),
+ TsbSettingsPltThreshField(
+ size=0,
+ growable=True),
+ TsbSettingsTransducerSpacingField(
+ size=0,
+ growable=True),
+ TsbSettingsCalibAccelField(
+ size=0,
+ growable=True),
+ TsbSettingsCalibGyroField(
+ size=0,
+ growable=True),
+ TsbSettingsCalibMagField(
+ size=0,
+ growable=True),
+ TsbSettingsCalibMagSoftXField(
+ size=0,
+ growable=True),
+ TsbSettingsCalibMagSoftYField(
+ size=0,
+ growable=True),
+ TsbSettingsCalibMagSoftZField(
+ size=0,
+ growable=True),
+ TsbSettingsMaxTxDutyCycleField(
+ size=0,
+ growable=True),
+ TsbSettingsTxChanField(
+ size=0,
+ growable=True),
+ TsbSettingsSearchGainField(
+ size=0,
+ growable=True)
+ ])
+
+ self.growable = True
+
+ @classmethod
+ def from_definition(cls, definition_message: DefinitionMessage,
+ developer_fields: list[DeveloperField] = None):
+ """Project a wire definition onto this message type (decode path).
+
+ Field sizes come from the definition; fields are not growable. Prefer this
+ over passing a definition into ``__init__``.
+ """
+ message = cls.__new__(cls)
+ DataMessage.__init__(
+ message,
+ name=cls.NAME,
+ global_id=cls.ID,
+ local_id=definition_message.local_id,
+ endian=definition_message.endian,
+ definition_message=definition_message,
+ developer_fields=developer_fields,
+ fields=[
+ TsbSettingsTxEnableField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsTxEnableField.ID),
+ growable=False),
+ TsbSettingsProportionalGainField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsProportionalGainField.ID),
+ growable=False),
+ TsbSettingsIntegralGainField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsIntegralGainField.ID),
+ growable=False),
+ TsbSettingsFixedGainField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsFixedGainField.ID),
+ growable=False),
+ TsbSettingsRssiSetpointField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsRssiSetpointField.ID),
+ growable=False),
+ TsbSettingsPltThreshMultField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsPltThreshMultField.ID),
+ growable=False),
+ TsbSettingsPltThreshField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsPltThreshField.ID),
+ growable=False),
+ TsbSettingsTransducerSpacingField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsTransducerSpacingField.ID),
+ growable=False),
+ TsbSettingsCalibAccelField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsCalibAccelField.ID),
+ growable=False),
+ TsbSettingsCalibGyroField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsCalibGyroField.ID),
+ growable=False),
+ TsbSettingsCalibMagField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsCalibMagField.ID),
+ growable=False),
+ TsbSettingsCalibMagSoftXField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsCalibMagSoftXField.ID),
+ growable=False),
+ TsbSettingsCalibMagSoftYField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsCalibMagSoftYField.ID),
+ growable=False),
+ TsbSettingsCalibMagSoftZField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsCalibMagSoftZField.ID),
+ growable=False),
+ TsbSettingsMaxTxDutyCycleField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsMaxTxDutyCycleField.ID),
+ growable=False),
+ TsbSettingsTxChanField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsTxChanField.ID),
+ growable=False),
+ TsbSettingsSearchGainField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSettingsSearchGainField.ID),
+ growable=False)
+ ])
+ message.growable = False
+ # Keep definition field ids not present in the Profile schema (Stage 2 E).
+ message.retain_unknown_fields()
+ return message
+
+ @classmethod
+ def from_bytes(cls, definition_message: DefinitionMessage, developer_fields: list[DeveloperField],
+ bytes_buffer: bytes, offset: int = 0):
+ message = cls.from_definition(definition_message, developer_fields=developer_fields)
+ message.read_from_bytes(bytes_buffer, offset)
+ return message
+
+
+
+
+ @property
+ def tx_enable(self) -> Optional[bool]:
+ field = self.get_field(TsbSettingsTxEnableField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @tx_enable.setter
+ def tx_enable(self, value: bool):
+ field = self.get_field(TsbSettingsTxEnableField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def proportional_gain(self) -> Optional[float]:
+ field = self.get_field(TsbSettingsProportionalGainField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @proportional_gain.setter
+ def proportional_gain(self, value: float):
+ field = self.get_field(TsbSettingsProportionalGainField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def integral_gain(self) -> Optional[float]:
+ field = self.get_field(TsbSettingsIntegralGainField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @integral_gain.setter
+ def integral_gain(self, value: float):
+ field = self.get_field(TsbSettingsIntegralGainField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def fixed_gain(self) -> Optional[int]:
+ field = self.get_field(TsbSettingsFixedGainField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @fixed_gain.setter
+ def fixed_gain(self, value: int):
+ field = self.get_field(TsbSettingsFixedGainField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def rssi_setpoint(self) -> Optional[int]:
+ field = self.get_field(TsbSettingsRssiSetpointField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @rssi_setpoint.setter
+ def rssi_setpoint(self, value: int):
+ field = self.get_field(TsbSettingsRssiSetpointField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def plt_thresh_mult(self) -> Optional[float]:
+ field = self.get_field(TsbSettingsPltThreshMultField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @plt_thresh_mult.setter
+ def plt_thresh_mult(self, value: float):
+ field = self.get_field(TsbSettingsPltThreshMultField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def plt_thresh(self) -> Optional[int]:
+ field = self.get_field(TsbSettingsPltThreshField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @plt_thresh.setter
+ def plt_thresh(self, value: int):
+ field = self.get_field(TsbSettingsPltThreshField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def transducer_spacing(self) -> Optional[float]:
+ field = self.get_field(TsbSettingsTransducerSpacingField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @transducer_spacing.setter
+ def transducer_spacing(self, value: float):
+ field = self.get_field(TsbSettingsTransducerSpacingField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def calib_accel(self) -> Optional[list[float]]:
+ field = self.get_field(TsbSettingsCalibAccelField.ID)
+ if field and field.is_valid():
+ return field.get_values()
+ else:
+ return None
+
+
+
+ @calib_accel.setter
+ def calib_accel(self, value: list[float]):
+ field = self.get_field(TsbSettingsCalibAccelField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ field.set_values(value)
+
+
+
+ @property
+ def calib_gyro(self) -> Optional[list[float]]:
+ field = self.get_field(TsbSettingsCalibGyroField.ID)
+ if field and field.is_valid():
+ return field.get_values()
+ else:
+ return None
+
+
+
+ @calib_gyro.setter
+ def calib_gyro(self, value: list[float]):
+ field = self.get_field(TsbSettingsCalibGyroField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ field.set_values(value)
+
+
+
+ @property
+ def calib_mag(self) -> Optional[list[float]]:
+ field = self.get_field(TsbSettingsCalibMagField.ID)
+ if field and field.is_valid():
+ return field.get_values()
+ else:
+ return None
+
+
+
+ @calib_mag.setter
+ def calib_mag(self, value: list[float]):
+ field = self.get_field(TsbSettingsCalibMagField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ field.set_values(value)
+
+
+
+ @property
+ def calib_mag_soft_x(self) -> Optional[list[float]]:
+ field = self.get_field(TsbSettingsCalibMagSoftXField.ID)
+ if field and field.is_valid():
+ return field.get_values()
+ else:
+ return None
+
+
+
+ @calib_mag_soft_x.setter
+ def calib_mag_soft_x(self, value: list[float]):
+ field = self.get_field(TsbSettingsCalibMagSoftXField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ field.set_values(value)
+
+
+
+ @property
+ def calib_mag_soft_y(self) -> Optional[list[float]]:
+ field = self.get_field(TsbSettingsCalibMagSoftYField.ID)
+ if field and field.is_valid():
+ return field.get_values()
+ else:
+ return None
+
+
+
+ @calib_mag_soft_y.setter
+ def calib_mag_soft_y(self, value: list[float]):
+ field = self.get_field(TsbSettingsCalibMagSoftYField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ field.set_values(value)
+
+
+
+ @property
+ def calib_mag_soft_z(self) -> Optional[list[float]]:
+ field = self.get_field(TsbSettingsCalibMagSoftZField.ID)
+ if field and field.is_valid():
+ return field.get_values()
+ else:
+ return None
+
+
+
+ @calib_mag_soft_z.setter
+ def calib_mag_soft_z(self, value: list[float]):
+ field = self.get_field(TsbSettingsCalibMagSoftZField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ field.set_values(value)
+
+
+
+ @property
+ def max_tx_duty_cycle(self) -> Optional[int]:
+ field = self.get_field(TsbSettingsMaxTxDutyCycleField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @max_tx_duty_cycle.setter
+ def max_tx_duty_cycle(self, value: int):
+ field = self.get_field(TsbSettingsMaxTxDutyCycleField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def tx_chan(self) -> Optional[int]:
+ field = self.get_field(TsbSettingsTxChanField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @tx_chan.setter
+ def tx_chan(self, value: int):
+ field = self.get_field(TsbSettingsTxChanField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def search_gain(self) -> Optional[int]:
+ field = self.get_field(TsbSettingsSearchGainField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @search_gain.setter
+ def search_gain(self, value: int):
+ field = self.get_field(TsbSettingsSearchGainField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+
+
+
+
+class TsbSettingsTxEnableField(Field):
+ ID = 0
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='tx_enable',
+ field_id=self.ID,
+ base_type=BaseType.UINT8,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'bool',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsProportionalGainField(Field):
+ ID = 1
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='proportional_gain',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ units = 'dB',
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsIntegralGainField(Field):
+ ID = 2
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='integral_gain',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ units = 'dB',
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsFixedGainField(Field):
+ ID = 3
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='fixed_gain',
+ field_id=self.ID,
+ base_type=BaseType.UINT8,
+ offset = 0,
+ scale = 1,
+ size = size,
+ units = 'dB',
+ type_name = 'uint8',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsRssiSetpointField(Field):
+ ID = 4
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='rssi_setpoint',
+ field_id=self.ID,
+ base_type=BaseType.UINT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'uint32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsPltThreshMultField(Field):
+ ID = 5
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='plt_thresh_mult',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsPltThreshField(Field):
+ ID = 6
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='plt_thresh',
+ field_id=self.ID,
+ base_type=BaseType.UINT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'uint32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsTransducerSpacingField(Field):
+ ID = 7
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='transducer_spacing',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ units = 'm',
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsCalibAccelField(Field):
+ ID = 8
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='calib_accel',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsCalibGyroField(Field):
+ ID = 9
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='calib_gyro',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsCalibMagField(Field):
+ ID = 10
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='calib_mag',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsCalibMagSoftXField(Field):
+ ID = 11
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='calib_mag_soft_x',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsCalibMagSoftYField(Field):
+ ID = 12
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='calib_mag_soft_y',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsCalibMagSoftZField(Field):
+ ID = 13
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='calib_mag_soft_z',
+ field_id=self.ID,
+ base_type=BaseType.FLOAT32,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'float32',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsMaxTxDutyCycleField(Field):
+ ID = 14
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='max_tx_duty_cycle',
+ field_id=self.ID,
+ base_type=BaseType.UINT8,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'uint8',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsTxChanField(Field):
+ ID = 15
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='tx_chan',
+ field_id=self.ID,
+ base_type=BaseType.UINT8,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'uint8',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSettingsSearchGainField(Field):
+ ID = 16
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='search_gain',
+ field_id=self.ID,
+ base_type=BaseType.UINT8,
+ offset = 0,
+ scale = 1,
+ size = size,
+ units = 'dB',
+ type_name = 'uint8',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
\ No newline at end of file
diff --git a/fit_tool/profile/messages/tsb_sonar_message_event_message.py b/fit_tool/profile/messages/tsb_sonar_message_event_message.py
new file mode 100644
index 0000000..193b27d
--- /dev/null
+++ b/fit_tool/profile/messages/tsb_sonar_message_event_message.py
@@ -0,0 +1,283 @@
+# Autogenerated. Do not modify.
+#
+# Profile: 21.221.0
+from typing import Optional
+
+from fit_tool.base_type import BaseType
+from fit_tool.data_message import DataMessage
+from fit_tool.definition_message import DefinitionMessage
+from fit_tool.developer_field import DeveloperField
+from fit_tool.endian import Endian
+from fit_tool.field import Field
+from fit_tool.sub_field import SubField
+from fit_tool.profile.messages.common_fields import MessageIndexField, TimestampField
+from fit_tool.profile.profile_type import *
+from typing import List as list
+from typing import Dict as dict
+
+
+class TsbSonarMessageEventMessage(DataMessage):
+ """TsbSonarMessageEventMessage — use blank construct for authoring, ``from_definition`` for decode.
+
+ * ``TsbSonarMessageEventMessage()`` — create path: growable fields, no wire definition.
+ * ``TsbSonarMessageEventMessage.from_definition(definition, developer_fields=...)`` —
+ project a local definition onto this type (decode / MessageFactory path).
+ """
+
+ ID = 364
+ NAME = 'tsb_sonar_message_event'
+
+ @staticmethod
+ def _field_size_from_definition(definition_message: DefinitionMessage, field_id: int) -> int:
+ field_definition = definition_message.get_field_definition(field_id)
+ if field_definition:
+ return field_definition.size
+ return 0
+
+ def __init__(self, developer_fields=None, local_id: int = 0,
+ endian: Endian = Endian.LITTLE):
+ """Create a blank message for authoring (growable fields, no definition)."""
+ super().__init__(name=TsbSonarMessageEventMessage.NAME,
+ global_id=TsbSonarMessageEventMessage.ID,
+ local_id=local_id,
+ endian=endian,
+ definition_message=None,
+ developer_fields=developer_fields,
+ fields=[
+ TsbSonarMessageEventSonarPacketIdField(
+ size=0,
+ growable=True),
+ TsbSonarMessageEventDiverLocationAccuracyField(
+ size=0,
+ growable=True),
+ TsbSonarMessageEventMessageTypeField(
+ size=0,
+ growable=True),
+ TsbSonarMessageEventMessageSourceField(
+ size=0,
+ growable=True)
+ ])
+
+ self.growable = True
+
+ @classmethod
+ def from_definition(cls, definition_message: DefinitionMessage,
+ developer_fields: list[DeveloperField] = None):
+ """Project a wire definition onto this message type (decode path).
+
+ Field sizes come from the definition; fields are not growable. Prefer this
+ over passing a definition into ``__init__``.
+ """
+ message = cls.__new__(cls)
+ DataMessage.__init__(
+ message,
+ name=cls.NAME,
+ global_id=cls.ID,
+ local_id=definition_message.local_id,
+ endian=definition_message.endian,
+ definition_message=definition_message,
+ developer_fields=developer_fields,
+ fields=[
+ TsbSonarMessageEventSonarPacketIdField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSonarMessageEventSonarPacketIdField.ID),
+ growable=False),
+ TsbSonarMessageEventDiverLocationAccuracyField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSonarMessageEventDiverLocationAccuracyField.ID),
+ growable=False),
+ TsbSonarMessageEventMessageTypeField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSonarMessageEventMessageTypeField.ID),
+ growable=False),
+ TsbSonarMessageEventMessageSourceField(
+ size=cls._field_size_from_definition(
+ definition_message, TsbSonarMessageEventMessageSourceField.ID),
+ growable=False)
+ ])
+ message.growable = False
+ # Keep definition field ids not present in the Profile schema (Stage 2 E).
+ message.retain_unknown_fields()
+ return message
+
+ @classmethod
+ def from_bytes(cls, definition_message: DefinitionMessage, developer_fields: list[DeveloperField],
+ bytes_buffer: bytes, offset: int = 0):
+ message = cls.from_definition(definition_message, developer_fields=developer_fields)
+ message.read_from_bytes(bytes_buffer, offset)
+ return message
+
+
+
+
+ @property
+ def sonar_packet_id(self) -> Optional[SonarPacketId]:
+ field = self.get_field(TsbSonarMessageEventSonarPacketIdField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @sonar_packet_id.setter
+ def sonar_packet_id(self, value: SonarPacketId):
+ field = self.get_field(TsbSonarMessageEventSonarPacketIdField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def diver_location_accuracy(self) -> Optional[int]:
+ field = self.get_field(TsbSonarMessageEventDiverLocationAccuracyField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @diver_location_accuracy.setter
+ def diver_location_accuracy(self, value: int):
+ field = self.get_field(TsbSonarMessageEventDiverLocationAccuracyField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def message_type(self) -> Optional[SonarMessageType]:
+ field = self.get_field(TsbSonarMessageEventMessageTypeField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @message_type.setter
+ def message_type(self, value: SonarMessageType):
+ field = self.get_field(TsbSonarMessageEventMessageTypeField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+ @property
+ def message_source(self) -> Optional[SonarMessageSource]:
+ field = self.get_field(TsbSonarMessageEventMessageSourceField.ID)
+ if field and field.is_valid():
+ sub_field = field.get_valid_sub_field(self.fields)
+ return field.get_value(sub_field=sub_field)
+ else:
+ return None
+
+
+
+ @message_source.setter
+ def message_source(self, value: SonarMessageSource):
+ field = self.get_field(TsbSonarMessageEventMessageSourceField.ID)
+
+ if field:
+ if value is None:
+ field.clear()
+ else:
+ sub_field = field.get_valid_sub_field(self.fields)
+ field.set_value(0, value, sub_field)
+
+
+
+
+
+
+
+class TsbSonarMessageEventSonarPacketIdField(Field):
+ ID = 0
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='sonar_packet_id',
+ field_id=self.ID,
+ base_type=BaseType.ENUM,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'sonar_packet_id',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSonarMessageEventDiverLocationAccuracyField(Field):
+ ID = 21
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='diver_location_accuracy',
+ field_id=self.ID,
+ base_type=BaseType.UINT16,
+ offset = 0,
+ scale = 1,
+ size = size,
+ units = 'degrees',
+ type_name = 'uint16',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSonarMessageEventMessageTypeField(Field):
+ ID = 22
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='message_type',
+ field_id=self.ID,
+ base_type=BaseType.ENUM,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'sonar_message_type',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
+
+
+class TsbSonarMessageEventMessageSourceField(Field):
+ ID = 23
+
+ def __init__(self, size: int = 0, growable: bool = True):
+ super().__init__(
+ name='message_source',
+ field_id=self.ID,
+ base_type=BaseType.ENUM,
+ offset = 0,
+ scale = 1,
+ size = size,
+ type_name = 'sonar_message_source',
+ growable = growable,
+ sub_fields = [
+ ]
+ )
\ No newline at end of file
diff --git a/fit_tool/profile/messages/user_profile_message.py b/fit_tool/profile/messages/user_profile_message.py
index 58cb027..5143aca 100644
--- a/fit_tool/profile/messages/user_profile_message.py
+++ b/fit_tool/profile/messages/user_profile_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/video_clip_message.py b/fit_tool/profile/messages/video_clip_message.py
index fb6dbe1..fc4c674 100644
--- a/fit_tool/profile/messages/video_clip_message.py
+++ b/fit_tool/profile/messages/video_clip_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/video_description_message.py b/fit_tool/profile/messages/video_description_message.py
index c513526..cf5cfb4 100644
--- a/fit_tool/profile/messages/video_description_message.py
+++ b/fit_tool/profile/messages/video_description_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/video_frame_message.py b/fit_tool/profile/messages/video_frame_message.py
index 6f9ae6a..4350110 100644
--- a/fit_tool/profile/messages/video_frame_message.py
+++ b/fit_tool/profile/messages/video_frame_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/video_message.py b/fit_tool/profile/messages/video_message.py
index 3945a5a..6ba6feb 100644
--- a/fit_tool/profile/messages/video_message.py
+++ b/fit_tool/profile/messages/video_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/video_title_message.py b/fit_tool/profile/messages/video_title_message.py
index 3286d47..801cbc3 100644
--- a/fit_tool/profile/messages/video_title_message.py
+++ b/fit_tool/profile/messages/video_title_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/watchface_settings_message.py b/fit_tool/profile/messages/watchface_settings_message.py
index 87c462a..b6fd8da 100644
--- a/fit_tool/profile/messages/watchface_settings_message.py
+++ b/fit_tool/profile/messages/watchface_settings_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/weather_alert_message.py b/fit_tool/profile/messages/weather_alert_message.py
index 1ae344b..1588c4b 100644
--- a/fit_tool/profile/messages/weather_alert_message.py
+++ b/fit_tool/profile/messages/weather_alert_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/weather_conditions_message.py b/fit_tool/profile/messages/weather_conditions_message.py
index beb7718..87e0eb8 100644
--- a/fit_tool/profile/messages/weather_conditions_message.py
+++ b/fit_tool/profile/messages/weather_conditions_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/weight_scale_message.py b/fit_tool/profile/messages/weight_scale_message.py
index ddaca37..0480af2 100644
--- a/fit_tool/profile/messages/weight_scale_message.py
+++ b/fit_tool/profile/messages/weight_scale_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/workout_message.py b/fit_tool/profile/messages/workout_message.py
index 1a04108..cd88471 100644
--- a/fit_tool/profile/messages/workout_message.py
+++ b/fit_tool/profile/messages/workout_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/workout_session_message.py b/fit_tool/profile/messages/workout_session_message.py
index a8038cb..5792a25 100644
--- a/fit_tool/profile/messages/workout_session_message.py
+++ b/fit_tool/profile/messages/workout_session_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/workout_step_message.py b/fit_tool/profile/messages/workout_step_message.py
index c6a513b..e51e1d6 100644
--- a/fit_tool/profile/messages/workout_step_message.py
+++ b/fit_tool/profile/messages/workout_step_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/messages/zones_target_message.py b/fit_tool/profile/messages/zones_target_message.py
index 926747a..2cfee52 100644
--- a/fit_tool/profile/messages/zones_target_message.py
+++ b/fit_tool/profile/messages/zones_target_message.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from typing import Optional
from fit_tool.base_type import BaseType
diff --git a/fit_tool/profile/profile_type.py b/fit_tool/profile/profile_type.py
index 0edd48d..448d253 100644
--- a/fit_tool/profile/profile_type.py
+++ b/fit_tool/profile/profile_type.py
@@ -1,6 +1,6 @@
# Autogenerated. Do not modify.
#
-# Profile: 21.218.0
+# Profile: 21.221.0
from enum import Enum
@@ -169,56 +169,60 @@ class ProfileType(Enum):
SLED_EXERCISE_NAME = 161
SLEEP_DISRUPTION_SEVERITY = 162
SLEEP_LEVEL = 163
- SOURCE_TYPE = 164
- SPLIT_STATUS = 165
- SPLIT_TYPE = 166
- SPO2_MEASUREMENT_TYPE = 167
- SPORT = 168
- SPORT_BITS_0 = 169
- SPORT_BITS_1 = 170
- SPORT_BITS_2 = 171
- SPORT_BITS_3 = 172
- SPORT_BITS_4 = 173
- SPORT_BITS_5 = 174
- SPORT_BITS_6 = 175
- SPORT_EVENT = 176
- SQUAT_EXERCISE_NAME = 177
- STAIR_STEPPER_EXERCISE_NAME = 178
- STROKE_TYPE = 179
- SUB_SPORT = 180
- SUPPORTED_EXD_SCREEN_LAYOUTS = 181
- SUSPENSION_EXERCISE_NAME = 182
- SWIM_STROKE = 183
- SWITCH = 184
- TAP_SENSITIVITY = 185
- TIMER_TRIGGER = 186
- TIME_INTO_DAY = 187
- TIME_MODE = 188
- TIME_ZONE = 189
- TIRE_EXERCISE_NAME = 190
- TISSUE_MODEL_TYPE = 191
- TONE = 192
- TOTAL_BODY_EXERCISE_NAME = 193
- TRICEPS_EXTENSION_EXERCISE_NAME = 194
- TURN_TYPE = 195
- UIAA_GRADING_SCALE = 196
- USER_LOCAL_ID = 197
- VERMIN_GRADING_SCALE = 198
- WARM_UP_EXERCISE_NAME = 199
- WATCHFACE_MODE = 200
- WATER_TYPE = 201
- WEATHER_REPORT = 202
- WEATHER_SEVERE_TYPE = 203
- WEATHER_SEVERITY = 204
- WEATHER_STATUS = 205
- WEIGHT = 206
- WORKOUT_CAPABILITIES = 207
- WORKOUT_EQUIPMENT = 208
- WORKOUT_HR = 209
- WORKOUT_POWER = 210
- WORKOUT_STEP_DURATION = 211
- WORKOUT_STEP_TARGET = 212
- YDS_GRADING_SCALE = 213
+ SONAR_HEADING = 164
+ SONAR_MESSAGE_SOURCE = 165
+ SONAR_MESSAGE_TYPE = 166
+ SONAR_PACKET_ID = 167
+ SOURCE_TYPE = 168
+ SPLIT_STATUS = 169
+ SPLIT_TYPE = 170
+ SPO2_MEASUREMENT_TYPE = 171
+ SPORT = 172
+ SPORT_BITS_0 = 173
+ SPORT_BITS_1 = 174
+ SPORT_BITS_2 = 175
+ SPORT_BITS_3 = 176
+ SPORT_BITS_4 = 177
+ SPORT_BITS_5 = 178
+ SPORT_BITS_6 = 179
+ SPORT_EVENT = 180
+ SQUAT_EXERCISE_NAME = 181
+ STAIR_STEPPER_EXERCISE_NAME = 182
+ STROKE_TYPE = 183
+ SUB_SPORT = 184
+ SUPPORTED_EXD_SCREEN_LAYOUTS = 185
+ SUSPENSION_EXERCISE_NAME = 186
+ SWIM_STROKE = 187
+ SWITCH = 188
+ TAP_SENSITIVITY = 189
+ TIMER_TRIGGER = 190
+ TIME_INTO_DAY = 191
+ TIME_MODE = 192
+ TIME_ZONE = 193
+ TIRE_EXERCISE_NAME = 194
+ TISSUE_MODEL_TYPE = 195
+ TONE = 196
+ TOTAL_BODY_EXERCISE_NAME = 197
+ TRICEPS_EXTENSION_EXERCISE_NAME = 198
+ TURN_TYPE = 199
+ UIAA_GRADING_SCALE = 200
+ USER_LOCAL_ID = 201
+ VERMIN_GRADING_SCALE = 202
+ WARM_UP_EXERCISE_NAME = 203
+ WATCHFACE_MODE = 204
+ WATER_TYPE = 205
+ WEATHER_REPORT = 206
+ WEATHER_SEVERE_TYPE = 207
+ WEATHER_SEVERITY = 208
+ WEATHER_STATUS = 209
+ WEIGHT = 210
+ WORKOUT_CAPABILITIES = 211
+ WORKOUT_EQUIPMENT = 212
+ WORKOUT_HR = 213
+ WORKOUT_POWER = 214
+ WORKOUT_STEP_DURATION = 215
+ WORKOUT_STEP_TARGET = 216
+ YDS_GRADING_SCALE = 217
@@ -241,6 +245,8 @@ class FileType(Enum):
SEGMENT = 34
SEGMENT_LIST = 35
EXD_CONFIGURATION = 40
+ TSB_SONAR_EVENTS = 66
+ TSB_DIVER_CONFIG = 67
MFG_RANGE_MIN = 247
MFG_RANGE_MAX = 254
@@ -357,6 +363,9 @@ class MesgNum(Enum):
TANK_UPDATE = 319
TANK_SUMMARY = 323
SLEEP_ASSESSMENT = 346
+ TSB_SONAR_MESSAGE_EVENT = 364
+ TSB_SETTINGS = 365
+ TSB_DIVER_CONFIG = 366
HRV_STATUS_SUMMARY = 370
HRV_VALUE = 371
RAW_BBI = 372
@@ -1529,6 +1538,10 @@ class Manufacturer(Enum):
TYMEWEAR = 352
EXPOSURE_LIGHTS = 353
FORTO_CYCLING = 354
+ FAIR_WEATHER_ATHLETICS = 356
+ HATCH_FACTORY = 357
+ TORQANO = 358
+ ROCKBROS = 359
ACTIGRAPHCORP = 5759
@@ -2010,9 +2023,14 @@ class GarminProduct(Enum):
FENIX9_PRO_SOLAR_51MM = 4956
FENIX9_43MM = 5133
FENIX9 = 5134
+ EDGE_1060 = 4962
INSTINCT_CROSSOVER_AMOLED = 4678
+ EDGE_EXPLORE3 = 4970
+ EDGE_EXPLORE3_PLUS = 4972
D2_AIR_X15 = 4944
+ MARQ3 = 5000
CIRQA_SMART_BAND = 5019
+ DESCENT_X10 = 5026
D2_MACH2_PRO = 5056
ENDURO4 = 5169
SDM4 = 10007
@@ -5559,6 +5577,62 @@ class NapSource(Enum):
MANUAL_GC = 2
+class SonarPacketId(Enum):
+ XX_ANT_ID = 0
+ T1_PRESSURE_DEPTH = 1
+ T1_MSG_RLY_FROM_TSB = 2
+ RSVD_3 = 3
+ T1_INFO_RESP = 4
+ T1_NAV_RLY_FROM_TSB = 5
+ RSVD_6 = 6
+ RSVD_7 = 7
+ RSVD_8 = 8
+ RSVD_9 = 9
+ T1_PRESSURE_HEART_RESP_RATE = 10
+ RSVD_11 = 11
+ T1_ACK_RELAY = 12
+ RSVD_13 = 13
+ RSVD_14 = 14
+ RSVD_15 = 15
+ TSB_EMER_ALERT = 16
+ TSB_CANNED_MSG = 17
+ TSB_INFO_REQ = 18
+ TSB_NAV = 19
+ RSVD_21 = 21
+ TSB_ACK = 22
+ RSVD_23 = 23
+ RSVD_24 = 24
+ RSVD_25 = 25
+ WCH_EMER_ALERT = 26
+ WCH_CANNED_MSG = 27
+ WCH_HEART_RESP_RATE = 28
+ WCH_ACK = 29
+ RSVD_30 = 30
+ RSVD_31 = 31
+ GEN_DEBUG = 32
+
+
+class SonarHeading(Enum):
+ NORTH = 0
+ NORTH_EAST = 1
+ EAST = 2
+ SOUTH_EAST = 3
+ SOUTH = 4
+ SOUTH_WEST = 5
+ WEST = 6
+ NORTH_WEST = 7
+
+
+class SonarMessageType(Enum):
+ EMERGENCY_MESSAGE = 0
+ CANNED_MESSAGE = 1
+
+
+class SonarMessageSource(Enum):
+ DIVE_APP = 0
+ WATCH = 1
+
+
class MaxMetSpeedSource(Enum):
ONBOARD_GPS = 0
CONNECTED_GPS = 1
diff --git a/fit_tool/tests/data/README.md b/fit_tool/tests/data/README.md
index a3332b1..7b27e8e 100644
--- a/fit_tool/tests/data/README.md
+++ b/fit_tool/tests/data/README.md
@@ -23,7 +23,7 @@ Garmin publishes sample FIT files and tools under their FIT SDK license.
- Site:
- Also: and language SDKs such as
(tag must match
- `fit_tool.SDK_VERSION`, currently Profile **21.218.0**).
+ `fit_tool.SDK_VERSION`, currently Profile **21.221.0**).
2. **What you may commit**
- Only small, redistributable SDK examples that Garmin ships as samples.
- Do **not** commit proprietary device dumps, Connect exports with PII, or
@@ -33,7 +33,7 @@ Garmin publishes sample FIT files and tools under their FIT SDK license.
- This repository already vendors a minimal subset under `sdk/` for CI; do
not bulk-replace it with a full SDK tree.
4. **Profile spreadsheet**
- - Bundled at `fit_tool/gen/Profile_21.218.0.xlsx` for codegen only; not a
+ - Bundled at `fit_tool/gen/Profile_21.221.0.xlsx` for codegen only; not a
runtime fixture.
## Live interop (optional)
diff --git a/fit_tool/tests/test_fit_file_header.py b/fit_tool/tests/test_fit_file_header.py
index c27651d..91070be 100755
--- a/fit_tool/tests/test_fit_file_header.py
+++ b/fit_tool/tests/test_fit_file_header.py
@@ -54,7 +54,7 @@ def test_profile_versions_after_scale_transition_use_current_scale(self):
def test_default_profile_version_matches_sdk_version(self):
header = FitFileHeader(records_size=0)
- self.assertEqual('21.218', str(header.profile_version))
+ self.assertEqual('21.221', str(header.profile_version))
def test_generate_crc(self):
protocol_version = ProtocolVersion(2, 3)
diff --git a/fit_tool/tests/test_garmin_sdk_interop.py b/fit_tool/tests/test_garmin_sdk_interop.py
index 9050033..5d96f99 100644
--- a/fit_tool/tests/test_garmin_sdk_interop.py
+++ b/fit_tool/tests/test_garmin_sdk_interop.py
@@ -220,7 +220,7 @@ def test_builder_declares_the_generated_profile_version(self):
builder.add(message)
fit_file = FitFile.from_bytes(builder.build_bytes())
- self.assertEqual('21.218', str(fit_file.header.profile_version))
+ self.assertEqual('21.221', str(fit_file.header.profile_version))
@unittest.skipUnless(
diff --git a/fit_tool/tests/test_public_api.py b/fit_tool/tests/test_public_api.py
index 249c0de..bf726bd 100644
--- a/fit_tool/tests/test_public_api.py
+++ b/fit_tool/tests/test_public_api.py
@@ -31,7 +31,7 @@ def test_core_symbols_importable_from_package_root(self) -> None:
validate_fit_file,
)
- self.assertEqual(SDK_VERSION, '21.218.0')
+ self.assertEqual(SDK_VERSION, '21.221.0')
self.assertEqual(PROTOCOL_VERSION, '2.0')
self.assertEqual(FIT_DATA_TYPE, b'.FIT')
self.assertTrue(issubclass(FitCRCError, FitParseError))
diff --git a/fit_tool/tests/test_validation_profile.py b/fit_tool/tests/test_validation_profile.py
index a73a665..dafad7d 100644
--- a/fit_tool/tests/test_validation_profile.py
+++ b/fit_tool/tests/test_validation_profile.py
@@ -293,10 +293,10 @@ def test_catalog_matches_sdk_version_and_counts(self):
from fit_tool import SDK_VERSION
self.assertEqual(PROFILE_SDK_VERSION, SDK_VERSION)
- self.assertEqual(PROFILE_MESSAGE_COUNT, 124)
- self.assertEqual(PROFILE_FIELD_COUNT, 1566)
- self.assertEqual(PROFILE_ENUM_TYPE_COUNT, 115)
- self.assertEqual(PROFILE_ENUM_FIELD_COUNT, 164)
+ self.assertEqual(PROFILE_MESSAGE_COUNT, 127)
+ self.assertEqual(PROFILE_FIELD_COUNT, 1593)
+ self.assertEqual(PROFILE_ENUM_TYPE_COUNT, 119)
+ self.assertEqual(PROFILE_ENUM_FIELD_COUNT, 167)
self.assertEqual(len(PROFILE_FIELDS), PROFILE_FIELD_COUNT)
def test_file_id_type_in_catalog(self):
diff --git a/news/86.dep b/news/86.dep
new file mode 100644
index 0000000..e5d2ab2
--- /dev/null
+++ b/news/86.dep
@@ -0,0 +1 @@
+Upgrade the bundled Garmin FIT SDK Profile to 21.221.0.