node-red-contrib-knx-ultimate 2.1.63 → 2.2.1

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.
@@ -1,3 +1,5 @@
1
+ /* eslint-disable no-param-reassign */
2
+ /* eslint-disable camelcase */
1
3
  /* eslint-disable max-len */
2
4
  /* eslint-disable no-lonely-if */
3
5
  module.exports = function (RED) {
@@ -32,12 +34,16 @@ module.exports = function (RED) {
32
34
  node.currentKNXGALightState = false; // Stores the current KNX value for the GA
33
35
  node.DayTime = true;
34
36
  node.isGrouped_light = config.hueDevice.split("#")[1] === "grouped_light";
35
- config.hueDevice = config.hueDevice.split("#")[0];
37
+ node.hueDevice = config.hueDevice.split("#")[0];
36
38
 
37
39
  // Used to call the status update from the config node.
38
- node.setNodeStatus = ({ fill, shape, text, payload }) => { };
40
+ node.setNodeStatus = ({
41
+ fill, shape, text, payload,
42
+ }) => { };
39
43
  // Used to call the status update from the HUE config node.
40
- node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
44
+ node.setNodeStatusHue = ({
45
+ fill, shape, text, payload,
46
+ }) => {
41
47
  if (payload === undefined) return;
42
48
  const dDate = new Date();
43
49
  payload = typeof payload === "object" ? JSON.stringify(payload) : payload.toString();
@@ -48,7 +54,7 @@ module.exports = function (RED) {
48
54
  fill: "grey",
49
55
  shape: "ring",
50
56
  text: "Connecting to the Bridge...",
51
- payload: ""
57
+ payload: "",
52
58
  });
53
59
 
54
60
  // This function is called by the hue-config.js
@@ -58,7 +64,7 @@ module.exports = function (RED) {
58
64
  fill: "red",
59
65
  shape: "ring",
60
66
  text: "Rejected KNX message. I'm connecting to the Bridge...",
61
- payload: ""
67
+ payload: "",
62
68
  });
63
69
  return;
64
70
  }
@@ -104,7 +110,7 @@ module.exports = function (RED) {
104
110
  } else {
105
111
  state = { on: { on: false } };
106
112
  }
107
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
113
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
108
114
  node.setNodeStatusHue({
109
115
  fill: "green",
110
116
  shape: "dot",
@@ -116,22 +122,8 @@ module.exports = function (RED) {
116
122
  // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
117
123
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
118
124
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM));
119
- if (msg.payload.data > 0) {
120
- const dimDirection = msg.payload.decr_incr === 1 ? "up" : "down";
121
- // First, switch on the light if off
122
- if (node.currentHUEDevice.hasOwnProperty('on') !== undefined && node.currentHUEDevice.on.on === false && dimDirection === "up") {
123
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, { on: { on: true } }, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
124
- }
125
- node.startDimStopper(dimDirection);
126
- } else {
127
- node.startDimStopper("stop");
128
- }
129
- node.setNodeStatusHue({
130
- fill: "green",
131
- shape: "dot",
132
- text: "KNX->HUE",
133
- payload: msg.payload,
134
- });
125
+ node.hueDimming(msg.payload.decr_incr, msg.payload.data, config.dimSpeed);
126
+ node.setNodeStatusHue({ fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload) });
135
127
  break;
136
128
  case config.GADaylightSensor:
137
129
  if (config.enableDayNightLighting === "yes") {
@@ -153,19 +145,9 @@ module.exports = function (RED) {
153
145
  // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
154
146
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
155
147
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightHSV));
156
- if (msg.payload.data > 0) {
157
- const dimDirectionTunableWhite = msg.payload.decr_incr === 1 ? "up" : "down";
158
- node.startDimStopperTunableWhite(dimDirectionTunableWhite);
159
- } else {
160
- node.startDimStopperTunableWhite("stop");
161
- }
148
+ node.hueDimmingTunableWhite(msg.payload.decr_incr, msg.payload.data, config.dimSpeed);
149
+ node.setNodeStatusHue({ fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload) });
162
150
  }
163
- node.setNodeStatusHue({
164
- fill: "green",
165
- shape: "dot",
166
- text: "KNX->HUE",
167
- payload: msg.payload,
168
- });
169
151
  break;
170
152
  case config.GALightHSVPercentage:
171
153
  if (config.dptLightHSVPercentage === "5.001") {
@@ -175,7 +157,7 @@ module.exports = function (RED) {
175
157
  const retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [0, 100], [153, 500]);
176
158
  msg.payload = retMirek;
177
159
  state = { color_temperature: { mirek: msg.payload } };
178
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
160
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
179
161
  node.setNodeStatusHue({
180
162
  fill: "green",
181
163
  shape: "dot",
@@ -201,7 +183,7 @@ module.exports = function (RED) {
201
183
  if (node.currentHUEDevice.on.on === false && msg.payload > 0) state.on = { on: true };
202
184
  if (node.currentHUEDevice.on.on === true && msg.payload === 0) state.on = { on: false };
203
185
  }
204
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
186
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
205
187
  node.setNodeStatusHue({
206
188
  fill: "green",
207
189
  shape: "dot",
@@ -231,7 +213,7 @@ module.exports = function (RED) {
231
213
  if (node.currentHUEDevice.on.on === false && bright > 0) state.on = { on: true };
232
214
  if (node.currentHUEDevice.on.on === true && bright === 0) state = { on: { on: false }, dimming: { brightness: bright } };
233
215
  }
234
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
216
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
235
217
  node.setNodeStatusHue({
236
218
  fill: "green",
237
219
  shape: "dot",
@@ -250,14 +232,14 @@ module.exports = function (RED) {
250
232
  state = msg.payload === true
251
233
  ? { on: { on: true }, dimming: { brightness: 100 }, dynamics: { duration: 0 } }
252
234
  : { on: { on: false }, dimming: { brightness: 0 }, dynamics: { duration: 0 } };
253
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
235
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
254
236
  }, 1000);
255
237
  } else {
256
238
  if (node.timerBlink !== undefined) clearInterval(node.timerBlink);
257
239
  node.serverHue.hueManager.writeHueQueueAdd(
258
- config.hueDevice,
240
+ node.hueDevice,
259
241
  { on: { on: false } },
260
- node.isGrouped_light === false ? "setLight" : "setGroupedLight"
242
+ node.isGrouped_light === false ? "setLight" : "setGroupedLight",
261
243
  );
262
244
  }
263
245
  node.setNodeStatusHue({
@@ -272,9 +254,9 @@ module.exports = function (RED) {
272
254
  const gaValColorCycle = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColorCycle));
273
255
  if (gaValColorCycle === true) {
274
256
  node.serverHue.hueManager.writeHueQueueAdd(
275
- config.hueDevice,
257
+ node.hueDevice,
276
258
  { on: { on: true } },
277
- node.isGrouped_light === false ? "setLight" : "setGroupedLight"
259
+ node.isGrouped_light === false ? "setLight" : "setGroupedLight",
278
260
  );
279
261
  node.timerColorCycle = setInterval(() => {
280
262
  try {
@@ -297,15 +279,15 @@ module.exports = function (RED) {
297
279
  const retXY = hueColorConverter.ColorConverter.rgbToXy(red, green, blue, gamut);
298
280
  const bright = hueColorConverter.ColorConverter.getBrightnessFromRGB(red, green, blue);
299
281
  state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } };
300
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
282
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
301
283
  } catch (error) { }
302
284
  }, 10000);
303
285
  } else {
304
286
  if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
305
287
  node.serverHue.hueManager.writeHueQueueAdd(
306
- config.hueDevice,
288
+ node.hueDevice,
307
289
  { on: { on: false } },
308
- node.isGrouped_light === false ? "setLight" : "setGroupedLight"
290
+ node.isGrouped_light === false ? "setLight" : "setGroupedLight",
309
291
  );
310
292
  }
311
293
  node.setNodeStatusHue({
@@ -329,80 +311,95 @@ module.exports = function (RED) {
329
311
 
330
312
  // Start dimming
331
313
  // ***********************************************************
332
- node.timerDim = undefined;
333
- node.dimDirection = {};
334
- node.timeoutDim = 0;
335
- node.startDimStopper = function (_direction) {
336
- node.timeoutDim = 0;
337
- if (node.timerDim !== undefined) clearInterval(node.timerDim);
338
- if (_direction === "stop") {
314
+ node.hueDimming = function hueDimming(_KNXaction, _KNXbrightness_delta, _dimSpeedInMillisecs = undefined) {
315
+ let dimDirection = 'stop';
316
+ let hueTelegram = {};
317
+ _dimSpeedInMillisecs = (_dimSpeedInMillisecs === undefined || _dimSpeedInMillisecs === '') ? 5000 : _dimSpeedInMillisecs;
318
+ let delta = 0;
319
+ const minDimLevelLight = config.minDimLevelLight === undefined ? 3 : config.minDimLevelLight;
320
+ const maxDimLevelLight = config.maxDimLevelLight === undefined ? 100 : config.maxDimLevelLight;
321
+
322
+ // We have also minDimLevelLight and maxDimLevelLight to take care of.
323
+
324
+ if (_KNXbrightness_delta === 0 && _KNXaction === 0) {
325
+ dimDirection = 'stop';
326
+ hueTelegram = { dimming_delta: { action: dimDirection } };
327
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
339
328
  return;
340
329
  }
341
- switch (_direction) {
342
- case "up":
343
- node.dimDirection = { dimming_delta: { action: "up", brightness_delta: 10 } };
344
- break;
345
- case "down":
346
- node.dimDirection = { dimming_delta: { action: "down", brightness_delta: 10 } };
347
- break;
348
- default:
349
- break;
330
+ if (_KNXbrightness_delta > 0 && _KNXaction === 1) {
331
+ delta = 100 - Math.round(node.currentHUEDevice.dimming.brightness, 0) - (100 - Number(maxDimLevelLight));
332
+ dimDirection = 'up';
350
333
  }
351
- node.timerDim = setInterval(() => {
352
- node.timeoutDim += 1;
353
- if (node.timeoutDim > 150) {
354
- node.timeoutDim = 0;
355
- clearInterval(node.timerDim);
356
- }
357
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, node.dimDirection, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
358
- }, 700);
334
+ if (_KNXbrightness_delta > 0 && _KNXaction === 0) {
335
+ // Set the minumum delta, taking care of the minimum brightness specified either in the HUE lamp itself, or specified by the user (parameter node.minDimLevelLight)
336
+ delta = Math.round(node.currentHUEDevice.dimming.brightness, 0) - (minDimLevelLight === 'useHueLightLevel' ? node.currentHUEDevice.dimming.min_dim_level : Number(minDimLevelLight));
337
+ dimDirection = 'down';
338
+ }
339
+ // Calculate the dimming time based on delta
340
+ // 10000:x=100:delta
341
+ // x = (10000 * delta) / 100
342
+ _dimSpeedInMillisecs = Math.round((_dimSpeedInMillisecs * delta) / 100, 0);
343
+
344
+ hueTelegram = { dimming_delta: { action: dimDirection, brightness_delta: delta }, dynamics: { duration: _dimSpeedInMillisecs } };
345
+ // Switch on the light if off
346
+ if (node.currentHUEDevice.hasOwnProperty('on') !== undefined && node.currentHUEDevice.on.on === false && dimDirection === "up") {
347
+ hueTelegram.on = { on: true };
348
+ }
349
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
359
350
  };
360
351
  // ***********************************************************
361
352
 
362
353
  // Start dimming tunable white
363
354
  // mirek: required(integer minimum: 153, maximum: 500)
364
355
  // ***********************************************************
365
- node.timerDimTunableWhite = undefined;
366
- node.dimDirectionTunableWhite = {};
367
- node.timeoutDimTunableWhite = 0;
368
- node.startDimStopperTunableWhite = function (_direction) {
369
- node.timeoutDimTunableWhite = 0;
370
- if (node.timerDimTunableWhite !== undefined) clearInterval(node.timerDimTunableWhite);
371
- if (_direction === "stop") return;
372
- switch (_direction) {
373
- case "up":
374
- node.dimDirectionTunableWhite = { color_temperature_delta: { action: "up", mirek_delta: 10 } };
375
- break;
376
- case "down":
377
- node.dimDirectionTunableWhite = { color_temperature_delta: { action: "down", mirek_delta: 10 } };
378
- break;
379
- default:
380
- break;
356
+ node.hueDimmingTunableWhite = function hueDimming(_KNXaction, _KNXbrightness_delta, _dimSpeedInMillisecs = undefined) {
357
+ let dimDirection = 'stop';
358
+ let hueTelegram = {};
359
+ _dimSpeedInMillisecs = (_dimSpeedInMillisecs === undefined || _dimSpeedInMillisecs === '') ? 5000 : _dimSpeedInMillisecs;
360
+ let delta = 0;
361
+ if (!node.currentHUEDevice.color_temperature.hasOwnProperty("mirek")) delta = 347 - Math.round(173, 0); // Unable to read the mirek, set medium as default
362
+ // We have also minDimLevelLight and maxDimLevelLight to take care of.
363
+ // Mirek limits are not taken in consideration.
364
+ // Maximum mirek is 347
365
+ if (_KNXbrightness_delta === 0 && _KNXaction === 0) {
366
+ dimDirection = 'stop';
367
+ hueTelegram = { color_temperature_delta: { action: dimDirection } };
368
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
369
+ return;
381
370
  }
382
- node.timerDimTunableWhite = setInterval(() => {
383
- node.timeoutDimTunableWhite += 1;
384
- if (node.timeoutDimTunableWhite > 150) {
385
- node.timeoutDimTunableWhite = 0;
386
- clearInterval(node.timerDimTunableWhite);
387
- }
388
- node.serverHue.hueManager.writeHueQueueAdd(
389
- config.hueDevice,
390
- node.dimDirectionTunableWhite,
391
- node.isGrouped_light === false ? "setLight" : "setGroupedLight"
392
- );
393
- }, 700);
371
+ if (_KNXbrightness_delta > 0 && _KNXaction === 1) {
372
+ if (node.currentHUEDevice.color_temperature.hasOwnProperty("mirek")) delta = 347 - Math.round(node.currentHUEDevice.color_temperature.mirek, 0);
373
+ dimDirection = 'up';
374
+ }
375
+ if (_KNXbrightness_delta > 0 && _KNXaction === 0) {
376
+ // Set the minumum delta, taking care of the minimum brightness specified either in the HUE lamp itself, or specified by the user (parameter node.minDimLevelLight)
377
+ if (node.currentHUEDevice.color_temperature.hasOwnProperty("mirek")) delta = Math.round(node.currentHUEDevice.color_temperature.mirek, 0);
378
+ dimDirection = 'down';
379
+ }
380
+ // Calculate the dimming time based on delta
381
+ // 10000:x=347:delta
382
+ // x = (10000 * delta) / 347
383
+ _dimSpeedInMillisecs = Math.round((_dimSpeedInMillisecs * delta) / 347, 0);
384
+
385
+ hueTelegram = { color_temperature_delta: { action: dimDirection, mirek_delta: delta }, dynamics: { duration: _dimSpeedInMillisecs } };
386
+ // Switch on the light if off
387
+ if (node.currentHUEDevice.hasOwnProperty('on') !== undefined && node.currentHUEDevice.on.on === false && dimDirection === "up") {
388
+ hueTelegram.on = { on: true };
389
+ }
390
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
394
391
  };
395
392
  // ***********************************************************
396
393
 
397
394
  node.handleSendHUE = (_event) => {
398
395
  try {
399
- if (_event.id === config.hueDevice) {
396
+ if (_event.id === node.hueDevice) {
400
397
  if (node.currentHUEDevice === undefined) {
401
398
  node.setNodeStatusHue({
402
399
  fill: "red",
403
400
  shape: "ring",
404
401
  text: "Rejected HUE message. I'm connecting to the Bridge...",
405
- payload: ""
402
+ payload: "",
406
403
  });
407
404
  return;
408
405
  }
@@ -419,13 +416,9 @@ module.exports = function (RED) {
419
416
  /* empty */
420
417
  }
421
418
  }
422
- if (node.currentHUEDevice !== undefined) node.currentHUEDevice.on = _event.on; // Update the internal object representing the current light
423
- return;
424
419
  }
425
420
  if (_event.hasOwnProperty("color")) {
426
421
  node.updateKNXLightColorState(_event.color);
427
- if (node.currentHUEDevice !== undefined) node.currentHUEDevice.color = _event.color; // Update the internal object representing the current light
428
- return;
429
422
  }
430
423
  if (_event.hasOwnProperty("dimming")) {
431
424
  // Every once on a time, the light transmit the brightness value of 0.39.
@@ -434,29 +427,42 @@ module.exports = function (RED) {
434
427
  if (node.currentHUEDevice.hasOwnProperty('on') && node.currentHUEDevice.on.on === false && _event.dimming.brightness === 0) return;
435
428
  if (node.currentHUEDevice.on.on === false) node.updateKNXLightState(_event.dimming.brightness > 0);
436
429
  node.updateKNXBrightnessState(_event.dimming.brightness);
437
- if (node.currentHUEDevice !== undefined) node.currentHUEDevice.dimming = _event.dimming; // Update the internal object representing the current light
438
430
  // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
439
431
  if (_event.dimming.brightness === 0) {
440
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, { on: { on: false } }, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
432
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, { on: { on: false } }, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
441
433
  }
442
- return;
443
434
  }
444
435
  if (_event.hasOwnProperty("color_temperature")) {
445
436
  node.updateKNXLightHSVState(_event.color_temperature.mirek);
446
- if (node.currentHUEDevice !== undefined) node.currentHUEDevice.color_temperature = _event.color_temperature; // Update the internal object representing the current light
447
- return;
448
437
  }
438
+
439
+ // Update the current HUE Device with the new _event
440
+ function copiaOggettoRicorsivo(objDestinazione, objOrigine) {
441
+ for (const prop in objOrigine) {
442
+ if (typeof objOrigine[prop] === "object" && objOrigine[prop] !== null) {
443
+ // Se la proprietà è un oggetto, copiamola in modo ricorsivo
444
+ objDestinazione[prop] = objDestinazione[prop] || {};
445
+ copiaOggettoRicorsivo(objDestinazione[prop], objOrigine[prop]);
446
+ } else {
447
+ // Altrimenti, copia il valore della proprietà
448
+ objDestinazione[prop] = objOrigine[prop];
449
+ }
450
+ }
451
+ }
452
+ // Copia l'oggettoOrigine nell'oggettoDestinazione mantenendo le proprietà esistenti
453
+ copiaOggettoRicorsivo(node.currentHUEDevice, _event);
449
454
  }
450
455
  } catch (error) {
451
456
  node.status({
452
457
  fill: "red",
453
458
  shape: "dot",
454
- text: 'HUE->KNX error ' + node.id + ' ' + error.message
459
+ text: `HUE->KNX error ${node.id} ${error.message}`,
455
460
  });
456
461
  }
457
462
  };
458
463
 
459
- node.updateKNXBrightnessState = function (_value) {
464
+ // Leave the name after "function", to avoid <anonymous function> in the stack trace, in caso of errors.
465
+ node.updateKNXBrightnessState = function updateKNXBrightnessState(_value) {
460
466
  if (config.GALightBrightnessState !== undefined && config.GALightBrightnessState !== "") {
461
467
  const knxMsgPayload = {};
462
468
  knxMsgPayload.topic = config.GALightBrightnessState;
@@ -480,7 +486,8 @@ module.exports = function (RED) {
480
486
  });
481
487
  }
482
488
  };
483
- node.updateKNXLightState = function (_value) {
489
+
490
+ node.updateKNXLightState = function updateKNXBrightnessState(_value) {
484
491
  try {
485
492
  const knxMsgPayload = {};
486
493
  knxMsgPayload.topic = config.GALightState;
@@ -513,7 +520,7 @@ module.exports = function (RED) {
513
520
  }
514
521
  };
515
522
 
516
- node.updateKNXLightHSVState = function (_value) {
523
+ node.updateKNXLightHSVState = function updateKNXLightState(_value) {
517
524
  if (config.GALightHSVState !== undefined && config.GALightHSVState !== "") {
518
525
  const knxMsgPayload = {};
519
526
  knxMsgPayload.topic = config.GALightHSVState;
@@ -541,7 +548,7 @@ module.exports = function (RED) {
541
548
  }
542
549
  };
543
550
 
544
- node.updateKNXLightColorState = function (_value) {
551
+ node.updateKNXLightColorState = function updateKNXLightColorState(_value) {
545
552
  if (config.GALightColorState !== undefined && config.GALightColorState !== "") {
546
553
  const knxMsgPayload = {};
547
554
  knxMsgPayload.topic = config.GALightColorState;
@@ -549,7 +556,7 @@ module.exports = function (RED) {
549
556
  knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBriToRgb(
550
557
  _value.xy.x,
551
558
  _value.xy.y,
552
- node.currentHUEDevice !== undefined ? node.currentHUEDevice.dimming.brightness : 100
559
+ node.currentHUEDevice !== undefined ? node.currentHUEDevice.dimming.brightness : 100,
553
560
  );
554
561
  // Send to KNX bus
555
562
  if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
@@ -577,30 +584,18 @@ module.exports = function (RED) {
577
584
  }
578
585
  if (node.serverHue) {
579
586
  node.serverHue.removeClient(node);
580
- // I must get the light object, to store it in the node.currentHUEDevice variable
581
- // I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
582
587
  if (node.serverHue !== null && node.serverHue.hueManager !== null) {
583
- (async () => {
584
- try {
585
- node.serverHue.addClient(node);
586
- await node.serverHue.hueManager.writeHueQueueAdd(
587
- config.hueDevice,
588
- null,
589
- node.isGrouped_light === false ? "getLight" : "getGroupedLight",
590
- (jLight) => {
591
- node.currentHUEDevice = jLight;
592
- node.setNodeStatusHue({
593
- fill: "blue",
594
- shape: "ring",
595
- text: "Connected. Is on: ",
596
- payload: node.currentHUEDevice.on.on === true,
597
- });
598
- }
599
- );
600
- } catch (err) {
601
- RED.log.error(`Errore knxUltimateHueLight node.currentHUEDevice ${err.message}`);
602
- }
603
- })();
588
+ try {
589
+ // Everytime the node is edited, it comes here to read the currentHueDevice, if any.
590
+ // It comes here also at node-red boot, but at node-red boot, the hueAllResources is null.
591
+ // The hue-config take cares of filling all properties of the node, after it has been connected to the hue Brigde.
592
+ if (node.serverHue.hueAllResources !== null) node.currentHUEDevice = node.serverHue.loadResourcesFromHUEBridge(node);
593
+ } catch (error) { }
594
+ try {
595
+ node.serverHue.addClient(node);
596
+ } catch (err) {
597
+ RED.log.error(`Errore knxUltimateHueLight node.currentHUEDevice ${err.message}`);
598
+ }
604
599
  }
605
600
  }
606
601
 
@@ -223,7 +223,7 @@
223
223
  <script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
224
224
 
225
225
  <script type="text/markdown" data-help-name="knxUltimateHueLightSensor">
226
- <p> This node lets you get the events from your HUE motion device.<br/>
226
+ This node lets you get the events from your HUE motion device.
227
227
 
228
228
  Here you can get the HUE Light Sensors light events, that represents a lux value, evetytime the ambient light changes.<br/>
229
229
  Start typing in the GA field, the name or group address of your KNX device, the avaiable devices start showing up while you're typing.
@@ -80,10 +80,10 @@ module.exports = function (RED) {
80
80
  // I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
81
81
  if (node.serverHue !== null && node.serverHue.hueManager !== null) {
82
82
  (async () => {
83
- node.serverHue.addClient(node)
83
+ node.serverHue.addClient(node);
84
84
  try {
85
85
  node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, null, 'getLightLevel', (jLight) => {
86
- node.handleSendHUE(jLight)
86
+ node.handleSendHUE(jLight);
87
87
  })
88
88
  } catch (error) {
89
89
  RED.log.error('Errore knxUltimateHueLightSensor subscribing: ' + error.message)
@@ -219,8 +219,8 @@ s<br/>
219
219
  </script>
220
220
  <script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
221
221
 
222
- <script type="text/markdown" data-help-name="knxUltimateHueMotion">
223
- <p> This node lets you get the events from your HUE motion device.<br/>
222
+ <script type="text/markdown" data-help-name="knxUltimateHueMotion"
223
+ This node lets you get the events from your HUE motion device.
224
224
 
225
225
  Here you can get the HUE motion events.<br/>
226
226
  Start typing in the GA field, the name or group address of your KNX device, the avaiable devices start showing up while you're typing.
@@ -260,7 +260,7 @@
260
260
  <script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
261
261
 
262
262
  <script type="text/markdown" data-help-name="knxUltimateHueScene">
263
- <p> This node lets you recall a HUE scene, via KNX.<br/>
263
+ This node lets you recall a HUE scene, via KNX.
264
264
 
265
265
  Start typing in the GA field, the name or group address of your KNX device, the avaiable devices start showing up while you're typing.
266
266
 
@@ -226,7 +226,7 @@
226
226
  <script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
227
227
 
228
228
  <script type="text/markdown" data-help-name="knxUltimateHueTapDial">
229
- <p> This node lets you get the events from your HUE rotary device, for example the Tap Dial.<br/>
229
+ This node lets you get the events from your HUE rotary device, for example the Tap Dial.
230
230
 
231
231
  The Tap Dial device has 4 buttons and 1 rotary knob.
232
232
  You can find the 4 buttons in the **Hue Button node**, not here!
@@ -147,7 +147,6 @@ module.exports = function (RED) {
147
147
  if (node.timerDimStop !== undefined) clearTimeout(node.timerDimStop);
148
148
  node.isTimerDimStopRunning = true;
149
149
  node.timerDimStop = setTimeout(() => {
150
- console.log('Stop banana');
151
150
  // KNX Stop DIM
152
151
  knxMsgPayload.payload = { decr_incr: 0, data: 0 }; // Payload for the output msg
153
152
  // Send to KNX bus
@@ -158,7 +157,7 @@ module.exports = function (RED) {
158
157
  }
159
158
  if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX Stop DIM' + ` (${new Date().getDate()}, ${new Date().toLocaleTimeString()})` });
160
159
  node.isTimerDimStopRunning = false;
161
- }, 1500);
160
+ }, 500);
162
161
  };
163
162
 
164
163
  // On each deploy, unsubscribe+resubscribe
@@ -220,8 +220,8 @@
220
220
  </script>
221
221
  <script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
222
222
 
223
- <script type="text/markdown" data-help-name="knxUltimateHueTemperatureSensor">
224
- <p> This node lets you get the events from your HUE temperature device.<br/>
223
+ <script type="text/markdown" data-help-name="knxUltimateHueTemperatureSensor"
224
+ This node lets you get the events from your HUE temperature device.
225
225
 
226
226
  Here you can get the HUE temperature events, that represents a celsius value, evetytime the ambient temp changes.<br/>
227
227
  Start typing in the GA field, the name or group address of your KNX device, the avaiable devices start showing up while you're typing.
@@ -376,7 +376,7 @@ The node turns off one device (or multiple devices) at a time, based on the orde
376
376
 
377
377
  Here you can add devices to turn off in case of overload. <br/>
378
378
  Choose the device to turn off. Enter the device name or its group address. <br/>
379
- Enter any group address that indicates the consumption of the device chosen in the first line. ** This is an optional parameter **. If the device is consuming more than a certain number of Watts, it means that it is in use. If it consumes less, the device will be considered "not in use" and both this and the next will be turned off at once.<br/>
379
+ Enter any group address that indicates the consumption of the device chosen in the first line. **This is an optional parameter**. If the device is consuming more than a certain number of Watts, it means that it is in use. If it consumes less, the device will be considered "not in use" and both this and the next will be turned off at once.<br/>
380
380
  If *Automatic recovery* is enabled, the device is automatically reactivated when the "reset delay" expires.
381
381
 
382
382
  ### Inputs
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable max-len */
2
2
  const { EventEmitter } = require('events');
3
3
  const EventSource = require('eventsource');
4
- const http = require('./http.js');
4
+ const http = require('./http');
5
5
 
6
6
  class classHUE extends EventEmitter {
7
7
  constructor(_hueBridgeIP, _username, _clientkey, _bridgeid, _sysLogger) {
@@ -89,6 +89,7 @@ class classHUE extends EventEmitter {
89
89
  if (this.commandQueue.length > 0) {
90
90
  // const jRet = { ...this.commandQueue.shift() } //Clone the object by value
91
91
  const jRet = this.commandQueue.shift();
92
+ // jRet is ({ _lightID, _state, _operation });;
92
93
  switch (jRet._operation) {
93
94
  case 'setLight':
94
95
  // It can be a light or a grouped light
@@ -105,23 +106,6 @@ class classHUE extends EventEmitter {
105
106
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.info(`KNXUltimatehueEngine: classHUE: handleQueue: setLight grouped_light: ${error.message}`);
106
107
  }
107
108
  break;
108
- case 'getLight':
109
- try {
110
- const jReturn = await this.hueApiV2.get(`/resource/light/${jRet._lightID}`);
111
- jRet._callback(jReturn[0]); // Need to call the callback, because the event is absolutely async
112
- } catch (error) {
113
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.info(`KNXUltimatehueEngine: classHUE: handleQueue: getLight light: ${error.message}`);
114
- }
115
- break;
116
- case 'getGroupedLight':
117
- try {
118
- const jReturn = await this.hueApiV2.get(`/resource/grouped_light/${jRet._lightID}`);
119
- // Need to call the callback, because the event is absolutely async
120
- jRet._callback(jReturn[0]);
121
- } catch (error) {
122
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.info(`KNXUltimatehueEngine: classHUE: handleQueue: getLight grouped_light: ${error.message}`);
123
- }
124
- break;
125
109
  case 'setScene':
126
110
  try {
127
111
  const sceneID = jRet._lightID;
@@ -146,14 +130,13 @@ class classHUE extends EventEmitter {
146
130
  case 'getBattery':
147
131
  try {
148
132
  const jReturn = await this.hueApiV2.get(`/resource/device_power/${jRet._lightID}`);
149
- jRet._callback(jReturn[0]); // Need to call the callback, because the event is absolutely async
150
133
  } catch (error) {
151
134
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error(`KNXUltimatehueEngine: classHUE: handleQueue: getBattery: ${error.message}`);
152
135
  }
136
+ break;
153
137
  case 'getLightLevel':
154
138
  try {
155
139
  const jReturn = await this.hueApiV2.get(`/resource/light_level/${jRet._lightID}`);
156
- jRet._callback(jReturn[0]); // Need to call the callback, because the event is absolutely async
157
140
  } catch (error) {
158
141
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error(`KNXUltimatehueEngine: classHUE: handleQueue: getLightLevel: ${error.message}`);
159
142
  }
@@ -161,7 +144,6 @@ class classHUE extends EventEmitter {
161
144
  case 'getTemperature':
162
145
  try {
163
146
  const jReturn = await this.hueApiV2.get(`/resource/temperature/${jRet._lightID}`);
164
- jRet._callback(jReturn[0]); // Need to call the callback, because the event is absolutely async
165
147
  } catch (error) {
166
148
  if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error(`KNXUltimatehueEngine: classHUE: handleQueue: getTemperature: ${error.message}`);
167
149
  }
@@ -174,11 +156,9 @@ class classHUE extends EventEmitter {
174
156
  this.timerwriteQueueAdd = setTimeout(this.handleQueue, 200);
175
157
  };
176
158
 
177
- writeHueQueueAdd = async (_lightID, _state, _operation, _callback) => {
159
+ writeHueQueueAdd = async (_lightID, _state, _operation) => {
178
160
  // Add the new item
179
- this.commandQueue.push({
180
- _lightID, _state, _operation, _callback,
181
- });
161
+ this.commandQueue.push({ _lightID, _state, _operation });
182
162
  };
183
163
  // ######################################
184
164