Derived metric producers: max speed, average HR, average cadence, normalised power #65

Open
opened 2026-09-01 17:35:44 +02:00 by robert · 0 comments
robert commented 2026-09-01 17:35:44 +02:00 (Migrated from git.butzei.de)

Goal

Give every FieldId a producer. #58 defines a 22-entry enum; several of those fields have nothing anywhere in the plan that computes them, so they could only ever render --.

Missing producers: MAX_SPEED, AVG_HR, HR_ZONE, AVG_CADENCE, NORM_POWER.

Acceptance criteria

  • MAX_SPEED tracked over the ride, from the arbitrated speed source, ignoring fixes rejected by the accuracy gate in #17
  • AVG_HR accumulated on the phone from the batched HR_SAMPLES uplink (#66), over moving time, consistent with the "stopped" definition in #69
  • HR_ZONE derived from the configured zones in #44; renders -- when zones are unconfigured, never a guessed default
  • AVG_CADENCE over moving time, excluding coasting - specify and document whether zero-cadence samples count, because both conventions exist
  • NORM_POWER by the standard method: 30 s rolling average, fourth power, mean, fourth root; needs at least 30 s of data before it reports anything other than --
  • All five sent under the keys in docs/PROTOCOL.md section 2.2, following the changed-keys-only policy in section 4
  • Values reset on ride start and on lap where the field is lap-scoped
  • Unit tests on the JVM with fixture data, alongside #22

Files

  • companion/.../ride/DerivedMetrics.kt
  • companion/.../ride/SessionState.kt

Notes

See D28. This is the half of the contract rewrite that is code rather than schema.

## Goal Give every `FieldId` a producer. #58 defines a 22-entry enum; several of those fields have nothing anywhere in the plan that computes them, so they could only ever render `--`. Missing producers: `MAX_SPEED`, `AVG_HR`, `HR_ZONE`, `AVG_CADENCE`, `NORM_POWER`. ## Acceptance criteria - [ ] `MAX_SPEED` tracked over the ride, from the arbitrated speed source, ignoring fixes rejected by the accuracy gate in #17 - [ ] `AVG_HR` accumulated on the phone from the batched `HR_SAMPLES` uplink (#66), over moving time, consistent with the "stopped" definition in #69 - [ ] `HR_ZONE` derived from the configured zones in #44; renders `--` when zones are unconfigured, never a guessed default - [ ] `AVG_CADENCE` over moving time, excluding coasting - specify and document whether zero-cadence samples count, because both conventions exist - [ ] `NORM_POWER` by the standard method: 30 s rolling average, fourth power, mean, fourth root; needs at least 30 s of data before it reports anything other than `--` - [ ] All five sent under the keys in docs/PROTOCOL.md section 2.2, following the changed-keys-only policy in section 4 - [ ] Values reset on ride start and on lap where the field is lap-scoped - [ ] Unit tests on the JVM with fixture data, alongside #22 ## Files - `companion/.../ride/DerivedMetrics.kt` - `companion/.../ride/SessionState.kt` ## Notes See D28. This is the half of the contract rewrite that is code rather than schema.
Sign in to join this conversation.
No description provided.