node-red-contrib-dmx-for-ha 0.3.0 → 0.3.4
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/nodes/ha-mqtt-button.html +1 -1
- package/nodes/ha-mqtt-button.js +39 -3
- package/nodes/ha-mqtt-dmx-group.html +1 -1
- package/nodes/ha-mqtt-dmx-group.js +39 -3
- package/nodes/ha-mqtt-dmx.html +1 -1
- package/nodes/ha-mqtt-dmx.js +41 -5
- package/nodes/ha-mqtt-pir.html +1 -1
- package/nodes/ha-mqtt-pir.js +38 -2
- package/nodes/ha-mqtt-relay.html +1 -1
- package/nodes/ha-mqtt-relay.js +39 -3
- package/package.json +1 -1
|
@@ -284,7 +284,7 @@
|
|
|
284
284
|
Debug output to NR debug tab
|
|
285
285
|
</label>
|
|
286
286
|
<div style="margin-left:106px; margin-top:4px; color:#e74c3c; font-size:0.8em;">
|
|
287
|
-
⚠ Disable in production — logs every MQTT publish
|
|
287
|
+
⚠ Disable in production — logs every MQTT publish. Auto-disables after 12hrs.
|
|
288
288
|
</div>
|
|
289
289
|
</div>
|
|
290
290
|
|
package/nodes/ha-mqtt-button.js
CHANGED
|
@@ -37,14 +37,32 @@ module.exports = function (RED) {
|
|
|
37
37
|
}, 1500);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// Track
|
|
40
|
+
// Track discovery state — prevents double-fire and allows reconnect re-discovery
|
|
41
41
|
let _discovered = false;
|
|
42
|
+
let _lastDiscoveryTime = 0;
|
|
43
|
+
const _DISCOVERY_COOLDOWN_MS = 5000; // 5 second cooldown between discoveries
|
|
44
|
+
|
|
42
45
|
function _tryDiscover() {
|
|
43
46
|
if (_discovered) return;
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) return;
|
|
44
49
|
_discovered = true;
|
|
50
|
+
_lastDiscoveryTime = now;
|
|
45
51
|
autoDiscover();
|
|
46
52
|
}
|
|
47
53
|
|
|
54
|
+
function _manualDiscover() {
|
|
55
|
+
// Manual trigger (canvas button or input msg) — bypass _discovered flag
|
|
56
|
+
// but still respect cooldown to prevent accidental rapid-fire
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) {
|
|
59
|
+
node.warn('Discovery cooldown active — please wait 5 seconds between manual triggers');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
_lastDiscoveryTime = now;
|
|
63
|
+
handleDeviceAdd();
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
// Auto-discover if broker already connected on deploy
|
|
49
67
|
if (broker.connected) {
|
|
50
68
|
_tryDiscover();
|
|
@@ -54,12 +72,30 @@ module.exports = function (RED) {
|
|
|
54
72
|
_tryDiscover();
|
|
55
73
|
});
|
|
56
74
|
broker.on('close', function () {
|
|
75
|
+
_discovered = false; // Allow re-discovery on reconnect
|
|
57
76
|
setStatus('red', 'ring', 'Broker disconnected');
|
|
58
77
|
});
|
|
59
78
|
broker.on('error', function (err) {
|
|
60
79
|
node.warn('MQTT broker error: ' + (err.message || err));
|
|
61
80
|
setStatus('red', 'dot', 'Broker error — check config');
|
|
62
81
|
});
|
|
82
|
+
// ── Debug mode safeguards ─────────────────────────────────────────
|
|
83
|
+
if (S.debugMode) {
|
|
84
|
+
// Permanent canvas warning so debug mode is obvious
|
|
85
|
+
setStatus('red', 'dot', `ha-mqtt-button "${fixtureId}" ⚠ DEBUG MODE ON`);
|
|
86
|
+
node.warn(`[DEBUG] ha-mqtt-button "${fixtureId}" — debug mode is enabled. Disable in production.`);
|
|
87
|
+
|
|
88
|
+
// Auto-disable after 12 hours — safety net for forgotten debug sessions
|
|
89
|
+
setTimeout(function () {
|
|
90
|
+
if (S.debugMode) {
|
|
91
|
+
S.debugMode = false;
|
|
92
|
+
node.warn(`[DEBUG] ha-mqtt-button "${fixtureId}" — debug mode auto-disabled after 12 hours`);
|
|
93
|
+
setStatus('yellow', 'ring', `${fixtureId} ready — awaiting HA`);
|
|
94
|
+
}
|
|
95
|
+
}, 12 * 60 * 60 * 1000);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
63
99
|
// Fallback — if connect event already fired before listener registered
|
|
64
100
|
setTimeout(function () {
|
|
65
101
|
_tryDiscover();
|
|
@@ -104,7 +140,7 @@ module.exports = function (RED) {
|
|
|
104
140
|
qos: cfg.qos,
|
|
105
141
|
retain: retain !== undefined ? retain : cfg.retain,
|
|
106
142
|
});
|
|
107
|
-
if (S.debugMode) node.
|
|
143
|
+
if (S.debugMode) node.warn(`[DEBUG] ${fixtureId} → ${topic} ${strPayload.substring(0, 120)}`);
|
|
108
144
|
}
|
|
109
145
|
|
|
110
146
|
function setStatus(fill, shape, text) {
|
|
@@ -190,7 +226,7 @@ module.exports = function (RED) {
|
|
|
190
226
|
|
|
191
227
|
if (devReq) {
|
|
192
228
|
switch (devReq) {
|
|
193
|
-
case 'add':
|
|
229
|
+
case 'add': _manualDiscover(); break;
|
|
194
230
|
case 'remove': handleDeviceRemove(); break;
|
|
195
231
|
default: node.warn(`${fixtureId} — unknown device.request: "${devReq}"`);
|
|
196
232
|
}
|
|
@@ -312,7 +312,7 @@
|
|
|
312
312
|
Debug output to NR debug tab
|
|
313
313
|
</label>
|
|
314
314
|
<div style="margin-left:106px; margin-top:4px; color:#e74c3c; font-size:0.8em;">
|
|
315
|
-
⚠ Disable in production — logs every MQTT publish
|
|
315
|
+
⚠ Disable in production — logs every MQTT publish. Auto-disables after 12hrs.
|
|
316
316
|
</div>
|
|
317
317
|
</div>
|
|
318
318
|
|
|
@@ -40,14 +40,32 @@ module.exports = function (RED) {
|
|
|
40
40
|
}, 1500);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// Track
|
|
43
|
+
// Track discovery state — prevents double-fire and allows reconnect re-discovery
|
|
44
44
|
let _discovered = false;
|
|
45
|
+
let _lastDiscoveryTime = 0;
|
|
46
|
+
const _DISCOVERY_COOLDOWN_MS = 5000; // 5 second cooldown between discoveries
|
|
47
|
+
|
|
45
48
|
function _tryDiscover() {
|
|
46
49
|
if (_discovered) return;
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) return;
|
|
47
52
|
_discovered = true;
|
|
53
|
+
_lastDiscoveryTime = now;
|
|
48
54
|
autoDiscover();
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
function _manualDiscover() {
|
|
58
|
+
// Manual trigger (canvas button or input msg) — bypass _discovered flag
|
|
59
|
+
// but still respect cooldown to prevent accidental rapid-fire
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) {
|
|
62
|
+
node.warn('Discovery cooldown active — please wait 5 seconds between manual triggers');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
_lastDiscoveryTime = now;
|
|
66
|
+
handleDeviceAdd();
|
|
67
|
+
}
|
|
68
|
+
|
|
51
69
|
// Auto-discover if broker already connected on deploy
|
|
52
70
|
if (broker.connected) {
|
|
53
71
|
_tryDiscover();
|
|
@@ -57,12 +75,30 @@ module.exports = function (RED) {
|
|
|
57
75
|
_tryDiscover();
|
|
58
76
|
});
|
|
59
77
|
broker.on('close', function () {
|
|
78
|
+
_discovered = false; // Allow re-discovery on reconnect
|
|
60
79
|
setStatus('red', 'ring', 'Broker disconnected');
|
|
61
80
|
});
|
|
62
81
|
broker.on('error', function (err) {
|
|
63
82
|
node.warn('MQTT broker error: ' + (err.message || err));
|
|
64
83
|
setStatus('red', 'dot', 'Broker error — check config');
|
|
65
84
|
});
|
|
85
|
+
// ── Debug mode safeguards ─────────────────────────────────────────
|
|
86
|
+
if (S.debugMode) {
|
|
87
|
+
// Permanent canvas warning so debug mode is obvious
|
|
88
|
+
setStatus('red', 'dot', `ha-mqtt-dmx-group "${groupId}" ⚠ DEBUG MODE ON`);
|
|
89
|
+
node.warn(`[DEBUG] ha-mqtt-dmx-group "${groupId}" — debug mode is enabled. Disable in production.`);
|
|
90
|
+
|
|
91
|
+
// Auto-disable after 12 hours — safety net for forgotten debug sessions
|
|
92
|
+
setTimeout(function () {
|
|
93
|
+
if (S.debugMode) {
|
|
94
|
+
S.debugMode = false;
|
|
95
|
+
node.warn(`[DEBUG] ha-mqtt-dmx-group "${groupId}" — debug mode auto-disabled after 12 hours`);
|
|
96
|
+
setStatus('yellow', 'ring', `${groupId} ready — awaiting HA`);
|
|
97
|
+
}
|
|
98
|
+
}, 12 * 60 * 60 * 1000);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
66
102
|
// Fallback — if connect event already fired before listener registered
|
|
67
103
|
setTimeout(function () {
|
|
68
104
|
_tryDiscover();
|
|
@@ -136,7 +172,7 @@ module.exports = function (RED) {
|
|
|
136
172
|
qos: cfg.qos,
|
|
137
173
|
retain: retain !== undefined ? retain : cfg.retain,
|
|
138
174
|
});
|
|
139
|
-
if (S.debugMode) node.
|
|
175
|
+
if (S.debugMode) node.warn(`[DEBUG] ${groupId} → ${topic} ${strPayload.substring(0, 120)}`);
|
|
140
176
|
}
|
|
141
177
|
|
|
142
178
|
function pubState(payload) {
|
|
@@ -303,7 +339,7 @@ module.exports = function (RED) {
|
|
|
303
339
|
|
|
304
340
|
if (devReq) {
|
|
305
341
|
switch (devReq) {
|
|
306
|
-
case 'add':
|
|
342
|
+
case 'add': _manualDiscover(); break;
|
|
307
343
|
case 'remove': handleDeviceRemove(null); break;
|
|
308
344
|
default: node.warn(`${groupId} — unknown device.request: "${devReq}"`);
|
|
309
345
|
}
|
package/nodes/ha-mqtt-dmx.html
CHANGED
|
@@ -548,7 +548,7 @@
|
|
|
548
548
|
Debug output to NR debug tab
|
|
549
549
|
</label>
|
|
550
550
|
<div style="margin-left:106px; margin-top:4px; color:#e74c3c; font-size:0.8em;">
|
|
551
|
-
⚠ Disable in production — logs every MQTT publish
|
|
551
|
+
⚠ Disable in production — logs every MQTT publish. Auto-disables after 12hrs.
|
|
552
552
|
</div>
|
|
553
553
|
</div>
|
|
554
554
|
|
package/nodes/ha-mqtt-dmx.js
CHANGED
|
@@ -47,14 +47,32 @@ module.exports = function (RED) {
|
|
|
47
47
|
}, 1500);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// Track
|
|
50
|
+
// Track discovery state — prevents double-fire and allows reconnect re-discovery
|
|
51
51
|
let _discovered = false;
|
|
52
|
+
let _lastDiscoveryTime = 0;
|
|
53
|
+
const _DISCOVERY_COOLDOWN_MS = 5000; // 5 second cooldown between discoveries
|
|
54
|
+
|
|
52
55
|
function _tryDiscover() {
|
|
53
56
|
if (_discovered) return;
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) return;
|
|
54
59
|
_discovered = true;
|
|
60
|
+
_lastDiscoveryTime = now;
|
|
55
61
|
autoDiscover();
|
|
56
62
|
}
|
|
57
63
|
|
|
64
|
+
function _manualDiscover() {
|
|
65
|
+
// Manual trigger (canvas button or input msg) — bypass _discovered flag
|
|
66
|
+
// but still respect cooldown to prevent accidental rapid-fire
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) {
|
|
69
|
+
node.warn('Discovery cooldown active — please wait 5 seconds between manual triggers');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
_lastDiscoveryTime = now;
|
|
73
|
+
handleDeviceAdd();
|
|
74
|
+
}
|
|
75
|
+
|
|
58
76
|
// Auto-discover if broker already connected on deploy
|
|
59
77
|
if (broker.connected) {
|
|
60
78
|
_tryDiscover();
|
|
@@ -64,12 +82,30 @@ module.exports = function (RED) {
|
|
|
64
82
|
_tryDiscover();
|
|
65
83
|
});
|
|
66
84
|
broker.on('close', function () {
|
|
85
|
+
_discovered = false; // Allow re-discovery on reconnect
|
|
67
86
|
setStatus('red', 'ring', 'Broker disconnected');
|
|
68
87
|
});
|
|
69
88
|
broker.on('error', function (err) {
|
|
70
89
|
node.warn('MQTT broker error: ' + (err.message || err));
|
|
71
90
|
setStatus('red', 'dot', 'Broker error — check config');
|
|
72
91
|
});
|
|
92
|
+
// ── Debug mode safeguards ─────────────────────────────────────────
|
|
93
|
+
if (S.debugMode) {
|
|
94
|
+
// Permanent canvas warning so debug mode is obvious
|
|
95
|
+
setStatus('red', 'dot', `ha-mqtt-dmx "${fixtureId}" ⚠ DEBUG MODE ON`);
|
|
96
|
+
node.warn(`[DEBUG] ha-mqtt-dmx "${fixtureId}" — debug mode is enabled. Disable in production.`);
|
|
97
|
+
|
|
98
|
+
// Auto-disable after 12 hours — safety net for forgotten debug sessions
|
|
99
|
+
setTimeout(function () {
|
|
100
|
+
if (S.debugMode) {
|
|
101
|
+
S.debugMode = false;
|
|
102
|
+
node.warn(`[DEBUG] ha-mqtt-dmx "${fixtureId}" — debug mode auto-disabled after 12 hours`);
|
|
103
|
+
setStatus('yellow', 'ring', `${fixtureId} ready — awaiting HA`);
|
|
104
|
+
}
|
|
105
|
+
}, 12 * 60 * 60 * 1000);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
73
109
|
// Fallback — if connect event already fired before listener registered
|
|
74
110
|
setTimeout(function () {
|
|
75
111
|
_tryDiscover();
|
|
@@ -180,12 +216,12 @@ module.exports = function (RED) {
|
|
|
180
216
|
if (payload === null) return;
|
|
181
217
|
// Skip if value unchanged since last publish
|
|
182
218
|
if (_lastSent[ch] === val) {
|
|
183
|
-
if (S.debugMode) node.
|
|
219
|
+
if (S.debugMode) node.warn(`[DEBUG] ${fixtureId} → SKIP ch${ch}=${val} (unchanged)`);
|
|
184
220
|
return;
|
|
185
221
|
}
|
|
186
222
|
_lastSent[ch] = val;
|
|
187
223
|
broker.publish({ topic: dmxTopic, payload, qos: cfg.qos, retain: false });
|
|
188
|
-
if (S.debugMode) node.
|
|
224
|
+
if (S.debugMode) node.warn(`[DEBUG] ${fixtureId} → ${dmxTopic} "${payload}"`);
|
|
189
225
|
});
|
|
190
226
|
}
|
|
191
227
|
|
|
@@ -204,7 +240,7 @@ module.exports = function (RED) {
|
|
|
204
240
|
qos: cfg.qos,
|
|
205
241
|
retain: retain !== undefined ? retain : cfg.retain,
|
|
206
242
|
});
|
|
207
|
-
if (S.debugMode) node.
|
|
243
|
+
if (S.debugMode) node.warn(`[DEBUG] ${fixtureId} → ${topic} ${strPayload.substring(0, 120)}`);
|
|
208
244
|
}
|
|
209
245
|
|
|
210
246
|
function pubState(payload) {
|
|
@@ -617,7 +653,7 @@ module.exports = function (RED) {
|
|
|
617
653
|
|
|
618
654
|
if (devReq) {
|
|
619
655
|
switch (devReq) {
|
|
620
|
-
case 'add':
|
|
656
|
+
case 'add': _manualDiscover(); break;
|
|
621
657
|
case 'remove': handleDeviceRemove(); break;
|
|
622
658
|
default: node.warn(`${fixtureId} — unknown device.request: "${devReq}"`);
|
|
623
659
|
}
|
package/nodes/ha-mqtt-pir.html
CHANGED
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
Debug output to NR debug tab
|
|
290
290
|
</label>
|
|
291
291
|
<div style="margin-left:106px; margin-top:4px; color:#e74c3c; font-size:0.8em;">
|
|
292
|
-
⚠ Disable in production — logs every MQTT publish
|
|
292
|
+
⚠ Disable in production — logs every MQTT publish. Auto-disables after 12hrs.
|
|
293
293
|
</div>
|
|
294
294
|
</div>
|
|
295
295
|
|
package/nodes/ha-mqtt-pir.js
CHANGED
|
@@ -37,14 +37,32 @@ module.exports = function (RED) {
|
|
|
37
37
|
}, 1500);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// Track
|
|
40
|
+
// Track discovery state — prevents double-fire and allows reconnect re-discovery
|
|
41
41
|
let _discovered = false;
|
|
42
|
+
let _lastDiscoveryTime = 0;
|
|
43
|
+
const _DISCOVERY_COOLDOWN_MS = 5000; // 5 second cooldown between discoveries
|
|
44
|
+
|
|
42
45
|
function _tryDiscover() {
|
|
43
46
|
if (_discovered) return;
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) return;
|
|
44
49
|
_discovered = true;
|
|
50
|
+
_lastDiscoveryTime = now;
|
|
45
51
|
autoDiscover();
|
|
46
52
|
}
|
|
47
53
|
|
|
54
|
+
function _manualDiscover() {
|
|
55
|
+
// Manual trigger (canvas button or input msg) — bypass _discovered flag
|
|
56
|
+
// but still respect cooldown to prevent accidental rapid-fire
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) {
|
|
59
|
+
node.warn('Discovery cooldown active — please wait 5 seconds between manual triggers');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
_lastDiscoveryTime = now;
|
|
63
|
+
handleDeviceAdd();
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
// Auto-discover if broker already connected on deploy
|
|
49
67
|
if (broker.connected) {
|
|
50
68
|
_tryDiscover();
|
|
@@ -54,12 +72,30 @@ module.exports = function (RED) {
|
|
|
54
72
|
_tryDiscover();
|
|
55
73
|
});
|
|
56
74
|
broker.on('close', function () {
|
|
75
|
+
_discovered = false; // Allow re-discovery on reconnect
|
|
57
76
|
setStatus('red', 'ring', 'Broker disconnected');
|
|
58
77
|
});
|
|
59
78
|
broker.on('error', function (err) {
|
|
60
79
|
node.warn('MQTT broker error: ' + (err.message || err));
|
|
61
80
|
setStatus('red', 'dot', 'Broker error — check config');
|
|
62
81
|
});
|
|
82
|
+
// ── Debug mode safeguards ─────────────────────────────────────────
|
|
83
|
+
if (S.debugMode) {
|
|
84
|
+
// Permanent canvas warning so debug mode is obvious
|
|
85
|
+
setStatus('red', 'dot', `ha-mqtt-pir "${fixtureId}" ⚠ DEBUG MODE ON`);
|
|
86
|
+
node.warn(`[DEBUG] ha-mqtt-pir "${fixtureId}" — debug mode is enabled. Disable in production.`);
|
|
87
|
+
|
|
88
|
+
// Auto-disable after 12 hours — safety net for forgotten debug sessions
|
|
89
|
+
setTimeout(function () {
|
|
90
|
+
if (S.debugMode) {
|
|
91
|
+
S.debugMode = false;
|
|
92
|
+
node.warn(`[DEBUG] ha-mqtt-pir "${fixtureId}" — debug mode auto-disabled after 12 hours`);
|
|
93
|
+
setStatus('yellow', 'ring', `${fixtureId} ready — awaiting HA`);
|
|
94
|
+
}
|
|
95
|
+
}, 12 * 60 * 60 * 1000);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
63
99
|
// Fallback — if connect event already fired before listener registered
|
|
64
100
|
setTimeout(function () {
|
|
65
101
|
_tryDiscover();
|
|
@@ -104,7 +140,7 @@ module.exports = function (RED) {
|
|
|
104
140
|
qos: cfg.qos,
|
|
105
141
|
retain: retain !== undefined ? retain : cfg.retain,
|
|
106
142
|
});
|
|
107
|
-
if (S.debugMode) node.
|
|
143
|
+
if (S.debugMode) node.warn(`[DEBUG] ${fixtureId} → ${topic} ${strPayload.substring(0, 120)}`);
|
|
108
144
|
}
|
|
109
145
|
|
|
110
146
|
function setStatus(fill, shape, text) {
|
package/nodes/ha-mqtt-relay.html
CHANGED
|
@@ -285,7 +285,7 @@
|
|
|
285
285
|
Debug output to NR debug tab
|
|
286
286
|
</label>
|
|
287
287
|
<div style="margin-left:106px; margin-top:4px; color:#e74c3c; font-size:0.8em;">
|
|
288
|
-
⚠ Disable in production — logs every MQTT publish
|
|
288
|
+
⚠ Disable in production — logs every MQTT publish. Auto-disables after 12hrs.
|
|
289
289
|
</div>
|
|
290
290
|
</div>
|
|
291
291
|
|
package/nodes/ha-mqtt-relay.js
CHANGED
|
@@ -40,14 +40,32 @@ module.exports = function (RED) {
|
|
|
40
40
|
}, 1500);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
// Track
|
|
43
|
+
// Track discovery state — prevents double-fire and allows reconnect re-discovery
|
|
44
44
|
let _discovered = false;
|
|
45
|
+
let _lastDiscoveryTime = 0;
|
|
46
|
+
const _DISCOVERY_COOLDOWN_MS = 5000; // 5 second cooldown between discoveries
|
|
47
|
+
|
|
45
48
|
function _tryDiscover() {
|
|
46
49
|
if (_discovered) return;
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) return;
|
|
47
52
|
_discovered = true;
|
|
53
|
+
_lastDiscoveryTime = now;
|
|
48
54
|
autoDiscover();
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
function _manualDiscover() {
|
|
58
|
+
// Manual trigger (canvas button or input msg) — bypass _discovered flag
|
|
59
|
+
// but still respect cooldown to prevent accidental rapid-fire
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
if (now - _lastDiscoveryTime < _DISCOVERY_COOLDOWN_MS) {
|
|
62
|
+
node.warn('Discovery cooldown active — please wait 5 seconds between manual triggers');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
_lastDiscoveryTime = now;
|
|
66
|
+
handleDeviceAdd();
|
|
67
|
+
}
|
|
68
|
+
|
|
51
69
|
// Auto-discover if broker already connected on deploy
|
|
52
70
|
if (broker.connected) {
|
|
53
71
|
_tryDiscover();
|
|
@@ -57,12 +75,30 @@ module.exports = function (RED) {
|
|
|
57
75
|
_tryDiscover();
|
|
58
76
|
});
|
|
59
77
|
broker.on('close', function () {
|
|
78
|
+
_discovered = false; // Allow re-discovery on reconnect
|
|
60
79
|
setStatus('red', 'ring', 'Broker disconnected');
|
|
61
80
|
});
|
|
62
81
|
broker.on('error', function (err) {
|
|
63
82
|
node.warn('MQTT broker error: ' + (err.message || err));
|
|
64
83
|
setStatus('red', 'dot', 'Broker error — check config');
|
|
65
84
|
});
|
|
85
|
+
// ── Debug mode safeguards ─────────────────────────────────────────
|
|
86
|
+
if (S.debugMode) {
|
|
87
|
+
// Permanent canvas warning so debug mode is obvious
|
|
88
|
+
setStatus('red', 'dot', `ha-mqtt-relay "${fixtureId}" ⚠ DEBUG MODE ON`);
|
|
89
|
+
node.warn(`[DEBUG] ha-mqtt-relay "${fixtureId}" — debug mode is enabled. Disable in production.`);
|
|
90
|
+
|
|
91
|
+
// Auto-disable after 12 hours — safety net for forgotten debug sessions
|
|
92
|
+
setTimeout(function () {
|
|
93
|
+
if (S.debugMode) {
|
|
94
|
+
S.debugMode = false;
|
|
95
|
+
node.warn(`[DEBUG] ha-mqtt-relay "${fixtureId}" — debug mode auto-disabled after 12 hours`);
|
|
96
|
+
setStatus('yellow', 'ring', `${fixtureId} ready — awaiting HA`);
|
|
97
|
+
}
|
|
98
|
+
}, 12 * 60 * 60 * 1000);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
66
102
|
// Fallback — if connect event already fired before listener registered
|
|
67
103
|
setTimeout(function () {
|
|
68
104
|
_tryDiscover();
|
|
@@ -140,7 +176,7 @@ module.exports = function (RED) {
|
|
|
140
176
|
qos: cfg.qos,
|
|
141
177
|
retain: retain !== undefined ? retain : cfg.retain,
|
|
142
178
|
});
|
|
143
|
-
if (S.debugMode) node.
|
|
179
|
+
if (S.debugMode) node.warn(`[DEBUG] ${fixtureId} → ${topic} ${strPayload.substring(0, 120)}`);
|
|
144
180
|
}
|
|
145
181
|
|
|
146
182
|
function pubRelay(value) {
|
|
@@ -325,7 +361,7 @@ module.exports = function (RED) {
|
|
|
325
361
|
|
|
326
362
|
if (devReq) {
|
|
327
363
|
switch (devReq) {
|
|
328
|
-
case 'add':
|
|
364
|
+
case 'add': _manualDiscover(); break;
|
|
329
365
|
case 'remove': handleDeviceRemove(); break;
|
|
330
366
|
default: node.warn(`${fixtureId} — unknown device.request: "${devReq}"`);
|
|
331
367
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-dmx-for-ha",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
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",
|