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,547 @@
|
|
|
1
|
+
<!-- ============================================================
|
|
2
|
+
ha-mqtt-dmx — DMX Node Editor
|
|
3
|
+
Package: node-red-contrib-dmx-for-ha
|
|
4
|
+
Author: DeSwaggy — Discord: @deswaggy
|
|
5
|
+
============================================================ -->
|
|
6
|
+
|
|
7
|
+
<script type="text/javascript">
|
|
8
|
+
|
|
9
|
+
// ── Areas and Sub-areas ────────────────────────────────────────
|
|
10
|
+
const HA_DMX_AREAS = [
|
|
11
|
+
{ v: 'Area 52', l: 'TBC' },
|
|
12
|
+
{ v: 'Attic Roof', l: 'Attic Roof' },
|
|
13
|
+
{ v: 'Backyard', l: 'Backyard' },
|
|
14
|
+
{ v: 'Balcony', l: 'Balcony' },
|
|
15
|
+
{ v: 'Bathroom', l: 'Bathroom' },
|
|
16
|
+
{ v: 'Bedroom 1', l: 'Bedroom 1' },
|
|
17
|
+
{ v: 'Bedroom 2', l: 'Bedroom 2' },
|
|
18
|
+
{ v: 'Bedroom 3', l: 'Bedroom 3' },
|
|
19
|
+
{ v: 'Bedroom 4', l: 'Bedroom 4' },
|
|
20
|
+
{ v: 'Carport', l: 'Carport' },
|
|
21
|
+
{ v: 'Cellar', l: 'Cellar' },
|
|
22
|
+
{ v: 'Dining', l: 'Dining' },
|
|
23
|
+
{ v: 'Driveway', l: 'Driveway' },
|
|
24
|
+
{ v: 'Entry', l: 'Entry' },
|
|
25
|
+
{ v: 'Garage', l: 'Garage' },
|
|
26
|
+
{ v: 'Gym', l: 'Gym' },
|
|
27
|
+
{ v: 'Hallway', l: 'Hallway' },
|
|
28
|
+
{ v: 'Kitchen', l: 'Kitchen' },
|
|
29
|
+
{ v: 'Laundry', l: 'Laundry' },
|
|
30
|
+
{ v: 'Link Bridge (Upper)', l: 'Link Bridge Upper' },
|
|
31
|
+
{ v: 'Link Bridge (Lower)', l: 'Link Bridge Lower' },
|
|
32
|
+
{ v: 'Living', l: 'Living' },
|
|
33
|
+
{ v: 'Media', l: 'Media' },
|
|
34
|
+
{ v: 'Office', l: 'Office' },
|
|
35
|
+
{ v: 'Pantry', l: 'Pantry' },
|
|
36
|
+
{ v: 'Pass Over', l: 'Pass Over' },
|
|
37
|
+
{ v: 'Pass Under', l: 'Pass Under' },
|
|
38
|
+
{ v: 'Passageway', l: 'Passageway' },
|
|
39
|
+
{ v: 'Pool', l: 'Pool' },
|
|
40
|
+
{ v: 'Portico', l: 'Portico' },
|
|
41
|
+
{ v: 'PowderRoom', l: 'PowderRoom' },
|
|
42
|
+
{ v: 'Reading', l: 'Reading' },
|
|
43
|
+
{ v: 'Rumpus', l: 'Rumpus' },
|
|
44
|
+
{ v: 'Spa', l: 'Spa' },
|
|
45
|
+
{ v: 'Stairs', l: 'Stairs' },
|
|
46
|
+
{ v: 'Store', l: 'Store' },
|
|
47
|
+
{ v: 'SubFloor', l: 'SubFloor' },
|
|
48
|
+
{ v: 'Terrace', l: 'Terrace' },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const HA_DMX_SUB_AREAS = [
|
|
52
|
+
{ v: '', l: 'None' },
|
|
53
|
+
{ v: 'Balcony', l: 'Balcony' },
|
|
54
|
+
{ v: 'Bed (North)', l: 'Bed North' },
|
|
55
|
+
{ v: 'Bed (South)', l: 'Bed South' },
|
|
56
|
+
{ v: 'Bed (East)', l: 'Bed East' },
|
|
57
|
+
{ v: 'Bed (West)', l: 'Bed West' },
|
|
58
|
+
{ v: 'Ceiling', l: 'Ceiling' },
|
|
59
|
+
{ v: 'Dress', l: 'Dress' },
|
|
60
|
+
{ v: 'Ensuite', l: 'Ensuite' },
|
|
61
|
+
{ v: 'Exterior', l: 'Exterior' },
|
|
62
|
+
{ v: 'Ground Floor', l: 'Ground Floor' },
|
|
63
|
+
{ v: '1st Floor', l: '1st Floor' },
|
|
64
|
+
{ v: 'Landing', l: 'Landing' },
|
|
65
|
+
{ v: 'Office', l: 'Office' },
|
|
66
|
+
{ v: 'Stairs', l: 'Stairs' },
|
|
67
|
+
{ v: 'WIR', l: 'WIR' },
|
|
68
|
+
{ v: '(North)', l: 'North' },
|
|
69
|
+
{ v: '(South)', l: 'South' },
|
|
70
|
+
{ v: '(East)', l: 'East' },
|
|
71
|
+
{ v: '(West)', l: 'West' },
|
|
72
|
+
{ v: 'Void', l: 'Void' },
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
// ── Helper — populate a select from an array of {v, l} ────────
|
|
76
|
+
function populateSelect(selectId, items, currentVal) {
|
|
77
|
+
const sel = $('#' + selectId);
|
|
78
|
+
sel.empty();
|
|
79
|
+
items.forEach(function (item) {
|
|
80
|
+
sel.append($('<option>')
|
|
81
|
+
.val(item.v)
|
|
82
|
+
.text(item.l)
|
|
83
|
+
.prop('selected', item.v === currentVal));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ── Show/hide DMX channel rows based on colour mode ─────────────
|
|
88
|
+
function updateChannelVisibility(mode) {
|
|
89
|
+
const show = function (id) { $('#dmx-ch-row-' + id).show(); };
|
|
90
|
+
const hide = function (id) { $('#dmx-ch-row-' + id).hide(); };
|
|
91
|
+
|
|
92
|
+
// Hide all first
|
|
93
|
+
['red','green','blue','white','warmWhite'].forEach(hide);
|
|
94
|
+
|
|
95
|
+
switch (mode) {
|
|
96
|
+
case 'rgbw':
|
|
97
|
+
show('red'); show('green'); show('blue'); show('white');
|
|
98
|
+
break;
|
|
99
|
+
case 'rgbww':
|
|
100
|
+
show('red'); show('green'); show('blue');
|
|
101
|
+
show('white'); show('warmWhite');
|
|
102
|
+
break;
|
|
103
|
+
case 'rgb':
|
|
104
|
+
show('red'); show('green'); show('blue');
|
|
105
|
+
break;
|
|
106
|
+
case 'color_temp':
|
|
107
|
+
show('white'); show('warmWhite');
|
|
108
|
+
break;
|
|
109
|
+
case 'brightness':
|
|
110
|
+
show('white'); // single channel — use white as master
|
|
111
|
+
break;
|
|
112
|
+
case 'onoff':
|
|
113
|
+
show('white'); // single channel
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ── Node Registration ──────────────────────────────────────────
|
|
119
|
+
RED.nodes.registerType('ha-mqtt-dmx', {
|
|
120
|
+
category: 'DMX for HA',
|
|
121
|
+
color: '#ae45ff',
|
|
122
|
+
icon: 'font-awesome/fa-lightbulb-o',
|
|
123
|
+
inputs: 1,
|
|
124
|
+
outputs: 0,
|
|
125
|
+
paletteLabel: 'DMX',
|
|
126
|
+
|
|
127
|
+
defaults: {
|
|
128
|
+
name: { value: '' },
|
|
129
|
+
config: { value: '', type: 'ha-mqtt-config', required: true },
|
|
130
|
+
// Fixture identity
|
|
131
|
+
colorMode: { value: 'rgbw', required: true },
|
|
132
|
+
deviceType: { value: 'Downlight', required: true },
|
|
133
|
+
uidPrefix: { value: 'L', required: true },
|
|
134
|
+
uid: { value: '', required: true },
|
|
135
|
+
uidPostfix: { value: '' },
|
|
136
|
+
// Location
|
|
137
|
+
area: { value: 'Area 52' },
|
|
138
|
+
situation: { value: 'in' },
|
|
139
|
+
subLocation: { value: '' },
|
|
140
|
+
// DMX channels
|
|
141
|
+
chRed: { value: '' },
|
|
142
|
+
chGreen: { value: '' },
|
|
143
|
+
chBlue: { value: '' },
|
|
144
|
+
chWhite: { value: '' },
|
|
145
|
+
chWarmWhite: { value: '' },
|
|
146
|
+
// DMX controller
|
|
147
|
+
controllerNum: { value: '1' },
|
|
148
|
+
universe: { value: '1' },
|
|
149
|
+
// Options
|
|
150
|
+
haIcon: { value: 'mdi:lightbulb' },
|
|
151
|
+
showEffects: { value: true },
|
|
152
|
+
transitions: { value: true },
|
|
153
|
+
groupSync: { value: false },
|
|
154
|
+
defaultState: { value: 'OFF' },
|
|
155
|
+
// Advanced
|
|
156
|
+
dmxLimiter: { value: '255' },
|
|
157
|
+
minOutput: { value: '1' },
|
|
158
|
+
brightBump: { value: '50' },
|
|
159
|
+
ticksPerSec: { value: '31' },
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
label: function () {
|
|
163
|
+
if (this.name) return this.name;
|
|
164
|
+
const prefix = this.uidPrefix || 'L';
|
|
165
|
+
const id = this.uid || '?';
|
|
166
|
+
const postfix = this.uidPostfix || '';
|
|
167
|
+
return prefix + '-' + id + postfix;
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
labelStyle: function () {
|
|
171
|
+
return this.name ? 'node_label_italic' : '';
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
outputLabels: [],
|
|
175
|
+
inputLabels: ['Input'],
|
|
176
|
+
|
|
177
|
+
oneditprepare: function () {
|
|
178
|
+
const node = this;
|
|
179
|
+
|
|
180
|
+
// Populate area dropdown
|
|
181
|
+
populateSelect('node-input-area', HA_DMX_AREAS, node.area);
|
|
182
|
+
|
|
183
|
+
// Populate sub-area dropdown
|
|
184
|
+
populateSelect('node-input-subLocation', HA_DMX_SUB_AREAS, node.subLocation);
|
|
185
|
+
|
|
186
|
+
// Set colour mode and update channel visibility
|
|
187
|
+
$('#node-input-colorMode').val(node.colorMode || 'rgbw');
|
|
188
|
+
updateChannelVisibility(node.colorMode || 'rgbw');
|
|
189
|
+
|
|
190
|
+
// Update channel visibility on colour mode change
|
|
191
|
+
$('#node-input-colorMode').on('change', function () {
|
|
192
|
+
updateChannelVisibility($(this).val());
|
|
193
|
+
});
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
oneditsave: function () {
|
|
197
|
+
// Sanitise UID — digits only
|
|
198
|
+
const uid = $('#node-input-uid').val().replace(/[^0-9]/g, '');
|
|
199
|
+
$('#node-input-uid').val(uid);
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
</script>
|
|
204
|
+
|
|
205
|
+
<!-- ============================================================
|
|
206
|
+
Editor Panel Template
|
|
207
|
+
============================================================ -->
|
|
208
|
+
<script type="text/html" data-template-name="ha-mqtt-dmx">
|
|
209
|
+
|
|
210
|
+
<!-- NAME (optional — defaults to fixture ID on canvas) -->
|
|
211
|
+
<div class="form-row">
|
|
212
|
+
<label for="node-input-name">
|
|
213
|
+
<i class="fa fa-tag"></i> Name
|
|
214
|
+
</label>
|
|
215
|
+
<input type="text" id="node-input-name"
|
|
216
|
+
placeholder="Optional — defaults to fixture ID e.g. L-992-A" />
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<!-- CONFIG NODE PICKER -->
|
|
220
|
+
<div class="form-row">
|
|
221
|
+
<label for="node-input-config">
|
|
222
|
+
<i class="fa fa-cog"></i> Config
|
|
223
|
+
</label>
|
|
224
|
+
<input type="text" id="node-input-config" />
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<hr/>
|
|
228
|
+
|
|
229
|
+
<!-- ── FIXTURE (* Required) ──────────────────────────────── -->
|
|
230
|
+
<div class="form-row">
|
|
231
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
232
|
+
<i class="fa fa-lightbulb-o"></i> Fixture <span style="color:#e74c3c">* Required</span>
|
|
233
|
+
</label>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<!-- Colour Mode -->
|
|
237
|
+
<div class="form-row">
|
|
238
|
+
<label for="node-input-colorMode">
|
|
239
|
+
<i class="fa fa-sliders"></i> Colour Mode
|
|
240
|
+
</label>
|
|
241
|
+
<select id="node-input-colorMode" style="width:55%">
|
|
242
|
+
<option value="rgbw">RGBW</option>
|
|
243
|
+
<option value="rgbww">RGBWW</option>
|
|
244
|
+
<option value="rgb">RGB</option>
|
|
245
|
+
<option value="color_temp">Colour Temperature (CCT)</option>
|
|
246
|
+
<option value="brightness">Brightness only</option>
|
|
247
|
+
<option value="onoff">On/Off only</option>
|
|
248
|
+
</select>
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
<!-- Device Type -->
|
|
252
|
+
<div class="form-row">
|
|
253
|
+
<label for="node-input-deviceType">
|
|
254
|
+
<i class="fa fa-lightbulb-o"></i> Device Type
|
|
255
|
+
</label>
|
|
256
|
+
<input type="text" id="node-input-deviceType"
|
|
257
|
+
placeholder="e.g. Downlight, Strip light, Panel"
|
|
258
|
+
style="width:55%" />
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<!-- Prefix / ID / Postfix on one row -->
|
|
262
|
+
<div class="form-row">
|
|
263
|
+
<label for="node-input-uidPrefix">
|
|
264
|
+
<i class="fa fa-tv"></i> Fixture ID
|
|
265
|
+
</label>
|
|
266
|
+
<select id="node-input-uidPrefix" style="width:55px">
|
|
267
|
+
<option value="L">L</option>
|
|
268
|
+
<option value="P">P</option>
|
|
269
|
+
</select>
|
|
270
|
+
-
|
|
271
|
+
<input type="text" id="node-input-uid"
|
|
272
|
+
placeholder="992" style="width:70px"
|
|
273
|
+
title="Cable/plan ID number from electrical drawing" />
|
|
274
|
+
|
|
275
|
+
<select id="node-input-uidPostfix" style="width:65px">
|
|
276
|
+
<option value="">(none)</option>
|
|
277
|
+
<option value="-A">-A</option>
|
|
278
|
+
<option value="-B">-B</option>
|
|
279
|
+
<option value="-C">-C</option>
|
|
280
|
+
<option value="-D">-D</option>
|
|
281
|
+
</select>
|
|
282
|
+
<span style="margin-left:8px; color:#999; font-size:0.85em;">
|
|
283
|
+
Prefix — Plan ID — Channel
|
|
284
|
+
</span>
|
|
285
|
+
</div>
|
|
286
|
+
|
|
287
|
+
<!-- Area -->
|
|
288
|
+
<div class="form-row">
|
|
289
|
+
<label for="node-input-area">
|
|
290
|
+
<i class="fa fa-map-marker"></i> Area
|
|
291
|
+
</label>
|
|
292
|
+
<select id="node-input-area" style="width:55%"></select>
|
|
293
|
+
</div>
|
|
294
|
+
|
|
295
|
+
<!-- Situation -->
|
|
296
|
+
<div class="form-row">
|
|
297
|
+
<label for="node-input-situation">
|
|
298
|
+
<i class="fa fa-compass"></i> Situation
|
|
299
|
+
</label>
|
|
300
|
+
<select id="node-input-situation" style="width:55%">
|
|
301
|
+
<option value="in">in</option>
|
|
302
|
+
<option value="above">above</option>
|
|
303
|
+
<option value="below">below</option>
|
|
304
|
+
<option value="outside">outside</option>
|
|
305
|
+
<option value="throughout">throughout</option>
|
|
306
|
+
<option value="under">under</option>
|
|
307
|
+
<option value="over">over</option>
|
|
308
|
+
</select>
|
|
309
|
+
</div>
|
|
310
|
+
|
|
311
|
+
<!-- Sub-Area -->
|
|
312
|
+
<div class="form-row">
|
|
313
|
+
<label for="node-input-subLocation">
|
|
314
|
+
<i class="fa fa-map-marker"></i> Sub-Area
|
|
315
|
+
</label>
|
|
316
|
+
<select id="node-input-subLocation" style="width:55%"></select>
|
|
317
|
+
</div>
|
|
318
|
+
|
|
319
|
+
<hr/>
|
|
320
|
+
|
|
321
|
+
<!-- ── DMX CHANNELS ──────────────────────────────────────── -->
|
|
322
|
+
<div class="form-row">
|
|
323
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
324
|
+
<i class="fa fa-sort-numeric-asc"></i> DMX Channels
|
|
325
|
+
</label>
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
<div class="form-row" id="dmx-ch-row-red">
|
|
329
|
+
<label for="node-input-chRed">
|
|
330
|
+
<i class="fa fa-circle" style="color:#e74c3c"></i> Red
|
|
331
|
+
</label>
|
|
332
|
+
<input type="number" id="node-input-chRed"
|
|
333
|
+
min="1" max="512" style="width:80px" placeholder="e.g. 201" />
|
|
334
|
+
</div>
|
|
335
|
+
|
|
336
|
+
<div class="form-row" id="dmx-ch-row-green">
|
|
337
|
+
<label for="node-input-chGreen">
|
|
338
|
+
<i class="fa fa-circle" style="color:#2ecc71"></i> Green
|
|
339
|
+
</label>
|
|
340
|
+
<input type="number" id="node-input-chGreen"
|
|
341
|
+
min="1" max="512" style="width:80px" placeholder="e.g. 202" />
|
|
342
|
+
</div>
|
|
343
|
+
|
|
344
|
+
<div class="form-row" id="dmx-ch-row-blue">
|
|
345
|
+
<label for="node-input-chBlue">
|
|
346
|
+
<i class="fa fa-circle" style="color:#3498db"></i> Blue
|
|
347
|
+
</label>
|
|
348
|
+
<input type="number" id="node-input-chBlue"
|
|
349
|
+
min="1" max="512" style="width:80px" placeholder="e.g. 203" />
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
<div class="form-row" id="dmx-ch-row-white">
|
|
353
|
+
<label for="node-input-chWhite">
|
|
354
|
+
<i class="fa fa-circle" style="color:#ecf0f1; text-shadow:0 0 1px #999"></i> White
|
|
355
|
+
</label>
|
|
356
|
+
<input type="number" id="node-input-chWhite"
|
|
357
|
+
min="1" max="512" style="width:80px" placeholder="e.g. 204" />
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<div class="form-row" id="dmx-ch-row-warmWhite">
|
|
361
|
+
<label for="node-input-chWarmWhite">
|
|
362
|
+
<i class="fa fa-circle" style="color:#f39c12"></i> Warm White
|
|
363
|
+
</label>
|
|
364
|
+
<input type="number" id="node-input-chWarmWhite"
|
|
365
|
+
min="1" max="512" style="width:80px" placeholder="e.g. 205" />
|
|
366
|
+
</div>
|
|
367
|
+
|
|
368
|
+
<hr/>
|
|
369
|
+
|
|
370
|
+
<!-- ── DMX CONTROLLER ────────────────────────────────────── -->
|
|
371
|
+
<div class="form-row">
|
|
372
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
373
|
+
<i class="fa fa-sort-numeric-asc"></i> DMX Controller
|
|
374
|
+
</label>
|
|
375
|
+
</div>
|
|
376
|
+
|
|
377
|
+
<div class="form-row">
|
|
378
|
+
<label for="node-input-controllerNum">
|
|
379
|
+
<i class="fa fa-sort-numeric-asc"></i> Controller
|
|
380
|
+
</label>
|
|
381
|
+
<input type="number" id="node-input-controllerNum"
|
|
382
|
+
min="1" style="width:70px" />
|
|
383
|
+
|
|
384
|
+
<label for="node-input-universe" style="width:auto">
|
|
385
|
+
Universe
|
|
386
|
+
</label>
|
|
387
|
+
<input type="number" id="node-input-universe"
|
|
388
|
+
min="1" style="width:70px" />
|
|
389
|
+
</div>
|
|
390
|
+
|
|
391
|
+
<hr/>
|
|
392
|
+
|
|
393
|
+
<!-- ── OPTIONS ───────────────────────────────────────────── -->
|
|
394
|
+
<div class="form-row">
|
|
395
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
396
|
+
<i class="fa fa-sliders"></i> Options
|
|
397
|
+
</label>
|
|
398
|
+
</div>
|
|
399
|
+
|
|
400
|
+
<div class="form-row">
|
|
401
|
+
<label for="node-input-haIcon">
|
|
402
|
+
<i class="fa fa-image"></i> HA Icon
|
|
403
|
+
</label>
|
|
404
|
+
<input type="text" id="node-input-haIcon"
|
|
405
|
+
placeholder="mdi:lightbulb" style="width:55%" />
|
|
406
|
+
</div>
|
|
407
|
+
|
|
408
|
+
<div class="form-row">
|
|
409
|
+
<label for="node-input-defaultState">
|
|
410
|
+
<i class="fa fa-toggle-off"></i> Default state
|
|
411
|
+
</label>
|
|
412
|
+
<select id="node-input-defaultState" style="width:100px">
|
|
413
|
+
<option value="OFF">OFF</option>
|
|
414
|
+
<option value="ON">ON</option>
|
|
415
|
+
</select>
|
|
416
|
+
</div>
|
|
417
|
+
|
|
418
|
+
<div class="form-row">
|
|
419
|
+
<label> </label>
|
|
420
|
+
<input type="checkbox" id="node-input-showEffects"
|
|
421
|
+
style="width:auto; margin-right:8px" />
|
|
422
|
+
<label for="node-input-showEffects" style="width:auto">
|
|
423
|
+
Show effects in HA
|
|
424
|
+
</label>
|
|
425
|
+
</div>
|
|
426
|
+
|
|
427
|
+
<div class="form-row">
|
|
428
|
+
<label> </label>
|
|
429
|
+
<input type="checkbox" id="node-input-transitions"
|
|
430
|
+
style="width:auto; margin-right:8px" />
|
|
431
|
+
<label for="node-input-transitions" style="width:auto">
|
|
432
|
+
Enable transitions
|
|
433
|
+
</label>
|
|
434
|
+
</div>
|
|
435
|
+
|
|
436
|
+
<div class="form-row">
|
|
437
|
+
<label> </label>
|
|
438
|
+
<input type="checkbox" id="node-input-groupSync"
|
|
439
|
+
style="width:auto; margin-right:8px" />
|
|
440
|
+
<label for="node-input-groupSync" style="width:auto">
|
|
441
|
+
Sync effects via Group Node
|
|
442
|
+
</label>
|
|
443
|
+
</div>
|
|
444
|
+
|
|
445
|
+
<hr/>
|
|
446
|
+
|
|
447
|
+
<!-- ── ADVANCED ──────────────────────────────────────────── -->
|
|
448
|
+
<div class="form-row">
|
|
449
|
+
<label style="width:100%; font-weight:bold; color:#999; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em;">
|
|
450
|
+
<i class="fa fa-wrench"></i> Advanced
|
|
451
|
+
</label>
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
<div class="form-row">
|
|
455
|
+
<label for="node-input-dmxLimiter">
|
|
456
|
+
<i class="fa fa-sort-numeric-asc"></i> DMX limiter
|
|
457
|
+
</label>
|
|
458
|
+
<input type="number" id="node-input-dmxLimiter"
|
|
459
|
+
min="0" max="255" style="width:70px" />
|
|
460
|
+
<span style="margin-left:8px; color:#999; font-size:0.85em;">0–255</span>
|
|
461
|
+
</div>
|
|
462
|
+
|
|
463
|
+
<div class="form-row">
|
|
464
|
+
<label for="node-input-minOutput">
|
|
465
|
+
<i class="fa fa-sort-numeric-asc"></i> Min output when ON
|
|
466
|
+
</label>
|
|
467
|
+
<input type="number" id="node-input-minOutput"
|
|
468
|
+
min="0" max="255" style="width:70px" />
|
|
469
|
+
<span style="margin-left:8px; color:#999; font-size:0.85em;">0 = pure gamma</span>
|
|
470
|
+
</div>
|
|
471
|
+
|
|
472
|
+
<div class="form-row">
|
|
473
|
+
<label for="node-input-brightBump">
|
|
474
|
+
<i class="fa fa-sort-numeric-asc"></i> Brightness bump
|
|
475
|
+
</label>
|
|
476
|
+
<input type="number" id="node-input-brightBump"
|
|
477
|
+
min="0" max="255" style="width:70px" />
|
|
478
|
+
<span style="margin-left:8px; color:#999; font-size:0.85em;">Initial ON value (0–255)</span>
|
|
479
|
+
</div>
|
|
480
|
+
|
|
481
|
+
<div class="form-row">
|
|
482
|
+
<label for="node-input-ticksPerSec">
|
|
483
|
+
<i class="fa fa-clock-o"></i> Transition ticks/sec
|
|
484
|
+
</label>
|
|
485
|
+
<input type="number" id="node-input-ticksPerSec"
|
|
486
|
+
min="1" max="100" style="width:70px" />
|
|
487
|
+
<span style="margin-left:8px; color:#999; font-size:0.85em;">Default 31</span>
|
|
488
|
+
</div>
|
|
489
|
+
|
|
490
|
+
</script>
|
|
491
|
+
|
|
492
|
+
<!-- ============================================================
|
|
493
|
+
Help Panel
|
|
494
|
+
============================================================ -->
|
|
495
|
+
<script type="text/html" data-help-name="ha-mqtt-dmx">
|
|
496
|
+
<p>
|
|
497
|
+
Controls a single DMX fixture via Home Assistant and MQTT.
|
|
498
|
+
Supports RGBW, RGBWW, RGB, CCT, brightness and on/off colour modes.
|
|
499
|
+
Handles HA MQTT discovery, state reporting, transitions, and effects.
|
|
500
|
+
</p>
|
|
501
|
+
|
|
502
|
+
<h3>Setup</h3>
|
|
503
|
+
<ol>
|
|
504
|
+
<li>Select your <strong>Config</strong> node (site and zone settings)</li>
|
|
505
|
+
<li>Choose <strong>Colour Mode</strong> — channel fields update automatically</li>
|
|
506
|
+
<li>Set <strong>Fixture ID</strong> — Prefix, Plan ID number, and Channel letter if applicable</li>
|
|
507
|
+
<li>Enter <strong>DMX Channels</strong> matching your fixture's DMX start address</li>
|
|
508
|
+
<li>Set <strong>Controller</strong> and <strong>Universe</strong> numbers</li>
|
|
509
|
+
<li>Deploy — the fixture appears in HA automatically</li>
|
|
510
|
+
</ol>
|
|
511
|
+
|
|
512
|
+
<h3>Fixture ID</h3>
|
|
513
|
+
<p>
|
|
514
|
+
Matches your electrical plan cable ID. <code>L-992-A</code> = Light fixture,
|
|
515
|
+
cable 992, channel A. The entity ID in HA is locked to this ID and
|
|
516
|
+
survives friendly name changes in the HA dashboard.
|
|
517
|
+
</p>
|
|
518
|
+
|
|
519
|
+
<h3>Inputs</h3>
|
|
520
|
+
<dl class="message-properties">
|
|
521
|
+
<dt>device:add <span class="property-type">msg.device = "add"</span></dt>
|
|
522
|
+
<dd>Run MQTT discovery. Wire from SYSTEM node inject.</dd>
|
|
523
|
+
<dt>device:remove <span class="property-type">msg.device = "remove"</span></dt>
|
|
524
|
+
<dd>Remove entity from HA and clear memory.</dd>
|
|
525
|
+
<dt>HA command <span class="property-type">msg.payload.state</span></dt>
|
|
526
|
+
<dd>Handled internally via MQTT — no wiring needed.</dd>
|
|
527
|
+
<dt>Group cascade <span class="property-type">msg.dmx_trace</span></dt>
|
|
528
|
+
<dd>Command forwarded from a DMX Group Node via its Link output.</dd>
|
|
529
|
+
</dl>
|
|
530
|
+
|
|
531
|
+
<h3>DMX output format</h3>
|
|
532
|
+
<p>
|
|
533
|
+
Publishes to <code>{siteId}/{zone}/dmx/{universe}</code><br/>
|
|
534
|
+
Payload: <code>"{channel3digits}{value3digits}"</code>
|
|
535
|
+
e.g. <code>"212255"</code> = channel 212, value 255.
|
|
536
|
+
</p>
|
|
537
|
+
|
|
538
|
+
<h3>Colour modes</h3>
|
|
539
|
+
<ul>
|
|
540
|
+
<li><strong>RGBW</strong> — Red, Green, Blue, White channels</li>
|
|
541
|
+
<li><strong>RGBWW</strong> — Red, Green, Blue, White, Warm White</li>
|
|
542
|
+
<li><strong>RGB</strong> — Red, Green, Blue only</li>
|
|
543
|
+
<li><strong>Colour Temperature</strong> — White + Warm White (CCT)</li>
|
|
544
|
+
<li><strong>Brightness</strong> — Single channel dimmer</li>
|
|
545
|
+
<li><strong>On/Off</strong> — Binary switching via DMX</li>
|
|
546
|
+
</ul>
|
|
547
|
+
</script>
|