node-red-contrib-dmx-for-ha 0.1.0
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 +282 -0
- package/docs/config_node_spec.md +236 -0
- package/docs/dmx_node_env_reference.md +341 -0
- package/docs/master_todo.md +428 -0
- package/docs/node_contracts.md +278 -0
- package/docs/nr_subflow_gotchas.md +258 -0
- package/nodes/ha-mqtt-button.html +326 -0
- package/nodes/ha-mqtt-button.js +158 -0
- package/nodes/ha-mqtt-config.html +233 -0
- package/nodes/ha-mqtt-config.js +81 -0
- package/nodes/ha-mqtt-dmx-group.html +392 -0
- package/nodes/ha-mqtt-dmx-group.js +265 -0
- package/nodes/ha-mqtt-dmx.html +547 -0
- package/nodes/ha-mqtt-dmx.js +537 -0
- package/nodes/ha-mqtt-pir.html +343 -0
- package/nodes/ha-mqtt-pir.js +183 -0
- package/nodes/ha-mqtt-relay.html +326 -0
- package/nodes/ha-mqtt-relay.js +289 -0
- package/package.json +39 -0
- package/subflow/README.md +35 -0
- package/subflow/button_node_v5.0.3.js +324 -0
- package/subflow/dmx_group_node_v0.3.8.js +860 -0
- package/subflow/dmx_node_v0.5.9.js +1994 -0
- package/subflow/pir_node_v1.0.3.js +365 -0
- package/subflow/relay_node_v4.0.2.js +553 -0
- package/subflow/subflow_definitions.json +6154 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
<!-- ============================================================
|
|
2
|
+
ha-mqtt-config — Config Node Editor
|
|
3
|
+
Package: node-red-contrib-dmx-for-ha
|
|
4
|
+
Author: DeSwaggy — Discord: @deswaggy
|
|
5
|
+
============================================================ -->
|
|
6
|
+
|
|
7
|
+
<script type="text/javascript">
|
|
8
|
+
RED.nodes.registerType('ha-mqtt-config', {
|
|
9
|
+
category: 'config',
|
|
10
|
+
defaults: {
|
|
11
|
+
name: { value: '', required: true },
|
|
12
|
+
siteId: { value: '', required: true },
|
|
13
|
+
zone: { value: '', required: true },
|
|
14
|
+
broker: { value: '', type: 'mqtt-broker', required: true },
|
|
15
|
+
discoveryPrefix: { value: 'homeassistant' },
|
|
16
|
+
qos: { value: '0' },
|
|
17
|
+
retain: { value: 'false' },
|
|
18
|
+
configTopic: { value: 'config' },
|
|
19
|
+
stateTopic: { value: 'state' },
|
|
20
|
+
commandTopic: { value: 'cmd' },
|
|
21
|
+
availTopic: { value: 'avty' },
|
|
22
|
+
enabledDefault: { value: 'true' },
|
|
23
|
+
diskDelay: { value: '10' },
|
|
24
|
+
flashShort: { value: '1' },
|
|
25
|
+
flashLong: { value: '10' },
|
|
26
|
+
},
|
|
27
|
+
label: function () {
|
|
28
|
+
return this.name || 'HA MQTT Config';
|
|
29
|
+
},
|
|
30
|
+
oneditprepare: function () {
|
|
31
|
+
// Zone is free text — no population needed
|
|
32
|
+
// Sanitisation happens in runtime .js
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<!-- ============================================================
|
|
38
|
+
Editor Panel Template
|
|
39
|
+
============================================================ -->
|
|
40
|
+
<script type="text/html" data-template-name="ha-mqtt-config">
|
|
41
|
+
|
|
42
|
+
<!-- NAME -->
|
|
43
|
+
<div class="form-row">
|
|
44
|
+
<label for="node-config-input-name">
|
|
45
|
+
<i class="fa fa-tag"></i> Name
|
|
46
|
+
</label>
|
|
47
|
+
<input type="text" id="node-config-input-name"
|
|
48
|
+
placeholder="e.g. Master Zone, Guest Wing" />
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<hr/>
|
|
52
|
+
|
|
53
|
+
<!-- SITE -->
|
|
54
|
+
<div class="form-row">
|
|
55
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
56
|
+
<i class="fa fa-home"></i> Site
|
|
57
|
+
</label>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="form-row">
|
|
61
|
+
<label for="node-config-input-siteId">
|
|
62
|
+
<i class="fa fa-id-badge"></i> Site ID
|
|
63
|
+
</label>
|
|
64
|
+
<input type="text" id="node-config-input-siteId"
|
|
65
|
+
placeholder="e.g. home, unit4, smithresidence"
|
|
66
|
+
style="width:60%" />
|
|
67
|
+
<span style="margin-left:8px; color:#999; font-size:0.85em;">
|
|
68
|
+
Used in MQTT topic construction
|
|
69
|
+
</span>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<div class="form-row">
|
|
73
|
+
<label for="node-config-input-zone">
|
|
74
|
+
<i class="fa fa-location-arrow"></i> Zone
|
|
75
|
+
</label>
|
|
76
|
+
<input type="text" id="node-config-input-zone"
|
|
77
|
+
placeholder="e.g. Master, BnB, GuestWing"
|
|
78
|
+
style="width:60%" />
|
|
79
|
+
<div style="margin-left:106px; margin-top:4px; color:#999; font-size:0.85em;">
|
|
80
|
+
Used in MQTT topics — no spaces or special characters ( # + / ).
|
|
81
|
+
Spaces are automatically converted to underscores.
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<hr/>
|
|
86
|
+
|
|
87
|
+
<!-- MQTT BROKER -->
|
|
88
|
+
<div class="form-row">
|
|
89
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
90
|
+
<i class="fa fa-exchange"></i> MQTT Broker
|
|
91
|
+
</label>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="form-row">
|
|
95
|
+
<label for="node-config-input-broker">
|
|
96
|
+
<i class="fa fa-server"></i> Broker
|
|
97
|
+
</label>
|
|
98
|
+
<input type="text" id="node-config-input-broker" />
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<hr/>
|
|
102
|
+
|
|
103
|
+
<!-- HOME ASSISTANT -->
|
|
104
|
+
<div class="form-row">
|
|
105
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
106
|
+
<i class="fa fa-home"></i> Home Assistant
|
|
107
|
+
</label>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div class="form-row">
|
|
111
|
+
<label for="node-config-input-discoveryPrefix">
|
|
112
|
+
<i class="fa fa-search"></i> Discovery prefix
|
|
113
|
+
</label>
|
|
114
|
+
<input type="text" id="node-config-input-discoveryPrefix"
|
|
115
|
+
placeholder="homeassistant" style="width:40%" />
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div class="form-row">
|
|
119
|
+
<label for="node-config-input-qos">
|
|
120
|
+
<i class="fa fa-signal"></i> QoS
|
|
121
|
+
</label>
|
|
122
|
+
<select id="node-config-input-qos" style="width:80px">
|
|
123
|
+
<option value="0">0</option>
|
|
124
|
+
<option value="1">1</option>
|
|
125
|
+
<option value="2">2</option>
|
|
126
|
+
</select>
|
|
127
|
+
|
|
128
|
+
<label for="node-config-input-retain" style="width:auto">
|
|
129
|
+
<i class="fa fa-thumb-tack"></i> Retain
|
|
130
|
+
</label>
|
|
131
|
+
<select id="node-config-input-retain" style="width:80px">
|
|
132
|
+
<option value="false">false</option>
|
|
133
|
+
<option value="true">true</option>
|
|
134
|
+
</select>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<hr/>
|
|
138
|
+
|
|
139
|
+
<!-- DEFAULTS -->
|
|
140
|
+
<div class="form-row">
|
|
141
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
142
|
+
<i class="fa fa-sliders"></i> Defaults
|
|
143
|
+
</label>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
<div class="form-row">
|
|
147
|
+
<label for="node-config-input-enabledDefault">
|
|
148
|
+
<i class="fa fa-toggle-on"></i> Enabled by default in HA
|
|
149
|
+
</label>
|
|
150
|
+
<select id="node-config-input-enabledDefault" style="width:80px">
|
|
151
|
+
<option value="true">true</option>
|
|
152
|
+
<option value="false">false</option>
|
|
153
|
+
</select>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<div class="form-row">
|
|
157
|
+
<label for="node-config-input-diskDelay">
|
|
158
|
+
<i class="fa fa-clock-o"></i> Disk save delay (s)
|
|
159
|
+
</label>
|
|
160
|
+
<input type="number" id="node-config-input-diskDelay"
|
|
161
|
+
min="1" max="60" style="width:70px" />
|
|
162
|
+
<span style="margin-left:8px; color:#999; font-size:0.85em;">
|
|
163
|
+
Debounce delay before writing state to disk
|
|
164
|
+
</span>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
<div class="form-row">
|
|
168
|
+
<label style="margin-left:106px; color:#999; font-size:0.85em;">
|
|
169
|
+
Flash durations (seconds):
|
|
170
|
+
</label>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="form-row">
|
|
173
|
+
<label for="node-config-input-flashShort">
|
|
174
|
+
<i class="fa fa-clock-o"></i> Flash Short
|
|
175
|
+
</label>
|
|
176
|
+
<input type="number" id="node-config-input-flashShort"
|
|
177
|
+
min="0.1" step="0.1" style="width:70px" />
|
|
178
|
+
|
|
179
|
+
<label for="node-config-input-flashLong" style="width:auto">
|
|
180
|
+
Flash Long
|
|
181
|
+
</label>
|
|
182
|
+
<input type="number" id="node-config-input-flashLong"
|
|
183
|
+
min="1" style="width:70px" />
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
</script>
|
|
187
|
+
|
|
188
|
+
<!-- ============================================================
|
|
189
|
+
Help Panel
|
|
190
|
+
============================================================ -->
|
|
191
|
+
<script type="text/html" data-help-name="ha-mqtt-config">
|
|
192
|
+
<p>
|
|
193
|
+
Shared configuration node for the <strong>DMX for HA</strong> package.
|
|
194
|
+
Create one config node per zone. All DMX, Relay, Button and PIR nodes
|
|
195
|
+
reference this config to inherit site-wide settings.
|
|
196
|
+
</p>
|
|
197
|
+
|
|
198
|
+
<h3>Setup</h3>
|
|
199
|
+
<ol>
|
|
200
|
+
<li>Set a meaningful <strong>Name</strong> — e.g. "Master Zone", "Guest Wing"</li>
|
|
201
|
+
<li>Enter your <strong>Site ID</strong> — a short slug used in MQTT topic construction (e.g. <code>home</code>)</li>
|
|
202
|
+
<li>Select your <strong>Zone</strong></li>
|
|
203
|
+
<li>Select your <strong>MQTT Broker</strong> from the dropdown</li>
|
|
204
|
+
<li>Leave HA defaults as-is unless you have a custom HA MQTT setup</li>
|
|
205
|
+
</ol>
|
|
206
|
+
|
|
207
|
+
<h3>Multi-zone deployments</h3>
|
|
208
|
+
<p>
|
|
209
|
+
Create one <code>ha-mqtt-config</code> node per zone. Each DMX, Relay,
|
|
210
|
+
Button or PIR node picks its zone via the Config dropdown in its own
|
|
211
|
+
editor panel.
|
|
212
|
+
</p>
|
|
213
|
+
|
|
214
|
+
<h3>MQTT topic format</h3>
|
|
215
|
+
<p>Topics are constructed as:</p>
|
|
216
|
+
<pre>{siteId}/{zone}/{controller}/...</pre>
|
|
217
|
+
<p>Example with Site ID <code>home</code> and Zone <code>Master</code>:</p>
|
|
218
|
+
<pre>home/Master/dmx/1</pre>
|
|
219
|
+
|
|
220
|
+
<h3>Details</h3>
|
|
221
|
+
<dl class="message-properties">
|
|
222
|
+
<dt>Site ID <span class="property-type">string</span></dt>
|
|
223
|
+
<dd>Short slug identifying this installation. Used in MQTT topic construction. No spaces.</dd>
|
|
224
|
+
<dt>Zone <span class="property-type">string</span></dt>
|
|
225
|
+
<dd>Physical zone of this config node. Becomes part of the MQTT topic.</dd>
|
|
226
|
+
<dt>Broker <span class="property-type">mqtt-broker</span></dt>
|
|
227
|
+
<dd>The MQTT broker all nodes in this zone connect to.</dd>
|
|
228
|
+
<dt>Discovery prefix <span class="property-type">string</span></dt>
|
|
229
|
+
<dd>HA MQTT discovery prefix. Default: <code>homeassistant</code></dd>
|
|
230
|
+
<dt>Disk save delay <span class="property-type">number</span></dt>
|
|
231
|
+
<dd>Seconds to debounce before writing fixture state to disk context store. Default: 10.</dd>
|
|
232
|
+
</dl>
|
|
233
|
+
</script>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// ha-mqtt-config — Config Node Runtime
|
|
3
|
+
// Package: node-red-contrib-dmx-for-ha
|
|
4
|
+
// Author: DeSwaggy — Discord: @deswaggy
|
|
5
|
+
//
|
|
6
|
+
// Shared configuration node. Holds site-wide settings and
|
|
7
|
+
// exposes the MQTT broker connection to all child nodes
|
|
8
|
+
// (ha-mqtt-dmx, ha-mqtt-dmx-group, ha-mqtt-relay,
|
|
9
|
+
// ha-mqtt-button, ha-mqtt-pir).
|
|
10
|
+
//
|
|
11
|
+
// Child nodes access config via:
|
|
12
|
+
// const config = RED.nodes.getNode(this.config);
|
|
13
|
+
// config.broker → MQTT broker node
|
|
14
|
+
// config.siteId → site ID string
|
|
15
|
+
// config.zone → zone string
|
|
16
|
+
// config.settings → all other settings
|
|
17
|
+
// ============================================================
|
|
18
|
+
|
|
19
|
+
module.exports = function (RED) {
|
|
20
|
+
|
|
21
|
+
function HaMqttConfigNode(config) {
|
|
22
|
+
RED.nodes.createNode(this, config);
|
|
23
|
+
|
|
24
|
+
// Site
|
|
25
|
+
// Sanitise siteId — same rules as zone
|
|
26
|
+
this.siteId = (config.siteId || '')
|
|
27
|
+
.trim()
|
|
28
|
+
.replace(/\s+/g, '_')
|
|
29
|
+
.replace(/[#\+\/]/g, '')
|
|
30
|
+
.replace(/_+/g, '_');
|
|
31
|
+
// Sanitise zone — strip characters invalid in MQTT topics
|
|
32
|
+
// Spaces → underscores, remove # + / and other special chars
|
|
33
|
+
this.zone = (config.zone || '')
|
|
34
|
+
.trim()
|
|
35
|
+
.replace(/\s+/g, '_')
|
|
36
|
+
.replace(/[#\+\/]/g, '')
|
|
37
|
+
.replace(/_+/g, '_');
|
|
38
|
+
|
|
39
|
+
// MQTT broker — child nodes subscribe/publish via this
|
|
40
|
+
this.broker = config.broker;
|
|
41
|
+
this.brokerNode = RED.nodes.getNode(config.broker);
|
|
42
|
+
|
|
43
|
+
// HA MQTT topic segments
|
|
44
|
+
this.discoveryPrefix = config.discoveryPrefix || 'homeassistant';
|
|
45
|
+
this.configTopic = config.configTopic || 'config';
|
|
46
|
+
this.stateTopic = config.stateTopic || 'state';
|
|
47
|
+
this.commandTopic = config.commandTopic || 'cmd';
|
|
48
|
+
this.availTopic = config.availTopic || 'avty';
|
|
49
|
+
|
|
50
|
+
// MQTT settings
|
|
51
|
+
this.qos = parseInt(config.qos) || 0;
|
|
52
|
+
this.retain = config.retain === 'true';
|
|
53
|
+
|
|
54
|
+
// HA defaults
|
|
55
|
+
this.enabledDefault = config.enabledDefault !== 'false';
|
|
56
|
+
|
|
57
|
+
// Timing defaults
|
|
58
|
+
this.diskDelay = parseInt(config.diskDelay) || 10;
|
|
59
|
+
this.flashShort = parseFloat(config.flashShort) || 1;
|
|
60
|
+
this.flashLong = parseFloat(config.flashLong) || 10;
|
|
61
|
+
|
|
62
|
+
// Expose a convenience settings object for child nodes
|
|
63
|
+
this.settings = {
|
|
64
|
+
siteId: this.siteId,
|
|
65
|
+
zone: this.zone,
|
|
66
|
+
discoveryPrefix: this.discoveryPrefix,
|
|
67
|
+
configTopic: this.configTopic,
|
|
68
|
+
stateTopic: this.stateTopic,
|
|
69
|
+
commandTopic: this.commandTopic,
|
|
70
|
+
availTopic: this.availTopic,
|
|
71
|
+
qos: this.qos,
|
|
72
|
+
retain: this.retain,
|
|
73
|
+
enabledDefault: this.enabledDefault,
|
|
74
|
+
diskDelay: this.diskDelay,
|
|
75
|
+
flashShort: this.flashShort,
|
|
76
|
+
flashLong: this.flashLong,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
RED.nodes.registerType('ha-mqtt-config', HaMqttConfigNode);
|
|
81
|
+
};
|