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

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.
@@ -57,6 +57,12 @@ module.exports = function (RED) {
57
57
  payload: "",
58
58
  });
59
59
 
60
+ function getRandomIntInclusive(min, max) {
61
+ min = Math.ceil(min);
62
+ max = Math.floor(max);
63
+ return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
64
+ }
65
+
60
66
  // This function is called by the hue-config.js
61
67
  node.handleSend = (msg) => {
62
68
  if (node.currentHUEDevice === undefined) {
@@ -105,7 +111,7 @@ module.exports = function (RED) {
105
111
  node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
106
112
  state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } };
107
113
  } else {
108
- state = { on: { on: true }, dimming: node.currentHUEDevice.dimming };
114
+ state = { on: { on: true } };
109
115
  }
110
116
  } else {
111
117
  state = { on: { on: false } };
@@ -123,7 +129,9 @@ module.exports = function (RED) {
123
129
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
124
130
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM));
125
131
  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) });
132
+ node.setNodeStatusHue({
133
+ fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload),
134
+ });
127
135
  break;
128
136
  case config.GADaylightSensor:
129
137
  if (config.enableDayNightLighting === "yes") {
@@ -146,7 +154,9 @@ module.exports = function (RED) {
146
154
  // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
147
155
  msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightHSV));
148
156
  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) });
157
+ node.setNodeStatusHue({
158
+ fill: "green", shape: "dot", text: "KNX->HUE", payload: JSON.stringify(msg.payload),
159
+ });
150
160
  }
151
161
  break;
152
162
  case config.GALightHSVPercentage:
@@ -250,52 +260,45 @@ module.exports = function (RED) {
250
260
  });
251
261
  break;
252
262
  case config.GALightColorCycle:
253
- if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
254
- const gaValColorCycle = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColorCycle));
255
- if (gaValColorCycle === true) {
256
- node.serverHue.hueManager.writeHueQueueAdd(
257
- node.hueDevice,
258
- { on: { on: true } },
259
- node.isGrouped_light === false ? "setLight" : "setGroupedLight",
260
- );
261
- node.timerColorCycle = setInterval(() => {
262
- try {
263
- function getRandomIntInclusive(min, max) {
264
- min = Math.ceil(min);
265
- max = Math.floor(max);
266
- return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
267
- }
268
- const red = getRandomIntInclusive(0, 255);
269
- const green = getRandomIntInclusive(0, 255);
270
- const blue = getRandomIntInclusive(0, 255);
271
- let gamut = null;
272
- if (
273
- node.currentHUEDevice !== undefined
274
- && node.currentHUEDevice.hasOwnProperty("color")
275
- && node.currentHUEDevice.color.hasOwnProperty("gamut_type")
276
- ) {
277
- gamut = node.currentHUEDevice.color.gamut_type;
278
- }
279
- const retXY = hueColorConverter.ColorConverter.rgbToXy(red, green, blue, gamut);
280
- const bright = hueColorConverter.ColorConverter.getBrightnessFromRGB(red, green, blue);
281
- state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } };
282
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
283
- } catch (error) { }
284
- }, 10000);
285
- } else {
263
+ {
286
264
  if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
287
- node.serverHue.hueManager.writeHueQueueAdd(
288
- node.hueDevice,
289
- { on: { on: false } },
290
- node.isGrouped_light === false ? "setLight" : "setGroupedLight",
291
- );
265
+ const gaValColorCycle = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColorCycle));
266
+ if (gaValColorCycle === true) {
267
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, { on: { on: true } }, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
268
+ node.timerColorCycle = setInterval(() => {
269
+ try {
270
+ const red = getRandomIntInclusive(0, 255);
271
+ const green = getRandomIntInclusive(0, 255);
272
+ const blue = getRandomIntInclusive(0, 255);
273
+ let gamut = null;
274
+ if (
275
+ node.currentHUEDevice !== undefined
276
+ && node.currentHUEDevice.hasOwnProperty("color")
277
+ && node.currentHUEDevice.color.hasOwnProperty("gamut_type")
278
+ ) {
279
+ gamut = node.currentHUEDevice.color.gamut_type;
280
+ }
281
+ const retXY = hueColorConverter.ColorConverter.rgbToXy(red, green, blue, gamut);
282
+ const bright = hueColorConverter.ColorConverter.getBrightnessFromRGB(red, green, blue);
283
+ state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } };
284
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
285
+ } catch (error) { }
286
+ }, 10000);
287
+ } else {
288
+ if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
289
+ node.serverHue.hueManager.writeHueQueueAdd(
290
+ node.hueDevice,
291
+ { on: { on: false } },
292
+ node.isGrouped_light === false ? "setLight" : "setGroupedLight",
293
+ );
294
+ }
295
+ node.setNodeStatusHue({
296
+ fill: "green",
297
+ shape: "dot",
298
+ text: "KNX->HUE",
299
+ payload: gaValColorCycle,
300
+ });
292
301
  }
293
- node.setNodeStatusHue({
294
- fill: "green",
295
- shape: "dot",
296
- text: "KNX->HUE",
297
- payload: gaValColorCycle,
298
- });
299
302
  break;
300
303
  default:
301
304
  break;
@@ -312,41 +315,63 @@ module.exports = function (RED) {
312
315
  // Start dimming
313
316
  // ***********************************************************
314
317
  node.hueDimming = function hueDimming(_KNXaction, _KNXbrightness_delta, _dimSpeedInMillisecs = undefined) {
315
- let dimDirection = 'stop';
318
+ // 31/10/2023 after many attempts to use dimming_delta function of the HueApeV2, loosing days of my life, without a decent success
319
+ // i decide to go to the "step brightness" way.
316
320
  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.
321
+ const numStep = 10; // Steps from 0 to 100 by 10
322
+ if (_dimSpeedInMillisecs === undefined || _dimSpeedInMillisecs === '') _dimSpeedInMillisecs = 5000;
323
323
 
324
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");
325
+ // STOP DIM
326
+ if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim);
327
+ node.brightnessStep = null;
328
328
  return;
329
329
  }
330
+
331
+ // Set the actual brightness to start with
332
+ if (node.brightnessStep === null || node.brightnessStep === undefined) node.brightnessStep = node.currentHUEDevice.dimming.brightness || 50;
333
+ node.brightnessStep = Math.ceil(Number(node.brightnessStep));
334
+
335
+ // Set the speed
336
+ _dimSpeedInMillisecs /= numStep;
337
+
338
+ // We have also minDimLevelLight and maxDimLevelLight to take care of.
339
+ let minDimLevelLight = config.minDimLevelLight === undefined ? 10 : Number(config.minDimLevelLight);
340
+ if (config.minDimLevelLight === "useHueLightLevel" && node.currentHUEDevice.dimming.min_dim_level === undefined) minDimLevelLight = 10;
341
+ const maxDimLevelLight = config.maxDimLevelLight === undefined ? 100 : Number(config.maxDimLevelLight);
342
+
330
343
  if (_KNXbrightness_delta > 0 && _KNXaction === 1) {
331
- delta = 100 - Math.round(node.currentHUEDevice.dimming.brightness, 0) - (100 - Number(maxDimLevelLight));
332
- dimDirection = 'up';
344
+ // DIM UP
345
+ if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim);
346
+ node.timerStepDim = setInterval(() => {
347
+ node.updateKNXBrightnessState(node.brightnessStep); // Unnecessary, but necessary to set the KNX Status in real time.
348
+ node.brightnessStep += numStep;
349
+ if (node.brightnessStep > maxDimLevelLight) node.brightnessStep = maxDimLevelLight;
350
+ hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs } };
351
+ // Switch on the light if off
352
+ if (node.currentHUEDevice.hasOwnProperty("on") !== undefined && node.currentHUEDevice.on.on === false) {
353
+ hueTelegram.on = { on: true };
354
+ }
355
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
356
+ if (node.brightnessStep >= maxDimLevelLight) clearInterval(node.timerStepDim);
357
+ }, _dimSpeedInMillisecs);
333
358
  }
334
359
  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 };
360
+ // DIM DOWN
361
+ if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim);
362
+ node.timerStepDim = setInterval(() => {
363
+ node.updateKNXBrightnessState(node.brightnessStep); // Unnecessary, but necessary to set the KNX Status in real time.
364
+ node.brightnessStep -= numStep;
365
+ if (node.brightnessStep < minDimLevelLight) node.brightnessStep = minDimLevelLight;
366
+ hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs } };
367
+ // Switch off the light if on
368
+ if (node.currentHUEDevice.hasOwnProperty("on") !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStep === 0) {
369
+ hueTelegram.on = { on: false };
370
+ }
371
+ node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
372
+ if (node.brightnessStep <= minDimLevelLight) clearInterval(node.timerStepDim);
373
+ }, _dimSpeedInMillisecs);
348
374
  }
349
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
350
375
  };
351
376
  // ***********************************************************
352
377
 
@@ -354,28 +379,28 @@ module.exports = function (RED) {
354
379
  // mirek: required(integer minimum: 153, maximum: 500)
355
380
  // ***********************************************************
356
381
  node.hueDimmingTunableWhite = function hueDimming(_KNXaction, _KNXbrightness_delta, _dimSpeedInMillisecs = undefined) {
357
- let dimDirection = 'stop';
382
+ let dimDirection = "stop";
358
383
  let hueTelegram = {};
359
- _dimSpeedInMillisecs = (_dimSpeedInMillisecs === undefined || _dimSpeedInMillisecs === '') ? 5000 : _dimSpeedInMillisecs;
384
+ _dimSpeedInMillisecs = _dimSpeedInMillisecs === undefined || _dimSpeedInMillisecs === "" ? 5000 : _dimSpeedInMillisecs;
360
385
  let delta = 0;
361
386
  if (!node.currentHUEDevice.color_temperature.hasOwnProperty("mirek")) delta = 347 - Math.round(173, 0); // Unable to read the mirek, set medium as default
362
387
  // We have also minDimLevelLight and maxDimLevelLight to take care of.
363
388
  // Mirek limits are not taken in consideration.
364
389
  // Maximum mirek is 347
365
390
  if (_KNXbrightness_delta === 0 && _KNXaction === 0) {
366
- dimDirection = 'stop';
391
+ dimDirection = "stop";
367
392
  hueTelegram = { color_temperature_delta: { action: dimDirection } };
368
393
  node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
369
394
  return;
370
395
  }
371
396
  if (_KNXbrightness_delta > 0 && _KNXaction === 1) {
372
397
  if (node.currentHUEDevice.color_temperature.hasOwnProperty("mirek")) delta = 347 - Math.round(node.currentHUEDevice.color_temperature.mirek, 0);
373
- dimDirection = 'up';
398
+ dimDirection = "up";
374
399
  }
375
400
  if (_KNXbrightness_delta > 0 && _KNXaction === 0) {
376
401
  // 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
402
  if (node.currentHUEDevice.color_temperature.hasOwnProperty("mirek")) delta = Math.round(node.currentHUEDevice.color_temperature.mirek, 0);
378
- dimDirection = 'down';
403
+ dimDirection = "down";
379
404
  }
380
405
  // Calculate the dimming time based on delta
381
406
  // 10000:x=347:delta
@@ -384,7 +409,7 @@ module.exports = function (RED) {
384
409
 
385
410
  hueTelegram = { color_temperature_delta: { action: dimDirection, mirek_delta: delta }, dynamics: { duration: _dimSpeedInMillisecs } };
386
411
  // Switch on the light if off
387
- if (node.currentHUEDevice.hasOwnProperty('on') !== undefined && node.currentHUEDevice.on.on === false && dimDirection === "up") {
412
+ if (node.currentHUEDevice.hasOwnProperty("on") !== undefined && node.currentHUEDevice.on.on === false && dimDirection === "up") {
388
413
  hueTelegram.on = { on: true };
389
414
  }
390
415
  node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
@@ -406,51 +431,64 @@ module.exports = function (RED) {
406
431
  if (_event.hasOwnProperty("on")) {
407
432
  node.updateKNXLightState(_event.on.on);
408
433
  // In case of switch off, set the dim to zero
409
- if (_event.on.on === false && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === 'onhueoff')) {
434
+ if (
435
+ _event.on.on === false
436
+ && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === "onhueoff")
437
+ ) {
410
438
  node.updateKNXBrightnessState(0);
439
+ node.currentHUEDevice.dimming.brightness = 0;
411
440
  } else {
412
- // Sends the previous brightness value
413
- try {
414
- node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
415
- } catch (error) {
416
- /* empty */
417
- }
441
+ // // Sends the previous brightness value
442
+ // try {
443
+ // node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
444
+ // } catch (error) {
445
+ // /* empty */
446
+ // }
418
447
  }
448
+ node.currentHUEDevice.on.on = _event.on.on;
419
449
  }
420
450
  if (_event.hasOwnProperty("color")) {
421
451
  node.updateKNXLightColorState(_event.color);
452
+ node.currentHUEDevice.color = _event.color;
422
453
  }
423
- if (_event.hasOwnProperty("dimming")) {
454
+ if (_event.hasOwnProperty("dimming") && _event.dimming.brightness !== undefined) {
424
455
  // Every once on a time, the light transmit the brightness value of 0.39.
425
456
  // To avoid wrongly turn light state on, exit
426
457
  if (_event.dimming.brightness < 1) _event.dimming.brightness = 0;
427
- if (node.currentHUEDevice.hasOwnProperty('on') && node.currentHUEDevice.on.on === false && _event.dimming.brightness === 0) return;
458
+ if (node.currentHUEDevice.hasOwnProperty("on") && node.currentHUEDevice.on.on === false && _event.dimming.brightness === 0) return;
428
459
  if (node.currentHUEDevice.on.on === false) node.updateKNXLightState(_event.dimming.brightness > 0);
429
460
  node.updateKNXBrightnessState(_event.dimming.brightness);
430
461
  // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
431
462
  if (_event.dimming.brightness === 0) {
432
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, { on: { on: false } }, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
463
+ node.serverHue.hueManager.writeHueQueueAdd(
464
+ node.hueDevice,
465
+ { on: { on: false } },
466
+ node.isGrouped_light === false ? "setLight" : "setGroupedLight",
467
+ );
468
+ node.currentHUEDevice.on.on = false;
433
469
  }
470
+ node.currentHUEDevice.dimming.brightness = _event.dimming.brightness;
434
471
  }
435
- if (_event.hasOwnProperty("color_temperature")) {
472
+ if (_event.hasOwnProperty("color_temperature") && _event.color_temperature.mirek !== undefined) {
436
473
  node.updateKNXLightHSVState(_event.color_temperature.mirek);
474
+ node.currentHUEDevice.color_temperature.mirek = _event.color_temperature.mirek;
437
475
  }
438
476
 
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);
477
+ // // Update the current HUE Device with the new _event
478
+ // function copiaOggettoRicorsivo(objDestinazione, objOrigine) {
479
+ // for (const prop in objOrigine) {
480
+ // if (typeof objOrigine[prop] === "object" && objOrigine[prop] !== null) {
481
+ // // Se la proprietà è un oggetto, copiamola in modo ricorsivo
482
+ // objDestinazione[prop] = objDestinazione[prop] || {};
483
+ // copiaOggettoRicorsivo(objDestinazione[prop], objOrigine[prop]);
484
+ // } else {
485
+ // // Altrimenti, copia il valore della proprietà
486
+ // objDestinazione[prop] = objOrigine[prop];
487
+ // }
488
+ // }
489
+ // }
490
+ // // Copia l'oggettoOrigine nell'oggettoDestinazione mantenendo le proprietà esistenti
491
+ // copiaOggettoRicorsivo(node.currentHUEDevice, _event);
454
492
  }
455
493
  } catch (error) {
456
494
  node.status({
@@ -481,7 +519,7 @@ module.exports = function (RED) {
481
519
  node.setNodeStatusHue({
482
520
  fill: "blue",
483
521
  shape: "ring",
484
- text: "HUE->KNX State",
522
+ text: "HUE->KNX Bright",
485
523
  payload: knxMsgPayload.payload,
486
524
  });
487
525
  }
@@ -509,7 +547,7 @@ module.exports = function (RED) {
509
547
  node.setNodeStatusHue({
510
548
  fill: "blue",
511
549
  shape: "ring",
512
- text: "HUE->KNX State",
550
+ text: "HUE->KNX On/Off",
513
551
  payload: knxMsgPayload.payload,
514
552
  });
515
553
  }
@@ -542,7 +580,7 @@ module.exports = function (RED) {
542
580
  node.setNodeStatusHue({
543
581
  fill: "blue",
544
582
  shape: "ring",
545
- text: "HUE->KNX State",
583
+ text: "HUE->KNX HSV",
546
584
  payload: knxMsgPayload.payload,
547
585
  });
548
586
  }
@@ -571,7 +609,7 @@ module.exports = function (RED) {
571
609
  node.setNodeStatusHue({
572
610
  fill: "blue",
573
611
  shape: "ring",
574
- text: "HUE->KNX State",
612
+ text: "HUE->KNX Color",
575
613
  payload: knxMsgPayload.payload,
576
614
  });
577
615
  }
@@ -585,12 +623,6 @@ module.exports = function (RED) {
585
623
  if (node.serverHue) {
586
624
  node.serverHue.removeClient(node);
587
625
  if (node.serverHue !== null && node.serverHue.hueManager !== null) {
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
626
  try {
595
627
  node.serverHue.addClient(node);
596
628
  } catch (err) {
@@ -1,110 +1,101 @@
1
1
  module.exports = function (RED) {
2
2
  function knxUltimateHueLightSensor(config) {
3
- RED.nodes.createNode(this, config)
4
- const node = this
5
- node.server = RED.nodes.getNode(config.server)
6
- node.serverHue = RED.nodes.getNode(config.serverHue)
7
- node.topic = node.name
8
- node.name = config.name === undefined ? 'Hue' : config.name
9
- node.dpt = ''
10
- node.notifyreadrequest = false
11
- node.notifyreadrequestalsorespondtobus = 'false'
12
- node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = ''
13
- node.notifyresponse = false
14
- node.notifywrite = true
15
- node.initialread = true
16
- node.listenallga = true // Don't remove
17
- node.outputtype = 'write'
18
- node.outputRBE = false // Apply or not RBE to the output (Messages coming from flow)
19
- node.inputRBE = false // Apply or not RBE to the input (Messages coming from BUS)
20
- node.currentPayload = '' // Current value for the RBE input and for the .previouspayload msg
21
- node.passthrough = 'no'
22
- node.formatmultiplyvalue = 1
23
- node.formatnegativevalue = 'leave'
24
- node.formatdecimalsvalue = 2
3
+ RED.nodes.createNode(this, config);
4
+ const node = this;
5
+ node.server = RED.nodes.getNode(config.server);
6
+ node.serverHue = RED.nodes.getNode(config.serverHue);
7
+ node.topic = node.name;
8
+ node.name = config.name === undefined ? 'Hue' : config.name;
9
+ node.dpt = '';
10
+ node.notifyreadrequest = false;
11
+ node.notifyreadrequestalsorespondtobus = 'false';
12
+ node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = '';
13
+ node.notifyresponse = false;
14
+ node.notifywrite = true;
15
+ node.initialread = true;
16
+ node.listenallga = true; // Don't remove
17
+ node.outputtype = 'write';
18
+ node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
19
+ node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
20
+ node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
21
+ node.passthrough = 'no';
22
+ node.formatmultiplyvalue = 1;
23
+ node.formatnegativevalue = 'leave';
24
+ node.formatdecimalsvalue = 2;
25
25
 
26
26
  // Used to call the status update from the config node.
27
27
  node.setNodeStatus = ({ fill, shape, text, payload }) => {
28
28
 
29
- }
29
+ };
30
30
  // Used to call the status update from the HUE config node.
31
31
  node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
32
- if (payload === undefined) return
33
- const dDate = new Date()
34
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
35
- node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
36
- }
32
+ if (payload === undefined) return;
33
+ const dDate = new Date();
34
+ payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
35
+ node.status({ fill, shape, text: text + ' ' + payload + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' });
36
+ };
37
37
 
38
38
  // This function is called by the knx-ultimate config node, to output a msg.payload.
39
39
  node.handleSend = msg => {
40
- }
40
+ };
41
41
 
42
42
  node.handleSendHUE = _event => {
43
43
  try {
44
44
  if (_event.id === config.hueDevice) {
45
- const knxMsgPayload = {}
46
- knxMsgPayload.topic = config.GAlightsensor
47
- knxMsgPayload.dpt = config.dptlightsensor
45
+ const knxMsgPayload = {};
46
+ knxMsgPayload.topic = config.GAlightsensor;
47
+ knxMsgPayload.dpt = config.dptlightsensor;
48
48
 
49
49
  if (_event.hasOwnProperty('light') && _event.light.hasOwnProperty('light_level')) {
50
50
  //console.log(Math.round(10 ** ((_event.light.light_level - 1) / 10000)))
51
51
  //console.log(_event.light.light_level === 0 ? 0 : Math.round(Math.pow(10, (_event.light.light_level - 1) / 10000)))
52
- knxMsgPayload.payload = _event.light.light_level === 0 ? 0 : Math.round(Math.pow(10, (_event.light.light_level - 1) / 10000))
52
+ knxMsgPayload.payload = _event.light.light_level === 0 ? 0 : Math.round(Math.pow(10, (_event.light.light_level - 1) / 10000));
53
53
  // Send to KNX bus
54
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id })
55
- node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX ' + JSON.stringify(knxMsgPayload.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
54
+ if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) node.server.writeQueueAdd({ grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id });
55
+ node.status({ fill: 'green', shape: 'dot', text: 'HUE->KNX ' + JSON.stringify(knxMsgPayload.payload) + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' });
56
56
 
57
57
  // Setup the output msg
58
- knxMsgPayload.name = node.name
59
- knxMsgPayload.event = 'light_level'
58
+ knxMsgPayload.name = node.name;
59
+ knxMsgPayload.event = 'light_level';
60
60
 
61
61
  // Send payload
62
- knxMsgPayload.rawEvent = _event
63
- node.send(knxMsgPayload)
64
- node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: knxMsgPayload.payload })
62
+ knxMsgPayload.rawEvent = _event;
63
+ node.send(knxMsgPayload);
64
+ node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: knxMsgPayload.payload });
65
65
  }
66
66
  }
67
67
  } catch (error) {
68
- node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' })
68
+ node.status({ fill: 'red', shape: 'dot', text: 'HUE->KNX error ' + error.message + ' (' + new Date().getDate() + ', ' + new Date().toLocaleTimeString() + ')' });
69
69
  }
70
- }
70
+ };
71
71
 
72
72
  // On each deploy, unsubscribe+resubscribe
73
73
  if (node.server) {
74
- node.server.removeClient(node)
75
- node.server.addClient(node)
74
+ node.server.removeClient(node);
75
+ node.server.addClient(node);
76
76
  }
77
77
  if (node.serverHue) {
78
- node.serverHue.removeClient(node)
78
+ node.serverHue.removeClient(node);
79
79
  // I must get the object, to store read the status
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
- (async () => {
83
- node.serverHue.addClient(node);
84
- try {
85
- node.serverHue.hueManager.writeHueQueueAdd(config.hueDevice, null, 'getLightLevel', (jLight) => {
86
- node.handleSendHUE(jLight);
87
- })
88
- } catch (error) {
89
- RED.log.error('Errore knxUltimateHueLightSensor subscribing: ' + error.message)
90
- }
91
- })()
82
+ node.serverHue.addClient(node);
92
83
  }
93
84
  }
94
85
 
95
86
  node.on('input', function (msg) {
96
87
 
97
- })
88
+ });
98
89
 
99
90
  node.on('close', function (done) {
100
91
  if (node.server) {
101
- node.server.removeClient(node)
92
+ node.server.removeClient(node);
102
93
  }
103
94
  if (node.serverHue) {
104
- node.serverHue.removeClient(node)
95
+ node.serverHue.removeClient(node);
105
96
  }
106
- done()
107
- })
97
+ done();
98
+ });
108
99
  }
109
- RED.nodes.registerType('knxUltimateHueLightSensor', knxUltimateHueLightSensor)
110
- }
100
+ RED.nodes.registerType('knxUltimateHueLightSensor', knxUltimateHueLightSensor);
101
+ };
@@ -211,7 +211,7 @@
211
211
  <input type="text" id="node-input-namemotion" style="width:200px;margin-left: 5px; text-align: left;">
212
212
  </div>
213
213
 
214
- s<br/>
214
+ <br/>
215
215
  <br/>
216
216
  <br/>
217
217
 
@@ -219,10 +219,10 @@ 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"
222
+ <script type="text/markdown" data-help-name="knxUltimateHueMotion">
223
223
  This node lets you get the events from your HUE motion device.
224
224
 
225
- Here you can get the HUE motion events.<br/>
225
+ Here you can get the HUE motion events.
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.
227
227
 
228
228
  **General**
@@ -245,7 +245,6 @@ Start typing in the GA field, the name or group address of your KNX device, the
245
245
 
246
246
  `msg.payload` is used as the payload of the published message.
247
247
  It contains the detailed event sent by your Hue devicem so you can use it for whatever you want.
248
- It contains the detailed event sent by your Hue devicem so you can use it for whatever you want.
249
248
 
250
249
  <br/>
251
250