node-red-contrib-knx-ultimate 2.2.26 → 2.2.27

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,12 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 2.2.27** - November 2023<br/>
10
+ This is an interim version, to quick fix some issues. Please report any issue with HUE Nodes, on gitHub.<br/>
11
+ - HUE Light: the UI now changes, to adapt to lamp type.<br/>
12
+ - HUE Light: "Get current" color button, now works for grouped light as well, by reading the first light belongin to the group.<br/>
13
+ - WARNING: the new HUE Light options are to be considered **BETA (= in testing with user feedback)**.<br/>
14
+
9
15
  **Version 2.2.26** - November 2023<br/>
10
16
  This is an interim version, to quick fix some issues. Please report any issue with HUE Nodes, on gitHub.<br/>
11
17
  - HUE Light: fixed some spurious node status errors.<br/>
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-underscore-dangle */
1
2
  /* eslint-disable no-lonely-if */
2
3
  /* eslint-disable no-param-reassign */
3
4
  /* eslint-disable no-inner-declarations */
@@ -170,7 +171,7 @@ module.exports = (RED) => {
170
171
  // Query the HUE Bridge to return the resources
171
172
  node.loadResourcesFromHUEBridge = async () => {
172
173
  if (node.linkStatus === "disconnected") return;
173
- //(async () => {
174
+ // (async () => {
174
175
  // °°°°°° Load ALL resources
175
176
  try {
176
177
  node.hueAllResources = await node.hueManager.hueApiV2.get("/resource");
@@ -226,24 +227,19 @@ module.exports = (RED) => {
226
227
  node.getFirstLightInGroup = function getFirstLightInGroup(_groupID) {
227
228
  if (node.hueAllResources === undefined || node.hueAllResources === null) return;
228
229
  try {
229
- // Find the group
230
230
  const group = node.hueAllResources.filter((a) => a.id === _groupID)[0];
231
- if (group === null || group === undefined) return;
232
231
  const owner = node.hueAllResources.filter((a) => a.id === group.owner.rid)[0];
233
- if (owner.children !== undefined && owner.children.length > 0) {
234
- const firstLightId = owner.children.find((a) => a.rtype === "light").rid;
235
- if (firstLightId !== undefined && firstLightId !== null) {
236
- const firstLight = node.hueAllResources.find((a) => a.id === firstLightId);
237
- if (firstLight !== null && firstLight !== undefined) {
238
- return firstLight;
239
- } else {
240
- return;
241
- }
232
+ if (owner.children !== undefined) {
233
+ const dev = node.hueAllResources.filter((a) => a.id === owner.children[0].rid)[0];
234
+ if (dev.type === "device" && dev.services !== undefined) {
235
+ const lightID = dev.services.filter((a) => a.rtype === 'light')[0].rid;
236
+ const oLight = node.hueAllResources.filter((a) => a.id === lightID)[0];
237
+ return oLight;
238
+ } else if (dev.type === "light") {
239
+ return dev;
242
240
  }
243
241
  }
244
- } catch (error) {
245
-
246
- }
242
+ } catch (error) { }
247
243
  };
248
244
 
249
245
  // Returns the cached devices (node.hueAllResources) by type.
@@ -445,18 +441,64 @@ module.exports = (RED) => {
445
441
 
446
442
  RED.httpAdmin.get("/knxUltimateGetHueColor", RED.auth.needsPermission("hue-config.read"), (req, res) => {
447
443
  try {
448
- const hexColor = node.getColorFromHueLight(req.query.id);
449
- res.json(hexColor);
444
+ // find wether the light is a light or is grouped_light
445
+ let hexColor;
446
+ const _oDevice = node.hueAllResources.filter((a) => a.id === req.query.id)[0];
447
+ if (_oDevice.type === "light") {
448
+ hexColor = node.getColorFromHueLight(req.query.id);
449
+ } else {
450
+ // grouped_light, get the first light in the group
451
+ const oLight = node.getFirstLightInGroup(_oDevice.id);
452
+ hexColor = node.getColorFromHueLight(oLight.id);
453
+ }
454
+ res.json(hexColor !== undefined ? hexColor : "Select the device first!");
450
455
  } catch (error) {
451
456
  res.json("Select the device first!");
452
457
  }
453
458
  });
454
459
  RED.httpAdmin.get("/knxUltimateGetKelvinColor", RED.auth.needsPermission("hue-config.read"), (req, res) => {
455
460
  try {
456
- const jKelvin = node.getKelvinFromHueLight(req.query.id);
457
- res.json(jKelvin);
461
+ // find wether the light is a light or is grouped_light
462
+ let kelvinValue;
463
+ const _oDevice = node.hueAllResources.filter((a) => a.id === req.query.id)[0];
464
+ if (_oDevice.type === "light") {
465
+ kelvinValue = node.getKelvinFromHueLight(req.query.id);
466
+ } else {
467
+ // grouped_light, get the first light in the group
468
+ const oLight = node.getFirstLightInGroup(_oDevice.id);
469
+ kelvinValue = node.getKelvinFromHueLight(oLight.id);
470
+ }
471
+ res.json(kelvinValue !== undefined ? kelvinValue : "Select the device first!");
458
472
  } catch (error) {
459
473
  res.json("Select the device first!");
474
+ };
475
+ });
476
+
477
+ RED.httpAdmin.get("/knxUltimateGetLightObject", RED.auth.needsPermission("hue-config.read"), (req, res) => {
478
+ try {
479
+ const _lightId = req.query.id;
480
+ const oLight = node.hueAllResources.filter((a) => a.id === _lightId)[0];
481
+ // Infer some useful info, so the HTML part cann avoid to query the server
482
+ // Kelvin
483
+ try {
484
+ if (oLight.color_temperature !== undefined && oLight.color_temperature.mirek !== undefined) {
485
+ oLight.calculatedKelvin = hueColorConverter.ColorConverter.mirekToKelvin(oLight.color_temperature.mirek);
486
+ }
487
+ } catch (error) {
488
+ oLight.calculatedKelvin = undefined;
489
+ }
490
+ // HEX value from XYBri
491
+ try {
492
+ const retRGB = hueColorConverter.ColorConverter.xyBriToRgb(oLight.color.xy.x, oLight.color.xy.y, oLight.dimming.brightness);
493
+ const ret = "#" + hueColorConverter.ColorConverter.rgbHex(retRGB.r, retRGB.g, retRGB.b).toString();
494
+ oLight.calculatedHEXColor = ret;
495
+ } catch (error) {
496
+ oLight.calculatedHEXColor = undefined;
497
+ }
498
+ res.json(oLight);
499
+ } catch (error) {
500
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`KNXUltimateHue: hueEngine: knxUltimateGetLightObject: error ${error.message}`);
501
+ res.json({});
460
502
  }
461
503
  });
462
504
 
@@ -486,6 +528,15 @@ module.exports = (RED) => {
486
528
  }
487
529
  });
488
530
 
531
+ RED.httpAdmin.get("/knxUltimateGetFirstLightInGroup", RED.auth.needsPermission("hue-config.read"), (req, res) => {
532
+ try {
533
+ res.json(node.getFirstLightInGroup(req.query.id));
534
+ } catch (error) {
535
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`KNXUltimateHue: hueEngine: knxUltimateGetFirstLightInGroup: error ${error.message}`);
536
+ res.json({});
537
+ }
538
+ });
539
+
489
540
  RED.httpAdmin.get("/knxUltimateDpts", RED.auth.needsPermission("hue-config.read"), (req, res) => {
490
541
  try {
491
542
  const dpts = Object.entries(dptlib).filter(onlyDptKeys).map(extractBaseNo).sort(sortBy("base")).reduce(toConcattedSubtypes, []);
@@ -1,108 +1,14 @@
1
1
  <!-- <script type="application/javascript;charset=utf-8" src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
2
2
  <script type="application/javascript;charset=utf-8" src="https://cdn.jsdelivr.net/npm/@jaames/iro@5"></script> -->
3
+
4
+ 'use strict'
3
5
  <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script>
4
6
 
5
7
  <script type="text/javascript">
8
+ (function () {
6
9
 
7
- RED.nodes.registerType("knxUltimateHueLight", {
8
- category: "KNX Ultimate",
9
- color: "#C0C7E9",
10
- defaults: {
11
- //buttonState: {value: true},
12
- server: { type: "knxUltimate-config", required: false },
13
- serverHue: { type: "hue-config", required: true },
14
- name: { value: "" },
15
-
16
- nameLightSwitch: { value: "" },
17
- GALightSwitch: { value: "" },
18
- dptLightSwitch: { value: "" },
19
-
20
- nameLightState: { value: "" },
21
- GALightState: { value: "" },
22
- dptLightState: { value: "" },
23
-
24
- nameLightDIM: { value: "" },
25
- GALightDIM: { value: "" },
26
- dptLightDIM: { value: "" },
27
-
28
- nameLightColor: { value: "" },
29
- GALightColor: { value: "" },
30
- dptLightColor: { value: "" },
31
-
32
- nameLightColorState: { value: "" },
33
- GALightColorState: { value: "" },
34
- dptLightColorState: { value: "" },
35
-
36
- nameLightHSV: { value: "" },
37
- GALightHSV: { value: "" },
38
- dptLightHSV: { value: "" },
39
-
40
- nameLightHSVPercentage: { value: "" },
41
- GALightHSVPercentage: { value: "" },
42
- dptLightHSVPercentage: { value: "" },
43
-
44
- nameLightHSVState: { value: "" },
45
- GALightHSVState: { value: "" },
46
- dptLightHSVState: { value: "" },
47
-
48
- nameLightBrightness: { value: "" },
49
- GALightBrightness: { value: "" },
50
- dptLightBrightness: { value: "" },
51
-
52
- nameLightBrightnessState: { value: "" },
53
- GALightBrightnessState: { value: "" },
54
- dptLightBrightnessState: { value: "" },
55
-
56
- nameLightBlink: { value: "" },
57
- GALightBlink: { value: "" },
58
- dptLightBlink: { value: "" },
59
-
60
- nameLightColorCycle: { value: "" },
61
- GALightColorCycle: { value: "" },
62
- dptLightColorCycle: { value: "" },
63
-
64
- nameDaylightSensor: { value: "" },
65
- GADaylightSensor: { value: "" },
66
- dptDaylightSensor: { value: "" },
67
-
68
- nameLightKelvin: { value: "" },
69
- GALightKelvin: { value: "" },
70
- dptLightKelvin: { value: "" },
71
-
72
- nameLightKelvinState: { value: "" },
73
- GALightKelvinState: { value: "" },
74
- dptLightKelvinState: { value: "" },
75
-
76
- specifySwitchOnBrightness: { value: "temperature" },
77
- colorAtSwitchOnDayTime: { value: '{"kelvin":3000, "brightness":100 }' },
78
-
79
- enableDayNightLighting: { value: "no" },
80
- colorAtSwitchOnNightTime: { value: '{ "kelvin":2700, "brightness":20 }' },
81
-
82
- invertDayNight: { value: false },
83
-
84
- updateKNXBrightnessStatusOnHUEOnOff: { value: "no" },
85
- dimSpeed: { value: 5000, required: false },
86
- minDimLevelLight: { value: 10, required: false },
87
- maxDimLevelLight: { value: 100, required: false },
88
- readStatusAtStartup: { value: "yes" },
89
- enableNodePINS: { value: "no" },
90
-
91
- outputs: { value: 0 },
92
- inputs: { value: 0 },
93
-
94
- hueDevice: { value: "" },
95
- hueDeviceObject: { value: {} },
96
- },
97
- inputs: 0,
98
- outputs: 0,
99
- icon: "node-hue-icon.svg",
100
- label: function () {
101
- return this.name;
102
- },
103
- paletteLabel: "Hue Light (beta)",
104
- oneditprepare: function () {
105
- var node = this;
10
+ function onEditPrepare(node) {
11
+ // var node = node;
106
12
  var oNodeServer = RED.nodes.node($("#node-input-server").val()); // Store the config-node
107
13
  var oNodeServerHue = RED.nodes.node($("#node-input-serverHue").val()); // Store the config-node
108
14
 
@@ -134,19 +40,19 @@
134
40
  // 19/02/2020 Used to get the server sooner als deploy.
135
41
  $("#node-input-server").change(function () {
136
42
  try {
137
- oNodeServer = RED.nodes.node($(this).val());
43
+ oNodeServer = RED.nodes.node($(node).val());
138
44
  } catch (error) { }
139
45
  });
140
46
  // 19/02/2020 Used to get the server sooner als deploy.
141
47
  $("#node-input-serverHue").change(function () {
142
48
  try {
143
- oNodeServerHue = RED.nodes.node($(this).val());
49
+ oNodeServerHue = RED.nodes.node($(node).val());
144
50
  } catch (error) { }
145
51
  });
146
52
 
147
53
  // 31/03/2020 Search Helper
148
54
  function fullSearch(sourceText, searchString) {
149
- // This searches for all words in a string
55
+ // node searches for all words in a string
150
56
  var aSearchWords = searchString.toLowerCase().split(" ");
151
57
  var i = 0;
152
58
  for (let index = 0; index < aSearchWords.length; index++) {
@@ -158,6 +64,7 @@
158
64
  function getDPT(_dpt, _destinationWidget) {
159
65
  // DPT Switch command
160
66
  // ########################
67
+ $(_destinationWidget).empty();
161
68
  $.getJSON("knxUltimateDpts", (data) => {
162
69
  data.forEach((dpt) => {
163
70
  if (dpt.value.startsWith(_dpt)) {
@@ -172,7 +79,7 @@
172
79
  }
173
80
  });
174
81
  // Eval
175
- const format = "this." + _destinationWidget.replace("#node-input-", "");
82
+ const format = "node." + _destinationWidget.replace("#node-input-", "");
176
83
  try {
177
84
  if (format !== undefined) $(_destinationWidget).val(eval(format).toString());
178
85
  } catch (error) { }
@@ -267,57 +174,138 @@
267
174
  getGroupAddress("#node-input-GALightKelvinState", "#node-input-nameLightKelvinState", "#node-input-dptLightKelvinState", " 9.002");
268
175
 
269
176
 
177
+ // Get the HUE capabilities to enable/disable UI parts
178
+ $.getJSON("knxUltimateGetLightObject?id=" + $("#node-input-hueDevice").val().split("#")[0], (data) => {
179
+ let oLight = data;
180
+ // Check if grouped, to hide/show the "Get current" buttons
181
+ if (oLight.type === "grouped_light") {
182
+ $("#tabs").tabs("enable", "#tabs-4");
183
+ $("#tabs").tabs("enable", "#tabs-3");
184
+ $("#tabs").tabs("enable", "#tabs-2");
185
+ $("#getColorAtSwitchOnDayTimeButton").show();
186
+ $("#getColorAtSwitchOnNightTimeButton").show();
187
+ $("#node-input-specifySwitchOnBrightness").empty().append(
188
+ $("<option>")
189
+ .val("no")
190
+ .text("Last status")
191
+ ).append(
192
+ $("<option>")
193
+ .val("yes")
194
+ .text("Select color")
195
+ ).append(
196
+ $("<option>")
197
+ .val("temperature")
198
+ .text("Select temperature and brightness")
199
+ );
200
+ $("#node-input-enableDayNightLighting").empty().append(
201
+ $("<option>")
202
+ .val("no")
203
+ .text("No")
204
+ ).append(
205
+ $("<option>")
206
+ .val("yes")
207
+ .text("Select color")
208
+ ).append(
209
+ $("<option>")
210
+ .val("temperature")
211
+ .text("Select temperature and brightness")
212
+ );
213
+ $("#node-input-specifySwitchOnBrightness").val(node.specifySwitchOnBrightness).trigger('change');
214
+ $("#node-input-enableDayNightLighting").val(node.enableDayNightLighting).trigger('change');
215
+ return;
216
+ } else {
270
217
 
271
- // Autocomplete suggestion with HUE Lights
272
- $("#node-input-name").autocomplete({
273
- minLength: 1,
274
- source: function (request, response) {
275
- $.getJSON("KNXUltimateGetResourcesHUE?rtype=light&nodeID=" + oNodeServerHue.id, (data) => {
276
- response(
277
- $.map(data.devices, function (value, key) {
278
- //alert(JSON.stringify(value) + " "+ key)
279
- var sSearch = value.name;
280
- if (!value.name.includes("I'm still connecting")) {
281
- if (fullSearch(sSearch, request.term)) {
282
- return {
283
- hueDevice: value.id,
284
- value: value.name,
285
- };
286
- } else {
287
- return null;
288
- }
289
- } else {
290
- return {
291
- hueDevice: value.id,
292
- value: value.name,
293
- };
294
- }
295
- })
296
- );
297
- });
298
- },
299
- select: function (event, ui) {
300
- // Distinguish between group of lights an single light.
301
- if (ui.item.value.toLowerCase().startsWith("grouped_light")) {
302
- $("#node-input-hueDevice").val(ui.item.hueDevice + "#grouped_light");
303
- $("#getColorAtSwitchOnDayTimeButton").hide();
304
- $("#getColorAtSwitchOnNightTimeButton").hide();
305
- } else {
306
- $("#node-input-hueDevice").val(ui.item.hueDevice + "#light");
307
- $("#getColorAtSwitchOnDayTimeButton").show();
308
- $("#getColorAtSwitchOnNightTimeButton").show();
309
- }
310
- $("#tabs").show();
311
- },
218
+ $("#getColorAtSwitchOnDayTimeButton").show();
219
+ $("#getColorAtSwitchOnNightTimeButton").show();
220
+ $("#node-input-specifySwitchOnBrightness").empty().append(
221
+ $("<option>")
222
+ .val("no")
223
+ .text("Last status")
224
+ );
225
+ $("#node-input-enableDayNightLighting").empty().append(
226
+ $("<option>")
227
+ .val("no")
228
+ .text("No")
229
+ );
230
+ }
231
+ $("#tabs").tabs("disable", "#tabs-4");
232
+ $("#tabs").tabs("disable", "#tabs-3");
233
+ $("#tabs").tabs("disable", "#tabs-2");
234
+ $("#divColorsAtSwitchOn").hide();
235
+ $("#divColorsAtSwitchOnNightTime").hide();
236
+ $("#divTemperatureAtSwitchOn").hide();
237
+ $("#divTemperatureAtSwitchOnNightTime").hide();
238
+ $("#divColorCycle").hide();
239
+ $("#divUpdateKNXBrightnessStatusOnHUEOnOff").hide();
240
+ $("#divMinMaxBrightness").hide();
241
+ $("#comboTemperatureAtSwitchOn").hide();
242
+ $("#comboTemperatureAtSwitchOnNightTime").hide();
243
+
244
+ // Enable options/tabs one by one
245
+ if (oLight.color !== undefined) {
246
+ $("#tabs").tabs("enable", "#tabs-4");
247
+ $("#divColorsAtSwitchOn").show();
248
+ $("#divColorsAtSwitchOnNightTime").show();
249
+ $("#divColorCycle").show();
250
+ $("#node-input-specifySwitchOnBrightness").append(
251
+ $("<option>")
252
+ .val("yes")
253
+ .text("Select color")
254
+ );
255
+ $("#node-input-enableDayNightLighting").append(
256
+ $("<option>")
257
+ .val("yes")
258
+ .text("Select color")
259
+ );
260
+ }
261
+ // Check temperature (if the light supports temperature, it support dimming as well)
262
+ if (oLight.color_temperature !== undefined) {
263
+ $("#tabs").tabs("enable", "#tabs-3");
264
+ $("#tabs").tabs("enable", "#tabs-2");
265
+ $("#node-input-specifySwitchOnBrightness").append(
266
+ $("<option>")
267
+ .val("temperature")
268
+ .text("Select temperature and brightness")
269
+ );
270
+ $("#node-input-enableDayNightLighting").append(
271
+ $("<option>")
272
+ .val("temperature")
273
+ .text("Select temperature and brightness")
274
+ );
275
+ $("#divTemperatureAtSwitchOn").show();
276
+ $("#divTemperatureAtSwitchOnNightTime").show();
277
+ $("#divUpdateKNXBrightnessStatusOnHUEOnOff").show();
278
+ $("#divMinMaxBrightness").show();
279
+ $("#comboTemperatureAtSwitchOn").show();
280
+ $("#comboTemperatureAtSwitchOnNightTime").show();
281
+ } else {
282
+ $("#tabs").tabs("enable", "#tabs-2");
283
+ $("#node-input-specifySwitchOnBrightness").append(
284
+ $("<option>")
285
+ .val("temperature")
286
+ .text("Select brightness")
287
+ );
288
+ $("#node-input-enableDayNightLighting").append(
289
+ $("<option>")
290
+ .val("temperature")
291
+ .text("Select brightness")
292
+ );
293
+ $("#comboTemperatureAtSwitchOn").val(0);
294
+ $("#comboTemperatureAtSwitchOnNightTime").val(0);
295
+ $("#divTemperatureAtSwitchOn").show();
296
+ $("#divTemperatureAtSwitchOnNightTime").show();
297
+ $("#divUpdateKNXBrightnessStatusOnHUEOnOff").show();
298
+ $("#divMinMaxBrightness").show();
299
+ }
300
+ $("#node-input-specifySwitchOnBrightness").val(node.specifySwitchOnBrightness).trigger('change');
301
+ $("#node-input-enableDayNightLighting").val(node.enableDayNightLighting).trigger('change');
312
302
  });
313
303
 
314
-
315
-
316
304
  // Show/Hide the div of the color at swich on
317
- if (this.specifySwitchOnBrightness === "yes") {
305
+ if (node.specifySwitchOnBrightness === "yes") {
318
306
  $("#divColorsAtSwitchOn").show();
319
307
  $("#divTemperatureAtSwitchOn").hide();
320
- } else if (this.specifySwitchOnBrightness === "temperature") {
308
+ } else if (node.specifySwitchOnBrightness === "temperature") {
321
309
  $("#divColorsAtSwitchOn").hide();
322
310
  $("#divTemperatureAtSwitchOn").show();
323
311
  } else {
@@ -340,12 +328,12 @@
340
328
  });
341
329
 
342
330
  // Show/Hide and enable/disable day/night Lighting behaviour
343
- if (this.enableDayNightLighting === "yes") {
331
+ if (node.enableDayNightLighting === "yes") {
344
332
  $("#divEnableDayNightLighting").show();
345
333
  $("#divCCSBoxAtNightLighting").css({ border: "1px solid dimgrey", "border-radius": "12px", padding: "5px" }); // Add little box to better understand the property page
346
334
  $("#divColorsAtSwitchOnNightTime").show();
347
335
  $("#divTemperatureAtSwitchOnNightTime").hide();
348
- } else if (this.enableDayNightLighting === "temperature") {
336
+ } else if (node.enableDayNightLighting === "temperature") {
349
337
  $("#divEnableDayNightLighting").show();
350
338
  $("#divCCSBoxAtNightLighting").css({ border: "1px solid dimgrey", "border-radius": "12px", padding: "5px" }); // Add little box to better understand the property page
351
339
  $("#divColorsAtSwitchOnNightTime").hide();
@@ -374,79 +362,6 @@
374
362
  }
375
363
  });
376
364
 
377
-
378
- // Get the HUE capabilities to enable/disable UI parts
379
- $.getJSON("KNXUltimateGetResourcesHUE?rtype=light&nodeID=" + oNodeServerHue.id, (data) => {
380
- data.devices.forEach((element) => {
381
- if (element.id === this.hueDevice.split("#")[0] && element.deviceObject !== undefined) {
382
-
383
- // Check color
384
- if (element.deviceObject.color_temperature === undefined) $("#tabs").tabs("disable", "#tabs-3");
385
- if (element.deviceObject.color === undefined || JSON.stringify(deviceObject.color) === "{}") {
386
- $("#tabs").tabs("disable", "#tabs-4");
387
- $("#divColorsAtSwitchOn").hide();
388
- $("#divColorCycle").hide();
389
- $("#node-input-specifySwitchOnBrightness").empty().append(
390
- $("<option>")
391
- .val("no")
392
- .text("Last status")
393
- ).append(
394
- $("<option>")
395
- .val("temperature")
396
- .text("Select temperature and brightness")
397
- );
398
- $("#node-input-specifySwitchOnBrightness").val(this.specifySwitchOnBrightness).trigger('change');
399
-
400
- $("#node-input-enableDayNightLighting").empty().append(
401
- $("<option>")
402
- .val("no")
403
- .text("Last status")
404
- ).append(
405
- $("<option>")
406
- .val("temperature")
407
- .text("Select temperature and brightness")
408
- );
409
- $("#node-input-enableDayNightLighting").val(this.enableDayNightLighting).trigger('change');
410
- }
411
-
412
- // Check dimming
413
- if (element.deviceObject.dimming === undefined) {
414
- $("#tabs").tabs("disable", "#tabs-2");
415
- $("#divColorsAtSwitchOn").hide();
416
- $("#divColorCycle").hide();
417
- $("#divUpdateKNXBrightnessStatusOnHUEOnOff").hide();
418
- $("#divCCSBoxAtNightLighting").hide();
419
- $("#node-input-specifySwitchOnBrightness").val("no");
420
- $("#node-input-enableDayNightLighting").val("no");
421
- $("#divMinMaxBrightness").hide();
422
- $("#node-input-specifySwitchOnBrightness").empty().append(
423
- $("<option>")
424
- .val("no")
425
- .text("Last status")
426
- )
427
- $("#node-input-specifySwitchOnBrightness").val(this.specifySwitchOnBrightness).trigger('change');
428
-
429
- $("#node-input-enableDayNightLighting").empty().append(
430
- $("<option>")
431
- .val("no")
432
- .text("Last status")
433
- )
434
- }
435
- $("#node-input-enableDayNightLighting").val(this.enableDayNightLighting).trigger('change');
436
-
437
- // Check if grouped, to hide/show the "Get current" buttons
438
- if (element.deviceObject.type === "grouped_light") {
439
- $("#getColorAtSwitchOnDayTimeButton").hide();
440
- $("#getColorAtSwitchOnNightTimeButton").hide();
441
- } else {
442
- $("#getColorAtSwitchOnDayTimeButton").show();
443
- $("#getColorAtSwitchOnNightTimeButton").show();
444
- }
445
- return;
446
- }
447
- });
448
- });
449
-
450
365
  $("#getColorAtSwitchOnDayTimeButton").on("click", function () {
451
366
  $("#getColorAtSwitchOnDayTimeButton").text("Wait...");
452
367
  let jRet;
@@ -476,7 +391,7 @@
476
391
  });
477
392
 
478
393
  // Fill options for minDimLevel and maxDimLevel and comboBrightnessAtSwitchOn (for color brightness at switch on, with temperature toghedher)
479
- for (let index = 0; index <= 100; index += 5) {
394
+ for (let index = 100; index >= 0; index -= 5) {
480
395
  if (index === 0) {
481
396
  $("#node-input-minDimLevelLight").append($("<option>").val(index).text(index.toString() + "% (Switch Off)"));
482
397
  $("#comboBrightnessAtSwitchOn").append($("<option>").val(index).text(index.toString() + "% (Switch Off)"));
@@ -519,18 +434,18 @@
519
434
 
520
435
  // Calculate kelvin/color
521
436
  let json;
522
- this.colorAtSwitchOnDayTime = this.colorAtSwitchOnDayTime.replace("geen", "green"); // Old bug in "geen" property
523
- this.colorAtSwitchOnNightTime = this.colorAtSwitchOnNightTime.replace("geen", "green"); // Old bug in "geen" property
437
+ node.colorAtSwitchOnDayTime = node.colorAtSwitchOnDayTime.replace("geen", "green"); // Old bug in "geen" property
438
+ node.colorAtSwitchOnNightTime = node.colorAtSwitchOnNightTime.replace("geen", "green"); // Old bug in "geen" property
524
439
  try {
525
- json = JSON.parse(this.colorAtSwitchOnDayTime);
440
+ json = JSON.parse(node.colorAtSwitchOnDayTime);
526
441
  } catch (error) {
527
- console.log("json = JSON.parse(this.colorAtSwitchOnDayTime) in HTML: " + error.message)
442
+ console.log("json = JSON.parse(node.colorAtSwitchOnDayTime) in HTML: " + error.message)
528
443
  }
529
444
  if (json !== undefined && json.kelvin !== undefined) {
530
445
  // Kelvin
531
446
  $("#comboTemperatureAtSwitchOn").val(json.kelvin);
532
447
  $("#comboBrightnessAtSwitchOn").val(json.brightness);
533
- if (this.specifySwitchOnBrightness !== 'no') $("#node-input-specifySwitchOnBrightness").val('temperature'); // Adjust in case of mismatch (from old geen bug)
448
+ if (node.specifySwitchOnBrightness !== 'no') $("#node-input-specifySwitchOnBrightness").val('temperature'); // Adjust in case of mismatch (from old geen bug)
534
449
  } else if (json !== undefined && json.red !== undefined) {
535
450
  // Must transform RGB into HTML HEX color
536
451
  try {
@@ -538,22 +453,22 @@
538
453
  } catch (error) {
539
454
  }
540
455
  $("#colorPickerDay").val($("#node-input-colorAtSwitchOnDayTime").val());
541
- if (this.specifySwitchOnBrightness !== 'no') $("#node-input-specifySwitchOnBrightness").val('yes'); // Adjust in case of mismatch (from old geen bug)
456
+ if (node.specifySwitchOnBrightness !== 'no') $("#node-input-specifySwitchOnBrightness").val('yes'); // Adjust in case of mismatch (from old geen bug)
542
457
  } else {
543
458
  // It's already an HEX color
544
- $("#colorPickerDay").val(this.colorAtSwitchOnDayTime);
545
- if (this.specifySwitchOnBrightness !== 'no') $("#node-input-specifySwitchOnBrightness").val('yes'); // Adjust in case of mismatch (from old geen bug)
459
+ $("#colorPickerDay").val(node.colorAtSwitchOnDayTime);
460
+ if (node.specifySwitchOnBrightness !== 'no') $("#node-input-specifySwitchOnBrightness").val('yes'); // Adjust in case of mismatch (from old geen bug)
546
461
  }
547
462
  //Night
548
463
  json = undefined;
549
464
  try {
550
- json = JSON.parse(this.colorAtSwitchOnNightTime);
465
+ json = JSON.parse(node.colorAtSwitchOnNightTime);
551
466
  } catch (error) { }
552
467
  if (json !== undefined && json.kelvin !== undefined) {
553
468
  // Kelvin
554
469
  $("#comboTemperatureAtSwitchOnNightTime").val(json.kelvin);
555
470
  $("#comboBrightnessAtSwitchOnNightTime").val(json.brightness);
556
- if (this.enableDayNightLighting !== 'no') $("#node-input-enableDayNightLighting").val('temperature'); // Adjust in case of mismatch (from old geen bug)
471
+ if (node.enableDayNightLighting !== 'no') $("#node-input-enableDayNightLighting").val('temperature'); // Adjust in case of mismatch (from old geen bug)
557
472
  } else if (json !== undefined && json.red !== undefined) {
558
473
  // Must transform RGB into HTML HEX color
559
474
  try {
@@ -561,11 +476,11 @@
561
476
  } catch (error) {
562
477
  }
563
478
  $("#colorPickerNight").val($("#node-input-colorAtSwitchOnNightTime").val());
564
- if (this.enableDayNightLighting !== 'no') $("#node-input-enableDayNightLighting").val('yes'); // Adjust in case of mismatch (from old geen bug)
479
+ if (node.enableDayNightLighting !== 'no') $("#node-input-enableDayNightLighting").val('yes'); // Adjust in case of mismatch (from old geen bug)
565
480
  } else {
566
481
  // It's already an HEX color
567
- $("#colorPickerNight").val(this.colorAtSwitchOnNightTime);
568
- if (this.enableDayNightLighting !== 'no') $("#node-input-enableDayNightLighting").val('yes'); // Adjust in case of mismatch (from old geen bug)
482
+ $("#colorPickerNight").val(node.colorAtSwitchOnNightTime);
483
+ if (node.enableDayNightLighting !== 'no') $("#node-input-enableDayNightLighting").val('yes'); // Adjust in case of mismatch (from old geen bug)
569
484
  }
570
485
 
571
486
 
@@ -585,7 +500,7 @@
585
500
  });
586
501
 
587
502
 
588
- $("#node-input-minDimLevelLight").val(this.minDimLevelLight);
503
+ $("#node-input-minDimLevelLight").val(node.minDimLevelLight);
589
504
  for (let index = 100; index >= 10; index--) {
590
505
  $("#node-input-maxDimLevelLight").append(
591
506
  $("<option>")
@@ -593,106 +508,248 @@
593
508
  .text(index.toString() + "%")
594
509
  );
595
510
  }
596
- $("#node-input-maxDimLevelLight").val(this.maxDimLevelLight);
597
-
598
- if (this.hueDevice !== "") $("#tabs").show(); // Light options
511
+ $("#node-input-maxDimLevelLight").val(node.maxDimLevelLight);
599
512
 
600
- },
601
- oneditsave: function () {
602
- //RED.sidebar.removeTab("tabNRColor");
603
- //RED.sidebar.show("help");
604
- if ($("#node-input-enableNodePINS").val() === "yes") {
605
- this.outputs = 1;
606
- this.inputs = 1;
607
- } else {
608
- this.outputs = 0;
609
- this.inputs = 0;
610
- }
611
- },
612
- oneditcancel: function () {
613
- //RED.sidebar.removeTab("tabNRColor");
614
- //RED.sidebar.show("help");
615
- }
616
- });
513
+ if (node.hueDevice !== "") $("#tabs").show(); // Light options
617
514
 
618
515
 
619
516
 
517
+ // Autocomplete suggestion with HUE Lights
518
+ $("#node-input-name").autocomplete({
519
+ minLength: 1,
520
+ source: function (request, response) {
521
+ $.getJSON("KNXUltimateGetResourcesHUE?rtype=light&nodeID=" + oNodeServerHue.id, (data) => {
522
+ response(
523
+ $.map(data.devices, function (value, key) {
524
+ //alert(JSON.stringify(value) + " "+ key)
525
+ var sSearch = value.name;
526
+ if (!value.name.includes("I'm still connecting")) {
527
+ if (fullSearch(sSearch, request.term)) {
528
+ return {
529
+ hueDevice: value.id,
530
+ value: value.name,
531
+ };
532
+ } else {
533
+ return null;
534
+ }
535
+ } else {
536
+ return {
537
+ hueDevice: value.id,
538
+ value: value.name,
539
+ };
540
+ }
541
+ })
542
+ );
543
+ });
544
+ },
545
+ select: function (event, ui) {
546
+ // Distinguish between group of lights an single light.
547
+ if (ui.item.value.toLowerCase().startsWith("grouped_light")) {
548
+ $("#node-input-hueDevice").val(ui.item.hueDevice + "#grouped_light");
549
+ } else {
550
+ $("#node-input-hueDevice").val(ui.item.hueDevice + "#light");
551
+ }
552
+ onEditPrepare(node);
553
+ $("#tabs").show();
554
+ },
555
+ });
556
+ }
620
557
 
621
- function rgbHex(red, green, blue, alpha) {
622
- const toHex = (red, green, blue, alpha) => ((blue | green << 8 | red << 16) | 1 << 24).toString(16).slice(1) + alpha;
623
- const parseCssRgbString = (input) => {
624
- const parts = input.replace(/rgba?\(([^)]+)\)/, '$1').split(/[,\s/]+/).filter(Boolean);
625
- if (parts.length < 3) {
626
- return;
558
+ RED.nodes.registerType("knxUltimateHueLight", {
559
+ category: "KNX Ultimate",
560
+ color: "#C0C7E9",
561
+ defaults: {
562
+ //buttonState: {value: true},
563
+ server: { type: "knxUltimate-config", required: false },
564
+ serverHue: { type: "hue-config", required: true },
565
+ name: { value: "" },
566
+
567
+ nameLightSwitch: { value: "" },
568
+ GALightSwitch: { value: "" },
569
+ dptLightSwitch: { value: "" },
570
+
571
+ nameLightState: { value: "" },
572
+ GALightState: { value: "" },
573
+ dptLightState: { value: "" },
574
+
575
+ nameLightDIM: { value: "" },
576
+ GALightDIM: { value: "" },
577
+ dptLightDIM: { value: "" },
578
+
579
+ nameLightColor: { value: "" },
580
+ GALightColor: { value: "" },
581
+ dptLightColor: { value: "" },
582
+
583
+ nameLightColorState: { value: "" },
584
+ GALightColorState: { value: "" },
585
+ dptLightColorState: { value: "" },
586
+
587
+ nameLightHSV: { value: "" },
588
+ GALightHSV: { value: "" },
589
+ dptLightHSV: { value: "" },
590
+
591
+ nameLightHSVPercentage: { value: "" },
592
+ GALightHSVPercentage: { value: "" },
593
+ dptLightHSVPercentage: { value: "" },
594
+
595
+ nameLightHSVState: { value: "" },
596
+ GALightHSVState: { value: "" },
597
+ dptLightHSVState: { value: "" },
598
+
599
+ nameLightBrightness: { value: "" },
600
+ GALightBrightness: { value: "" },
601
+ dptLightBrightness: { value: "" },
602
+
603
+ nameLightBrightnessState: { value: "" },
604
+ GALightBrightnessState: { value: "" },
605
+ dptLightBrightnessState: { value: "" },
606
+
607
+ nameLightBlink: { value: "" },
608
+ GALightBlink: { value: "" },
609
+ dptLightBlink: { value: "" },
610
+
611
+ nameLightColorCycle: { value: "" },
612
+ GALightColorCycle: { value: "" },
613
+ dptLightColorCycle: { value: "" },
614
+
615
+ nameDaylightSensor: { value: "" },
616
+ GADaylightSensor: { value: "" },
617
+ dptDaylightSensor: { value: "" },
618
+
619
+ nameLightKelvin: { value: "" },
620
+ GALightKelvin: { value: "" },
621
+ dptLightKelvin: { value: "" },
622
+
623
+ nameLightKelvinState: { value: "" },
624
+ GALightKelvinState: { value: "" },
625
+ dptLightKelvinState: { value: "" },
626
+
627
+ specifySwitchOnBrightness: { value: "temperature" },
628
+ colorAtSwitchOnDayTime: { value: '{"kelvin":3000, "brightness":100 }' },
629
+
630
+ enableDayNightLighting: { value: "no" },
631
+ colorAtSwitchOnNightTime: { value: '{ "kelvin":2700, "brightness":20 }' },
632
+
633
+ invertDayNight: { value: false },
634
+
635
+ updateKNXBrightnessStatusOnHUEOnOff: { value: "no" },
636
+ dimSpeed: { value: 5000, required: false },
637
+ minDimLevelLight: { value: 10, required: false },
638
+ maxDimLevelLight: { value: 100, required: false },
639
+ readStatusAtStartup: { value: "yes" },
640
+ enableNodePINS: { value: "no" },
641
+
642
+ outputs: { value: 0 },
643
+ inputs: { value: 0 },
644
+
645
+ hueDevice: { value: "" },
646
+ hueDeviceObject: { value: {} },
647
+ },
648
+ inputs: 0,
649
+ outputs: 0,
650
+ icon: "node-hue-icon.svg",
651
+ label: function () {
652
+ return this.name;
653
+ },
654
+ paletteLabel: "Hue Light (beta)",
655
+ oneditprepare: function () {
656
+ onEditPrepare(this);
657
+ },
658
+ oneditsave: function () {
659
+ //RED.sidebar.removeTab("tabNRColor");
660
+ //RED.sidebar.show("help");
661
+ if ($("#node-input-enableNodePINS").val() === "yes") {
662
+ this.outputs = 1;
663
+ this.inputs = 1;
664
+ } else {
665
+ this.outputs = 0;
666
+ this.inputs = 0;
667
+ }
668
+ },
669
+ oneditcancel: function () {
670
+ //RED.sidebar.removeTab("tabNRColor");
671
+ //RED.sidebar.show("help");
627
672
  }
673
+ });
674
+
628
675
 
629
- const parseValue = (value, max) => {
630
- value = value.trim();
631
676
 
632
- if (value.endsWith('%')) {
633
- return Math.min(Number.parseFloat(value) * max / 100, max);
677
+
678
+ function rgbHex(red, green, blue, alpha) {
679
+ const toHex = (red, green, blue, alpha) => ((blue | green << 8 | red << 16) | 1 << 24).toString(16).slice(1) + alpha;
680
+ const parseCssRgbString = (input) => {
681
+ const parts = input.replace(/rgba?\(([^)]+)\)/, '$1').split(/[,\s/]+/).filter(Boolean);
682
+ if (parts.length < 3) {
683
+ return;
634
684
  }
635
685
 
636
- return Math.min(Number.parseFloat(value), max);
637
- };
686
+ const parseValue = (value, max) => {
687
+ value = value.trim();
638
688
 
639
- const red = parseValue(parts[0], 255);
640
- const green = parseValue(parts[1], 255);
641
- const blue = parseValue(parts[2], 255);
642
- let alpha;
689
+ if (value.endsWith('%')) {
690
+ return Math.min(Number.parseFloat(value) * max / 100, max);
691
+ }
643
692
 
644
- if (parts.length === 4) {
645
- alpha = parseValue(parts[3], 1);
646
- }
693
+ return Math.min(Number.parseFloat(value), max);
694
+ };
647
695
 
648
- return [red, green, blue, alpha];
649
- };
696
+ const red = parseValue(parts[0], 255);
697
+ const green = parseValue(parts[1], 255);
698
+ const blue = parseValue(parts[2], 255);
699
+ let alpha;
650
700
 
651
- let isPercent = (red + (alpha || '')).toString().includes('%');
701
+ if (parts.length === 4) {
702
+ alpha = parseValue(parts[3], 1);
703
+ }
704
+
705
+ return [red, green, blue, alpha];
706
+ };
707
+
708
+ let isPercent = (red + (alpha || '')).toString().includes('%');
652
709
 
653
- if (typeof red === 'string' && !green) { // Single string parameter.
654
- const parsed = parseCssRgbString(red);
655
- if (!parsed) {
656
- throw new TypeError('Invalid or unsupported color format.');
710
+ if (typeof red === 'string' && !green) { // Single string parameter.
711
+ const parsed = parseCssRgbString(red);
712
+ if (!parsed) {
713
+ throw new TypeError('Invalid or unsupported color format.');
714
+ }
715
+
716
+ isPercent = false;
717
+ [red, green, blue, alpha] = parsed;
718
+ } else if (alpha !== undefined) {
719
+ alpha = Number.parseFloat(alpha);
657
720
  }
658
721
 
659
- isPercent = false;
660
- [red, green, blue, alpha] = parsed;
661
- } else if (alpha !== undefined) {
662
- alpha = Number.parseFloat(alpha);
663
- }
722
+ if (typeof red !== 'number'
723
+ || typeof green !== 'number'
724
+ || typeof blue !== 'number'
725
+ || red > 255
726
+ || green > 255
727
+ || blue > 255
728
+ ) {
729
+ throw new TypeError('Expected three numbers below 256');
730
+ }
664
731
 
665
- if (typeof red !== 'number'
666
- || typeof green !== 'number'
667
- || typeof blue !== 'number'
668
- || red > 255
669
- || green > 255
670
- || blue > 255
671
- ) {
672
- throw new TypeError('Expected three numbers below 256');
673
- }
732
+ if (typeof alpha === 'number') {
733
+ if (!isPercent && alpha >= 0 && alpha <= 1) {
734
+ alpha = Math.round(255 * alpha);
735
+ } else if (isPercent && alpha >= 0 && alpha <= 100) {
736
+ alpha = Math.round(255 * alpha / 100);
737
+ } else {
738
+ throw new TypeError(`Expected alpha value (${alpha}) as a fraction or percentage`);
739
+ }
674
740
 
675
- if (typeof alpha === 'number') {
676
- if (!isPercent && alpha >= 0 && alpha <= 1) {
677
- alpha = Math.round(255 * alpha);
678
- } else if (isPercent && alpha >= 0 && alpha <= 100) {
679
- alpha = Math.round(255 * alpha / 100);
741
+ alpha = (alpha | 1 << 8).toString(16).slice(1); // eslint-disable-line no-mixed-operators
680
742
  } else {
681
- throw new TypeError(`Expected alpha value (${alpha}) as a fraction or percentage`);
743
+ alpha = '';
682
744
  }
683
745
 
684
- alpha = (alpha | 1 << 8).toString(16).slice(1); // eslint-disable-line no-mixed-operators
685
- } else {
686
- alpha = '';
746
+ return toHex(red, green, blue, alpha);
687
747
  }
688
748
 
689
- return toHex(red, green, blue, alpha);
690
- }
691
-
749
+ }())
692
750
 
693
751
  </script>
694
752
 
695
-
696
753
  <script type="text/html" data-template-name="knxUltimateHueLight">
697
754
 
698
755
  <div class="form-row">
@@ -1003,9 +1060,9 @@
1003
1060
  <i class="fa fa-tag"></i> Switch on behaviour
1004
1061
  </label>
1005
1062
  <select id="node-input-specifySwitchOnBrightness">
1006
- <option value="temperature">Select temperature and brightness</option>
1007
- <option value="yes">Select color</option>
1008
1063
  <option value="no">Last status</option>
1064
+ <!-- <option value="temperature">Select temperature and brightness</option>
1065
+ <option value="yes">Select color</option> -->
1009
1066
  </select>
1010
1067
  </div>
1011
1068
 
@@ -1019,8 +1076,8 @@
1019
1076
  <div class="form-row" id="divTemperatureAtSwitchOn" hidden>
1020
1077
  <label for="node-input-colorAtSwitchOnDayTime" style="width:260px">
1021
1078
  </label>
1022
- <select style="width:180px;" id="comboTemperatureAtSwitchOn"></select>
1023
- <select style="width:180px;" id="comboBrightnessAtSwitchOn"></select>
1079
+ <select style="width:12%;" id="comboTemperatureAtSwitchOn"></select>
1080
+ <select style="width:25%;" id="comboBrightnessAtSwitchOn"></select>
1024
1081
  </div>
1025
1082
 
1026
1083
  <div id="divCCSBoxAtNightLighting">
@@ -1029,9 +1086,9 @@
1029
1086
  <i class="fa fa-clone"></i> Night Lighting
1030
1087
  </label>
1031
1088
  <select id="node-input-enableDayNightLighting">
1032
- <option value="temperature">Select temperature and brightness</option>
1033
- <option value="yes">Select color</option>
1034
1089
  <option value="no">No night lighting</option>
1090
+ <!-- <option value="temperature">Select temperature and brightness</option>
1091
+ <option value="yes">Select color</option> -->
1035
1092
  </select>
1036
1093
  </div>
1037
1094
 
@@ -1110,7 +1167,10 @@
1110
1167
  <br />
1111
1168
  </script>
1112
1169
 
1170
+
1113
1171
  <script type="text/markdown" data-help-name="knxUltimateHueLight">
1172
+
1173
+
1114
1174
  <p>This node lets you control your Philips HUE light and grouped lights and also gets the states of this lights, to be sent to the KNX bus.</p>
1115
1175
 
1116
1176
  **General**
@@ -1194,4 +1254,4 @@ The Dimming function works in **KNX mode `start` and `stop`**. To start dimming,
1194
1254
  [Find it useful?](https://www.paypal.me/techtoday)
1195
1255
 
1196
1256
  <br/>
1197
- </script>-
1257
+ </script>
@@ -99,36 +99,56 @@ module.exports = function (RED) {
99
99
  case config.GALightSwitch:
100
100
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightSwitch));
101
101
  if (msg.payload === true) {
102
- // Check wether the user selected specific color/brightness at switch on.
103
- let jColorChoosen = null;
104
- if (node.DayTime === true && (config.specifySwitchOnBrightness === "yes" || config.specifySwitchOnBrightness === "temperature")) {
105
- jColorChoosen = config.colorAtSwitchOnDayTime;
106
- } else if (node.DayTime === false && (config.enableDayNightLighting === "yes" || config.enableDayNightLighting === "temperature")) {
107
- jColorChoosen = config.colorAtSwitchOnNightTime;
102
+ let colorChoosen;
103
+ let temperatureChoosen;
104
+ let brightnessChoosen;
105
+ // The light must support the temperature (in this case, colorAtSwitchOnNightTime is an object {kelvin:xx, brightness:yy})
106
+ if (node.currentHUEDevice.color_temperature !== undefined) {
107
+ if (node.DayTime === true && config.specifySwitchOnBrightness === "temperature") {
108
+ temperatureChoosen = config.colorAtSwitchOnDayTime.kelvin;
109
+ } else if (node.DayTime === false && config.enableDayNightLighting === "temperature") {
110
+ temperatureChoosen = config.colorAtSwitchOnNightTime.kelvin;
111
+ }
112
+ }
113
+ if (node.currentHUEDevice.dimming !== undefined) {
114
+ // Check wether the user selected specific brightness at switch on (in this case, colorAtSwitchOnNightTime is an object {kelvin:xx, brightness:yy})
115
+ if (node.DayTime === true && config.specifySwitchOnBrightness === "temperature") {
116
+ brightnessChoosen = config.colorAtSwitchOnDayTime.brightness;
117
+ } else if (node.DayTime === false && config.enableDayNightLighting === "temperature") {
118
+ brightnessChoosen = config.colorAtSwitchOnNightTime.brightness;
119
+ }
120
+ }
121
+ if (node.currentHUEDevice.color !== undefined) {
122
+ // Check wether the user selected specific color at switch on (in this case, colorAtSwitchOnDayTime is a text with HTML web color)
123
+ if (node.DayTime === true && config.specifySwitchOnBrightness === "yes") {
124
+ colorChoosen = config.colorAtSwitchOnDayTime;
125
+ } else if (node.DayTime === false && config.enableDayNightLighting === "yes") {
126
+ colorChoosen = config.colorAtSwitchOnNightTime;
127
+ }
108
128
  }
109
129
 
110
- // Now we have a jColorChoosen. Proceed illuminating the light
111
- if (jColorChoosen !== null && jColorChoosen.kelvin === undefined) {
112
- // RGB
130
+ if (colorChoosen !== undefined) {
131
+ // Now we have a jColorChoosen. Proceed illuminating the light
113
132
  let gamut = null;
114
- if (node.currentHUEDevice !== undefined && node.currentHUEDevice.hasOwnProperty("color") && node.currentHUEDevice.color.hasOwnProperty("gamut_type")) {
133
+ if (node.currentHUEDevice.color.gamut_type !== undefined) {
115
134
  gamut = node.currentHUEDevice.color.gamut_type;
116
135
  }
117
- const dretXY = hueColorConverter.ColorConverter.rgbToXy(jColorChoosen.red, jColorChoosen.green, jColorChoosen.blue, gamut);
118
- const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(jColorChoosen.red, jColorChoosen.green, jColorChoosen.blue);
136
+ const dretXY = hueColorConverter.ColorConverter.rgbToXy(colorChoosen.red, colorChoosen.green, colorChoosen.blue, gamut);
137
+ const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(colorChoosen.red, colorChoosen.green, colorChoosen.blue);
119
138
  node.currentHUEDevice.dimming.brightness = Math.round(dbright, 0);
120
139
  node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
121
140
  state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } };
122
- } if (jColorChoosen !== null && jColorChoosen.kelvin !== undefined) {
141
+ } else if (temperatureChoosen !== undefined) {
123
142
  // Kelvin
124
- const dbright = jColorChoosen.brightness;
125
- const mirek = hueColorConverter.ColorConverter.kelvinToMirek(jColorChoosen.kelvin);
143
+ const mirek = hueColorConverter.ColorConverter.kelvinToMirek(temperatureChoosen);
126
144
  node.currentHUEDevice.color_temperature.mirek = mirek;
127
- node.currentHUEDevice.dimming.brightness = dbright;
145
+ node.currentHUEDevice.dimming.brightness = brightnessChoosen;
128
146
  node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
129
147
  // Kelvin temp
130
- state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color_temperature: { mirek: mirek } } : { on: { on: false } };
131
- } else if (jColorChoosen === null || jColorChoosen === undefined) {
148
+ state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek: mirek } } : { on: { on: false } };
149
+ } else if (brightnessChoosen !== undefined) {
150
+ state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen } } : { on: { on: false } };
151
+ } else {
132
152
  state = { on: { on: true } };
133
153
  }
134
154
  } else {
@@ -506,10 +526,10 @@ module.exports = function (RED) {
506
526
  try {
507
527
  const firstLightInGroup = node.serverHue.getFirstLightInGroup(_event.id);
508
528
  if (firstLightInGroup !== null && firstLightInGroup !== undefined) {
509
- if (_event.color === undefined || Object.keys(_event.color).length === 0) {
529
+ if (_event.color === undefined) {
510
530
  _event.color = firstLightInGroup.color;
511
531
  }
512
- if (_event.color_temperature === undefined || Object.keys(_event.color_temperature).length === 0) {
532
+ if (_event.color_temperature === undefined) {
513
533
  _event.color_temperature = firstLightInGroup.color_temperature;
514
534
  }
515
535
  }
@@ -537,7 +557,7 @@ module.exports = function (RED) {
537
557
  }
538
558
 
539
559
  if (_event.hasOwnProperty("dimming") && _event.dimming.brightness !== undefined) {
540
- // Every once on a time, the light transmit the brightness value of 0.39.
560
+ // Once upon n a time, the light transmit the brightness value of 0.39.
541
561
  // To avoid wrongly turn light state on, exit
542
562
  if (_event.dimming.brightness < 1) _event.dimming.brightness = 0;
543
563
  if (node.currentHUEDevice.hasOwnProperty("on") && node.currentHUEDevice.on.on === false && _event.dimming.brightness === 0) {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.2.26",
6
+ "version": "2.2.27",
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",