node-red-contrib-knx-ultimate 2.0.20 → 2.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/.vscode/launch.json +17 -0
- package/CHANGELOG.md +10 -0
- package/nodes/hue-config.js +6 -9
- package/nodes/knxUltimate-config.js +0 -9
- package/nodes/knxUltimateHueButton.html +6 -3
- package/nodes/knxUltimateHueButton.js +1 -1
- package/nodes/knxUltimateHueLight.html +6 -2
- package/nodes/knxUltimateHueLight.js +4 -1
- package/nodes/knxUltimateHueLightSensor.html +6 -2
- package/nodes/knxUltimateHueMotion.html +6 -2
- package/nodes/knxUltimateHueTapDial.html +6 -2
- package/nodes/knxUltimateHueTemperatureSensor.html +6 -2
- package/nodes/utils/hueUtils.js +82 -66
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Usare IntelliSense per informazioni sui possibili attributi.
|
|
3
|
+
// Al passaggio del mouse vengono visualizzate le descrizioni degli attributi esistenti.
|
|
4
|
+
// Per altre informazioni, visitare: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Avvia programma",
|
|
11
|
+
"skipFiles": [
|
|
12
|
+
"<node_internals>/**"
|
|
13
|
+
],
|
|
14
|
+
"program": "${workspaceFolder}/nodes/utils/hueUtils.js"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
+
<p>
|
|
10
|
+
<b>Version 2.1.0</b> - June 2023<br/>
|
|
11
|
+
- HUE nodes exited the BETA version. You can now start using HUE nodes.<br/>
|
|
12
|
+
</p>
|
|
13
|
+
<p>
|
|
14
|
+
<b>Version 2.0.21</b> - June 2023<br/>
|
|
15
|
+
- HUE: CAUTION POSSIBLE BREAKING CHANGES TO THE HUE NODES. PLEASE BE AWARE THAT HUE NODES ARE STILL IN BETA<br/>
|
|
16
|
+
- Revamped hue clipv2 push event client.<br/>
|
|
17
|
+
- New service icons.<br/>
|
|
18
|
+
</p>
|
|
9
19
|
<p>
|
|
10
20
|
<b>Version 2.0.20</b> - June 2023<br/>
|
|
11
21
|
- HUE: CAUTION POSSIBLE BREAKING CHANGES TO THE HUE NODES. PLEASE BE AWARE THAT HUE NODES ARE STILL IN BETA<br/>
|
package/nodes/hue-config.js
CHANGED
|
@@ -57,14 +57,7 @@ module.exports = (RED) => {
|
|
|
57
57
|
.sort(sortBy('base'))
|
|
58
58
|
.reduce(toConcattedSubtypes, [])
|
|
59
59
|
|
|
60
|
-
res.json(dpts)
|
|
61
|
-
// Utilità per visualizzare i datapoints, da copiare in README
|
|
62
|
-
// var stringa = "";
|
|
63
|
-
// for (let index = 0; index < dpts.length; index++) {
|
|
64
|
-
// const element = dpts[index];
|
|
65
|
-
// stringa += element.text + "<br/>\n";
|
|
66
|
-
// }
|
|
67
|
-
// if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.warn(stringa)
|
|
60
|
+
res.json(dpts)
|
|
68
61
|
})
|
|
69
62
|
|
|
70
63
|
function hueConfig(config) {
|
|
@@ -86,7 +79,11 @@ module.exports = (RED) => {
|
|
|
86
79
|
node.hueManager.on('event', _event => {
|
|
87
80
|
node.nodeClients.forEach(_oClient => {
|
|
88
81
|
const oClient = RED.nodes.getNode(_oClient.id)
|
|
89
|
-
|
|
82
|
+
try {
|
|
83
|
+
oClient.handleSendHUE(_event)
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error('Errore node.hueManager.on(event): ' + error.message)
|
|
86
|
+
}
|
|
90
87
|
})
|
|
91
88
|
})
|
|
92
89
|
|
|
@@ -38,15 +38,6 @@ const convertSubtype = (baseType) => (kv) => {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
// 06/02/2020 To be tested
|
|
42
|
-
// convertSubtype = (baseType) => (kv) => {
|
|
43
|
-
// let value = `${baseType.base}.${kv[0]}`
|
|
44
|
-
// return {
|
|
45
|
-
// value: value
|
|
46
|
-
// , text: value + ` (${kv[1].name}${kv[1].unit !== undefined?" - " + kv[1].unit:""})`
|
|
47
|
-
// }
|
|
48
|
-
// }
|
|
49
|
-
|
|
50
41
|
const toConcattedSubtypes = (acc, baseType) => {
|
|
51
42
|
const subtypes =
|
|
52
43
|
Object.entries(baseType.subtypes)
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
label: function () {
|
|
30
30
|
return (this.name);
|
|
31
31
|
},
|
|
32
|
-
paletteLabel: "Hue Button
|
|
32
|
+
paletteLabel: "Hue Button",
|
|
33
33
|
// button: {
|
|
34
34
|
// enabled: function() {
|
|
35
35
|
// // return whether or not the button is enabled, based on the current
|
|
@@ -309,7 +309,10 @@
|
|
|
309
309
|
 <i class="fa fa-question-circle"></i></span>
|
|
310
310
|
 <a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration"><u>Configuration</u></a>
|
|
311
311
|
<br />
|
|
312
|
-
<
|
|
312
|
+
<br />
|
|
313
|
+
<p align="center">
|
|
314
|
+
<i class="fa-regular fa-circle-dot fa-beat-fade fa-8x"></i>
|
|
315
|
+
</p>
|
|
313
316
|
<br />
|
|
314
317
|
<label for="node-input-server" >
|
|
315
318
|
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
|
|
@@ -340,7 +343,6 @@
|
|
|
340
343
|
|
|
341
344
|
<br/>
|
|
342
345
|
|
|
343
|
-
<!-- <p> <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/knx.png' width='32px'> -> <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/hue.png' width='32px'></p> -->
|
|
344
346
|
|
|
345
347
|
<p>
|
|
346
348
|
<b>KNX DATAPOINTS</b>
|
|
@@ -406,6 +408,7 @@
|
|
|
406
408
|
|
|
407
409
|
|
|
408
410
|
</script>
|
|
411
|
+
<script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
|
|
409
412
|
|
|
410
413
|
<script type="text/markdown" data-help-name="knxUltimateHueButton">
|
|
411
414
|
<p> This node lets you get the events from your HUE button.<br/>
|
|
@@ -103,7 +103,7 @@ module.exports = function (RED) {
|
|
|
103
103
|
// Set KNX Dim up/down start
|
|
104
104
|
knxMsgPayload.topic = config.GArepeat
|
|
105
105
|
knxMsgPayload.dpt = config.dptrepeat
|
|
106
|
-
knxMsgPayload.payload = node.long_pressValue ? { decr_incr:
|
|
106
|
+
knxMsgPayload.payload = node.long_pressValue ? { decr_incr: 0, data: 3 } : { decr_incr: 1, data: 3 } // If the light is turned on, the initial DIM direction must be down, otherwise, up
|
|
107
107
|
// Send to KNX bus
|
|
108
108
|
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
|
|
109
109
|
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX start Dim' + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
label: function () {
|
|
45
45
|
return (this.name);
|
|
46
46
|
},
|
|
47
|
-
paletteLabel: "Hue Light
|
|
47
|
+
paletteLabel: "Hue Light",
|
|
48
48
|
// button: {
|
|
49
49
|
// enabled: function() {
|
|
50
50
|
// // return whether or not the button is enabled, based on the current
|
|
@@ -436,6 +436,7 @@
|
|
|
436
436
|
})
|
|
437
437
|
|
|
438
438
|
</script>
|
|
439
|
+
<script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
|
|
439
440
|
|
|
440
441
|
<script type="text/x-red" data-template-name="knxUltimateHueLight">
|
|
441
442
|
|
|
@@ -445,7 +446,10 @@
|
|
|
445
446
|
 
|
|
446
447
|
 <i class="fa fa-youtube"></i></span> <a target="_blank" href="https://youtu.be/3M02Du2gero"><u>Youtube sample</u></a>
|
|
447
448
|
<br />
|
|
448
|
-
<
|
|
449
|
+
<br />
|
|
450
|
+
<p align="center">
|
|
451
|
+
<i class="fa-regular fa-lightbulb fa-bounce fa-8x"></i>
|
|
452
|
+
</p>
|
|
449
453
|
<br />
|
|
450
454
|
<label for="node-input-server" >
|
|
451
455
|
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
|
|
@@ -162,7 +162,10 @@ module.exports = function (RED) {
|
|
|
162
162
|
try {
|
|
163
163
|
if (node !== null && node.serverHue !== null && node.serverHue.hueManager !== null) {
|
|
164
164
|
node.serverHue.hueManager.getLight(config.hueDevice).then(ret => {
|
|
165
|
-
|
|
165
|
+
try {
|
|
166
|
+
if (ret !== undefined && ret.length > 0) node.currentHUEDevice = ret[0]
|
|
167
|
+
} catch (error) {
|
|
168
|
+
}
|
|
166
169
|
//console.log("retrieving node.currentHUEDevice" + node.currentHUEDevice.metadata.name)
|
|
167
170
|
})
|
|
168
171
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
label: function () {
|
|
21
21
|
return (this.name);
|
|
22
22
|
},
|
|
23
|
-
paletteLabel: "Hue Light Sensor
|
|
23
|
+
paletteLabel: "Hue Light Sensor",
|
|
24
24
|
// button: {
|
|
25
25
|
// enabled: function() {
|
|
26
26
|
// // return whether or not the button is enabled, based on the current
|
|
@@ -161,7 +161,10 @@
|
|
|
161
161
|
 <i class="fa fa-question-circle"></i></span>
|
|
162
162
|
 <a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration"><u>Configuration</u></a>
|
|
163
163
|
<br />
|
|
164
|
-
<
|
|
164
|
+
<br />
|
|
165
|
+
<p align="center">
|
|
166
|
+
<i class="fa-solid fa-circle-half-stroke fa-8x"></i>
|
|
167
|
+
</p>
|
|
165
168
|
<br />
|
|
166
169
|
<label for="node-input-server" >
|
|
167
170
|
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
|
|
@@ -218,6 +221,7 @@
|
|
|
218
221
|
|
|
219
222
|
|
|
220
223
|
</script>
|
|
224
|
+
<script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
|
|
221
225
|
|
|
222
226
|
<script type="text/markdown" data-help-name="knxUltimateHueLightSensor">
|
|
223
227
|
<p> This node lets you get the events from your HUE motion device.<br/>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
label: function () {
|
|
21
21
|
return (this.name);
|
|
22
22
|
},
|
|
23
|
-
paletteLabel: "Hue Motion
|
|
23
|
+
paletteLabel: "Hue Motion",
|
|
24
24
|
// button: {
|
|
25
25
|
// enabled: function() {
|
|
26
26
|
// // return whether or not the button is enabled, based on the current
|
|
@@ -161,7 +161,10 @@
|
|
|
161
161
|
 <i class="fa fa-question-circle"></i></span>
|
|
162
162
|
 <a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration"><u>Configuration</u></a>
|
|
163
163
|
<br />
|
|
164
|
-
<
|
|
164
|
+
<br />
|
|
165
|
+
<p align="center">
|
|
166
|
+
<i class="fa-solid fa-person-walking fa-shake fa-8x"></i>
|
|
167
|
+
</p>
|
|
165
168
|
<br />
|
|
166
169
|
<label for="node-input-server" >
|
|
167
170
|
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
|
|
@@ -218,6 +221,7 @@
|
|
|
218
221
|
|
|
219
222
|
|
|
220
223
|
</script>
|
|
224
|
+
<script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
|
|
221
225
|
|
|
222
226
|
<script type="text/markdown" data-help-name="knxUltimateHueMotion">
|
|
223
227
|
<p> This node lets you get the events from your HUE motion device.<br/>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
label: function () {
|
|
21
21
|
return (this.name);
|
|
22
22
|
},
|
|
23
|
-
paletteLabel: "Hue Tap Dial
|
|
23
|
+
paletteLabel: "Hue Tap Dial",
|
|
24
24
|
// button: {
|
|
25
25
|
// enabled: function() {
|
|
26
26
|
// // return whether or not the button is enabled, based on the current
|
|
@@ -163,7 +163,10 @@
|
|
|
163
163
|
 <i class="fa fa-question-circle"></i></span>
|
|
164
164
|
 <a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration"><u>Configuration</u></a>
|
|
165
165
|
<br />
|
|
166
|
-
<
|
|
166
|
+
<br />
|
|
167
|
+
<p align="center">
|
|
168
|
+
<i class="fa-solid fa-circle-notch fa-spin fa-8x"></i>
|
|
169
|
+
</p>
|
|
167
170
|
<br />
|
|
168
171
|
<label for="node-input-server" >
|
|
169
172
|
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
|
|
@@ -221,6 +224,7 @@
|
|
|
221
224
|
|
|
222
225
|
|
|
223
226
|
</script>
|
|
227
|
+
<script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
|
|
224
228
|
|
|
225
229
|
<script type="text/markdown" data-help-name="knxUltimateHueTapDial">
|
|
226
230
|
<p> This node lets you get the events from your HUE rotary device, for example the Tap Dial.<br/>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
label: function () {
|
|
21
21
|
return (this.name);
|
|
22
22
|
},
|
|
23
|
-
paletteLabel: "Hue Temperature Sensor
|
|
23
|
+
paletteLabel: "Hue Temperature Sensor",
|
|
24
24
|
// button: {
|
|
25
25
|
// enabled: function() {
|
|
26
26
|
// // return whether or not the button is enabled, based on the current
|
|
@@ -161,7 +161,10 @@
|
|
|
161
161
|
 <i class="fa fa-question-circle"></i></span>
|
|
162
162
|
 <a target="_blank" href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration"><u>Configuration</u></a>
|
|
163
163
|
<br />
|
|
164
|
-
<
|
|
164
|
+
<br />
|
|
165
|
+
<p align="center">
|
|
166
|
+
<i class="fa-solid fa-temperature-full fa-beat fa-8x"></i>
|
|
167
|
+
</p>
|
|
165
168
|
<br />
|
|
166
169
|
<label for="node-input-server" >
|
|
167
170
|
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img>
|
|
@@ -218,6 +221,7 @@
|
|
|
218
221
|
|
|
219
222
|
|
|
220
223
|
</script>
|
|
224
|
+
<script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
|
|
221
225
|
|
|
222
226
|
<script type="text/markdown" data-help-name="knxUltimateHueTemperatureSensor">
|
|
223
227
|
<p> This node lets you get the events from your HUE temperature device.<br/>
|
package/nodes/utils/hueUtils.js
CHANGED
|
@@ -4,35 +4,98 @@
|
|
|
4
4
|
const hueApiV2 = require('node-hue')
|
|
5
5
|
const { EventEmitter } = require('events')
|
|
6
6
|
|
|
7
|
+
|
|
8
|
+
const https = require('https');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
7
14
|
class classHUE extends EventEmitter {
|
|
8
|
-
constructor(
|
|
15
|
+
constructor(_hueBridgeIP, _username, _clientkey, _bridgeid) {
|
|
9
16
|
super()
|
|
10
|
-
this.setup(
|
|
17
|
+
this.setup(_hueBridgeIP, _username, _clientkey, _bridgeid)
|
|
11
18
|
}
|
|
12
19
|
|
|
13
|
-
setup = async (
|
|
14
|
-
this.
|
|
20
|
+
setup = async (_hueBridgeIP, _username, _clientkey, _bridgeid) => {
|
|
21
|
+
this.hueBridgeIP = _hueBridgeIP
|
|
15
22
|
this.username = _username
|
|
16
23
|
this.clientkey = _clientkey
|
|
17
24
|
this.bridgeid = _bridgeid
|
|
18
|
-
this.timerWatchDog = undefined
|
|
19
25
|
this.commandQueue = []
|
|
20
|
-
this.
|
|
21
|
-
// The Hue bridge allows about 10 telegram per second, so i need to make a queue manager
|
|
22
|
-
this.timerwriteQueueAdd = setTimeout(this.handleQueue, 2000)
|
|
23
|
-
}
|
|
26
|
+
this.timerwriteQueueAdd = setTimeout(this.handleQueue, 3000) // First start
|
|
24
27
|
|
|
28
|
+
// start the SSE Stream Receiver
|
|
29
|
+
const options = {
|
|
30
|
+
host: _hueBridgeIP, // Indirizzo IP del tuo bridge Philips Hue
|
|
31
|
+
path: '/eventstream/clip/v2', // Il percorso dell'API per gli eventi
|
|
32
|
+
method: 'GET',
|
|
33
|
+
headers: {
|
|
34
|
+
'Connection': 'keep-alive',
|
|
35
|
+
'hue-application-key': _username
|
|
36
|
+
//'Accept': 'text/event-stream'
|
|
37
|
+
},
|
|
38
|
+
rejectUnauthorized: false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Funzione per la gestione della risposta
|
|
42
|
+
const handleResponse = (response) => {
|
|
43
|
+
let data = '';
|
|
44
|
+
|
|
45
|
+
response.on('data', (chunk) => {
|
|
46
|
+
data += chunk;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
response.on('end', () => {
|
|
50
|
+
try {
|
|
51
|
+
const events = JSON.parse(data)
|
|
52
|
+
// An array event "Container", can have multiple events.
|
|
53
|
+
// for..loop is more efficent. We need speed.
|
|
54
|
+
for (let index = 0; index < events.length; index++) {
|
|
55
|
+
const oEvento = events[index]
|
|
56
|
+
if (oEvento.type === 'update') {
|
|
57
|
+
for (let index = 0; index < oEvento.data.length; index++) {
|
|
58
|
+
const element = oEvento.data[index]
|
|
59
|
+
this.emit('event', element)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.log('KNXUltimateHUEConfig: classHUE: response.on(end): ' + error.message)
|
|
65
|
+
}
|
|
66
|
+
req();
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
// Funzione per richiedere gli eventi
|
|
70
|
+
const req = () => {
|
|
71
|
+
const request = https.request(options, handleResponse);
|
|
72
|
+
request.on('error', (error) => {
|
|
73
|
+
console.log('KNXUltimateHUEConfig: classHUE: request.on(error): ' + error.message)
|
|
74
|
+
// Restart the connection
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
req();
|
|
77
|
+
}, 2000);
|
|
78
|
+
});
|
|
79
|
+
request.end();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Starts the connection for the first time
|
|
83
|
+
req();
|
|
84
|
+
}
|
|
25
85
|
|
|
86
|
+
// Handle the sed queue
|
|
26
87
|
handleQueue = async () => {
|
|
27
88
|
if (this.commandQueue.length > 0) {
|
|
28
89
|
const jRet = this.commandQueue.shift()
|
|
29
90
|
try {
|
|
30
|
-
|
|
31
|
-
const ok = await
|
|
91
|
+
const hue = hueApiV2.connect({ host: this.hueBridgeIP, key: this.username })
|
|
92
|
+
const ok = await hue.setLight(jRet._lightID, jRet._state)
|
|
32
93
|
} catch (error) {
|
|
94
|
+
console.log('KNXUltimateHUEConfig: classHUE: handleQueue: ' + error.message)
|
|
33
95
|
return ({ error: error.message })
|
|
34
96
|
}
|
|
35
97
|
}
|
|
98
|
+
// The Hue bridge allows about 10 telegram per second, so i need to make a queue manager
|
|
36
99
|
setTimeout(this.handleQueue, 100)
|
|
37
100
|
}
|
|
38
101
|
writeHueQueueAdd = async (_lightID, _state) => {
|
|
@@ -44,10 +107,10 @@ class classHUE extends EventEmitter {
|
|
|
44
107
|
getResources = async (_rtype, _host, _username) => {
|
|
45
108
|
try {
|
|
46
109
|
// V2
|
|
47
|
-
|
|
110
|
+
const hue = hueApiV2.connect({ host: _host, key: _username })
|
|
48
111
|
const retArray = []
|
|
49
|
-
const allResources = await
|
|
50
|
-
const allRooms = await
|
|
112
|
+
const allResources = await hue.getResources()
|
|
113
|
+
const allRooms = await hue.getRooms()
|
|
51
114
|
const newArray = allResources.filter(x => x.type === _rtype)
|
|
52
115
|
// Add room name to the device name
|
|
53
116
|
newArray.forEach(device => {
|
|
@@ -73,10 +136,10 @@ class classHUE extends EventEmitter {
|
|
|
73
136
|
retArray.push({ name: 'Light Level: ' + linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
|
|
74
137
|
}
|
|
75
138
|
if (_rtype === 'temperature') {
|
|
76
|
-
retArray.push({ name: '
|
|
139
|
+
retArray.push({ name: 'Temperature: ' + linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
|
|
77
140
|
}
|
|
78
141
|
if (_rtype === 'scene') {
|
|
79
|
-
retArray.push({ name: '
|
|
142
|
+
retArray.push({ name: 'Scene: ' + linkedDevName + (Room !== undefined ? ', room ' + Room.metadata.name : ''), id: device.id })
|
|
80
143
|
}
|
|
81
144
|
|
|
82
145
|
})
|
|
@@ -91,59 +154,12 @@ class classHUE extends EventEmitter {
|
|
|
91
154
|
// Get light state
|
|
92
155
|
getLight = async (_LightID) => {
|
|
93
156
|
try {
|
|
94
|
-
|
|
95
|
-
return await
|
|
157
|
+
const hue = hueApiV2.connect({ host: this.hueBridgeIP, key: this.username })
|
|
158
|
+
return await hue.getLight(_LightID)
|
|
96
159
|
} catch (error) {
|
|
97
160
|
console.log('KNXUltimateHUEConfig: classHUE: getLight: ' + error.message)
|
|
98
161
|
}
|
|
99
162
|
}
|
|
100
|
-
|
|
101
|
-
// Check the bridge for disconnections
|
|
102
|
-
handleTheDog = async () => {
|
|
103
|
-
this.timerWatchDog = setInterval(async () => {
|
|
104
|
-
try {
|
|
105
|
-
// const hue = hueApiV2.connect({ host: this.HUEBridgeIP, key: this.username })
|
|
106
|
-
if (this.hue !== undefined) {
|
|
107
|
-
const sRet = await this.hue.getBridges()
|
|
108
|
-
if (sRet.filter(e => e.bridge_id.toString().toLowerCase() === this.bridgeid.toString().toLowerCase()).length === 0) {
|
|
109
|
-
/* oBridge doesn't contains the element we're looking for */
|
|
110
|
-
return (new Error('This machine is online, but this bridgeid is not found: ' + this.bridgeid))
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
} catch (error) {
|
|
114
|
-
if (this.timerWatchDog !== undefined) clearInterval(this.timerWatchDog)
|
|
115
|
-
if (this.hue !== undefined) this.hue.close()
|
|
116
|
-
console.log('KNXUltimateHUEConfig: classHUE: timerWatchDog: ' + error.message)
|
|
117
|
-
this.startPushEvents()
|
|
118
|
-
}
|
|
119
|
-
}, 5000)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
listener = (event) => {
|
|
123
|
-
event.data.forEach(oEvento => {
|
|
124
|
-
this.emit('event', oEvento)
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
startPushEvents = async () => {
|
|
129
|
-
try {
|
|
130
|
-
this.hue = await hueApiV2.connect({
|
|
131
|
-
log: {
|
|
132
|
-
trace: (msg) => { },
|
|
133
|
-
debug: (msg) => { },
|
|
134
|
-
info: (msg) => { },
|
|
135
|
-
warn: (msg) => { },
|
|
136
|
-
error: (msg) => { }
|
|
137
|
-
},
|
|
138
|
-
host: this.HUEBridgeIP,
|
|
139
|
-
key: this.username,
|
|
140
|
-
eventListener: this.listener // The eventlistener is given as option
|
|
141
|
-
})
|
|
142
|
-
} catch (error) {
|
|
143
|
-
if (this.hue !== undefined) this.hue.close()
|
|
144
|
-
console.log('KNXUltimateHUEConfig: classHUE: ' + error.message)
|
|
145
|
-
}
|
|
146
|
-
this.handleTheDog() // Start watchdog timer
|
|
147
|
-
}
|
|
163
|
+
|
|
148
164
|
}
|
|
149
165
|
module.exports.classHUE = classHUE
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=14.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.0
|
|
6
|
+
"version": "2.1.0",
|
|
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",
|