Detect a LiveTrack session ending the moment Garmin confirms it, not 30min later
Watched the session from the last two commits actually get saved: Garmin updated its `end` field from the future 24h placeholder to within a second of the last point's own time, immediately — much faster than the recency-of-last-point fallback alone would have noticed (that only flips after ACTIVE_WITHIN with no new points, so a just-saved session with a last point seconds old would still read as active for up to 30 more minutes). Now checks end-already-in-the-past first (authoritative and near instant when Garmin has set it), falling back to point recency only when end still shows the future placeholder — the case an abandoned, never-saved session never updates.
This commit is contained in:
1 parent
3106f8c103
commit
b0c93d10d7
2 files changed
+41
-13
No files matched your search
@@ -56,16 +56,25 @@ module Maptool
|
||||
# doesn't set `end` until the activity actually stops — disproven
|
||||
# against a real still-recording session (2026-09-20): `end` was
|
||||
# already non-nil, set to exactly `start + 24h`, the share link's own
|
||||
# expiry, not an actual end time (a genuinely ended session's `end`
|
||||
# instead reflects its real end — ~2h after start for the 2026-09-06
|
||||
# session this was originally, and only, verified against). Recency of
|
||||
# the last track point is a directly-observable signal instead of
|
||||
# trying to reverse-engineer what a given `end` value means: Garmin
|
||||
# posts one roughly every `postTrackPointFrequency` seconds (~15,
|
||||
# observed) while genuinely still recording, so a point older than
|
||||
# ACTIVE_WITHIN means the activity has actually stopped (or, at worst,
|
||||
# lost signal for a while — same "looks ended until it isn't" behavior
|
||||
# Garmin's own LiveTrack page shows in that case).
|
||||
# expiry, not an actual end time. Two signals now, both verified live
|
||||
# against that same session:
|
||||
#
|
||||
# * `end` itself, once it's actually in the past — watched the same
|
||||
# session update it from that 24h placeholder to within a second of
|
||||
# the last point's own time, immediately after the activity was
|
||||
# saved on the watch. Authoritative and near-instant when present,
|
||||
# so this is checked first.
|
||||
# * failing that (still showing the future placeholder — an abandoned
|
||||
# session never gets saved, so `end` never moves), recency of the
|
||||
# last track point: Garmin posts one roughly every
|
||||
# `postTrackPointFrequency` seconds (~15, observed) while genuinely
|
||||
# still recording, so one older than ACTIVE_WITHIN means signal was
|
||||
# lost a while ago (same "looks ended until it isn't" behavior
|
||||
# Garmin's own LiveTrack page shows in that case).
|
||||
#
|
||||
# Both must agree the session is live — `end` already in the past
|
||||
# means stopped even if the last point is only seconds old (exactly
|
||||
# the save-immediately-after-the-last-point case above).
|
||||
ACTIVE_WITHIN = 30 * 60 # seconds
|
||||
|
||||
def self.summarize(result)
|
||||
@@ -76,16 +85,19 @@ module Maptool
|
||||
"activity_type" => last["activityType"],
|
||||
"distance_meters" => last["totalDistanceMeters"],
|
||||
"duration_secs" => last["totalDurationSecs"],
|
||||
"active" => active?(last["dateTime"]),
|
||||
"active" => active?(last["dateTime"], session["end"]),
|
||||
"start" => session["start"],
|
||||
"end" => session["end"],
|
||||
}
|
||||
end
|
||||
|
||||
def self.active?(last_point_time)
|
||||
def self.active?(last_point_time, session_end)
|
||||
return false unless last_point_time
|
||||
|
||||
Time.parse(last_point_time) > Time.now.utc - ACTIVE_WITHIN
|
||||
now = Time.now.utc
|
||||
return false if session_end && Time.parse(session_end) <= now
|
||||
|
||||
Time.parse(last_point_time) > now - ACTIVE_WITHIN
|
||||
rescue ArgumentError, TypeError
|
||||
false
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user