node-red-contrib-dmx-for-ha 0.6.14 → 0.6.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/nodes/ha-mqtt-button.js +17 -0
- package/nodes/ha-mqtt-dmx.js +22 -0
- package/nodes/ha-mqtt-pir.js +17 -0
- package/nodes/ha-mqtt-relay.js +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -226,6 +226,37 @@ Typical workflow: Remove → update node settings → Deploy → node auto-disco
|
|
|
226
226
|
|
|
227
227
|
---
|
|
228
228
|
|
|
229
|
+
## System control topic
|
|
230
|
+
|
|
231
|
+
All nodes subscribe to a system control topic for **bulk add/remove during commissioning**. No wiring needed — publish one MQTT message and all matching nodes respond.
|
|
232
|
+
|
|
233
|
+
**Topic:** `{siteId}/system/control` (e.g. `MW3D/system/control`)
|
|
234
|
+
|
|
235
|
+
**Payload:**
|
|
236
|
+
```json
|
|
237
|
+
{"cmd": "remove", "zone": "all", "type": "all"}
|
|
238
|
+
{"cmd": "add", "zone": "Master", "type": "dmx"}
|
|
239
|
+
{"cmd": "remove", "zone": "BnB", "type": "button"}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
| Field | Values | Description |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| `cmd` | `add`, `remove` | Add or remove HA discovery |
|
|
245
|
+
| `zone` | `all`, `Master`, `BnB` | Matches config node zone |
|
|
246
|
+
| `type` | `all`, `dmx`, `button`, `pir`, `relay` | Node type filter |
|
|
247
|
+
|
|
248
|
+
**Commissioning workflow:**
|
|
249
|
+
```
|
|
250
|
+
1. ADD Master DMX → test all lights
|
|
251
|
+
2. REMOVE Master DMX → fix wrong names/channels
|
|
252
|
+
3. ADD Master DMX → verify clean
|
|
253
|
+
4. Move to next type: Button → PIR → Relay
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
A **System Control flow** ships with the package (`system_control_flow.json`). Import it into Node-RED, connect the MQTT out node to your broker, and you have one-click bulk control per zone and type.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
229
260
|
## DMX Group Node
|
|
230
261
|
|
|
231
262
|
Appears as a single light entity in HA. Commands fan out to all nodes on its **Link** output.
|
package/nodes/ha-mqtt-button.js
CHANGED
|
@@ -70,6 +70,23 @@ module.exports = function (RED) {
|
|
|
70
70
|
handleDeviceAdd();
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// ── System control topic ─────────────────────────────────
|
|
74
|
+
const systemTopic = `${cfg.siteId}/system/control`;
|
|
75
|
+
broker.subscribe(systemTopic, 0, function (topic, rawPayload) {
|
|
76
|
+
let msg;
|
|
77
|
+
try { msg = JSON.parse(rawPayload.toString()); } catch(e) { return; }
|
|
78
|
+
if (!msg.cmd) return;
|
|
79
|
+
const zone = (msg.zone || 'all').toLowerCase();
|
|
80
|
+
if (zone !== 'all' && zone !== cfg.zone.toLowerCase()) return;
|
|
81
|
+
const type = (msg.type || 'all').toLowerCase();
|
|
82
|
+
if (type !== 'all' && type !== 'button') return;
|
|
83
|
+
if (msg.cmd === 'remove') {
|
|
84
|
+
handleDeviceRemove();
|
|
85
|
+
} else if (msg.cmd === 'add') {
|
|
86
|
+
_tryDiscover();
|
|
87
|
+
}
|
|
88
|
+
}, node.id + '_sys');
|
|
89
|
+
|
|
73
90
|
// Auto-discover if broker already connected on deploy
|
|
74
91
|
if (broker.connected) {
|
|
75
92
|
_tryDiscover();
|
package/nodes/ha-mqtt-dmx.js
CHANGED
|
@@ -78,6 +78,28 @@ module.exports = function (RED) {
|
|
|
78
78
|
handleDeviceAdd();
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
// ── System control topic ─────────────────────────────────
|
|
82
|
+
// Subscribes to: {siteId}/system/control
|
|
83
|
+
// Payload: {"cmd":"remove","zone":"all"} or {"cmd":"add","zone":"Master"}
|
|
84
|
+
const systemTopic = `${cfg.siteId}/system/control`;
|
|
85
|
+
broker.subscribe(systemTopic, 0, function (topic, rawPayload) {
|
|
86
|
+
let msg;
|
|
87
|
+
try { msg = JSON.parse(rawPayload.toString()); } catch(e) { return; }
|
|
88
|
+
if (!msg.cmd) return;
|
|
89
|
+
// Zone filter — "all" or match config zone
|
|
90
|
+
const zone = (msg.zone || 'all').toLowerCase();
|
|
91
|
+
if (zone !== 'all' && zone !== cfg.zone.toLowerCase()) return;
|
|
92
|
+
// Type filter — "all" or match node type
|
|
93
|
+
const type = (msg.type || 'all').toLowerCase();
|
|
94
|
+
if (type !== 'all' && type !== 'dmx') return;
|
|
95
|
+
// Execute command
|
|
96
|
+
if (msg.cmd === 'remove') {
|
|
97
|
+
handleDeviceRemove();
|
|
98
|
+
} else if (msg.cmd === 'add') {
|
|
99
|
+
_tryDiscover();
|
|
100
|
+
}
|
|
101
|
+
}, node.id + '_sys');
|
|
102
|
+
|
|
81
103
|
// Auto-discover if broker already connected on deploy
|
|
82
104
|
if (broker.connected) {
|
|
83
105
|
_tryDiscover();
|
package/nodes/ha-mqtt-pir.js
CHANGED
|
@@ -67,6 +67,23 @@ module.exports = function (RED) {
|
|
|
67
67
|
handleDeviceAdd();
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
// ── System control topic ─────────────────────────────────
|
|
71
|
+
const systemTopic = `${cfg.siteId}/system/control`;
|
|
72
|
+
broker.subscribe(systemTopic, 0, function (topic, rawPayload) {
|
|
73
|
+
let msg;
|
|
74
|
+
try { msg = JSON.parse(rawPayload.toString()); } catch(e) { return; }
|
|
75
|
+
if (!msg.cmd) return;
|
|
76
|
+
const zone = (msg.zone || 'all').toLowerCase();
|
|
77
|
+
if (zone !== 'all' && zone !== cfg.zone.toLowerCase()) return;
|
|
78
|
+
const type = (msg.type || 'all').toLowerCase();
|
|
79
|
+
if (type !== 'all' && type !== 'pir') return;
|
|
80
|
+
if (msg.cmd === 'remove') {
|
|
81
|
+
handleDeviceRemove();
|
|
82
|
+
} else if (msg.cmd === 'add') {
|
|
83
|
+
_tryDiscover();
|
|
84
|
+
}
|
|
85
|
+
}, node.id + '_sys');
|
|
86
|
+
|
|
70
87
|
// Auto-discover if broker already connected on deploy
|
|
71
88
|
if (broker.connected) {
|
|
72
89
|
_tryDiscover();
|
package/nodes/ha-mqtt-relay.js
CHANGED
|
@@ -70,6 +70,23 @@ module.exports = function (RED) {
|
|
|
70
70
|
handleDeviceAdd();
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// ── System control topic ─────────────────────────────────
|
|
74
|
+
const systemTopic = `${cfg.siteId}/system/control`;
|
|
75
|
+
broker.subscribe(systemTopic, 0, function (topic, rawPayload) {
|
|
76
|
+
let msg;
|
|
77
|
+
try { msg = JSON.parse(rawPayload.toString()); } catch(e) { return; }
|
|
78
|
+
if (!msg.cmd) return;
|
|
79
|
+
const zone = (msg.zone || 'all').toLowerCase();
|
|
80
|
+
if (zone !== 'all' && zone !== cfg.zone.toLowerCase()) return;
|
|
81
|
+
const type = (msg.type || 'all').toLowerCase();
|
|
82
|
+
if (type !== 'all' && type !== 'relay') return;
|
|
83
|
+
if (msg.cmd === 'remove') {
|
|
84
|
+
handleDeviceRemove();
|
|
85
|
+
} else if (msg.cmd === 'add') {
|
|
86
|
+
_tryDiscover();
|
|
87
|
+
}
|
|
88
|
+
}, node.id + '_sys');
|
|
89
|
+
|
|
73
90
|
// Auto-discover if broker already connected on deploy
|
|
74
91
|
if (broker.connected) {
|
|
75
92
|
_tryDiscover();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-dmx-for-ha",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.15",
|
|
4
4
|
"description": "DMX lighting control for Home Assistant via Node-RED and MQTT. Place a node, fill in the settings, deploy. Full HA device registry integration with RGBW/RGBWW/CCT/brightness colour modes, transitions, effects, and group control.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node-red",
|