fix(fb_room): latch ha_all_on/off on rising edge, not level

Node-RED sends ha_all_on and ha_all_off as short NVL pulses (same as
zigbee_swN). Level-sensitive IF switches.ha_all_on caused all outputs to
drop when the pulse cleared (~1s flash then off).

Use R_TRIG plus all_on_latch: ALL ON edge latches room on until ALL OFF
edge. Document behaviour and Node-RED sparse merge in integration guide.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
root
2026-05-26 18:30:06 +00:00
parent d98c44bfa3
commit 4010649388
2 changed files with 35 additions and 11 deletions

View File

@@ -88,7 +88,7 @@ flowchart LR
|-------------|---------|---------|
| HA pulses | `ha_l1_on``ha_l6_on`, `ha_l1_off``ha_l6_off` | `fb_light` via `R_TRIG` (rising edge only) |
| Zigbee pulses | `zigbee_sw1``zigbee_sw6` | `fb_light` toggle on edge |
| Room-wide | `ha_all_on`, `ha_all_off` | Room-level FBs |
| Room-wide | `ha_all_on`, `ha_all_off` | `fb_room`: `R_TRIG` + `all_on_latch` (rising edge only; see below) |
**`struct_room_outs`** (in `NVL_Sender` as `light_*` rooms)—per-room outputs:
@@ -112,6 +112,20 @@ Physical mapping: see `codesys-tree/_io.md` (EtherCAT `%QX*` → `Application.NV
Outputs feed `NVL_Sender`; EtherCAT maps those BOOLs to contactors.
### Room-wide ALL ON / ALL OFF (`fb_room`)
Node-RED sends **`ha_all_on` / `ha_all_off` as short rising-edge pulses** (PLC Troubleshoot dashboard, same as `zigbee_swN`). They must **not** be treated as level-sensitive BOOLs.
**Previous behaviour (bug):** `IF switches.ha_all_on THEN …` forced all outputs on only while the NVL bit stayed `TRUE`. When Node-RED cleared the pulse (~120 ms1 s), outputs fell back to per-light `fb_light` state (usually off) → “flash then all off”.
**Current behaviour (`fb_room.st`):**
1. `R_TRIG` on `ha_all_on` / `ha_all_off`.
2. Rising edge on `ha_all_on` sets internal `all_on_latch := TRUE` (all six outputs forced on each scan until released).
3. Rising edge on `ha_all_off` clears `all_on_latch`; per-light `fb_light` outputs apply again.
**Node-RED alignment:** `room-config-lib.js` uses sparse `buildNvlSendPayload` (only `TRUE` bits merged into `nvl-send`) and does not send a follow-up `ha_all_on := FALSE` frame for ALL ON. After deploying this PLC change, download the application to the controller.
---
## Node-RED side
@@ -141,7 +155,7 @@ Outputs feed `NVL_Sender`; EtherCAT maps those BOOLs to contactors.
5. **Return path:** **`udp in`** `:1202`**`nvl-receive`** (parses **`NVL_Sender`**) → **NVL to HA Sync** → Home Assistant `api-call-service` (`turn_on` / `turn_off` on mapped helpers).
6. **Edge clearing** — after ~80 ms, **Clear NVL edges** / **Clear zigbee edge** reset pulse bits so the PLC sees rising edges on the next command (matches `R_TRIG` in ST).
6. **Edge clearing** — after ~120 ms, **Clear NVL edges** reset `zigbee_sw*` / `ha_lN_*` pulse bits via `buildNvlClearPayload` (explicit `FALSE` merge only for cleared keys). **`ha_all_on` / `ha_all_off`** are not cleared over UDP (one rising-edge frame only); the PLC latch in `fb_room` holds the room on until `ha_all_off`.
### Configuration files (single source of truth)