Repository navigation
feat(app): set-tempo control — tap, numeric, ± (ESP-037) - #10
Merged
Merged
Conversation
"I see kstouch. not the headless." The X32Link was powered, on the network, and following the Link session, and the app showed nothing. Adding `x32link` to the hostname prefix list is the small half of this. The real cause was in the firmware: that unit had NO mDNS WHATSOEVER -- it never advertised, so no matcher on this side could have found it, and `dns-sd` could not see it either. Fixed in link-devices (ESP-035), where it now announces `x32link-<mac>` like the rest of the fleet and serves the shared /status and /config.json. The prefix list stays a documented HEURISTIC, not a guarantee -- a TXT record is still the fix that would make identity a fact. Tests pin both halves: the headless is one of ours, and a stranger's box at a venue still is not. Verified against the real unit: both devices now appear in the list, live BPM. Claude-Session: https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6
The app can now set a clock box's free-run tempo, the last piece of ESP-037.
- KsLiveEdit.setTempo(Double) -> the `bpm` /live field. Formatted en_US_POSIX so a
European phone's decimal comma can't turn 128.5 into a "128" the firmware's atof stops
at. Tap, numeric and ± all resolve to this one number.
- KsConfig.tempo (Double?), decoded from `bpm`. nil = listener-only (X32Link omits it),
the same nil-means-not-fitted rule as metronome/led. This is the SET tempo, distinct
from KsStatus.bpm (the EFFECTIVE tempo Link drives) -- so the control doesn't jump when
a session takes over. apply(.setTempo) only reflects it when tempo != nil.
- TempoControl: the set surface, shown only when config.tempo != nil.
tap -- computed HERE from local tap intervals, never sent as tap events over
WiFi (jitter would wreck the timing); resolves to a BPM and sends it.
numeric -- tap the readout, type it.
± -- nudge by 1.
Clamped to 20..300 (the firmware's band). When a Link session is driving it says "LINK
IS DRIVING" -- a set tempo the device is currently ignoring is exactly the silent lie
this app keeps stamping out.
Verified against the bench Touch protocol side: /live bpm applies on the wire and
/config.json reads the stored tempo back; the app model decodes it and posts the same
field. Full app suite green; installed on the phone.
Claude-Session: https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6
Reported: set 150 manually, turn on Link (Ableton 120), and the control kept showing 150 while the box clocked 120. It should track what's actually playing. - The control now shows the EFFECTIVE tempo (status.bpm, polled) via DeviceDetailViewModel.tempoDisplay, not the stored set value. So it follows Link while a session drives, and when Link leaves there's no jump: the box keeps Link's tempo (the firmware arbiter's free-run seed) and the control was already showing it. - While Link drives, the ± / tap / numeric stand down (dimmed, disabled) -- Link owns the tempo; the control just reports it. Editable again when solo. - Edits are OPTIMISTIC: a ± tap shows immediately instead of waiting ~500 ms for the next /status to catch up, then reconciles when the device's reported tempo converges. Pairs with a firmware change (the box records Link's tempo as its own and persists it, so a power-cycle comes back at the last tempo it played). Full app suite green; installed on the phone. Claude-Session: https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6
…turn key The numeric entry was a dead end: .onSubmit/.submitLabel(.done) do nothing on a decimalPad keyboard, which has no return key at all. You could type a BPM and never set it. Focus drives it now: a "Set" button in the keyboard toolbar, and commit-on-dismiss when you tap away from the field. commitDraft guards against the double (Set button also drops focus). ± and TAP were never affected. Claude-Session: https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The app can now set a clock box's free-run tempo. Pairs with link-devices #123.
KsLiveEdit.setTempo(Double)→ thebpm/livefield (formatteden_US_POSIXso a European decimal comma can't truncate it). Tap, numeric, and ± all resolve to this one number.KsConfig.tempo(Double?), decoded frombpm;nil= listener-only (X32Link omits it). This is the set tempo, distinct fromKsStatus.bpm(the effective, Link-driven one).TempoControl— shown only when the device has a settable tempo:Full app suite green; installed and exercised on a real phone against the bench Touch.
https://claude.ai/code/session_01F7YsQgso3KNpeXbP5vNVj6