Repository navigation
Garmin heart-rate broadcast during a workout: device-agnostic HRM naming + ANT+ reception (narrows #1326) #1359
Description
Reporter: shredness_10860 (Discord, #feature-requests, thread 1564577349666607135)
Type: Enhancement / feature request
Repo: 9thlevelsoftware/project-phoenix-mp (mobile)
Requested: app listens for a Garmin device heart-rate broadcast during a workout
Summary
The user wants the Phoenix mobile app to listen for a Garmin device heart-rate broadcast during a workout and show and record live heart rate. Garmin devices broadcast heart rate over two distinct radio paths — standard Bluetooth Low Energy (BLE) Heart Rate Service 0x180D, and ANT+ — so Garmin HR support is two separable concerns.
Relationship to in-flight PR #1326 (read before scoping work)
Open PR #1326 — feat(polar): add Polar H10 concurrent BLE telemetry, 3D torso biomechanics, and HRR analytics (author StuGotz, branch feature/polar-h10-telemetry, currently mergeable: CONFLICTING) — already implements a standard Bluetooth-SIG heart-rate path, not a Polar-proprietary one. Because Garmin Broadcast Heart Rate over BLE advertises the same standard 0x180D service, #1326 largely covers the BLE half of this request already:
- Discover device: isPolarH10Advertisement() matches name prefix Polar H10 OR any advertisement carrying Heart Rate Service 0x180D -> covers Garmin (BLE)
- Parse HR stream: parsePolarHrMeasurement() decodes standard 0x2A37 -> covers Garmin (BLE)
- Contact gating: contact-status flags map 0/1 to contact-OK, so telemetry is not dropped when a device reports Sensor Contact NOT supported -> covers Garmin
- Battery gate: isBatteryCritical() is null-safe when 0x2A19 is absent -> covers Garmin
- Polar proprietary PMD/ECG/ACC: best-effort in try/catch, does not block connect -> degrades gracefully on non-Polar
- Live / session / post-workout HR: PolarH10WorkoutStrip, MetricSample.heartRateBpm, WorkoutSession HR plus HRR60/HRR300 -> covers Garmin (BLE)
This issue is NOT a request to build BLE HR from scratch. It is scoped to the genuine gaps below.
Requested work (the gap)
- ANT+ heart-rate reception (the real missing capability). Garmin common gym-broadcast mode is ANT+, a separate radio and protocol from BLE. There are currently zero antplus / ant+ / garmin references in the feat(polar): add Polar H10 concurrent BLE telemetry, 3D torso biomechanics, and HRR analytics #1326 diff. Adding ANT+ HR reception is the primary new work. Platform limit: ANT+ is Android-only (iOS exposes no public ANT+ API); on iOS Garmin HR must come over BLE 0x180D (already handled by feat(polar): add Polar H10 concurrent BLE telemetry, 3D torso biomechanics, and HRR analytics #1326). State this limit so iOS users are not promised ANT+.
- Device-agnostic naming and UX (BLE and ANT+). The feat(polar): add Polar H10 concurrent BLE telemetry, 3D torso biomechanics, and HRR analytics #1326 HR layer is Polar-hardcoded and will mislabel Garmin hardware: a nameless advertisement defaults to the label Polar H10; settings keys are polar_h10_*; UI components and logs read PolarH10SettingsCard, PolarH10WorkoutStrip, and a Connected to Polar H10 log line. Rename to device-agnostic identifiers, keys, and logs so a Garmin (or any 0x180D / ANT+ HR sensor) is labeled correctly and its settings do not collide with Polar-specific ones.
- HRV / RMSSD completeness (nice-to-have). RR intervals are parsed from standard 0x2A37, so HRV/RMSSD works only if the specific Garmin unit emits RR intervals over BLE. Torso biomechanics and ECG (FB005C82) are Polar-proprietary and irrelevant to Garmin; do not attempt to map them.
Expected behavior
The app discovers and pairs a Garmin watch or chest strap broadcasting heart rate (BLE 0x180D on iOS and Android; ANT+ on Android), shows live HR during a workout, and records avg/max/min HR (and HRR where available) to the session, with the hardware correctly labeled as the Garmin device rather than Polar H10.
Actual behavior / current state
- BLE standard-HR discovery and parsing exists in open PR feat(polar): add Polar H10 concurrent BLE telemetry, 3D torso biomechanics, and HRR analytics #1326 but is not yet merged (CONFLICTING) and its naming is Polar-specific.
- ANT+ HR reception does not exist anywhere in the codebase.
Impact / notes
- High value for Garmin users (running, cycling, and gym HR broadcast is a common setup).
- Nothing here ships until PR feat(polar): add Polar H10 concurrent BLE telemetry, 3D torso biomechanics, and HRR analytics #1326 merge conflicts are resolved and it lands; this feature builds on that HRM layer.
Acceptance notes / verification caveat
- The feat(polar): add Polar H10 concurrent BLE telemetry, 3D torso biomechanics, and HRR analytics #1326 coverage above is derived from reading the PR diff, not from a running build. A real Garmin pairing is NOT verified. The Phantom harness cannot verify physical Bluetooth/RF/firmware — it covers app UI/state/persistence and deterministic simulator behavior. The real acceptance gate is a physical-device pairing test (Garmin watch or chest strap to app, live HR during a workout), on Android for ANT+ and on iOS for BLE.
Attachments
No attachments recorded on the Discord report.
Original Discord report (verbatim)
<@1502654170031849644> Feature request: "listen" for Garmin heart rate broadcasting during a workout
Discord-Message-ID: 1564577349666607135
Activity
9thLevelSoftware commentedon Oct 28, 2026
Feasibility assessment — recommendation: accept (phased)
Phase 1 (accept now): device-agnostic HRM naming + Garmin BLE verification. Phase 2 (defer): ANT+ reception.
Key findings (verified 2026-10-28)
0x180D/0x2A37half of this request for any HR sensor, including Garmin. It is not yet merged — it must land first.Effort (rough)
polar_h10_*keys + migration, labels, logs)Risks / unknowns
Full artifact:
phoenix-enhancements/issue-1359-1564577349666607135/feasibility.md. Next stage: architecture.