node-red-contrib-knx-ultimate 2.4.26 → 2.4.28

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,24 +6,13 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
- **Version 2.4.26** - Mai 2024<br/>
10
- - Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
11
- - HUE light node: fixed status refresh of kelvin and brightness of a light belonging to a grouped_light.<br/>
12
- - KNOW ISSUE: HUE light node: grouped_lights: the status group address is updated multiple times, equals to the lights contained in the grouped_light. To avoid repeating the same telegram multiple times, simply enable the RBE filter on the KNX node. <br/>
13
-
14
- **Version 2.4.25** - Mai 2024<br/>
15
- - Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
16
- - HUE light node: fixed status sent to the KNX bus after issuing a read request for grouped_lights.<br/>
17
- - KNOW ISSUE: HUE light node: grouped_lights: the status group address is updated multiple times, equals to the lights contained in the grouped_light. To avoid repeating the same telegram multiple times, simply enable the RBE filter on the KNX node. <br/>
18
-
19
- **Version 2.4.24** - Mai 2024<br/>
20
- - Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
21
- - HUE light node: fixed kelvin temp status with datapoint 7.600, that sent wrong values to the bus.<br/>
9
+ **Version 2.4.28**
10
+ - temporary reveft to 2.4.23
22
11
 
23
12
  **Version 2.4.23** - Mai 2024<br/>
24
13
  - Warning: Node-Red version **equals or major than 3.1.1** is needed to run this node.<br/>
25
14
  - HUE Scene node: fixed max scene count to 64.<br/>
26
-
15
+
27
16
  **Version 2.4.22** - April 2024<br/>
28
17
  - Warning: this version uses the Node-Red plugin system; the Node-Red version must be **equals or major than 3.1.1**<br/>
29
18
  - HUE button node: NEW: now you can select the value and the dim direction to be transmitted, when Toggle Status is set to unchecked. Thanks @cybersmart-eu for the suggestion.<br/>
package/README.md CHANGED
@@ -50,17 +50,14 @@ msg.payload = {red:255, green:200, blue:30} // Put some colors in our life
50
50
 
51
51
  * See <a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/blob/master/CHANGELOG.md">here the changelog</a>
52
52
 
53
-
54
- ## SUPPORTED TECHNOLOGIES
55
-
56
53
  |Technology|Supported|
57
54
  |--|--|
58
55
  | KNX Tunnelling | ![](https://placehold.co/200x20/green/white?text=YES) |
59
56
  | KNX Routing | ![](https://placehold.co/200x20/green/white?text=YES) |
60
57
  | KNX Secure Tunnelling | ![](https://placehold.co/200x20/orange/white?text=UNDER+DEVELOPMENT) |
61
58
  | KNX Secure Routing | ![](https://placehold.co/200x20/red/white?text=NO) |
62
- | KNX 3rd PARTY IOT API client | ![](https://placehold.co/200x20/orange/white?text=UNDER+DEVELOPMENT) |
63
- | Matter | ![](https://placehold.co/200x20/blue/white?text=UNDER+BRAINSTORMING) |
59
+ | KNX 3rd PARTY IOT API | ![](https://placehold.co/200x20/orange/white?text=UNDER+DEVELOPMENT) |
60
+
64
61
 
65
62
  <br/>
66
63
 
@@ -8,7 +8,6 @@ const cloneDeep = require("lodash/cloneDeep");
8
8
  const HueClass = require("./utils/hueEngine").classHUE;
9
9
  const loggerEngine = require("./utils/sysLogger");
10
10
  const hueColorConverter = require("./utils/colorManipulators/hueColorConverter");
11
- const { AsyncObservable } = require("@project-chip/matter-node.js/util");
12
11
 
13
12
  module.exports = (RED) => {
14
13
  function hueConfig(config) {
@@ -51,9 +50,6 @@ module.exports = (RED) => {
51
50
  node.nodeClients.forEach((_oClient) => {
52
51
  const oClient = _oClient;
53
52
  try {
54
- // if (_event.type === "light" || _event.type === "grouped_light") {
55
- // console.log(_event);
56
- // }
57
53
  if (oClient.handleSendHUE !== undefined) oClient.handleSendHUE(_event);
58
54
  } catch (error) {
59
55
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`Errore node.hueManager.on(event): ${error.message}`);
@@ -69,11 +65,7 @@ module.exports = (RED) => {
69
65
  node.timerDoInitialRead = setTimeout(() => {
70
66
  (async () => {
71
67
  try {
72
- if (node.hueAllResources === undefined) {
73
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`HTTP getting resource from HUE bridge : ${node.name}`);
74
- await node.loadResourcesFromHUEBridge();
75
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`Total HUE resources count : ${node.hueAllResources.length}`);
76
- }
68
+ await node.loadResourcesFromHUEBridge();
77
69
  } catch (error) {
78
70
  node.linkStatus = "disconnected";
79
71
  node.nodeClients.forEach((_oClient) => {
@@ -122,7 +114,6 @@ module.exports = (RED) => {
122
114
  };
123
115
  node.startWatchdogTimer();
124
116
 
125
- // Functions called from the nodes ----------------------------------------------------------------
126
117
  // Query the HUE Bridge to return the resources
127
118
  node.loadResourcesFromHUEBridge = async () => {
128
119
  if (node.linkStatus === "disconnected") return;
@@ -145,7 +136,7 @@ module.exports = (RED) => {
145
136
  });
146
137
  _node.currentHUEDevice = cloneDeep(oHUEDevice); // Copy by Value and not by ref
147
138
  if (_node.initializingAtStart === true) {
148
- _node.handleSendHUE(_node.currentHUEDevice); // Pass by value
139
+ _node.handleSendHUE(oHUEDevice); // Pass by value
149
140
  }
150
141
  }
151
142
  }
@@ -182,13 +173,11 @@ module.exports = (RED) => {
182
173
  };
183
174
 
184
175
  // Return an array of light belonging to the groupID
185
- node.getAllLightsBelongingToTheGroup = async function getAllLightsBelongingToTheGroup(_groupID, refreshResourcesFromBridge = true) {
176
+ node.getAllLightsBelongingToTheGroup = async function getAllLightsBelongingToTheGroup(_groupID) {
186
177
  if (node.hueAllResources === undefined || node.hueAllResources === null) return;
187
178
  const retArr = [];
188
179
  try {
189
- if (refreshResourcesFromBridge === true) {
190
- await node.loadResourcesFromHUEBridge();
191
- }
180
+ await node.loadResourcesFromHUEBridge();
192
181
  node.hueAllResources.forEach((res) => {
193
182
  if (res.services !== undefined && res.services.length > 0) {
194
183
  res.services.forEach((serv) => {
@@ -198,8 +187,7 @@ module.exports = (RED) => {
198
187
  for (let index = 0; index < children.length; index++) {
199
188
  const element = children[index];
200
189
  const oLight = node.hueAllResources.filter((a) => a.id === element.rid);
201
- //if (oLight !== null && oLight !== undefined) retArr.push({ groupID: _groupID, light: oLight[0] });
202
- if (oLight !== null && oLight !== undefined) retArr.push(oLight[0]);
190
+ if (oLight !== null && oLight !== undefined) retArr.push({ groupID: _groupID, light: oLight });
203
191
  }
204
192
  }
205
193
  }
@@ -375,46 +363,6 @@ module.exports = (RED) => {
375
363
  }
376
364
  };
377
365
 
378
- /**
379
- * Get average color XY from a light array
380
- * @param {array} _arrayLights - Light array
381
- * @returns { x,y,mirek,brightness } - Object containing all infos
382
- */
383
- node.getAverageColorsXYBrightnessAndTemperature = async function getAverageColorsXYBrightnessAndTemperature(_arrayLights) {
384
- let x; let y; let mirek; let brightness;
385
- let countColor = 0, countColor_Temperature = 0, countDimming = 0;
386
- _arrayLights.forEach((element) => {
387
- if (element.color !== undefined && element.color.xy !== undefined) {
388
- if (x === undefined) { x = 0; y = 0; }
389
- x += element.color.xy.x;
390
- y += element.color.xy.y;
391
- countColor += 1;
392
- }
393
- if (element.color_temperature !== undefined && element.color_temperature.mirek !== undefined) {
394
- if (mirek === undefined) mirek = 0;
395
- mirek += element.color_temperature.mirek;
396
- countColor_Temperature += 1;
397
- }
398
- if (element.dimming !== undefined && element.dimming.brightness !== undefined) {
399
- if (brightness === undefined) brightness = 0;
400
- brightness += element.dimming.brightness;
401
- countDimming += 1;
402
- }
403
- });
404
- // Calculate and return the averages
405
- const retX = countColor === 0 ? undefined : x / countColor;
406
- const retY = countColor === 0 ? undefined : y / countColor;
407
- const retMirek = countColor_Temperature === 0 ? undefined : mirek / countColor_Temperature;
408
- const retBrightness = countDimming === 0 ? undefined : brightness / countDimming;
409
-
410
- return {
411
- x: retX, y: retY, mirek: retMirek, brightness: retBrightness
412
- };
413
- };
414
- // END functions called from the nodes ----------------------------------------------------------------
415
-
416
-
417
-
418
366
  node.addClient = (_Node) => {
419
367
  // Update the node hue device, as soon as a node register itself to hue-config nodeClients
420
368
  if (node.nodeClients.filter((x) => x.id === _Node.id).length === 0) {
@@ -156,14 +156,14 @@ module.exports = function (RED) {
156
156
  // The DayNight has switched into day, so restore the previous light state, belonging to the group
157
157
  let bAtLeastOneIsOn = false;
158
158
  for (let index = 0; index < node.HUELightsBelongingToGroupWhileDaytime.length; index++) { // Ensure, at least 1 lamp was on, otherwise turn all lamps on
159
- const element = node.HUELightsBelongingToGroupWhileDaytime[index];
159
+ const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0];
160
160
  if (element.on.on === true) {
161
161
  bAtLeastOneIsOn = true;
162
162
  break;
163
163
  }
164
164
  }
165
165
  for (let index = 0; index < node.HUELightsBelongingToGroupWhileDaytime.length; index++) {
166
- const element = node.HUELightsBelongingToGroupWhileDaytime[index];
166
+ const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0];
167
167
  if (bAtLeastOneIsOn === true) {
168
168
  state = { on: element.on, dimming: element.dimming, color: element.color, color_temperature: element.color_temperature };
169
169
  } else {
@@ -317,7 +317,7 @@ module.exports = function (RED) {
317
317
  if (node.isGrouped_light === true) {
318
318
  (async () => {
319
319
  try {
320
- const retLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
320
+ const retLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice);
321
321
  node.HUELightsBelongingToGroupWhileDaytime = cloneDeep(retLights); // DayTime has switched to false: save the lights belonging to the group into the HUELightsBelongingToGroupWhileDaytime array
322
322
  } catch (error) { /* empty */ }
323
323
  })();
@@ -509,56 +509,16 @@ module.exports = function (RED) {
509
509
  if (ret !== undefined) node.updateKNXLightColorState(node.currentHUEDevice.color, "response");
510
510
  break;
511
511
  case config.GALightKelvinPercentageState:
512
- // The kelvin level belongs to the group defice, so i don't need to get the first light in the collection (if the device is a grouped_light)
513
512
  ret = node.currentHUEDevice.color_temperature.mirek;
514
513
  if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, "response");
515
- // if (node.isGrouped_light === false) {
516
- // ret = node.currentHUEDevice.color_temperature.mirek;
517
- // if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, "response");
518
- // } else {
519
- // (async () => {
520
- // try {
521
- // // Find the first light in the collection, having the color_temperature capabilities
522
- // const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
523
- // for (let index = 0; index < devices.length; index++) {
524
- // const element = devices[index];
525
- // if (element.light[0].color_temperature !== undefined) {
526
- // ret = element.light[0].color_temperature.mirek;
527
- // break;
528
- // }
529
- // }
530
- // if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, "response");
531
- // } catch (error) { /* empty */ }
532
- // })();
533
- // }
534
514
  break;
535
515
  case config.GALightBrightnessState:
536
516
  ret = node.currentHUEDevice.dimming.brightness;
537
517
  if (ret !== undefined) node.updateKNXBrightnessState(ret, "response");
538
518
  break;
539
519
  case config.GALightKelvinState:
540
- // The kelvin level belongs to the group defice, so i don't need to get the first light in the collection (if the device is a grouped_light)
541
520
  ret = node.currentHUEDevice.color_temperature.mirek;
542
521
  if (ret !== undefined) node.updateKNXLightKelvinState(ret, "response");
543
- // if (node.isGrouped_light === false) {
544
- // ret = node.currentHUEDevice.color_temperature.mirek;
545
- // if (ret !== undefined) node.updateKNXLightKelvinState(ret, "response");
546
- // } else {
547
- // (async () => {
548
- // try {
549
- // // Find the first light in the collection, having the color_temperature capabilities
550
- // const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
551
- // for (let index = 0; index < devices.length; index++) {
552
- // const element = devices[index];
553
- // if (element.light[0].color_temperature !== undefined) {
554
- // ret = element.light[0].color_temperature.mirek;
555
- // break;
556
- // }
557
- // }
558
- // if (ret !== undefined) node.updateKNXLightKelvinState(ret, "response");
559
- // } catch (error) { /* empty */ }
560
- // })();
561
- // }
562
522
  break;
563
523
  default:
564
524
  break;
@@ -910,87 +870,22 @@ module.exports = function (RED) {
910
870
  };
911
871
  // ***********************************************************
912
872
 
913
- node.handleSendHUE = async (_event) => {
914
- if (_event === undefined) return;
915
- if (_event.type !== 'grouped_light' && _event.type !== 'light') return;
916
-
917
- // !!!! >>> if the node is a grouped_light, the only values required, thus present, by HUE apis are "on" and "dimming".
918
- // !!!! >>> For all others properties like for example color and tunable white, i must get the data from one of the child lights.
919
-
920
- //(async () => {
921
- // Check and set canContinue true or false ------------------------------------------------------------
873
+ node.handleSendHUE = (_event) => {
922
874
  try {
923
- if (node.currentHUEDevice === undefined || node.serverHue === null || node.serverHue === undefined) {
924
- node.setNodeStatusHue({
925
- fill: "red",
926
- shape: "ring",
927
- text: "Rejected HUE light settings. I'm still not ready...",
928
- payload: "",
929
- });
930
- return;
931
- }
932
-
933
- const receivedHUEObject = cloneDeep(_event);
934
- let canContinue = false;
935
- // If the current node is a grouped lights, i must check wether the receivedHUEObject (containing a light) belongs to the node lights collection.
936
- if (node.isGrouped_light === true && receivedHUEObject.type === 'grouped_light' && receivedHUEObject.id === node.hueDevice) {
937
- canContinue = true;
938
- } else if (node.isGrouped_light === true && receivedHUEObject.type === 'light') {
939
- // Handling of not by HUE handled Color Temperature and ColorXY
940
- // let groupChilds = undefined;
941
- // let AverageColorsXYBrightnessAndTemperature = undefined; // Average color xy and color temp if the node is a grouped light.
942
- // // If the current node is a grouped lights, i must check wether the receivedHUEObject (containing a light) belongs to the node lights collection.
943
- // try {
944
- // // Find all the lights in the collection, having the color_temperature capabilities, belonging to the group.
945
- // const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, true);
946
- // groupChilds = [];
947
- // for (let index = 0; index < devices.length; index++) {
948
- // const element = devices[index];
949
- // if (receivedHUEObject.id === element.id) {
950
- // //if (groupChilds === undefined) groupChilds = [];
951
- // // groupChilds.push(element);
952
- // let modifiedLight = cloneDeep(element);
953
- // // The dimming is not necessary, beacause the HUE API already sends a group_light event with the average brightness //if (receivedHUEObject.dimming !== undefined) modifiedLight.dimming = { brightness: receivedHUEObject.dimming.brightness };
954
- // if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined) modifiedLight.color = receivedHUEObject.color;
955
- // if (receivedHUEObject.color_temperature !== undefined) modifiedLight.color_temperature = receivedHUEObject.color_temperature;
956
- // groupChilds.push(modifiedLight);
957
- // } else {
958
- // // Simply ppend the light
959
- // groupChilds.push(element);
960
- // }
961
- // }
962
-
963
- // // Use the arithmetic average of color xy, brightness and color temperature "averageColorXYandKelvinOfGroupedLights"
964
- // if (groupChilds !== undefined) AverageColorsXYBrightnessAndTemperature = await node.serverHue.getAverageColorsXYBrightnessAndTemperature(groupChilds);
965
-
966
- // // Set the new values based on average calculated above
967
- // try {
968
- // // CHECK FIRST THE COLOR_TEMPERATURE, because it can be undefined, because the current selected color
969
- // // is out of the mirek range, so it cannot be represented with the colore temperature.
970
- // if (receivedHUEObject.color_temperature !== undefined && AverageColorsXYBrightnessAndTemperature.mirek !== undefined) {
971
- // receivedHUEObject.color_temperature = { mirek: AverageColorsXYBrightnessAndTemperature.mirek };
972
- // } else if (receivedHUEObject.color !== undefined && AverageColorsXYBrightnessAndTemperature.x !== undefined) {
973
- // receivedHUEObject.color = {
974
- // xy: { x: AverageColorsXYBrightnessAndTemperature.x, y: AverageColorsXYBrightnessAndTemperature.y }
975
- // };
976
- // }
977
- // // The dimming is not necessary, beacause the HUE API already sends a group_light event with the average brightness
978
- // // if (receivedHUEObject.dimming !== undefined && AverageColorsXYBrightnessAndTemperature.brightness !== undefined) {
979
- // // receivedHUEObject.dimming = { brightness: AverageColorsXYBrightnessAndTemperature.brightness };
980
- // // }
981
- // } catch (error) { /* empty */ }
982
-
983
- canContinue = true;
984
- //} catch (error) { /* empty */ }
985
- } else if (node.isGrouped_light === false && receivedHUEObject.type === 'light' && receivedHUEObject.id === node.hueDevice) {
986
- canContinue = true;
987
- }
988
-
989
- // --------------------------------------------------------------------------------------------------
875
+ const deviceByRef = cloneDeep(_event);
876
+ if (deviceByRef.id === node.hueDevice) {
877
+ if (node.currentHUEDevice === undefined || node.serverHue === null || node.serverHue === undefined) {
878
+ node.setNodeStatusHue({
879
+ fill: "red",
880
+ shape: "ring",
881
+ text: "Rejected HUE message. I'm connecting to the Bridge...",
882
+ payload: "",
883
+ });
884
+ return;
885
+ }
990
886
 
991
- if (canContinue === true) {
992
887
  // Output the msg to the flow
993
- node.send(receivedHUEObject);
888
+ node.send(deviceByRef);
994
889
 
995
890
  // // DEBUG testing enable/disable HTML UI Tabs
996
891
  //delete _event.dimming;
@@ -998,39 +893,53 @@ module.exports = function (RED) {
998
893
  //delete _event.color_temperature;
999
894
  //delete _event.color_temperature_delta;
1000
895
 
1001
- if (receivedHUEObject.on !== undefined) {
1002
- node.updateKNXLightState(receivedHUEObject.on.on);
896
+ // As grouped_light doesn't contain all requested properties, i find the first light in the group, and use this below in the code
897
+ // If the event type is grouped light, and there are missing properties, i infer these missing properties from the first light in the group!
898
+ if ((deviceByRef.color !== undefined || deviceByRef.dimming !== undefined || deviceByRef.color_temperature !== undefined) && deviceByRef.type === 'grouped_light') {
899
+ try {
900
+ const firstLightInGroup = node.serverHue.getFirstLightInGroup(deviceByRef.id);
901
+ if (firstLightInGroup !== null && firstLightInGroup !== undefined) {
902
+ if (deviceByRef.color === undefined) {
903
+ deviceByRef.color = firstLightInGroup.color;
904
+ }
905
+ if (deviceByRef.color_temperature === undefined) {
906
+ deviceByRef.color_temperature = firstLightInGroup.color_temperature;
907
+ }
908
+ }
909
+ } catch (error) { }
910
+ }
911
+
912
+ if (deviceByRef.on !== undefined) {
913
+ node.updateKNXLightState(deviceByRef.on.on);
1003
914
  // In case of switch off, set the dim to zero
1004
- if (receivedHUEObject.on.on === false && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === "onhueoff")) {
915
+ if (deviceByRef.on.on === false && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === "onhueoff")) {
1005
916
  node.updateKNXBrightnessState(0);
1006
- if (receivedHUEObject.dimming !== undefined) delete receivedHUEObject.dimming; // Remove event.dimming, because has beem handled by this function and i don't want the function below to take care of it.
1007
- } else if (receivedHUEObject.on.on === true && node.currentHUEDevice.on.on === false) {
1008
- let brightVal = 50;
917
+ if (deviceByRef.dimming !== undefined) delete deviceByRef.dimming; // Remove event.dimming, because has beem handled by this function and i don't want the function below to take care of it.
918
+ } else if (deviceByRef.on.on === true && node.currentHUEDevice.on.on === false) {
1009
919
  // Turn on always update the dimming KNX Status value as well.
1010
- if (node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness !== undefined) {
1011
- brightVal = node.currentHUEDevice.dimming.brightness;
1012
- }
920
+ let brightVal = 50;
921
+ if (node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness !== undefined) brightVal = node.currentHUEDevice.dimming.brightness;
1013
922
  node.updateKNXBrightnessState(brightVal);
1014
923
  }
1015
- node.currentHUEDevice.on.on = receivedHUEObject.on.on;
924
+ node.currentHUEDevice.on.on = deviceByRef.on.on;
1016
925
  }
1017
926
 
1018
- if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined) { // fixed https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/287
1019
- node.updateKNXLightColorState(receivedHUEObject.color);
1020
- node.currentHUEDevice.color = receivedHUEObject.color;
927
+ if (deviceByRef.color !== undefined) { // fixed https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/287
928
+ node.updateKNXLightColorState(deviceByRef.color);
929
+ node.currentHUEDevice.color = deviceByRef.color;
1021
930
  }
1022
931
 
1023
- if (receivedHUEObject.dimming !== undefined && receivedHUEObject.dimming.brightness !== undefined) {
932
+ if (deviceByRef.dimming !== undefined && deviceByRef.dimming.brightness !== undefined) {
1024
933
  // Once upon n a time, the light transmit the brightness value of 0.39.
1025
934
  // To avoid wrongly turn light state on, exit
1026
- if (receivedHUEObject.dimming.brightness < 1) receivedHUEObject.dimming.brightness = 0;
1027
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && receivedHUEObject.dimming.brightness === 0) {
935
+ if (deviceByRef.dimming.brightness < 1) deviceByRef.dimming.brightness = 0;
936
+ if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && deviceByRef.dimming.brightness === 0) {
1028
937
  // Do nothing, because the light is off and the dimming also is 0
1029
938
  } else {
1030
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && (receivedHUEObject.on === undefined || (receivedHUEObject.on !== undefined && receivedHUEObject.on.on === true))) node.updateKNXLightState(receivedHUEObject.dimming.brightness > 0);
1031
- node.updateKNXBrightnessState(receivedHUEObject.dimming.brightness);
939
+ if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && (deviceByRef.on === undefined || (deviceByRef.on !== undefined && deviceByRef.on.on === true))) node.updateKNXLightState(deviceByRef.dimming.brightness > 0);
940
+ node.updateKNXBrightnessState(deviceByRef.dimming.brightness);
1032
941
  // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
1033
- if (receivedHUEObject.dimming.brightness === 0 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true) {
942
+ if (deviceByRef.dimming.brightness === 0 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true) {
1034
943
  node.serverHue.hueManager.writeHueQueueAdd(
1035
944
  node.hueDevice,
1036
945
  { on: { on: false } },
@@ -1038,15 +947,14 @@ module.exports = function (RED) {
1038
947
  );
1039
948
  node.currentHUEDevice.on.on = false;
1040
949
  }
1041
- node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness;
950
+ node.currentHUEDevice.dimming.brightness = deviceByRef.dimming.brightness;
1042
951
  }
1043
952
  }
1044
-
1045
- if (receivedHUEObject.color_temperature !== undefined && receivedHUEObject.color_temperature.mirek !== undefined) {
1046
- node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek);
1047
- node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek);
1048
- node.currentHUEDevice.color_temperature.mirek = receivedHUEObject.color_temperature.mirek;
1049
- };
953
+ if (deviceByRef.color_temperature !== undefined && deviceByRef.color_temperature.mirek !== undefined) {
954
+ node.updateKNXLightKelvinPercentageState(deviceByRef.color_temperature.mirek);
955
+ node.updateKNXLightKelvinState(deviceByRef.color_temperature.mirek);
956
+ node.currentHUEDevice.color_temperature.mirek = deviceByRef.color_temperature.mirek;
957
+ }
1050
958
  }
1051
959
  } catch (error) {
1052
960
  node.status({
@@ -1056,163 +964,8 @@ module.exports = function (RED) {
1056
964
  });
1057
965
  RED.log.error(`knxUltimateHueLight: node.handleSendHUE = (_event): ${error.stack}`);
1058
966
  }
1059
- //})();
1060
967
  };
1061
968
 
1062
-
1063
- // node.handleSendHUE = async (_event) => {
1064
- // if (_event === undefined) return;
1065
- // if (_event.type !== 'grouped_light' && _event.type !== 'light') return;
1066
-
1067
- // // if the node is a grouped_light, the only values required, thus present, by HUE apis are "on" and "dimming".
1068
- // // For all others properties like for example color and tunable white, i must get the data from one of the child lights.
1069
- // //(async () => {
1070
- // // Check and set canContinue true or false ------------------------------------------------------------
1071
- // try {
1072
- // if (node.currentHUEDevice === undefined || node.serverHue === null || node.serverHue === undefined) {
1073
- // node.setNodeStatusHue({
1074
- // fill: "red",
1075
- // shape: "ring",
1076
- // text: "Rejected HUE light settings. I'm still not ready...",
1077
- // payload: "",
1078
- // });
1079
- // return;
1080
- // }
1081
-
1082
- // const receivedHUEObject = cloneDeep(_event);
1083
- // let groupChilds = undefined;
1084
- // let AverageColorsXYBrightnessAndTemperature = undefined; // Average color and temp if the node is a grouped light.
1085
- // let canContinue = false;
1086
- // // If the current node is a grouped lights, i must check wether the receivedHUEObject (containing a light) belongs to the node lights collection.
1087
- // if (node.isGrouped_light === true) {
1088
- // try {
1089
- // // Find all the lights in the collection, having the color_temperature capabilities, belonging to the group.
1090
- // if (receivedHUEObject.type === "grouped_light") {
1091
- // groupChilds = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
1092
- // } else {
1093
- // const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
1094
- // groupChilds = [];
1095
- // for (let index = 0; index < devices.length; index++) {
1096
- // const element = devices[index];
1097
- // if (receivedHUEObject.id === element.id) {
1098
- // //if (groupChilds === undefined) groupChilds = [];
1099
- // // groupChilds.push(element);
1100
- // let modifiedLight = cloneDeep(element);
1101
- // if (receivedHUEObject.dimming !== undefined) modifiedLight.dimming = { brightness: receivedHUEObject.dimming.brightness };
1102
- // if (receivedHUEObject.color !== undefined) modifiedLight.color = receivedHUEObject.color;
1103
- // if (receivedHUEObject.color_temperature !== undefined) modifiedLight.color_temperature = receivedHUEObject.color_temperature;
1104
- // groupChilds.push(modifiedLight);
1105
- // } else {
1106
- // // Simply ppend the light
1107
- // groupChilds.push(element);
1108
- // }
1109
- // }
1110
- // }
1111
- // if (groupChilds !== undefined) AverageColorsXYBrightnessAndTemperature = await node.serverHue.getAverageColorsXYBrightnessAndTemperature(groupChilds);
1112
-
1113
- // // Set the new values based on average calculated above
1114
- // try {
1115
- // // Use the arithmetic average of color xy, brightness and color temperature "averageColorXYandKelvinOfGroupedLights"
1116
- // if (receivedHUEObject.color !== undefined && AverageColorsXYBrightnessAndTemperature.x !== undefined) {
1117
- // receivedHUEObject.color = {
1118
- // xy: { x: AverageColorsXYBrightnessAndTemperature.x, y: AverageColorsXYBrightnessAndTemperature.y }
1119
- // };
1120
- // }
1121
- // if (receivedHUEObject.color_temperature !== undefined && AverageColorsXYBrightnessAndTemperature.mirek !== undefined) {
1122
- // receivedHUEObject.color_temperature = { mirek: AverageColorsXYBrightnessAndTemperature.mirek };
1123
- // }
1124
- // if (receivedHUEObject.dimming !== undefined && AverageColorsXYBrightnessAndTemperature.brightness !== undefined) {
1125
- // receivedHUEObject.dimming = { brightness: AverageColorsXYBrightnessAndTemperature.brightness };
1126
- // }
1127
- // } catch (error) { /* empty */ }
1128
-
1129
- // canContinue = true;
1130
- // } catch (error) { /* empty */ }
1131
- // } else {
1132
- // if (receivedHUEObject.type !== "light") return;
1133
- // if (receivedHUEObject.id === node.hueDevice) {
1134
- // canContinue = true;
1135
- // }
1136
- // }
1137
- // // --------------------------------------------------------------------------------------------------
1138
-
1139
- // if (canContinue === true) {
1140
-
1141
- // // Output the msg to the flow
1142
- // node.send(receivedHUEObject);
1143
-
1144
- // // // DEBUG testing enable/disable HTML UI Tabs
1145
- // //delete _event.dimming;
1146
- // //delete _event.color;
1147
- // //delete _event.color_temperature;
1148
- // //delete _event.color_temperature_delta;
1149
-
1150
-
1151
- // if (receivedHUEObject.on !== undefined) {
1152
- // node.updateKNXLightState(receivedHUEObject.on.on);
1153
- // // In case of switch off, set the dim to zero
1154
- // if (receivedHUEObject.on.on === false && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === "onhueoff")) {
1155
- // node.updateKNXBrightnessState(0);
1156
- // if (receivedHUEObject.dimming !== undefined) delete receivedHUEObject.dimming; // Remove event.dimming, because has beem handled by this function and i don't want the function below to take care of it.
1157
- // } else if (receivedHUEObject.on.on === true && node.currentHUEDevice.on.on === false) {
1158
- // let brightVal = 50;
1159
- // if (node.currentHUEDevice.type === "light") {
1160
- // // Turn on always update the dimming KNX Status value as well.
1161
- // if (node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness !== undefined) {
1162
- // brightVal = node.currentHUEDevice.dimming.brightness;
1163
- // }
1164
- // } else if (node.currentHUEDevice.type === "grouped_light") {
1165
- // brightVal = AverageColorsXYBrightnessAndTemperature;
1166
- // }
1167
- // node.updateKNXBrightnessState(brightVal);
1168
- // }
1169
- // node.currentHUEDevice.on.on = receivedHUEObject.on.on;
1170
- // }
1171
-
1172
- // if (receivedHUEObject.color !== undefined) { // fixed https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/287
1173
- // node.updateKNXLightColorState(receivedHUEObject.color);
1174
- // node.currentHUEDevice.color = receivedHUEObject.color;
1175
- // }
1176
-
1177
- // if (receivedHUEObject.dimming !== undefined && receivedHUEObject.dimming.brightness !== undefined) {
1178
- // // Once upon n a time, the light transmit the brightness value of 0.39.
1179
- // // To avoid wrongly turn light state on, exit
1180
- // if (receivedHUEObject.dimming.brightness < 1) receivedHUEObject.dimming.brightness = 0;
1181
- // if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && receivedHUEObject.dimming.brightness === 0) {
1182
- // // Do nothing, because the light is off and the dimming also is 0
1183
- // } else {
1184
- // if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && (receivedHUEObject.on === undefined || (receivedHUEObject.on !== undefined && receivedHUEObject.on.on === true))) node.updateKNXLightState(receivedHUEObject.dimming.brightness > 0);
1185
- // node.updateKNXBrightnessState(receivedHUEObject.dimming.brightness);
1186
- // // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
1187
- // if (receivedHUEObject.dimming.brightness === 0 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true) {
1188
- // node.serverHue.hueManager.writeHueQueueAdd(
1189
- // node.hueDevice,
1190
- // { on: { on: false } },
1191
- // node.isGrouped_light === false ? "setLight" : "setGroupedLight",
1192
- // );
1193
- // node.currentHUEDevice.on.on = false;
1194
- // }
1195
- // node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness;
1196
- // }
1197
- // }
1198
-
1199
- // if (receivedHUEObject.color_temperature !== undefined) {
1200
- // node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek);
1201
- // node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek);
1202
- // node.currentHUEDevice.color_temperature.mirek = receivedHUEObject.color_temperature.mirek;
1203
- // };
1204
- // }
1205
- // } catch (error) {
1206
- // node.status({
1207
- // fill: "red",
1208
- // shape: "dot",
1209
- // text: `HUE->KNX error ${node.id} ${error.message}. Seee Log`,
1210
- // });
1211
- // RED.log.error(`knxUltimateHueLight: node.handleSendHUE = (_event): ${error.stack}`);
1212
- // }
1213
- // //})();
1214
- // };
1215
-
1216
969
  // Leave the name after "function", to avoid <anonymous function> in the stack trace, in caso of errors.
1217
970
  node.updateKNXBrightnessState = function updateKNXBrightnessState(_value, _outputtype = "write") {
1218
971
  if (config.GALightBrightnessState !== undefined && config.GALightBrightnessState !== "") {
@@ -1375,11 +1128,11 @@ module.exports = function (RED) {
1375
1128
  // };
1376
1129
 
1377
1130
  /**
1378
- * Update the KNC colors and HSV states group addresses
1379
- * @param {object} _value {xy:{x,y}} in 0-1 scale
1380
- * @param {string} _outputtype "write" is the default KNX command
1381
- * @returns {}
1382
- */
1131
+ * Update the KNC colors and HSV states group addresses
1132
+ * @param {object} _value {xy:{x,y}} in 0-1 scale
1133
+ * @param {string} _outputtype "write" is the default KNX command
1134
+ * @returns {}
1135
+ */
1383
1136
  node.updateKNXLightColorState = function updateKNXLightColorState(_value, _outputtype = "write") {
1384
1137
  if (config.GALightColorState !== undefined && config.GALightColorState !== "") {
1385
1138
  if (_value.xy === undefined || _value.xy.x === undefined) return;
@@ -1476,8 +1229,8 @@ module.exports = function (RED) {
1476
1229
  knxMsgPayload.topic = config.GALightKelvinState;
1477
1230
  knxMsgPayload.dpt = config.dptLightKelvinState;
1478
1231
  if (config.dptLightKelvinState === "7.600") {
1479
- knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value);
1480
- //knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(kelvinValue, [2000, 6535], [0, 65535]);
1232
+ kelvinValue = hueColorConverter.ColorConverter.mirekToKelvin(_value);
1233
+ knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(kelvinValue, [2000, 6535], [0, 65535]);
1481
1234
  } else if (config.dptLightKelvinState === "9.002") {
1482
1235
  knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value);
1483
1236
  }
@@ -1497,7 +1250,7 @@ module.exports = function (RED) {
1497
1250
  fill: "blue",
1498
1251
  shape: "ring",
1499
1252
  text: "HUE->KNX Kelvin",
1500
- payload: knxMsgPayload.payload,
1253
+ payload: kelvinValue,
1501
1254
  });
1502
1255
  }
1503
1256
  }
@@ -53,6 +53,5 @@ module.exports.fetchFromObject = function fetchFromObject(
53
53
  if (typeof _msg[_payloadPropName] === "object") return undefined;
54
54
  return _msg[_payloadPropName];
55
55
  };
56
-
57
56
  const DEFAULTTRANSLATIONINPUT =
58
57
  "on:true\noff:false\nactive:true\ninactive:false\nopen:true\nclosed:false\nclose:false\n1:true\n0:false\ntrue:true\nfalse:false\nhome:true\nnot_home:false\nnormal:false\nviolated:true";
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.4.26",
6
+ "version": "2.4.28",
7
7
  "description": "Control your KNX intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control and ETS group address importer. Easy to use and highly configurable.",
8
8
  "dependencies": {
9
9
  "binary-parser": "2.2.1",