node-red-contrib-knx-ultimate 2.1.2 → 2.1.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/CHANGELOG.md +11 -0
- package/nodes/hue-config.js +17 -8
- package/nodes/knxUltimate-config.js +3 -2
- package/nodes/knxUltimateHueButton.js +9 -1
- package/nodes/knxUltimateHueLight.html +66 -1
- package/nodes/knxUltimateHueLight.js +34 -2
- package/nodes/knxUltimateHueLightSensor.js +9 -1
- package/nodes/knxUltimateHueMotion.js +9 -1
- package/nodes/knxUltimateHueTapDial.js +11 -3
- package/nodes/knxUltimateHueTemperatureSensor.js +9 -0
- package/nodes/utils/hueUtils.js +19 -3
- package/nodes/utils/sysLogger.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
+
<p>
|
|
10
|
+
<b>Version 2.1.4</b> - June 2023<br/>
|
|
11
|
+
- NEW: Hue light node: added random color cycle effect group address.<br/>
|
|
12
|
+
- Fixed destroying KNX nodes.<br/>
|
|
13
|
+
- Fixed destroying HUE nodes.<br/>
|
|
14
|
+
- Several HUE bugfixes.<br/>
|
|
15
|
+
</p>
|
|
16
|
+
<p>
|
|
17
|
+
<b>Version 2.1.3</b> - June 2023<br/>
|
|
18
|
+
- Bugfix.<br/>
|
|
19
|
+
</p>
|
|
9
20
|
<p>
|
|
10
21
|
<b>Version 2.1.2</b> - June 2023<br/>
|
|
11
22
|
- NEW: Hue Hue Light node, added BLINK option.<br/>
|
package/nodes/hue-config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
const dptlib = require('./../KNXEngine/dptlib')
|
|
3
3
|
const hueClass = require('./utils/hueUtils').classHUE
|
|
4
|
-
|
|
4
|
+
const loggerEngine = require('./utils/sysLogger.js')
|
|
5
5
|
// Helpers
|
|
6
6
|
const sortBy = (field) => (a, b) => {
|
|
7
7
|
if (a[field] > b[field]) { return 1 } else { return -1 }
|
|
@@ -57,7 +57,7 @@ module.exports = (RED) => {
|
|
|
57
57
|
.sort(sortBy('base'))
|
|
58
58
|
.reduce(toConcattedSubtypes, [])
|
|
59
59
|
|
|
60
|
-
res.json(dpts)
|
|
60
|
+
res.json(dpts)
|
|
61
61
|
})
|
|
62
62
|
|
|
63
63
|
function hueConfig(config) {
|
|
@@ -68,7 +68,7 @@ module.exports = (RED) => {
|
|
|
68
68
|
node.loglevel = config.loglevel !== undefined ? config.loglevel : 'error' // 18/02/2020 Loglevel default error
|
|
69
69
|
node.sysLogger = null // 20/03/2022 Default
|
|
70
70
|
try {
|
|
71
|
-
node.sysLogger =
|
|
71
|
+
node.sysLogger = loggerEngine.get({ loglevel: node.loglevel }) // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
|
|
72
72
|
} catch (error) { }
|
|
73
73
|
node.name = (config.name === undefined || config.name === '') ? node.host : config.name // 12/08/2021
|
|
74
74
|
|
|
@@ -80,7 +80,7 @@ module.exports = (RED) => {
|
|
|
80
80
|
node.nodeClients.forEach(_oClient => {
|
|
81
81
|
const oClient = RED.nodes.getNode(_oClient.id)
|
|
82
82
|
try {
|
|
83
|
-
oClient.handleSendHUE(_event)
|
|
83
|
+
if (oClient.handleSendHUE !== undefined) oClient.handleSendHUE(_event)
|
|
84
84
|
} catch (error) {
|
|
85
85
|
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error('Errore node.hueManager.on(event): ' + error.message)
|
|
86
86
|
}
|
|
@@ -112,7 +112,7 @@ module.exports = (RED) => {
|
|
|
112
112
|
// Check if node already exists
|
|
113
113
|
if (node.nodeClients.filter(x => x.id === _Node.id).length === 0) {
|
|
114
114
|
// Add _Node to the clients array
|
|
115
|
-
_Node.
|
|
115
|
+
_Node.setNodeStatusHue({ fill: 'grey', shape: 'ring', text: 'Hue initialized.' })
|
|
116
116
|
// 01/06/2023 Add node to the array
|
|
117
117
|
const jNode = {}
|
|
118
118
|
jNode.id = _Node.id
|
|
@@ -130,10 +130,19 @@ module.exports = (RED) => {
|
|
|
130
130
|
|
|
131
131
|
node.on('close', function (done) {
|
|
132
132
|
try {
|
|
133
|
-
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.destroy()
|
|
133
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger = null; loggerEngine.destroy()
|
|
134
134
|
node.nodeClients = []
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
node.hueManager.removeAllListeners();
|
|
136
|
+
(async () => {
|
|
137
|
+
await node.hueManager.close()
|
|
138
|
+
node.hueManager = null;
|
|
139
|
+
delete node.hueManager;
|
|
140
|
+
done()
|
|
141
|
+
})()
|
|
142
|
+
} catch (error) {
|
|
143
|
+
done()
|
|
144
|
+
console.log(error.message)
|
|
145
|
+
}
|
|
137
146
|
})
|
|
138
147
|
}
|
|
139
148
|
|
|
@@ -11,6 +11,7 @@ const path = require('path')
|
|
|
11
11
|
const fs = require('fs')
|
|
12
12
|
// const { Server } = require('http')
|
|
13
13
|
const payloadRounder = require('./utils/payloadManipulation')
|
|
14
|
+
const loggerEngine = require('./utils/sysLogger.js')
|
|
14
15
|
|
|
15
16
|
// Helpers
|
|
16
17
|
const sortBy = (field) => (a, b) => {
|
|
@@ -127,7 +128,7 @@ return msg;`,
|
|
|
127
128
|
node.loglevel = config.loglevel !== undefined ? config.loglevel : 'error' // 18/02/2020 Loglevel default error
|
|
128
129
|
node.sysLogger = null // 20/03/2022 Default
|
|
129
130
|
try {
|
|
130
|
-
node.sysLogger =
|
|
131
|
+
node.sysLogger = loggerEngine.get({ loglevel: node.loglevel }) // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
|
|
131
132
|
} catch (error) { }
|
|
132
133
|
// 12/11/2021 Connect at start delay
|
|
133
134
|
node.autoReconnect = true // 20/03/2022 Default
|
|
@@ -1840,7 +1841,7 @@ return msg;`,
|
|
|
1840
1841
|
node.telegramsQueue = []
|
|
1841
1842
|
node.nodeClients = [] // 05/04/2022 Nullify
|
|
1842
1843
|
try {
|
|
1843
|
-
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.destroy()
|
|
1844
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger = null; loggerEngine.destroy()
|
|
1844
1845
|
} catch (error) { }
|
|
1845
1846
|
done()
|
|
1846
1847
|
})
|
|
@@ -31,7 +31,12 @@ module.exports = function (RED) {
|
|
|
31
31
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
32
32
|
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// Used to call the status update from the HUE config node.
|
|
35
|
+
node.setNodeStatusHue = ({ fill, shape, text }) => {
|
|
36
|
+
const dDate = new Date()
|
|
37
|
+
node.status({ fill: fill, shape: shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
36
41
|
node.handleSend = msg => {
|
|
37
42
|
const state = {}
|
|
@@ -159,6 +164,9 @@ module.exports = function (RED) {
|
|
|
159
164
|
if (node.server) {
|
|
160
165
|
node.server.removeClient(node)
|
|
161
166
|
}
|
|
167
|
+
if (node.serverHue) {
|
|
168
|
+
node.serverHue.removeClient(node)
|
|
169
|
+
}
|
|
162
170
|
done()
|
|
163
171
|
})
|
|
164
172
|
}
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
GALightBlink: { value: "" },
|
|
41
41
|
dptLightBlink: { value: "" },
|
|
42
42
|
|
|
43
|
+
nameLightColorCycle: { value: "" },
|
|
44
|
+
GALightColorCycle: { value: "" },
|
|
45
|
+
dptLightColorCycle: { value: "" },
|
|
46
|
+
|
|
43
47
|
hueDevice: { value: "" }
|
|
44
48
|
},
|
|
45
49
|
inputs: 0,
|
|
@@ -447,6 +451,54 @@
|
|
|
447
451
|
|
|
448
452
|
|
|
449
453
|
|
|
454
|
+
// DPT Cycle Colors
|
|
455
|
+
// ########################
|
|
456
|
+
$.getJSON('knxUltimateDpts', (data) => {
|
|
457
|
+
data.forEach(dpt => {
|
|
458
|
+
if (dpt.value.startsWith("1.")) {
|
|
459
|
+
$("#node-input-dptLightColorCycle").append($("<option></option>")
|
|
460
|
+
.attr("value", dpt.value)
|
|
461
|
+
.text(dpt.text))
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
$("#node-input-dptLightColorCycle").val(this.dptLightColorCycle)
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
// Autocomplete suggestion with ETS csv File
|
|
468
|
+
$("#node-input-GALightColorCycle").autocomplete({
|
|
469
|
+
minLength: 1,
|
|
470
|
+
source: function (request, response) {
|
|
471
|
+
//$.getJSON("csv", request, function( data, status, xhr ) {
|
|
472
|
+
$.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => {
|
|
473
|
+
response($.map(data, function (value, key) {
|
|
474
|
+
var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt);
|
|
475
|
+
if (fullSearch(sSearch, request.term + " 1.")) {
|
|
476
|
+
return {
|
|
477
|
+
label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
|
|
478
|
+
value: value.ga // Value
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}));
|
|
484
|
+
});
|
|
485
|
+
}, select: function (event, ui) {
|
|
486
|
+
// Sets Datapoint and device name automatically
|
|
487
|
+
var sDevName = ui.item.label.split("#")[1].trim();
|
|
488
|
+
try {
|
|
489
|
+
sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim();
|
|
490
|
+
} catch (error) {
|
|
491
|
+
}
|
|
492
|
+
$('#node-input-nameLightColorCycle').val(sDevName);
|
|
493
|
+
var optVal = $("#node-input-dptLightColorCycle option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value');
|
|
494
|
+
// Select the option value
|
|
495
|
+
$("#node-input-dptLightColorCycle").val(optVal);
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
// ########################
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
450
502
|
// Autocomplete suggestion with HUE Lights
|
|
451
503
|
$("#node-input-name").autocomplete({
|
|
452
504
|
minLength: 1,
|
|
@@ -643,7 +695,19 @@
|
|
|
643
695
|
<label for="node-input-nameLightBlink" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
|
|
644
696
|
<input type="text" id="node-input-nameLightBlink" style="width:200px;margin-left: 5px; text-align: left;">
|
|
645
697
|
</div>
|
|
698
|
+
</div>
|
|
699
|
+
<div class="form-row">
|
|
700
|
+
<label for="node-input-nameLightColorCycle" style="width:100px;"><i class="fa fa-play-circle-o"></i> Color Cycle</label>
|
|
646
701
|
|
|
702
|
+
<label for="node-input-GALightColorCycle" style="width:20px;">GA</label>
|
|
703
|
+
<input type="text" id="node-input-GALightColorCycle" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
704
|
+
|
|
705
|
+
<label for="node-input-dptLightColorCycle" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
|
|
706
|
+
<select id="node-input-dptLightColorCycle" style="width:140px;"></select>
|
|
707
|
+
|
|
708
|
+
<label for="node-input-nameLightColorCycle" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
|
|
709
|
+
<input type="text" id="node-input-nameLightColorCycle" style="width:200px;margin-left: 5px; text-align: left;">
|
|
710
|
+
</div>
|
|
647
711
|
<br/>
|
|
648
712
|
<br/>
|
|
649
713
|
<br/>
|
|
@@ -676,7 +740,8 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
676
740
|
| Color Status | Link this to the light's color status group address. Accepted datapoint is RGB triplet (r,g,b)|
|
|
677
741
|
| Brightness | This command is used to change the absolute HUE light's brightness |
|
|
678
742
|
| Brightness Status| Link this to the light's brightness status group address |
|
|
679
|
-
| Blink| *true* Blink the light, *false* Stop blinking. Blinks the light on and off. Useful for signalling.
|
|
743
|
+
| Blink| *true* Blink the light, *false* Stop blinking. Blinks the light on and off. Useful for signalling. Works with all HUE lights. |
|
|
744
|
+
| Color Cycle| *true* start cycle, *false* Stop cycle. Randomly changes the HUE light's color at regular interval. Works with all HUE lights having color capabilities. |
|
|
680
745
|
|
|
681
746
|
<br/>
|
|
682
747
|
|
|
@@ -33,6 +33,11 @@ module.exports = function (RED) {
|
|
|
33
33
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
34
34
|
|
|
35
35
|
}
|
|
36
|
+
// Used to call the status update from the HUE config node.
|
|
37
|
+
node.setNodeStatusHue = ({ fill, shape, text }) => {
|
|
38
|
+
const dDate = new Date()
|
|
39
|
+
node.status({ fill: fill, shape: shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
|
|
40
|
+
}
|
|
36
41
|
|
|
37
42
|
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
38
43
|
node.handleSend = msg => {
|
|
@@ -81,13 +86,37 @@ module.exports = function (RED) {
|
|
|
81
86
|
//state = msg.payload === true ? { on: { on: true } } : { on: { on: false } }
|
|
82
87
|
state = msg.payload === true ? { on: { on: true }, dimming: { brightness: 100 } } : { on: { on: false } }
|
|
83
88
|
node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state)
|
|
84
|
-
node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state)
|
|
89
|
+
node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state) // It's ok twice, so the light turns off immeridaley
|
|
85
90
|
}, 600);
|
|
86
91
|
} else {
|
|
87
92
|
if (node.timerBlink !== undefined) clearInterval(node.timerBlink)
|
|
88
93
|
node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, { on: { on: false } })
|
|
89
94
|
}
|
|
90
95
|
break
|
|
96
|
+
case config.GALightColorCycle:
|
|
97
|
+
const gaValColorCycle = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightSwitch))
|
|
98
|
+
if (gaValColorCycle) {
|
|
99
|
+
node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, { on: { on: true } })
|
|
100
|
+
node.timerColorCycle = setInterval(() => {
|
|
101
|
+
function getRandomIntInclusive(min, max) {
|
|
102
|
+
min = Math.ceil(min);
|
|
103
|
+
max = Math.floor(max);
|
|
104
|
+
return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
|
|
105
|
+
}
|
|
106
|
+
const red = getRandomIntInclusive(0, 255)
|
|
107
|
+
const green = getRandomIntInclusive(0, 255)
|
|
108
|
+
const blue = getRandomIntInclusive(0, 255)
|
|
109
|
+
const gamut = node.currentHUEDevice.color.gamut_type || null
|
|
110
|
+
const retXY = hueColorConverter.ColorConverter.rgbToXy(red, green, blue, gamut)
|
|
111
|
+
const bright = hueColorConverter.ColorConverter.getBrightnessFromRGB(red, green, blue)
|
|
112
|
+
state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } }
|
|
113
|
+
node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state)
|
|
114
|
+
}, 10000);
|
|
115
|
+
} else {
|
|
116
|
+
if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle)
|
|
117
|
+
node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, { on: { on: false } })
|
|
118
|
+
}
|
|
119
|
+
break
|
|
91
120
|
default:
|
|
92
121
|
break
|
|
93
122
|
}
|
|
@@ -189,7 +218,7 @@ module.exports = function (RED) {
|
|
|
189
218
|
} catch (error) {
|
|
190
219
|
console.log('Error: knxUltimateHueLight: node.serverHue.hueManager.getLight: ' + error.message)
|
|
191
220
|
}
|
|
192
|
-
},
|
|
221
|
+
}, 5000);
|
|
193
222
|
|
|
194
223
|
}
|
|
195
224
|
|
|
@@ -202,6 +231,9 @@ module.exports = function (RED) {
|
|
|
202
231
|
if (node.server) {
|
|
203
232
|
node.server.removeClient(node)
|
|
204
233
|
}
|
|
234
|
+
if (node.serverHue) {
|
|
235
|
+
node.serverHue.removeClient(node)
|
|
236
|
+
}
|
|
205
237
|
done()
|
|
206
238
|
})
|
|
207
239
|
}
|
|
@@ -31,7 +31,12 @@ module.exports = function (RED) {
|
|
|
31
31
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
32
32
|
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// Used to call the status update from the HUE config node.
|
|
35
|
+
node.setNodeStatusHue = ({ fill, shape, text }) => {
|
|
36
|
+
const dDate = new Date()
|
|
37
|
+
node.status({ fill: fill, shape: shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
36
41
|
node.handleSend = msg => {
|
|
37
42
|
}
|
|
@@ -81,6 +86,9 @@ module.exports = function (RED) {
|
|
|
81
86
|
if (node.server) {
|
|
82
87
|
node.server.removeClient(node)
|
|
83
88
|
}
|
|
89
|
+
if (node.serverHue) {
|
|
90
|
+
node.serverHue.removeClient(node)
|
|
91
|
+
}
|
|
84
92
|
done()
|
|
85
93
|
})
|
|
86
94
|
}
|
|
@@ -31,7 +31,12 @@ module.exports = function (RED) {
|
|
|
31
31
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
32
32
|
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// Used to call the status update from the HUE config node.
|
|
35
|
+
node.setNodeStatusHue = ({ fill, shape, text }) => {
|
|
36
|
+
const dDate = new Date()
|
|
37
|
+
node.status({ fill: fill, shape: shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
36
41
|
node.handleSend = msg => {
|
|
37
42
|
}
|
|
@@ -81,6 +86,9 @@ module.exports = function (RED) {
|
|
|
81
86
|
if (node.server) {
|
|
82
87
|
node.server.removeClient(node)
|
|
83
88
|
}
|
|
89
|
+
if (node.serverHue) {
|
|
90
|
+
node.serverHue.removeClient(node)
|
|
91
|
+
}
|
|
84
92
|
done()
|
|
85
93
|
})
|
|
86
94
|
}
|
|
@@ -53,7 +53,12 @@ module.exports = function (RED) {
|
|
|
53
53
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
54
54
|
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
// Used to call the status update from the HUE config node.
|
|
57
|
+
node.setNodeStatusHue = ({ fill, shape, text }) => {
|
|
58
|
+
const dDate = new Date()
|
|
59
|
+
node.status({ fill: fill, shape: shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
58
63
|
node.handleSend = msg => {
|
|
59
64
|
}
|
|
@@ -88,7 +93,7 @@ module.exports = function (RED) {
|
|
|
88
93
|
}
|
|
89
94
|
// Send to KNX bus
|
|
90
95
|
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
|
|
91
|
-
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX
|
|
96
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX Change color clockwise' + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
|
|
92
97
|
}
|
|
93
98
|
} else if (_event.relative_rotary.last_event.rotation.direction === 'counter_clock_wise') {
|
|
94
99
|
if (knxMsgPayload.dpt.startsWith('3.007')) {
|
|
@@ -112,7 +117,7 @@ module.exports = function (RED) {
|
|
|
112
117
|
}
|
|
113
118
|
// Send to KNX bus
|
|
114
119
|
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
|
|
115
|
-
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX
|
|
120
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX Change color counterclockwise' + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
|
|
116
121
|
}
|
|
117
122
|
}
|
|
118
123
|
|
|
@@ -159,6 +164,9 @@ module.exports = function (RED) {
|
|
|
159
164
|
if (node.server) {
|
|
160
165
|
node.server.removeClient(node)
|
|
161
166
|
}
|
|
167
|
+
if (node.serverHue) {
|
|
168
|
+
node.serverHue.removeClient(node)
|
|
169
|
+
}
|
|
162
170
|
done()
|
|
163
171
|
})
|
|
164
172
|
}
|
|
@@ -31,6 +31,12 @@ module.exports = function (RED) {
|
|
|
31
31
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
32
32
|
|
|
33
33
|
}
|
|
34
|
+
// Used to call the status update from the HUE config node.
|
|
35
|
+
node.setNodeStatusHue = ({ fill, shape, text }) => {
|
|
36
|
+
const dDate = new Date()
|
|
37
|
+
node.status({ fill: fill, shape: shape, text: text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
|
|
35
41
|
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
36
42
|
node.handleSend = msg => {
|
|
@@ -81,6 +87,9 @@ module.exports = function (RED) {
|
|
|
81
87
|
if (node.server) {
|
|
82
88
|
node.server.removeClient(node)
|
|
83
89
|
}
|
|
90
|
+
if (node.serverHue) {
|
|
91
|
+
node.serverHue.removeClient(node)
|
|
92
|
+
}
|
|
84
93
|
done()
|
|
85
94
|
})
|
|
86
95
|
}
|
package/nodes/utils/hueUtils.js
CHANGED
|
@@ -23,6 +23,7 @@ class classHUE extends EventEmitter {
|
|
|
23
23
|
this.clientkey = _clientkey
|
|
24
24
|
this.bridgeid = _bridgeid
|
|
25
25
|
this.commandQueue = []
|
|
26
|
+
this.closePushEventStream = false
|
|
26
27
|
this.timerwriteQueueAdd = setTimeout(this.handleQueue, 3000) // First start
|
|
27
28
|
|
|
28
29
|
// start the SSE Stream Receiver
|
|
@@ -54,8 +55,8 @@ class classHUE extends EventEmitter {
|
|
|
54
55
|
for (let index = 0; index < events.length; index++) {
|
|
55
56
|
const oEvento = events[index]
|
|
56
57
|
if (oEvento.type === 'update') {
|
|
57
|
-
for (let
|
|
58
|
-
const element = oEvento.data[
|
|
58
|
+
for (let i = 0; i < oEvento.data.length; i++) {
|
|
59
|
+
const element = oEvento.data[i]
|
|
59
60
|
this.emit('event', element)
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -68,6 +69,7 @@ class classHUE extends EventEmitter {
|
|
|
68
69
|
};
|
|
69
70
|
// Funzione per richiedere gli eventi
|
|
70
71
|
const req = () => {
|
|
72
|
+
if (this.closePushEventStream) return // I'm destroying the class
|
|
71
73
|
const request = https.request(options, handleResponse);
|
|
72
74
|
request.on('error', (error) => {
|
|
73
75
|
console.log('KNXUltimateHUEConfig: classHUE: request.on(error): ' + error.message)
|
|
@@ -160,6 +162,20 @@ class classHUE extends EventEmitter {
|
|
|
160
162
|
console.log('KNXUltimateHUEConfig: classHUE: getLight: ' + error.message)
|
|
161
163
|
}
|
|
162
164
|
}
|
|
163
|
-
|
|
165
|
+
|
|
166
|
+
close = async () => {
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
try {
|
|
169
|
+
this.closePushEventStream = true
|
|
170
|
+
setTimeout(() => {
|
|
171
|
+
resolve(true)
|
|
172
|
+
}, 1000);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
reject(error)
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
}
|
|
164
180
|
}
|
|
165
181
|
module.exports.classHUE = classHUE
|
package/nodes/utils/sysLogger.js
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=14.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.1.
|
|
6
|
+
"version": "2.1.4",
|
|
7
7
|
"description": "Control your KNX intallation via Node-Red! Single Node KNX IN/OUT with optional ETS group address importer. Easy to use and highly configurable. With integrated Philips HUE devices handling.",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"mkdirp": "1.0.4",
|