BLE Cycling Power meter support #50
Labels
No labels
area:companion
area:docs
area:shared
area:tooling
area:watchapp
blocker
kind:chore
kind:feature
kind:spike
kind:test
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Depends on
#18 BLE CSC wheel sensor client and wheel-circumference calibration
robert/PedalPebble
Reference
robert/PedalPebble#50
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Support a power meter over the standard BLE Cycling Power profile. Unlike cadence this is a genuine addition: a separate profile, its own client and its own derived metrics.
Acceptance criteria
0x1818discovered and connectedCycling Power Measurement0x2A63parsed, including the variable-length flags fieldFiles
companion/.../sensors/CyclingPowerClient.ktwatchapp/src/c/view_ride.cNotes
The flags field makes this parser materially more involved than CSC - fields are optional and their offsets shift. See docs/DECISIONS.md D16.
Closed by PR #113 (merged). Cycling Power Measurement (0x2A63) format verified live against two independent sources -- confirmed three real differences from CSC's layout rather than assuming symmetry: a 2-byte Flags field (not CSC's 1 byte), signed sint16 instantaneous power (a negative reading decodes as negative, tested explicitly, not left to wrap), and Wheel Revolution Data's event-time at 1/2048s resolution vs CSC's 1/1024s (crank data keeps 1/1024s, correctly reused). Decoded: instantaneous power, pedal power balance/reference (no consumer yet, carried through honestly), crank data (feeds a real CrankCadenceTracker since resolution matches CSC). Correctly walked past but did NOT decode wheel revolution data from a power meter -- feeding it through the CSC-tuned WheelSpeedTracker would have silently halved the computed speed given the resolution mismatch; a real bug avoided by cross-checking rather than assuming code reuse was safe.
SensorPermissions reused unchanged, not duplicated. Dropout/reconnect mirrors CscClient's proven structure exactly. NormalizedPowerCalculator and a new Power3sAverage are now genuinely fed live power samples; AvgPowerAccumulator exists with the same honest "no ride orchestrator yet" gap as AvgCadenceAccumulator/AvgHrAccumulator.
Verified for real: :companion:core:test (CyclingPowerMeasurementTest 14, Power3sAverageTest 6, AvgPowerAccumulatorTest 4), :companion:pebble:testDebugUnitTest, :companion:sensors:assembleDebug and :companion:assembleDebug all green. No Bluetooth hardware in this sandbox -- AndroidCyclingPowerClient is compile-verified only, same honest disclosure as #18/#49.