e5ed67a282
Dual plug only responds to per-channel state_1/state_2 commands, not the
shared {state:TOGGLE} payload. Route single-filter through a couch-mapper
that emits {"state_1":"TOGGLE","state_2":"TOGGLE"} so both outlets flip.
Also adds state-in node, /set out node, and dashboard widget showing
state_1/state_2. Verified E2E + 567 Rego checks pass.
Refs: david/nr-flow-validator#2
195 lines
4.7 KiB
YAML
195 lines
4.7 KiB
YAML
version: 1
|
|
|
|
brokers:
|
|
mosquitto:
|
|
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:
|
|
- page: Home
|
|
icon: home
|
|
path: /home
|
|
groups:
|
|
- name: Plugs
|
|
width: 6
|
|
|
|
flows:
|
|
- tab: Zigbee Monitor
|
|
description: Button dispatches single vs hold-release to different plug sets
|
|
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
|
|
topic: zigbee2mqtt/Door Button
|
|
qos: 0
|
|
|
|
- id: single-filter
|
|
type: function
|
|
name: Single click
|
|
code: |
|
|
const now = Date.now();
|
|
const last = context.get('lastTime') || 0;
|
|
if (now - last < 50) return null;
|
|
context.set('lastTime', now);
|
|
try {
|
|
const p = JSON.parse(msg.payload);
|
|
if (p.action === 'single') {
|
|
msg.payload = { state: 'TOGGLE' };
|
|
return msg;
|
|
}
|
|
} catch (e) {}
|
|
return null;
|
|
|
|
- id: hold-filter
|
|
type: function
|
|
name: Hold release
|
|
code: |
|
|
const now = Date.now();
|
|
const last = context.get('lastTime') || 0;
|
|
if (now - last < 50) return null;
|
|
context.set('lastTime', now);
|
|
try {
|
|
const p = JSON.parse(msg.payload);
|
|
if (p.action === 'release') {
|
|
msg.payload = { state: 'TOGGLE' };
|
|
return msg;
|
|
}
|
|
} 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
|
|
label: Permit Join (60s)
|
|
topic: zigbee2mqtt/bridge/request/permit_join
|
|
payload:
|
|
value: true
|
|
time: 60
|
|
order: 5
|
|
|
|
- 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]
|