Part of LightWitch M1 — see the rework plan. Builds on #457 (arbitration) and #458 (LightOverrideMsg). Completes the M1 demo: a button on device A makes one light on device B turn green — or blink for 2 s and return on its own — while everything else stays in its group scene.
Proposed change
- New
ActionId::SetLight in ActionExecutor targeting targetMac + lightIndex (works for local lights too, same path).
- Deliberately minimal parameters: color, brightness, pattern (
static or strobe for blinking), optional durationMs. The sender builds the full LightConfig snapshot from the target's mesh-synced group state plus these fields — full-snapshot construction stays a capability of the message (and of graph nodes from M2 on), not of the button UI.
- Button config UI: device picker showing names from the peer registry, storing the MAC (renames never break bindings), then light picker, color/brightness/pattern/duration fields.
- Targeting "the farthest device" is out of scope — that needs proximity data and arrives as a graph capability in M7.
Acceptance criteria
- The M1 demo above works end-to-end on hardware (verifiable via the PR's
pr-<N> firmware build).
- Renaming the target device does not break the binding.
- A
durationMs action reverts on its own; a subsequent group change also takes the light back.
Checklist obligations
CONFIG_SCHEMA_VERSION bump + migrateDoc() step for the new action params
- Mock parity: button config UI flow against
server/index.js (peers in MOCK_PEERS as picker source)
/validate-ui on the button-config flow
Part of LightWitch M1 — see the rework plan. Builds on #457 (arbitration) and #458 (
LightOverrideMsg). Completes the M1 demo: a button on device A makes one light on device B turn green — or blink for 2 s and return on its own — while everything else stays in its group scene.Proposed change
ActionId::SetLightinActionExecutortargetingtargetMac+lightIndex(works for local lights too, same path).staticorstrobefor blinking), optionaldurationMs. The sender builds the fullLightConfigsnapshot from the target's mesh-synced group state plus these fields — full-snapshot construction stays a capability of the message (and of graph nodes from M2 on), not of the button UI.Acceptance criteria
pr-<N>firmware build).durationMsaction reverts on its own; a subsequent group change also takes the light back.Checklist obligations
CONFIG_SCHEMA_VERSIONbump +migrateDoc()step for the new action paramsserver/index.js(peers inMOCK_PEERSas picker source)/validate-uion the button-config flow