feat(train): the Loop's live heart rate in a recording (ADR 0030, D41)
A recording with a Loop set up reads its heart rate through Polar's SDK while no strap sends: the strap first, the Loop where there is none or while it is lost. The SDK is one for the process, held by the open app's bridge and by the recording service, so that the band stays connected with the app gone; the app reopening finds it connected. The recording file gains `loop` state lines; the rate is kept alone, as `h` lines, and the Record sheet names the source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
388b3b1ae6
commit
fa7680821d
1 changed files with 577 additions and 72 deletions
|
|
@ -1,10 +1,10 @@
|
|||
# ADR 0030: Halkyon Train, what it does and where its data comes from
|
||||
|
||||
- **Status:** decided 27–28 Oct 2026, by the developer (D1–D40 below). The shell (D12)
|
||||
- **Status:** decided 27–28 Oct 2026, by the developer (D1–D41 below). The shell (D12)
|
||||
is built; recording (D13–D28) is built on Android, iOS waiting for a Mac; Health
|
||||
Connect (D29–D31) is built; the Loop's setup and keeping (7a, D34–D36) and its
|
||||
daily data (7b, D37, D38), its sessions (7c, D39) and its firmware (D10, D40) are
|
||||
built.
|
||||
built, and its live heart rate (7d, D41).
|
||||
- **Numbering:** 0025 is held by the federation draft (stashed), 0026–0029 by the .NET
|
||||
rewrite on the local branch `rewrite-dotnet`, abandoned on 27 Oct; Train takes the next
|
||||
free number so that neither is ever read as this one.
|
||||
|
|
@ -768,6 +768,39 @@ Strava. What was found, 27 Oct:
|
|||
by itself after its restart, and whether the SDK takes the relayed file as it takes
|
||||
the one it fetches.
|
||||
|
||||
- **D41 The Loop's live heart rate in a recording (7d)** (recommended, the developer's;
|
||||
28 Oct): Polar's SDK names live heart rate (beats per minute) among the Loop's and
|
||||
the Polar 360's features (its `Polar360.md`), with PPI, PPG, acceleration and skin
|
||||
temperature streams. A recording with a Loop remembered takes its heart rate from
|
||||
the strap where one is remembered and switched on, and from the Loop where there is
|
||||
none, or while the strap is lost, so that the gap fills (over the strap alone where
|
||||
remembered, and over choosing one for each recording): a chest strap reads a workout
|
||||
more truly than the wrist (D32). The recording service reads the Loop through
|
||||
Polar's SDK (`startHrStreaming`), which already holds the band's connection, the
|
||||
SDK moving into a holder the open app and the service share, so that the band stays
|
||||
connected with the screen off and the app gone (over the service's own connection
|
||||
to the band's Heart Rate Service, as for a strap, a second client on the SDK's
|
||||
connection, the two fighting over its notifications). It keeps the heart rate
|
||||
alone, as `h` lines like the strap's (over pulse-to-pulse intervals too, which
|
||||
nothing uses yet and which cost battery). The Heart rate row names the source.
|
||||
|
||||
Built so (28 Oct), with choices of mine for the developer to look at: Polar's SDK is
|
||||
one for the app's process (`PolarSdk.kt`), held by the open app's bridge and by a
|
||||
recording reading a Loop, shut down as the last lets go; the background job (D37)
|
||||
leaves the band alone while either holds it, and the app opening again during a
|
||||
recording finds the band connected and is told so rather than connecting anew. The
|
||||
app doesn't disconnect a band a recording reads. The SDK now asks for `FEATURE_HR`
|
||||
as well. A recording takes the Loop whenever the person has one set up, the strap's
|
||||
switch on the Record sheet switching off the strap alone (so a strap left at home
|
||||
is no gap); the Loop's rate is written only while the strap isn't connected, as
|
||||
`h` lines, the band's state as `loop <time> connecting|connected|lost` lines (the
|
||||
file's version stays 1, as `strap` lines did), and a rate read off the skin is
|
||||
none. The stream is asked for again five seconds after it stops (`LoopHeart.kt`,
|
||||
tested on the JVM). The screen shows *Strap lost* only while the Loop isn't
|
||||
sending in its place. A rower's own heart rate is kept only where neither a strap
|
||||
nor a Loop is there. Not yet tried with a Loop: whether its live rate needs the
|
||||
band in a mode of its own, and how far the wrist's rate lags a strap's.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Train's sensors are one pattern: open profiles read by the app itself, on the phone;
|
||||
|
|
|
|||
Loading…
Reference in a new issue