Skip to content

Fix multi-sport activity import (#289)#313

Merged
tcgoetz merged 5 commits into
tcgoetz:developfrom
philippeauriach:fix/multisport-activities
May 14, 2026
Merged

Fix multi-sport activity import (#289)#313
tcgoetz merged 5 commits into
tcgoetz:developfrom
philippeauriach:fix/multisport-activities

Conversation

@philippeauriach

Copy link
Copy Markdown

Multi-sport activities (triathlon / brick sessions) are stored by Garmin as a single FIT file containing multiple session messages plus child sessions for transitions. Previously the importer wrote every session under the bare parent activity_id, so the last session silently overwrote all the others and laps/records/HR zones/devices ended up attached to the wrong activity (or dropped entirely when the hr_zones_timer processing order created empty rows that blocked the real lap writes).

This change detects multi-sport files by checking len(fit_file.session) > 1 and, when detected:

  • creates one activity row per session with a suffixed id <parent>_<n> (e.g. 22638574127_1 ... _5 for swim→T1→run→T2→swim)
  • derives each session's stop_time from start_time + total_elapsed_time (Garmin reuses the parent start_time as every child's timestamp, which would otherwise result in stop_time <= start_time)
  • partitions laps by session using each session's num_laps and rewrites lap_num to be session-local (0..N per session), so every child has its own contiguous lap sequence
  • partitions records (GPS trackpoints) by matching their timestamp against each session's time window
  • remaps session/lap HR-zone writes to the correct child activity_id
  • associates device entries with every child activity

_write_lap_entry was also switched to ActivityLaps.s_insert_or_update so lap data correctly coalesces with the hr_zones_timer rows that the generic message dispatcher creates earlier in the import; the same stop_time correction applies when the file is multi-sport.

Single-session FIT files go through the exact same code path as before.

Extends and supersedes the single-session subset fixed in #310 (same root cause for stop_time, lap-ordering race, and the add-vs-insert-or-update issue).

Fixes #289

Tom Goetz and others added 4 commits November 9, 2025 12:45
Multi-sport activities (triathlon / brick sessions) are stored by Garmin as
a single FIT file containing multiple `session` messages plus child sessions
for transitions. Previously the importer wrote every session under the bare
parent activity_id, so the last session silently overwrote all the others
and laps/records/HR zones/devices ended up attached to the wrong activity
(or dropped entirely when the hr_zones_timer processing order created empty
rows that blocked the real lap writes).

This change detects multi-sport files by checking `len(fit_file.session) > 1`
and, when detected:

- creates one activity row per session with a suffixed id `<parent>_<n>`
  (e.g. 22638574127_1 ... _5 for swim→T1→run→T2→swim)
- derives each session's `stop_time` from `start_time + total_elapsed_time`
  (Garmin reuses the parent start_time as every child's `timestamp`, which
  would otherwise result in stop_time <= start_time)
- partitions laps by session using each session's `num_laps` and rewrites
  `lap_num` to be session-local (0..N per session), so every child has its
  own contiguous lap sequence
- partitions records (GPS trackpoints) by matching their timestamp against
  each session's time window
- remaps session/lap HR-zone writes to the correct child activity_id
- associates device entries with every child activity

`_write_lap_entry` was also switched to `ActivityLaps.s_insert_or_update` so
lap data correctly coalesces with the hr_zones_timer rows that the generic
message dispatcher creates earlier in the import; the same `stop_time`
correction applies when the file is multi-sport.

Single-session FIT files go through the exact same code path as before.

Extends and supersedes the single-session subset fixed in tcgoetz#310 (same root
cause for `stop_time`, lap-ordering race, and the add-vs-insert-or-update
issue).

Fixes tcgoetz#289
@tcgoetz

tcgoetz commented Apr 29, 2026

Copy link
Copy Markdown
Owner

Please re-target this Pr against the develop branch.

@philippeauriach
philippeauriach changed the base branch from master to develop April 29, 2026 13:16
@philippeauriach

Copy link
Copy Markdown
Author

hello @tcgoetz , base branch update to develop! thanks

@tcgoetz
tcgoetz merged commit f4c53f0 into tcgoetz:develop May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi sport activities are not totally supported

2 participants