60ac42e711
zigbee-monitor.yaml: - Single click (action=single) toggles Squiggle, Sideboard Lamp, Bamboo Lights - Press-hold-release (action=release after hold) toggles DJ Booth only - Two filter functions: "Single click" and "Hold release", button-in fan-out wires to both - DJ Booth added to zigbee-state-in and ui-text widgets for visibility - "plugs:" list replaced with "single_plugs:" and "hold_plugs:" for declarative clarity (generator doesn't use them, but documents intent) infra/zigbee2mqtt/configuration.yaml: - Removed DJ Booth from "all_plugs" group (now Squiggle, Sideboard Lamp, Bamboo Lights only) - Pushed same change to live /root/zigbee2mqtt/configuration.yaml and restarted zigbee2mqtt container Diagnostics in justfile + scripts/: justfile: - Constants: RPI_HOST, MQTT_HOST, MQTT_PORT, RPI_DIR, NR_PORT - rpi, mqtt-pub, mqtt-sub, mqtt-watch, mqtt-button - nr-show, nr-diff, nr-logs, nr-editor, nr-dashboard - z2m-devices, z2m-logs, z2m-state - mqtt-logs, restart, restart-all scripts/mqtt.py: - MQTT publish/subscribe/watch helpers using paho-mqtt v2.x - Run via uv run --with paho-mqtt (no global install needed) scripts/diag.py: - nr-show: live flow summary with mqtt-out topic list - nr-diff: structural diff deployed vs repo, normalizes random uuids - z2m-devices: paired devices + group membership - mqtt-button: publish action and watch /set topics (E2E test) Verified end-to-end via `just mqtt-button`: single → 3 messages on .../set (Squiggle, Sideboard Lamp, Bamboo Lights) release → 1 message on .../set (DJ Booth)
infra/
Full stack configuration as deployed on the RPi 3B+ at 192.168.81.147.
Layout on host
/root/
├── compose.yaml → infra/compose.yaml
├── mosquitto/config/mosquitto.conf → infra/mosquitto/config/mosquitto.conf
├── zigbee2mqtt/ → infra/zigbee2mqtt/
│ ├── configuration.yaml # device pairings + friendly names + groups
│ ├── coordinator_backup.json # zigbee network key + pan id (recovery)
│ └── state.json # per-device persisted state (ON/OFF, etc.)
└── nodered/ → bind-mount for nodered container's /data
├── flows.json → generated from ../flows/zigbee-monitor.yaml
├── settings.js → infra/nodered/settings.js
└── start.sh → infra/nodered/start.sh (patches Dashboard SPA)
Rebuild procedure from a fresh host
- Install Docker,
docker compose. - Clone this repo,
cd infra. mkdir -p mosquitto/data mosquitto/log(empty dirs for the volume mounts).docker compose up -d.- Pair zigbee devices (IEEE addresses in
zigbee2mqtt/configuration.yamlwill be wrong; re-pair or use the existingcoordinator_backup.jsonto rejoin the same network). just deployfrom the repo root to push the Node-RED flow.
Files that drift at runtime
nodered/flows.json— managed by the generator, do not hand-edit.nodered/node_modules/@flowfuse/node-red-dashboard/dist/index.html— patched bystart.shat every container start; survives reboots, lost ondocker compose down -v.mosquitto/data/— broker persistence, transient.zigbee2mqtt/database.db— sqlite, transient (regenerated fromconfiguration.yaml+coordinator_backup.json).zigbee2mqtt/state.json— committed so device ON/OFF state survives full rebuilds.