Ride state machine: idle / running / paused / stopped #11
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.
Blocks
Depends on
#12 Persist ride state across app restart and crash
robert/PedalPebble
#46 Lap function
robert/PedalPebble
#8 Watchapp skeleton: window stack, view switching, button handling
robert/PedalPebble
Reference
robert/PedalPebble#11
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
Explicit ride lifecycle driving what is recorded and what is displayed.
Acceptance criteria
CMDFiles
watchapp/src/c/state.cwatchapp/src/c/state.hUpdate — 2026-09-02: commands survive a dropout, and the watch never auto-pauses
The phone is authoritative on
RIDE_STATEonce connected; the rider can pause from the wrist; thewatch runs on its own through a dropout; and dropouts of tens of seconds are ordinary (D31). Put
together, the rider pauses at a café mid-dropout, the phone reconnects asserting
running, and thepause is silently undone (D43).
CMDis stamped withCMD_TIMEand held in a watch-side queue until the phoneacknowledges it via
STATE_ACKRIDE_STATEis appliedRIDE_STATEpushsource when disconnected and cannot implement it even in principle
not as moving time; on reconnect the phone's moving time replaces it
paused
Closed by PR #84 (merged): state.h/state.c (host-testable, zero SDK calls) implements idle/running/paused/stopped, the D43 dropout-survival CMD queue (cumulative STATE_ACK, drop-newest not oldest on overflow), and the moving-time/wall-clock split while disconnected. ride_link.c is the SDK-facing shell (AppMessage send/decode, connection_service, 1Hz tick, vibration). 24 new host test cases including the D43 café scenario end to end; ride_link.c itself verified live in the emery emulator (
pebble emu-bt-connection) rather than host-tested, since faithfully stubbing AppMessage timing would test a fake transport, not real logic.\n\nFlagging two things for whoever lands #7 (codegen): (1)RideCmd's numeric values are this PR's own interpretation of PROTOCOL.md section 3's prose list (start/pause/resume/stop/lap/re-centre/zoom in/zoom out) — PROTOCOL.md gives CMD no numbered table the way RIDE_STATE gets one, so these are provisional; a mismatch against #7's codegen would silently send the wrong byte with no compiler error, since both ends only see a bare uint8. (2) The wire key ids (RIDE_STATE=4, STATE_ACK=6, CMD=71, CMD_TIME=74) are local #defines hand-copied from PROTOCOL.md's tables in ride_link.c, since #7's generated header does not exist yet (package.json's messageKeys is still["dummy"]). Both should be reconciled against #7's actual output when it lands, not just assumed compatible.\n\nSelect-button overlap with #8/#60: not rewired — page_view.c's Select still only cycles pages. state.h's rider-facing functions (start_pause/stop_request/stop_confirm/stop_cancel) are exposed but deliberately called from no click handler yet; wiring DESIGN.md section 5's real button assignment (Select=start/pause, long Select=stop, Up/Down=carousel) is #60's job.