feat: CLI for 0xB6 extended effects, segments, scribble, and timers#542
Draft
asxzy wants to merge 8 commits into
Draft
feat: CLI for 0xB6 extended effects, segments, scribble, and timers#542asxzy wants to merge 8 commits into
asxzy wants to merge 8 commits into
Conversation
Codecov Report❌ Patch coverage is
... and 2 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Introduces a dedicated protocol class for the Surplife 0xB6 device, switches the model to it, and adds synchronous-path support. - protocol.py: PROTOCOL_LEDENET_EXTENDED_CUSTOM, LEDENET_EXTENDED_STATE_RESPONSE_LEN, and ProtocolLEDENETExtendedCustom (name, 21-byte state length, extended-only is_valid_state_response, white-off-aware extended_state_to_state, and named_raw_state that converts extended -> standard for the sync path) - device.py: read the full 21-byte extended state and accept it while probing - base_device.py: register the protocol and add supports_extended_custom_effects - models_db.py: point the 0xB6 model at PROTOCOL_LEDENET_EXTENDED_CUSTOM Stacked on the reuse PR.
- const.py: ExtendedCustomEffectPattern / Direction / Option enums - pattern.py: EXTENDED_CUSTOM_EFFECT_ID_NAME / NAME_ID maps - protocol.py: construct_extended_custom_effect (0xE1 0x21), construct_custom_segment_colors (0xE1 0x22), construct_levels_change and the HSV(+W) byte helpers on ProtocolLEDENETExtendedCustom - base_device.py: extended_custom_effect_pattern_list, _generate_* helpers and pattern-name lookup in _named_effect - aiodevice.py / device.py: async_set_* and set* entry points Stacked on the dedicated-protocol PR.
The 0xB6 device uses a distinct timer wire format (e0 05/06 wrapped commands, variable-length 6-slot list, per-slot set): - const.py: TIMER_ACTION_* and TIMER_EFFECT_* constants - protocol.py: MSG_TIMERS_EXTENDED and the timer methods on ProtocolLEDENETExtendedCustom - timer.py: LedTimerExtended dataclass (to_bytes/from_bytes, __str__) - aiodevice.py: timer types widened, async_set_timers sends 0xB6 timers one at a time, new async_set_timer Stacked on the effect-APIs PR.
- fluxled.py: processCustomArgs reworked to a dict supporting extended custom effect and segment modes; new --density / --direction / --colorchange options; updated --listpresets; -C and --settimer dispatch; processSetTimerArgsExtended Stacked on the timers PR.
- Add processCustomArgs 'scribble' branch (before speed=int(args[1])) with _process_scribble_args helper and _parse_scribble_led_token - Parse effect names (static/flowing/twinkling/stars_wink/accumulate) - Expand run-length syntax: NxCOLOR, w<level>, off, bare color - Parse optional key=value trailing tokens: speed, density, dir, blink, blinkspeed - Bake global blink into each ScribbleLED at parse time - Add dispatch block (mode=="scribble") calling bulb.async_set_scribble - Update --custom help text and showUsageExamples/--listpresets with scribble example - Add 10 CLI parsing tests covering run-length, white, off, malformed, kv args
…ffect id, per-LED blink, enter_mode, extended variant) - Gap 1: accept numeric effect id 0-8 in -C scribble <effect>; named effects still work; out-of-range/garbage -> parser.error - Gap 2: per-LED blink suffix syntax <value>[/blinkmode[/blinkspeed]]; per-token blink overrides global blink=/blinkspeed= defaults - Gap 3: enter=true|false spec token controls async_set_scribble enter_mode; default true - Gap 4: --variant 0|1|2 optparse option overrides --colorchange for ExtendedCustomEffect option byte; threaded through processCustomArgs and parseArgs call site - Dispatch: pass raw int effect id (not ScribbleEffect()) so unnamed ids 3/4/6/7 don't raise ValueError; pass enter_mode from parsed dict - 23 new TDD tests covering all four gaps (parser-level); all 287 tests pass
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.
Merge order: #538 → #539 → #540 → #541 → this. Draft until predecessors land.
Exposes everything in PR3/PR4 through
fluxled.py, reusing the existing-C/--customscaffold.
CLI surface
-C <pattern> <speed> "<colors>"— pattern is a name (incl.multi-word, e.g.
"rainbow bridge"); options--density 0-100,--direction l2r|r2l,--colorchange(= variant 1),--variant 0|1|2.-C segments <speed> "<up to 20 colors>".-C scribble <effect> "<per-led-spec>"<effect>: a name (static|flowing|twinkling|stars_wink|accumulate) or raw id0-8.<color>,<n>x<color>,w<level>,off, each with an optionalblink suffix
…/mode[/speed](e.g.40xred/fast/80); global tokensdensity= speed= dir= blink= blinkspeed= enter=.led_count(pads with off / truncates, witha warning).
-t,-T,--getclock,--setclock;--listpresetsshows the 0xB6effect names; help text updated for all of the above.
Notes for review
utils.color_object_to_tuple; effect→id andblink-name→enum maps live next to the parser. The
w<level>white token uses adigits-only regex so color names starting with
w(e.g.white,wheat) still parse ascolors. The per-token blink suffix uses
/(unambiguous — colors/hex/r,g,bcontain no/).inttoasync_set_scribble(which acceptsScribbleEffect | int), so ids 3/4/6/7 work without a wrappingScribbleEffect(...).Testing
segments, scribble effect names + numeric + range errors, per-LED blink grammar,
enter=,--variantvalidation, run-length expansion, count reconcile pad/truncate).pytestgreen,ruffclean, no newmypyerrors.On-device verification (device
192.168.1.78): the entire on-device test pass wasdriven through this CLI (power, color/white, extended effects, segments, scribble, timers,
clock all issued via
flux_led …). The CLI-completeness options specifically:-C scribble 4 "20x255,0,0 20x0,255,0 20x0,0,255 20x255,255,0"-C scribble static "40x255,0,0/fast/80 40x0,255,0"enter=false-C scribble static "80x0,0,255 enter=false"E1 23init--variant 2-C "rainbow bridge" 60 "255,0,0 0,255,0 0,0,255" --variant 2CLI coverage matrix: every device/API capability is reachable from the CLI; the only
remaining item is informational (
led_countis not printed in-i).