Shot protocol v2: higher-resolution encoding and extended pump modes - #5
Open
ChampionDesigns wants to merge 1 commit into
Open
ChampionDesigns wants to merge 1 commit into
ChampionDesigns wants to merge 1 commit into
Conversation
Two changes to profile-frame encoding, both selected per connection by the negotiated protocol version. A DE1 keeps today's encoding byte for byte. Part A -- the v2 flow and pressure encoding. Those fields are one byte. v1 uses U8P4: step 0.0625, ceiling 15.9375, which suits a DE1 whose pump tops out at 8 mL/s. A Bengle reaches 20 and cannot be commanded above 15.9375. v2 uses U8D1: step 0.1, ceiling 25.5, with HeaderV 2 so the firmware knows which to expect. Coarser near zero; the ceiling is the limit that bites. decentespresso/decaid makes the same choice on the same rule. Part B -- four new per-frame pump modes and hydraulic-power exits, using four of T_ShotExtFrame's five spare bytes: [2] Mode [3] ModeMaxP [4] LeverSpring [5] LeverGive [6] Reserved 0 legacy, 1 power, 2 lever, 3 HOLD-P, 4 HOLD-F, 5 HOLD-W, >= 6 unknown Power exits use DC_ComparePower (0x80), which deliberately does NOT set DoCompare so firmware that does not know the mode ignores the threshold rather than reading watts as bar. The byte offsets, the mode numbering and the flag bit are the firmware's, taken from T_ShotExtFrame and T_E_FrameFlags in APIDataTypes.hpp. Part A's U8D1 SetVal is on firmware master; Part B's Mode fields are on the Bengle integration branch and in tester builds. A frame using no v2 feature encodes identically to today; the extension frame is emitted only when something needs it. validate_shot_protocol_compatibility refuses to encode any v2 feature under HeaderV 1 rather than writing a frame the machine will misread. HOLD is rejected in frame 0, where there is no prior value to latch. An unknown mode keeps the authored legacy command, and Reserved survives a decode and re-encode, so an older client can round-trip a profile it does not know. require_finite_range rejects infinities and out-of-range values before the encoder sees them: the fixed-point converters clamp by design, which is right for telemetry and wrong for an authored profile. Verified in tclsh: both ceilings, both encodings and decodings at 6.0 and 20, clamping at each limit, all six mode names, the unknown-mode passthrough, which modes require a pressure cap, and the range validator. Co-Authored-By: Claude Opus 5 (1M context) <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.
merges. 536 insertions, 2 files.
Summary
Two changes to profile-frame encoding, both selected per connection by the negotiated
protocol version. A DE1 keeps today's encoding byte for byte.
A. The v2 flow and pressure encoding
Those fields are one byte. v1 uses U8P4: step 0.0625, ceiling 15.9375, which suits a
DE1 whose pump tops out at 8 mL/s. A Bengle reaches 20 and cannot be commanded above
15.9375. v2 uses U8D1: step 0.1, ceiling 25.5, with
HeaderV2 so the firmware knowswhich to expect.
Coarser near zero, and that is the trade — 0.0625 against 0.1 is well inside pump
repeatability, and the ceiling is the limit that bites.
decentespresso/decaidmakes thesame choice on the same rule.
B. Extended pump modes
Four of
T_ShotExtFrame's five spare bytes:Two new exit conditions,
power_underandpower_over, useDC_ComparePower(0x80).It deliberately does not set
DoCompare, so firmware that does not know the modeignores the threshold rather than reading watts as bar.
The byte offsets, the mode numbering and the flag bit are the firmware's, taken from
T_ShotExtFrameandT_E_FrameFlagsinAPIDataTypes.hpp, not invented here.Firmware requirement
Part A's
U8D1 SetValis on firmware master. Part B'sModefields and the0x80flagare on the Bengle integration branch, released to testers and not yet merged to firmware
master. Reviewers testing part B need that build.
Compatibility
only when something needs it.
validate_shot_protocol_compatibilityrefuses to encode any v2 feature underHeaderV1, failing loudly rather than writing a frame the machine will misread.
and
Reservedsurvives a decode and re-encode — so an older client can round-trip aprofile it does not understand.
require_finite_rangerejects infinities and out-of-range values before the encoder seesthem. The fixed-point converters clamp by design, which is right for telemetry and wrong
for an authored profile.
A note on
profile.tclIt carries its own copies of three small mode helpers because it loads before
binary.tcl,so save, load and display cannot depend on the encoder being present. The duplication is
avoidable if the helpers move to a file both can require — happy to restructure if you
prefer.
Impact on a DE1
use_ble_v2is false, soHeaderVstays 1 and both byte converters stay U8P4. A profilewith no v2 feature produces identical bytes. One that uses a v2 feature is refused at
encode time with a clear error.
Test plan
all six mode names, the unknown-mode passthrough, which modes require a pressure cap,
and the range validator — all run in
tclsh.this PR. They must be identical.
Reserved.power_underexit fires at the authored threshold.Testing
Manual verification plus the
tclshharness above. There is no automated test coverage forthese Tcl paths in the repo.