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 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/>
@@ -91,14 +91,15 @@ module.exports = (RED) => {
91
91
  });
92
92
  // Connected
93
93
  node.hueManager.on("connected", () => {
94
- (async () => {
95
- try {
96
- await node.loadResourcesFromHUEBridge(); // Then, you can use node.getResources, that works locally and doesn't query the HUE Bridge.
97
- } catch (error) {
98
- /* empty */
99
- }
100
- })();
101
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info("node.hueManager connected event");
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("Next cycle will reconnect...", "grey", "");
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 && (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "no")) return;
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, copy the <b>Result RGB</b> text and paste it into the required fields.</p>
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
- <h3>Result RGB</h3>
144
- <div>
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
- $(destTextBox).val(resultRGB);
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
- <div class="form-row">
669
- <label for="node-input-nameLightHSV" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control</label>
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
- <label for="node-input-GALightHSV" style="width:20px;">GA</label>
672
- <input type="text" id="node-input-GALightHSV" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
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
- <label for="node-input-dptLightHSV" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
675
- <select id="node-input-dptLightHSV" style="width:140px;"></select>
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
- <label for="node-input-nameLightHSV" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
678
- <input type="text" id="node-input-nameLightHSV" style="width:190px;margin-left: 5px; text-align: left;">
679
- </div>
680
- <div class="form-row">
681
- <label for="node-input-nameLightHSVPercentage" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control %</label>
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
- <label for="node-input-GALightHSVPercentage" style="width:20px;">GA</label>
684
- <input type="text" id="node-input-GALightHSVPercentage" placeholder="Ex: 1/1/1"
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-dptLightHSVPercentage" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
688
- <select id="node-input-dptLightHSVPercentage" style="width:140px;"></select>
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-nameLightHSVPercentage" style="width:50px; margin-left: 0px; text-align: right;">Name</label>
691
- <input type="text" id="node-input-nameLightHSVPercentage" style="width:190px;margin-left: 5px; text-align: left;">
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
- <div class="form-row">
694
- <label for="node-input-nameLightHSVState" style="width:110px;"><i class="fa fa-play-circle-o"></i> Status</label>
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
- <label for="node-input-GALightHSVState" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightState"></span></label>
697
- <input type="text" id="node-input-GALightHSVState" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
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
- <label for="node-input-dptLightHSVState" style="width:40px; margin-left: 0px; text-align: right;">DPT</label>
700
- <select id="node-input-dptLightHSVState" style="width:140px;"></select>
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
- <label for="node-input-nameLightHSVState" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="knxUltimateHueLight.node-input-name"></span></label>
703
- <input type="text" id="node-input-nameLightHSVState" style="width:190px;margin-left: 5px; text-align: left;">
704
- </div>
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
- | Status | Link this to the light temperature status group address. Datapoint is 5.001 absolute value. 0 is full warm, 100 is full cold.|
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: "red",
63
+ fill: "grey",
64
64
  shape: "ring",
65
- text: "Currently not ready.",
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
- node.serverHue.removeClient(node);
629
- node.serverHue.addClient(node);
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 && (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "no")) return;
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 && (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "no")) return;
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 && (config.readStatusAtStartup === undefined || config.readStatusAtStartup === "no")) return;
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
@@ -1,6 +1,8 @@
1
1
  const convert = require('color-convert');
2
2
 
3
3
  class ColorConverter {
4
+
5
+
4
6
  static getGamutRanges() {
5
7
  const gamutA = {
6
8
  red: [0.704, 0.296],
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.2.6",
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",