Per updated policy:
- Water heater (node 95): new switch entity + on/off state read-back.
- Awning (node 75): new cover entity (open=op01 / close=op02 / stop=op00), with
current_operation published from the page-3 motion byte (C2/C3/C0). First
actuation must be attended; single-shot commands can't run the motor away.
- Water pump (node 61): added to command_guard denylist (winterizing-only,
panel/app only) alongside slides/jacks. Guard re-tested 8/8 (host g++).
Switch/cover comments + HANDOFF safety notes and remaining-work updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per policy, the firmware must never command a slide or jack. command_guard.h adds
command_blocked(node, type): refuses any motor-class (0x21) node except the
awning (0x75), with an explicit slide/jack denylist (6A/7F/9C) that holds even
before a node's page-2 identity is observed.
Enforced in two independent places — the command-entry script (send_load_command)
and the actual transmit point (on_frame, right before TX) — so loosening one
can't open the other. Adding a slide/jack switch entity cannot actuate it. Node
device class is learned from page-2 broadcasts (g_node_type). Predicate
unit-tested 9/9 (host g++). Switch comments + HANDOFF safety notes updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>