Commit Graph
5 Commits
Author SHA1 Message Date
dtourolleandClaude Opus 5 3143e7e51c Put listen before the tests, where clippy can live with it
🚴 Build and Test BikeControl / Workspace tests (push) Successful in 21m48s
Build & Release / Run tests (push) Successful in 14m3s
🚴 Build and Test BikeControl / Android compile check (push) Failing after 10s
Build & Release / Build Linux (deb + AppImage) (push) Successful in 17m22s
Build & Release / Build Arch package (push) Successful in 29m45s
Build & Release / Build Android APK (push) Failing after 22s
Build & Release / Create release (push) Skipped
`probe listen` was appended to the end of commands.rs, which put it
after `mod tests` — `clippy::items_after_test_module`, denied by the
`-D warnings` in the workspace clippy job. Pure code motion: the listen
section moves up as a block, above the test module, and nothing else
changes.

This is the first commit whose clippy run can actually be observed. The
job has been in .gitea/workflows since the images were pinned, but the
image was never in the registry, so it has never run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 22:53:40 +02:00
dtourolleandClaude Opus 5 be046f341c Make the BLE layer say what it actually received
Chasing a paddle that shifted on one platform and not the other cost
several rebuilds, and most of that was spent unable to tell two very
different situations apart: a pod that was sending nothing, and a pod
whose frames we were receiving and quietly discarding. The logs looked
identical because every decoder in this path fails by dropping.

`click.rs` now logs every notification with its length and bytes before
anything tries to interpret it, and the unhandled-frame line in
`controller.rs` carries the payload rather than just the type byte —
which is the least useful part of a frame you could not parse, since it
is usually the framing that is wrong and not the content.

The default log filter gains `bikecontrol_ble=debug`. It was `info`,
which silenced the entire crate that owns every BLE conversation —
subscribe failures included. Survivable on desktop where RUST_LOG can
override it; not on Android, which has no environment to set and is
exactly where the subscribe was failing.

Adds `probe listen`, which decodes nothing on purpose: the GATT tree with
descriptors (the CCCD value is where a subscribe goes wrong, and
`inspect` stops short of it), then a subscribe to every notifying
characteristic across all services, reporting each as ok or FAILED. Each
notification prints characteristic, length and raw bytes, and the summary
names the characteristics that stayed silent — the difference between a
quiet device and listening in the wrong place.

That last part is what settled this one: it recorded 304 button frames
from a pod the app was reporting as dead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 19:16:26 +02:00
dtourolleandClaude Opus 5 57eb5e809b Virtual gearing, trainer-speed blend, and cadence decode
Gears are expressed as an offset to the commanded gradient, leaving the
physics on the route's true gradient so shifting changes effort, not speed.
Neutral gear commands exactly the route gradient, so an un-shifted ride is
unchanged.

Cadence is not in FTMS on this trainer but is on its Zwift channel, decoded
against captured frames. The undeclared FTMS trailing bytes were ruled out:
wheel RPM restated at a fixed 73.8x speed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 15:33:28 +02:00
dtourolleandClaude Opus 5 7c17ca6158 Core ride logic, FTMS client, FIT encoder and probe CLI
Adds backing state for Resistance and Erg control modes, which had no
value to hold and so could never satisfy FR-4.3/FR-4.6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 13:34:27 +02:00
dtourolleandClaude Opus 5 eb216dd9e6 Scaffold workspace, shared types and requirements spec
Cargo workspace with core/ble/fit/probe crates. crates/core/src/types.rs
is the fixed contract between the BLE layer, ride engine and UI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 13:11:32 +02:00