-
Notifications
You must be signed in to change notification settings - Fork 26
fix(api): PUT /machine/ledStrip echoes the palette the machine stored - #794
Open
ChampionDesigns wants to merge 2 commits into
Open
fix(api): PUT /machine/ledStrip echoes the palette the machine stored #794ChampionDesigns wants to merge 2 commits into
ChampionDesigns wants to merge 2 commits into
Conversation
The handler answered a bare {"status":"accepted"}, so a client had no way to
learn how its colours were actually stored. The firmware canonicalises what it
is given -- a replicated-byte spelling like FFFF22220000 comes back as
FF0022000000 -- and a subsequent GET returned that canonical form, so the PUT
response and the GET disagreed about the same write.
The PUT now reads the stored state back and returns it, falling back to the
old ack only when the machine reports nothing. A PUT body and the following
GET body are now byte-identical.
The tests were written first, as decide/ledstrip-canonical, and pin four
things upstream did not cover: replicated-byte input is stored and echoed
canonically, the audited F-044 write on frontStrip.awake echoes the palette
the machine recorded, canonical input is echoed byte-identically, and a reset
after a PUT returns the same canonical body.
Verified: flutter analyze clean, de1handler_led_strip_test 18 passed (was 12
upstream), dart format clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
MockReplayDe1.setLedStrip stored whatever it was handed. The firmware canonicalises — a replicated-byte spelling like FFFF22220000 comes back as FF0022000000 — so the mock could hold a value the machine never could, and a GET against it answered something no real machine would say. Color16.quantized() and ZoneLedState.quantized() hoist that arithmetic onto the model, where both the mock and any future caller can reach it, instead of each one keeping its own copy inline. Same class of defect as the fan-threshold clamp: a mock more permissive than the hardware hides the bug it is supposed to expose. Verified: flutter analyze clean, replay + ledStrip handler tests 37 passed, dart format clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Summary
PUT /api/v1/machine/ledStripanswered a bare{"status":"accepted"}, so a client had no way tolearn how its colours were actually stored. The firmware canonicalises what it is given — a
replicated-byte spelling like
FFFF22220000comes back asFF0022000000— and a followingGETreturned that canonical form. So the PUT response and the GET disagreed about the same write.
The handler now reads the stored state back and returns it. A PUT body and the following GET body
are byte-identical.
Base:
main. Independent.Design notes
MockReplayDe1.setLedStripstored whatever it was handed, so the replay mock could hold a spellingthe machine never would. It now canonicalises too.
Color16.quantized()andZoneLedState.quantized()hoist that arithmetic onto the model, where both the mock and any futurecaller reach one copy instead of keeping their own inline.
Same class of defect as a mock that does not clamp: a mock more permissive than the hardware hides
the bug it exists to expose.
Linked Issue
N/A
Verification
flutter analyze— clean.flutter test— full suite 3897 passed / 1 skipped, run against currentmainon5 Sep 2026.
flutter test—de1handler_led_strip_test18 passed, up from upstream's 12, plus the replaytests: 37 across both files.
The four new cases pin what upstream did not cover: replicated-byte input stored and echoed
canonically, the audited F-044 write on
frontStrip.awake, canonical input echoedbyte-identically, and a reset after a PUT returning the same canonical body.
dart format— clean on every changed file.Verified on hardware. This change ships in the Decaid-Canary build Ben runs on his own
machine, and has been exercised in normal use rather than only under test.
Impact
PUT /machine/ledStrip200 body changes from{"status":"accepted"}to the storedpalette. A client that ignored the body is unaffected; a client that parsed it for
status == acceptedmust be updated.PR. The old body carried no information.
Contributor Responsibility
AI-assisted development is allowed. The submitter remains responsible for the submitted work.