version: 1 brokers: mosquitto: host: mosquitto port: 1883 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. 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: 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: permit-btn type: ui-button group: Plugs label: Permit Join (60s) topic: zigbee2mqtt/bridge/request/permit_join payload: value: true time: 60 order: 9 - id: mqtt-out type: mqtt out broker: mosquitto wires: button-in: [single-filter, hold-filter] permit-btn: [mqtt-out]