generator: auto-expand declarative plug lists with per-channel mapper

Add build_plugs() to flow2json.py: a flow can declare a plugs: table
({id, name, channels?}) plus single_plugs/hold_plugs lists and the
generator emits all plumbing automatically — state-in node, /set out node,
dashboard widget, and (for multi-channel devices) a mapper function that
toggles each channel (state_1/state_2) instead of the ignored shared
{state:TOGGLE} payload.

Rewrite zigbee-monitor.yaml to the declarative form; Dual Outlet - Couch
is multi-channel (channels: [1,2]). Adding a plug is one line, no manual
node/wire duplication. Single press toggles 5 devices (couch via mapper
verified E2E ON/OFF), hold-release still DJ Booth only.

Refs: david/nr-flow-validator#2
This commit is contained in:
2026-08-15 02:55:29 -07:00
parent e5ed67a282
commit b9c53c1a23
2 changed files with 154 additions and 119 deletions
+29 -118
View File
@@ -5,17 +5,6 @@ brokers:
host: mosquitto
port: 1883
# Plugs toggled on brief single press
single_plugs:
- Squiggle
- Sideboard Lamp
- Bamboo Lights
- Dual Outlet - Couch
# Plugs toggled on press-hold-release (action: "release" after a "hold")
hold_plugs:
- DJ Booth
dashboards:
- base: Dashboard
pages:
@@ -28,38 +17,35 @@ dashboards:
flows:
- tab: Zigbee Monitor
description: Button dispatches single vs hold-release to different plug sets
description: Button dispatches single vs hold-release to different plug sets.
Plug plumbing (state-in, /set out, dashboard widget, per-channel mapper)
is generated by flow2json.py from the plugs lists below.
# Declarative plug set. channels:[] marks a multi-channel device, which gets
# a mapper that toggles each channel and a widget showing each state_N.
plugs:
- id: squiggle
name: Squiggle
- id: sideboard
name: Sideboard Lamp
- id: bamboo
name: Bamboo Lights
- id: djbooth
name: DJ Booth
- id: couch
name: Dual Outlet - Couch
channels: [1, 2]
# Device ids toggled on brief single press (driven by single_filter)
single_plugs: [squiggle, sideboard, bamboo, couch]
# Device ids toggled on press-hold-release (driven by hold_filter)
hold_plugs: [djbooth]
single_filter: single-filter
hold_filter: hold-filter
nodes:
- id: zigbee-state-squiggle
type: mqtt in
broker: mosquitto
topic: zigbee2mqtt/Squiggle
qos: 0
- id: zigbee-state-sideboard
type: mqtt in
broker: mosquitto
topic: zigbee2mqtt/Sideboard Lamp
qos: 0
- id: zigbee-state-bamboo
type: mqtt in
broker: mosquitto
topic: zigbee2mqtt/Bamboo Lights
qos: 0
- id: zigbee-state-djbooth
type: mqtt in
broker: mosquitto
topic: zigbee2mqtt/DJ Booth
qos: 0
- id: zigbee-state-couch
type: mqtt in
broker: mosquitto
topic: zigbee2mqtt/Dual Outlet - Couch
qos: 0
- id: button-in
type: mqtt in
broker: mosquitto
@@ -100,73 +86,6 @@ flows:
} catch (e) {}
return null;
- id: plug-out-squiggle
type: mqtt out
broker: mosquitto
topic: zigbee2mqtt/Squiggle/set
- id: plug-out-sideboard
type: mqtt out
broker: mosquitto
topic: zigbee2mqtt/Sideboard Lamp/set
- id: plug-out-bamboo
type: mqtt out
broker: mosquitto
topic: zigbee2mqtt/Bamboo Lights/set
- id: plug-out-djbooth
type: mqtt out
broker: mosquitto
topic: zigbee2mqtt/DJ Booth/set
- id: couch-mapper
type: function
name: Toggle both outlets
code: |
msg.payload = { state_1: 'TOGGLE', state_2: 'TOGGLE' };
return msg;
- id: plug-out-couch
type: mqtt out
broker: mosquitto
topic: zigbee2mqtt/Dual Outlet - Couch/set
- id: text-squiggle
type: ui-text
group: Plugs
label: Squiggle
format: "{{msg.payload.state}}"
order: 1
- id: text-sideboard
type: ui-text
group: Plugs
label: Sideboard Lamp
format: "{{msg.payload.state}}"
order: 2
- id: text-bamboo
type: ui-text
group: Plugs
label: Bamboo Lights
format: "{{msg.payload.state}}"
order: 3
- id: text-djbooth
type: ui-text
group: Plugs
label: DJ Booth
format: "{{msg.payload.state}}"
order: 4
- id: text-couch
type: ui-text
group: Plugs
label: Dual Outlet - Couch
format: "{{msg.payload.state_1}} / {{msg.payload.state_2}}"
order: 6
- id: permit-btn
type: ui-button
group: Plugs
@@ -175,20 +94,12 @@ flows:
payload:
value: true
time: 60
order: 5
order: 9
- id: mqtt-out
type: mqtt out
broker: mosquitto
wires:
zigbee-state-squiggle: [text-squiggle]
zigbee-state-sideboard: [text-sideboard]
zigbee-state-bamboo: [text-bamboo]
zigbee-state-djbooth: [text-djbooth]
zigbee-state-couch: [text-couch]
button-in: [single-filter, hold-filter]
single-filter: [plug-out-squiggle, plug-out-sideboard, plug-out-bamboo, couch-mapper]
couch-mapper: [plug-out-couch]
hold-filter: [plug-out-djbooth]
permit-btn: [mqtt-out]