node-red-contrib-knx-ultimate 2.2.6 → 2.2.9
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 +8 -0
- package/nodes/hue-config.js +11 -10
- package/nodes/knxUltimate-config.js +1 -1
- package/nodes/knxUltimateHueButton.html +0 -9
- package/nodes/knxUltimateHueButton.js +1 -1
- package/nodes/knxUltimateHueLight.html +102 -41
- package/nodes/knxUltimateHueLight.js +47 -34
- package/nodes/knxUltimateHueMotion.html +0 -10
- package/nodes/knxUltimateHueMotion.js +1 -1
- package/nodes/knxUltimateHueScene.html +0 -9
- package/nodes/knxUltimateHueScene.js +1 -1
- package/nodes/knxUltimateHueTapDial.html +0 -12
- package/nodes/knxUltimateHueTapDial.js +1 -1
- package/nodes/utils/hueColorConverter.js +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
+
<b>Version 2.2.9</b> - November 2023<br/>
|
|
10
|
+
- Fixed errors in Iobroker.<br/>
|
|
11
|
+
</p>
|
|
12
|
+
<b>Version 2.2.8</b> - November 2023<br/>
|
|
13
|
+
- HUE Light: NEW: color selection show now the temperature in kelvin.<br/>
|
|
14
|
+
- HUE Light: NEW: Tunable White: added control and status in kelvin (DPT 7.600). This is in BETA testing.<br/>
|
|
15
|
+
- Removed some options in button and scene nodes, because they are unnecessary.<br/>
|
|
16
|
+
</p>
|
|
9
17
|
<b>Version 2.2.6</b> - October 2023<br/>
|
|
10
18
|
- Fix: fixed HUE button sending a KNX telegram at startup. Fixed also other nodes.<br/>
|
|
11
19
|
- HUE Nodes: added the option to inizialize at startup or not.<br/>
|
package/nodes/hue-config.js
CHANGED
|
@@ -91,14 +91,15 @@ module.exports = (RED) => {
|
|
|
91
91
|
});
|
|
92
92
|
// Connected
|
|
93
93
|
node.hueManager.on("connected", () => {
|
|
94
|
-
(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
(async () => {
|
|
96
|
+
try {
|
|
97
|
+
await node.loadResourcesFromHUEBridge(); // Then, you can use node.getResources, that works locally and doesn't query the HUE Bridge.
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error("hue-Config node.hueManager.on('connected' " + error.message);
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
}, 5000);
|
|
102
103
|
});
|
|
103
104
|
};
|
|
104
105
|
|
|
@@ -119,7 +120,7 @@ module.exports = (RED) => {
|
|
|
119
120
|
node.nodeClientsAwaitingInit = [];
|
|
120
121
|
}
|
|
121
122
|
node.nodeClients.forEach((nodeClient) => {
|
|
122
|
-
if (nodeClient.hueDevice !== undefined) {
|
|
123
|
+
if (nodeClient.hueDevice !== undefined && node.hueAllResources !== undefined) {
|
|
123
124
|
const oHUEDevice = node.hueAllResources.filter((a) => a.id === nodeClient.hueDevice)[0];
|
|
124
125
|
if (oHUEDevice !== undefined) {
|
|
125
126
|
// Add _Node to the clients array
|
|
@@ -274,7 +275,7 @@ module.exports = (RED) => {
|
|
|
274
275
|
|
|
275
276
|
node.addClient = (_Node) => {
|
|
276
277
|
// Update the node hue device, as soon as a node register itself to hue-config nodeClients
|
|
277
|
-
if (node.hueAllResources !== null) {
|
|
278
|
+
if (node.hueAllResources !== undefined && node.hueAllResources !== null) {
|
|
278
279
|
if (node.nodeClients.filter((x) => x.id === _Node.id).length === 0) { // At first start, due to the async method for retrieving hueAllResources, hueAllResources is still null. The first start is handled in node.hueManager.on("connected")
|
|
279
280
|
const oHUEDevice = node.hueAllResources.filter((a) => a.id === _Node.hueDevice)[0];
|
|
280
281
|
_Node.currentHUEDevice = oHUEDevice;
|
|
@@ -2110,7 +2110,7 @@ return msg;`,
|
|
|
2110
2110
|
node.allowLauch_initKNXConnection = true; // Next cycle, launch initKNXConnection, so it pauses more and leave more time
|
|
2111
2111
|
const t = setTimeout(() => {
|
|
2112
2112
|
// 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
|
|
2113
|
-
node.setAllClientsStatus("
|
|
2113
|
+
node.setAllClientsStatus("Retry connection", "grey", "");
|
|
2114
2114
|
}, 1000);
|
|
2115
2115
|
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug(
|
|
2116
2116
|
"knxUltimate-config: Waiting next cycle to reconect. node.LinkStatus: " + node.linkStatus + ", node.autoReconnect:" + node.autoReconnect,
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
nameshort_releaseStatus: { value: "" },
|
|
20
20
|
GAshort_releaseStatus: { value: "" },
|
|
21
21
|
dptshort_releaseStatus: { value: "1.001" },
|
|
22
|
-
readStatusAtStartup: { value: "no" },
|
|
23
22
|
|
|
24
23
|
toggleValues: { value: true },
|
|
25
24
|
hueDevice: { value: "" }
|
|
@@ -397,13 +396,6 @@
|
|
|
397
396
|
Toggle values
|
|
398
397
|
</label>
|
|
399
398
|
</div>
|
|
400
|
-
<div class="form-row">
|
|
401
|
-
<label style="width:180px" for="node-input-readStatusAtStartup"><i class="fa fa-play-circle"></i> Read status at startup</label>
|
|
402
|
-
<select id="node-input-readStatusAtStartup">
|
|
403
|
-
<option value="no">No</option>
|
|
404
|
-
<option value="yes">Yes, and emit KNX telegrams.</option>
|
|
405
|
-
</select>
|
|
406
|
-
</div>
|
|
407
399
|
|
|
408
400
|
|
|
409
401
|
<br/>
|
|
@@ -439,7 +431,6 @@ This allows the internal logic to be aware of external devices, like wall switch
|
|
|
439
431
|
| Switch Status | To allow internal logic to take care of the external KNX devices, for example an external wall switch, you should set this group address |
|
|
440
432
|
| Dim | This event is used either to send DIM (increase/decrease) or true/false commands to the KNX group address |
|
|
441
433
|
| Toggle values | Enable or disable toggling values. If enabled, all values toggles, otherwise, all values are sent as *true* or *increase dim*, to the selected KNX group address |
|
|
442
|
-
| Read status at startup | Read the status at startup and emit the event to the KNX bus at startup/reconnection. (Default "no") |
|
|
443
434
|
|
|
444
435
|
### Outputs
|
|
445
436
|
|
|
@@ -78,7 +78,7 @@ module.exports = function (RED) {
|
|
|
78
78
|
if (_event.id === config.hueDevice) {
|
|
79
79
|
|
|
80
80
|
// IMPORTANT: exit if no button last_event present.
|
|
81
|
-
if (_event.initializingAtStart === true
|
|
81
|
+
if (_event.initializingAtStart === true) return;
|
|
82
82
|
if (!_event.hasOwnProperty("button") || _event.button.last_event === undefined) return;
|
|
83
83
|
|
|
84
84
|
const knxMsgPayload = {};
|
|
@@ -85,6 +85,14 @@
|
|
|
85
85
|
GADaylightSensor: { value: "" },
|
|
86
86
|
dptDaylightSensor: { value: "" },
|
|
87
87
|
|
|
88
|
+
nameLightKelvin: { value: "" },
|
|
89
|
+
GALightKelvin: { value: "" },
|
|
90
|
+
dptLightKelvin: { value: "" },
|
|
91
|
+
|
|
92
|
+
nameLightKelvinState: { value: "" },
|
|
93
|
+
GALightKelvinState: { value: "" },
|
|
94
|
+
dptLightKelvinState: { value: "" },
|
|
95
|
+
|
|
88
96
|
specifySwitchOnBrightness: { value: "yes" },
|
|
89
97
|
updateKNXBrightnessStatusOnHUEOnOff: { value: "no" },
|
|
90
98
|
dimSpeed: { value: 5000, required: false },
|
|
@@ -128,23 +136,25 @@
|
|
|
128
136
|
<div class="red-ui-sidebar-header">Color Selector</div>
|
|
129
137
|
</head>
|
|
130
138
|
<div style='position:relative;height:100%;margin:10px'>
|
|
131
|
-
<p>Choose the desired color/temperature,
|
|
139
|
+
<p>Choose the desired color/temperature, then click <b>Apply</b></p>
|
|
132
140
|
<div>
|
|
133
|
-
<h3>Color</h3>
|
|
141
|
+
<h3>Color RGB</h3>
|
|
134
142
|
<div id="colorPicker"></div>
|
|
135
143
|
</div>
|
|
136
|
-
</br>
|
|
144
|
+
</br>
|
|
145
|
+
<div>
|
|
146
|
+
<input style="width:100%" type="text" id="resultRGB">
|
|
147
|
+
<input type="hidden" id="tabNRColor_destinationTextbox">
|
|
148
|
+
</div>
|
|
149
|
+
</br>
|
|
137
150
|
<div>
|
|
138
|
-
<h3>Temperature</h3>
|
|
151
|
+
<h3>Temperature Kelvin</h3>
|
|
139
152
|
<div id="kelvinPicker"></div>
|
|
140
153
|
</div>
|
|
141
|
-
</br>
|
|
154
|
+
</br>
|
|
142
155
|
<div>
|
|
143
|
-
<
|
|
144
|
-
<
|
|
145
|
-
<input style="width:100%" type="text" id="resultRGB">
|
|
146
|
-
<input type="hidden" id="tabNRColor_destinationTextbox">
|
|
147
|
-
</div>
|
|
156
|
+
<input style="width:100%" type="text" id="resultKelvin">
|
|
157
|
+
<input type="hidden" id="tabNRColor_destinationTextbox">
|
|
148
158
|
</div>
|
|
149
159
|
<div id="tabNRColor_divApplyCancel" hidden>
|
|
150
160
|
<button id="tabNRColor_colorSelectorTABApplyTextButton" type="button" class="red-ui-button">Apply</button>
|
|
@@ -186,8 +196,19 @@
|
|
|
186
196
|
node.kelvinPicker.on("color:change", function (color) {
|
|
187
197
|
const resultRGBForNode = '{"red": ' + color.rgb.r + ', "green": ' + color.rgb.g + ', "blue": ' + color.rgb.b + "}";
|
|
188
198
|
$("#resultRGB").val(resultRGBForNode);
|
|
199
|
+
$("#resultKelvin").val(Math.round(color.kelvin, 0));
|
|
189
200
|
});
|
|
190
201
|
|
|
202
|
+
$("#resultKelvin").on("keyup", function () {
|
|
203
|
+
setIroColorKelvin();
|
|
204
|
+
});
|
|
205
|
+
function setIroColorKelvin() {
|
|
206
|
+
try {
|
|
207
|
+
const color = JSON.parse($("#resultKelvin").val());
|
|
208
|
+
node.kelvinPicker.color.setChannel("kelvin", color);
|
|
209
|
+
} catch (error) { }
|
|
210
|
+
}
|
|
211
|
+
|
|
191
212
|
// Color
|
|
192
213
|
node.colorPicker = new iro.ColorPicker("#colorPicker", {
|
|
193
214
|
width: 250,
|
|
@@ -213,6 +234,7 @@
|
|
|
213
234
|
const resultRGBForNode = '{"red": ' + color.rgb.r + ', "green": ' + color.rgb.g + ', "blue": ' + color.rgb.b + "}";
|
|
214
235
|
$("#resultRGB").val(resultRGBForNode);
|
|
215
236
|
});
|
|
237
|
+
|
|
216
238
|
$("#resultRGB").on("keyup", function () {
|
|
217
239
|
setIroColor();
|
|
218
240
|
});
|
|
@@ -230,7 +252,12 @@
|
|
|
230
252
|
// navigator.clipboard.writeText(aa)
|
|
231
253
|
const destTextBox = "#" + $("#tabNRColor_destinationTextbox").val();
|
|
232
254
|
const resultRGB = $("#resultRGB").val();
|
|
233
|
-
|
|
255
|
+
const resultKelvin = node.kelvinPicker.colors[0].kelvin;
|
|
256
|
+
if (destTextBox === "#node-input-colorAtSwitchOnNightTime" || destTextBox === "#node-input-colorAtSwitchOnDayTime") {
|
|
257
|
+
$(destTextBox).val(resultRGB);
|
|
258
|
+
} else {
|
|
259
|
+
$(destTextBox).val(resultKelvin);
|
|
260
|
+
}
|
|
234
261
|
// Flash the destination control
|
|
235
262
|
$(destTextBox).css("background-color", "lightgreen");
|
|
236
263
|
$("#tabNRColor_divApplyCancel").hide();
|
|
@@ -380,6 +407,13 @@
|
|
|
380
407
|
getDPT("1.", "#node-input-dptDaylightSensor");
|
|
381
408
|
getGroupAddress("#node-input-GADaylightSensor", "#node-input-nameDaylightSensor", "#node-input-dptDaylightSensor", " 1.");
|
|
382
409
|
|
|
410
|
+
getDPT("7.600", "#node-input-dptLightKelvin");
|
|
411
|
+
getGroupAddress("#node-input-GALightKelvin", "#node-input-nameLightKelvin", "#node-input-dptLightKelvin", " 7.600");
|
|
412
|
+
|
|
413
|
+
getDPT("7.600", "#node-input-dptLightKelvinState");
|
|
414
|
+
getGroupAddress("#node-input-GALightKelvinState", "#node-input-nameLightKelvinState", "#node-input-dptLightKelvinState", " 7.600");
|
|
415
|
+
|
|
416
|
+
|
|
383
417
|
// Show/Hide and enable/disable day/night Lighting behaviour
|
|
384
418
|
if (this.enableDayNightLighting === "yes") {
|
|
385
419
|
$("#divEnableDayNightLighting").show();
|
|
@@ -484,7 +518,6 @@
|
|
|
484
518
|
});
|
|
485
519
|
|
|
486
520
|
$("#getColorAtSwitchOnDayTimeButton").on("click", function () {
|
|
487
|
-
// Get the HUE capabilities to enable/disable UI parts
|
|
488
521
|
$("#getColorAtSwitchOnDayTimeButton").text("Wait...");
|
|
489
522
|
$.getJSON("knxUltimateGetHueColor?id=" + $("#node-input-hueDevice").val().split("#")[0], (data) => {
|
|
490
523
|
$("#node-input-colorAtSwitchOnDayTime").val(data.toString());
|
|
@@ -496,7 +529,6 @@
|
|
|
496
529
|
});
|
|
497
530
|
});
|
|
498
531
|
$("#getColorAtSwitchOnNightTimeButton").on("click", function () {
|
|
499
|
-
// Get the HUE capabilities to enable/disable UI parts
|
|
500
532
|
$("#getColorAtSwitchOnNightTimeButton").text("Wait...");
|
|
501
533
|
$.getJSON("knxUltimateGetHueColor?id=" + $("#node-input-hueDevice").val().split("#")[0], (data) => {
|
|
502
534
|
$("#node-input-colorAtSwitchOnNightTime").val(data.toString());
|
|
@@ -528,6 +560,8 @@
|
|
|
528
560
|
$("#node-input-maxDimLevelLight").val(node.maxDimLevelLight);
|
|
529
561
|
|
|
530
562
|
if (this.hueDevice !== "") $("#tabs").show();
|
|
563
|
+
|
|
564
|
+
|
|
531
565
|
},
|
|
532
566
|
oneditsave: function () {
|
|
533
567
|
RED.sidebar.removeTab("tabNRColor");
|
|
@@ -665,43 +699,68 @@
|
|
|
665
699
|
</div>
|
|
666
700
|
<div id="tabs-3">
|
|
667
701
|
<p>
|
|
668
|
-
|
|
669
|
-
|
|
702
|
+
<div class="form-row">
|
|
703
|
+
<label for="node-input-nameLightHSV" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control dim</label>
|
|
670
704
|
|
|
671
|
-
|
|
672
|
-
|
|
705
|
+
<label for="node-input-GALightHSV" style="width:20px;">GA</label>
|
|
706
|
+
<input type="text" id="node-input-GALightHSV" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
673
707
|
|
|
674
|
-
|
|
675
|
-
|
|
708
|
+
<label for="node-input-dptLightHSV" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
|
|
709
|
+
<select id="node-input-dptLightHSV" style="width:140px;"></select>
|
|
676
710
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
711
|
+
<label for="node-input-nameLightHSV" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
|
|
712
|
+
<input type="text" id="node-input-nameLightHSV" style="width:190px;margin-left: 5px; text-align: left;">
|
|
713
|
+
</div>
|
|
714
|
+
<div class="form-row">
|
|
715
|
+
<label for="node-input-nameLightHSVPercentage" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control %</label>
|
|
682
716
|
|
|
683
|
-
|
|
684
|
-
|
|
717
|
+
<label for="node-input-GALightHSVPercentage" style="width:20px;">GA</label>
|
|
718
|
+
<input type="text" id="node-input-GALightHSVPercentage" placeholder="Ex: 1/1/1"
|
|
719
|
+
style="width:70px;margin-left: 5px; text-align: left;">
|
|
720
|
+
|
|
721
|
+
<label for="node-input-dptLightHSVPercentage" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
|
|
722
|
+
<select id="node-input-dptLightHSVPercentage" style="width:140px;"></select>
|
|
723
|
+
|
|
724
|
+
<label for="node-input-nameLightHSVPercentage" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
|
|
725
|
+
<input type="text" id="node-input-nameLightHSVPercentage" style="width:190px;margin-left: 5px; text-align: left;">
|
|
726
|
+
</div>
|
|
727
|
+
<div class="form-row">
|
|
728
|
+
<label for="node-input-nameLightKelvin" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control Kelvin</label>
|
|
729
|
+
|
|
730
|
+
<label for="node-input-GALightKelvin" style="width:20px;">GA</label>
|
|
731
|
+
<input type="text" id="node-input-GALightKelvin" placeholder="Ex: 1/1/1"
|
|
685
732
|
style="width:70px;margin-left: 5px; text-align: left;">
|
|
686
733
|
|
|
687
|
-
<label for="node-input-
|
|
688
|
-
<select id="node-input-
|
|
734
|
+
<label for="node-input-dptLightKelvin" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
|
|
735
|
+
<select id="node-input-dptLightKelvin" style="width:140px;"></select>
|
|
689
736
|
|
|
690
|
-
<label for="node-input-
|
|
691
|
-
<input type="text" id="node-input-
|
|
737
|
+
<label for="node-input-nameLightKelvin" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
|
|
738
|
+
<input type="text" id="node-input-nameLightKelvin" style="width:190px;margin-left: 5px; text-align: left;">
|
|
692
739
|
</div>
|
|
693
|
-
|
|
694
|
-
|
|
740
|
+
<div class="form-row">
|
|
741
|
+
<label for="node-input-nameLightHSVState" style="width:110px;"><i class="fa fa-play-circle-o"></i> Status %</label>
|
|
695
742
|
|
|
696
|
-
|
|
697
|
-
|
|
743
|
+
<label for="node-input-GALightHSVState" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightState"></span></label>
|
|
744
|
+
<input type="text" id="node-input-GALightHSVState" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
698
745
|
|
|
699
|
-
|
|
700
|
-
|
|
746
|
+
<label for="node-input-dptLightHSVState" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
|
|
747
|
+
<select id="node-input-dptLightHSVState" style="width:140px;"></select>
|
|
701
748
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
749
|
+
<label for="node-input-nameLightHSVState" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
|
|
750
|
+
<input type="text" id="node-input-nameLightHSVState" style="width:190px;margin-left: 5px; text-align: left;">
|
|
751
|
+
</div>
|
|
752
|
+
<div class="form-row">
|
|
753
|
+
<label for="node-input-nameLightKelvinState" style="width:110px;"><i class="fa fa-play-circle-o"></i> Status Kelvin</label>
|
|
754
|
+
|
|
755
|
+
<label for="node-input-GALightKelvinState" style="width:20px;">GA</label>
|
|
756
|
+
<input type="text" id="node-input-GALightKelvinState" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
757
|
+
|
|
758
|
+
<label for="node-input-dptLightKelvinState" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
|
|
759
|
+
<select id="node-input-dptLightKelvinState" style="width:140px;"></select>
|
|
760
|
+
|
|
761
|
+
<label for="node-input-nameLightKelvinState" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
|
|
762
|
+
<input type="text" id="node-input-nameLightKelvinState" style="width:190px;margin-left: 5px; text-align: left;">
|
|
763
|
+
</div>
|
|
705
764
|
</p>
|
|
706
765
|
</div>
|
|
707
766
|
<div id="tabs-4">
|
|
@@ -907,9 +966,11 @@
|
|
|
907
966
|
**Tunable white**
|
|
908
967
|
|Property|Description|
|
|
909
968
|
|--|--|
|
|
910
|
-
| Control| Changes the HUE light's white temperature, using DPT 3.007 dimming. You can set the dimming speed in the **_Behaviour_** tab.|
|
|
969
|
+
| Control dim | Changes the HUE light's white temperature, using DPT 3.007 dimming. You can set the dimming speed in the **_Behaviour_** tab.|
|
|
911
970
|
| Control % | Changes the HUE light's white temperature, using the DPT 5.001. A value of 0 is full warm, a value of 100 is full cold.|
|
|
912
|
-
|
|
|
971
|
+
| Control kelvin | Changes the HUE light's temperature in Kelvin degrees, using the DPT 7.600. |
|
|
972
|
+
| Status %| Link this to the light temperature status group address. Datapoint is 5.001 absolute value. 0 is full warm, 100 is full cold.|
|
|
973
|
+
| Status kelvin | Link this to the light temperature status group address. Datapoint 7.600. |
|
|
913
974
|
|
|
914
975
|
<br/>
|
|
915
976
|
|
|
@@ -60,9 +60,9 @@ module.exports = function (RED) {
|
|
|
60
60
|
node.handleSend = (msg) => {
|
|
61
61
|
if (node.currentHUEDevice === undefined) {
|
|
62
62
|
node.setNodeStatusHue({
|
|
63
|
-
fill: "
|
|
63
|
+
fill: "grey",
|
|
64
64
|
shape: "ring",
|
|
65
|
-
text: "
|
|
65
|
+
text: "Initializing. Please wait.",
|
|
66
66
|
payload: "",
|
|
67
67
|
});
|
|
68
68
|
return;
|
|
@@ -126,6 +126,18 @@ module.exports = function (RED) {
|
|
|
126
126
|
fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload),
|
|
127
127
|
});
|
|
128
128
|
break;
|
|
129
|
+
case config.GALightKelvin:
|
|
130
|
+
msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvin));
|
|
131
|
+
let retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [153, 500]);
|
|
132
|
+
state = { color_temperature: { mirek: retMirek } };
|
|
133
|
+
node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
|
|
134
|
+
node.setNodeStatusHue({
|
|
135
|
+
fill: "green",
|
|
136
|
+
shape: "dot",
|
|
137
|
+
text: "KNX->HUE",
|
|
138
|
+
payload: state,
|
|
139
|
+
});
|
|
140
|
+
break;
|
|
129
141
|
case config.GADaylightSensor:
|
|
130
142
|
if (config.enableDayNightLighting === "yes") {
|
|
131
143
|
node.DayTime = Boolean(dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptDaylightSensor)));
|
|
@@ -168,12 +180,6 @@ module.exports = function (RED) {
|
|
|
168
180
|
payload: state,
|
|
169
181
|
});
|
|
170
182
|
}
|
|
171
|
-
node.setNodeStatusHue({
|
|
172
|
-
fill: "green",
|
|
173
|
-
shape: "dot",
|
|
174
|
-
text: "KNX->HUE",
|
|
175
|
-
payload: msg.payload,
|
|
176
|
-
});
|
|
177
183
|
break;
|
|
178
184
|
case config.GALightBrightness:
|
|
179
185
|
msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightBrightness));
|
|
@@ -433,13 +439,6 @@ module.exports = function (RED) {
|
|
|
433
439
|
) {
|
|
434
440
|
node.updateKNXBrightnessState(0);
|
|
435
441
|
node.currentHUEDevice.dimming.brightness = 0;
|
|
436
|
-
} else {
|
|
437
|
-
// // Sends the previous brightness value
|
|
438
|
-
// try {
|
|
439
|
-
// node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
|
|
440
|
-
// } catch (error) {
|
|
441
|
-
// /* empty */
|
|
442
|
-
// }
|
|
443
442
|
}
|
|
444
443
|
node.currentHUEDevice.on.on = _event.on.on;
|
|
445
444
|
}
|
|
@@ -473,24 +472,9 @@ module.exports = function (RED) {
|
|
|
473
472
|
}
|
|
474
473
|
if (_event.hasOwnProperty("color_temperature") && _event.color_temperature.mirek !== undefined) {
|
|
475
474
|
node.updateKNXLightHSVState(_event.color_temperature.mirek);
|
|
475
|
+
node.updateKNXLightKelvinState(_event.color_temperature.mirek);
|
|
476
476
|
node.currentHUEDevice.color_temperature.mirek = _event.color_temperature.mirek;
|
|
477
477
|
}
|
|
478
|
-
|
|
479
|
-
// // Update the current HUE Device with the new _event
|
|
480
|
-
// function copiaOggettoRicorsivo(objDestinazione, objOrigine) {
|
|
481
|
-
// for (const prop in objOrigine) {
|
|
482
|
-
// if (typeof objOrigine[prop] === "object" && objOrigine[prop] !== null) {
|
|
483
|
-
// // Se la proprietà è un oggetto, copiamola in modo ricorsivo
|
|
484
|
-
// objDestinazione[prop] = objDestinazione[prop] || {};
|
|
485
|
-
// copiaOggettoRicorsivo(objDestinazione[prop], objOrigine[prop]);
|
|
486
|
-
// } else {
|
|
487
|
-
// // Altrimenti, copia il valore della proprietà
|
|
488
|
-
// objDestinazione[prop] = objOrigine[prop];
|
|
489
|
-
// }
|
|
490
|
-
// }
|
|
491
|
-
// }
|
|
492
|
-
// // Copia l'oggettoOrigine nell'oggettoDestinazione mantenendo le proprietà esistenti
|
|
493
|
-
// copiaOggettoRicorsivo(node.currentHUEDevice, _event);
|
|
494
478
|
}
|
|
495
479
|
} catch (error) {
|
|
496
480
|
node.status({
|
|
@@ -617,7 +601,32 @@ module.exports = function (RED) {
|
|
|
617
601
|
}
|
|
618
602
|
};
|
|
619
603
|
|
|
620
|
-
|
|
604
|
+
node.updateKNXLightKelvinState = function updateKNXLightKelvinState(_value) {
|
|
605
|
+
if (config.GALightKelvinState !== undefined && config.GALightKelvinState !== "") {
|
|
606
|
+
const knxMsgPayload = {};
|
|
607
|
+
knxMsgPayload.topic = config.GALightKelvinState;
|
|
608
|
+
knxMsgPayload.dpt = config.dptLightKelvinState;
|
|
609
|
+
if (config.dptLightKelvinState === "7.600") {
|
|
610
|
+
knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(_value, [153, 500], [0, 65535]);
|
|
611
|
+
// Send to KNX bus
|
|
612
|
+
if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
|
|
613
|
+
node.server.writeQueueAdd({
|
|
614
|
+
grpaddr: knxMsgPayload.topic,
|
|
615
|
+
payload: knxMsgPayload.payload,
|
|
616
|
+
dpt: knxMsgPayload.dpt,
|
|
617
|
+
outputtype: "write",
|
|
618
|
+
nodecallerid: node.id,
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
node.setNodeStatusHue({
|
|
622
|
+
fill: "blue",
|
|
623
|
+
shape: "ring",
|
|
624
|
+
text: "HUE->KNX HSV",
|
|
625
|
+
payload: knxMsgPayload.payload,
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
};
|
|
621
630
|
|
|
622
631
|
// On each deploy, unsubscribe+resubscribe
|
|
623
632
|
if (node.server) {
|
|
@@ -625,8 +634,12 @@ module.exports = function (RED) {
|
|
|
625
634
|
node.server.addClient(node);
|
|
626
635
|
}
|
|
627
636
|
if (node.serverHue) {
|
|
628
|
-
|
|
629
|
-
|
|
637
|
+
try {
|
|
638
|
+
node.serverHue.removeClient(node);
|
|
639
|
+
node.serverHue.addClient(node);
|
|
640
|
+
} catch (error) {
|
|
641
|
+
RED.log.error("knxUltimateHueLight: if (node.server): " + error.message);
|
|
642
|
+
}
|
|
630
643
|
}
|
|
631
644
|
|
|
632
645
|
node.on("input", (msg) => { });
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
namemotion: { value: "" },
|
|
12
12
|
GAmotion: { value: "" },
|
|
13
13
|
dptmotion: { value: "" },
|
|
14
|
-
readStatusAtStartup: { value: "no" },
|
|
15
14
|
|
|
16
15
|
hueDevice: { value: "" }
|
|
17
16
|
},
|
|
@@ -212,14 +211,6 @@
|
|
|
212
211
|
<input type="text" id="node-input-namemotion" style="width:200px;margin-left: 5px; text-align: left;">
|
|
213
212
|
</div>
|
|
214
213
|
|
|
215
|
-
<div class="form-row">
|
|
216
|
-
<label style="width:180px" for="node-input-readStatusAtStartup"><i class="fa fa-play-circle"></i> Read status at startup</label>
|
|
217
|
-
<select id="node-input-readStatusAtStartup">
|
|
218
|
-
<option value="no">No</option>
|
|
219
|
-
<option value="yes">Yes, and emit KNX telegrams.</option>
|
|
220
|
-
</select>
|
|
221
|
-
</div>
|
|
222
|
-
|
|
223
214
|
<br/>
|
|
224
215
|
<br/>
|
|
225
216
|
<br/>
|
|
@@ -244,7 +235,6 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
244
235
|
|Property|Description|
|
|
245
236
|
|--|--|
|
|
246
237
|
| Motion | As soon as someone moves in the motion device's range, a *true* KNX value is sent to this group address, otherwise *false* is sent. |
|
|
247
|
-
| Read status at startup | Read the status at startup and emit the event to the KNX bus at startup/reconnection. (Default "no")|
|
|
248
238
|
|
|
249
239
|
### Outputs
|
|
250
240
|
|
|
@@ -42,7 +42,7 @@ module.exports = function (RED) {
|
|
|
42
42
|
if (_event.id === config.hueDevice) {
|
|
43
43
|
|
|
44
44
|
// IMPORTANT: exit if no event presen.
|
|
45
|
-
if (_event.initializingAtStart === true
|
|
45
|
+
if (_event.initializingAtStart === true) return;
|
|
46
46
|
if (!_event.hasOwnProperty("motion") || _event.motion.motion === undefined) return;
|
|
47
47
|
|
|
48
48
|
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
GAscene: { value: "" },
|
|
13
13
|
dptscene: { value: "" },
|
|
14
14
|
valscene: { value: 0 }, // the scene number or true/false
|
|
15
|
-
readStatusAtStartup: { value: "no" },
|
|
16
15
|
|
|
17
16
|
hueDevice: { value: "" },
|
|
18
17
|
hueSceneRecallType: { value: "active" }
|
|
@@ -252,13 +251,6 @@
|
|
|
252
251
|
<select id="node-input-valscene" style="width:180px;margin-left: 5px; text-align: left;"></select>
|
|
253
252
|
</div>
|
|
254
253
|
|
|
255
|
-
<div class="form-row">
|
|
256
|
-
<label style="width:180px" for="node-input-readStatusAtStartup"><i class="fa fa-play-circle"></i> Read status at startup</label>
|
|
257
|
-
<select id="node-input-readStatusAtStartup">
|
|
258
|
-
<option value="no">No</option>
|
|
259
|
-
<option value="yes">Yes, and emit KNX telegrams.</option>
|
|
260
|
-
</select>
|
|
261
|
-
</div>
|
|
262
254
|
|
|
263
255
|
<br/>
|
|
264
256
|
<br/>
|
|
@@ -285,7 +277,6 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
285
277
|
|--|--|
|
|
286
278
|
| Recall | Choose your group address to be used for recalling the HUE scene. In case of Datapoint 1.x, send *true* to that group address to recall the scene, *false* to switch off all lights belonging to the scene. |
|
|
287
279
|
| # | Select the KNX scene number. Visible only with datapoint 18.001. |
|
|
288
|
-
| Read status at startup | Read the status at startup and emit the event to the KNX bus at startup/reconnection. (Default "no")|
|
|
289
280
|
|
|
290
281
|
<br/>
|
|
291
282
|
|
|
@@ -80,7 +80,7 @@ module.exports = function (RED) {
|
|
|
80
80
|
if (_event.id === config.hueDevice) {
|
|
81
81
|
|
|
82
82
|
// IMPORTANT: exit if no event presen.
|
|
83
|
-
if (_event.initializingAtStart === true
|
|
83
|
+
if (_event.initializingAtStart === true) return;
|
|
84
84
|
|
|
85
85
|
// const knxMsgPayload = {}
|
|
86
86
|
// knxMsgPayload.topic = config.GAmotion
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
namerepeat: { value: "" },
|
|
12
12
|
GArepeat: { value: "" },
|
|
13
13
|
dptrepeat: { value: "" },
|
|
14
|
-
readStatusAtStartup: { value: "no" },
|
|
15
14
|
|
|
16
15
|
hueDevice: { value: "" }
|
|
17
16
|
},
|
|
@@ -214,16 +213,6 @@
|
|
|
214
213
|
<input type="text" id="node-input-namerepeat" style="width:200px;margin-left: 5px; text-align: left;">
|
|
215
214
|
</div>
|
|
216
215
|
|
|
217
|
-
|
|
218
|
-
<div class="form-row">
|
|
219
|
-
<label style="width:180px" for="node-input-readStatusAtStartup"><i class="fa fa-play-circle"></i> Read status at startup</label>
|
|
220
|
-
<select id="node-input-readStatusAtStartup">
|
|
221
|
-
<option value="no">No</option>
|
|
222
|
-
<option value="yes">Yes, and emit KNX telegrams.</option>
|
|
223
|
-
</select>
|
|
224
|
-
</div>
|
|
225
|
-
|
|
226
|
-
|
|
227
216
|
<br/>
|
|
228
217
|
<br/>
|
|
229
218
|
<br/>
|
|
@@ -252,7 +241,6 @@ or a random color (Datapoint 232.600) to the selected group address.
|
|
|
252
241
|
|Property|Description|
|
|
253
242
|
|--|--|
|
|
254
243
|
| Rotate | This command is used either to send DIM (increase/decrease), aboslute brightness, or a random color, depending on the selected datapoint. If the random color (datapoint 232.600) is selected, **clockwise rotation** changes random colors and **counterclockwise rotation** set the light to **white** |
|
|
255
|
-
| Read status at startup | Read the status at startup and emit the event to the KNX bus at startup/reconnection. (Default "no")|
|
|
256
244
|
|
|
257
245
|
### Outputs
|
|
258
246
|
|
|
@@ -51,7 +51,7 @@ module.exports = function (RED) {
|
|
|
51
51
|
if (_event.id === config.hueDevice) {
|
|
52
52
|
|
|
53
53
|
// IMPORTANT: exit if no event presen.
|
|
54
|
-
if (_event.initializingAtStart === true
|
|
54
|
+
if (_event.initializingAtStart === true) return;
|
|
55
55
|
if (!_event.hasOwnProperty("relative_rotary")
|
|
56
56
|
|| !_event.relative_rotary.hasOwnProperty("last_event")
|
|
57
57
|
|| _event.relative_rotary.last_event === undefined
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=16.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.2.
|
|
6
|
+
"version": "2.2.9",
|
|
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 control.",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"binary-parser": "2.2.1",
|