node-red-contrib-knx-ultimate 2.2.4 → 2.2.5

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,9 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ <b>Version 2.2.5</b> - October 2023<br/>
10
+ - Fix: fixed some HUE nodes not able to register to the event notification service.<br/>
11
+ </p>
9
12
  <b>Version 2.2.4</b> - October 2023<br/>
10
13
  - HUE Light: fixed some status hiccups and better handling of async hue bridge functions.<br/>
11
14
  </p>
@@ -765,7 +768,7 @@
765
768
  </p>
766
769
  <p>
767
770
  <b>Version 1.2.33</b> - May 2021<br/>
768
- - Gateway configuration -> Advanced Options -> Node list in all flows: added more infos to each node in the list, to allow more control on the nodes overview. The options are: "No Initial Read, React to Write, React to Response, No React to Read, No Autorespond to Read Requests, Output type write, No RBE on Output to Bus, No RBE on Input from Bus"<br/>
771
+ - Gateway configuration -> Advanced Options -> Node list in all flows: added more infos to each node in the list, to allow more control on the nodes overview. The options are: "No Initial Read, React to Write, React to Response, No React to Read, No Autorespond to Read Requests, Telegram type write, No RBE on Output to Bus, No RBE on Input from Bus"<br/>
769
772
  </p>
770
773
  <p>
771
774
  <b>Version 1.2.32</b> - May 2021<br/>
@@ -1067,7 +1070,7 @@
1067
1070
  </p>
1068
1071
  <p>
1069
1072
  <b>Version 1.1.64</b> - April 2020<br/>
1070
- - NEW: Added output type "Read", to issue a read by simply pass a payload to the node. Thanks @waldbaer for the suggestion.<br/>
1073
+ - NEW: Added Telegram type "Read", to issue a read by simply pass a payload to the node. Thanks @waldbaer for the suggestion.<br/>
1071
1074
  </p>
1072
1075
  <p>
1073
1076
  <b>Version 1.1.63</b> - April 2020<br/>
@@ -1304,7 +1307,7 @@
1304
1307
  </p>
1305
1308
  <p>
1306
1309
  <b>Version 1.1.10</b><br/>
1307
- - Auto send node value as response to the KNX Bus. It works in conjunction with React to event GroupValue read. When checked, whenever the node receives a read request from bus, it sends a response to the KNX Bus with the stored payload value.<br/>
1310
+ - Auto send node value as response to the KNX Bus. It works in conjunction with React to read telegrams. When checked, whenever the node receives a read request from bus, it sends a response to the KNX Bus with the stored payload value.<br/>
1308
1311
  - Fixed an issue where if you have a node set to Universal mode (listen to all Group Addresses) (with ETS CSV File set) and you create a new node having a Group Addr. not in the ETS CSV file, an exception is raised but not caught and the nodes may not receive the values from KNX BUS.<br/>
1309
1312
  </p>
1310
1313
  <p>
@@ -1413,7 +1416,7 @@
1413
1416
  </p>
1414
1417
  <p>
1415
1418
  <b>Version 0.0.6 BETA</b><br/>
1416
- - Fixed Output Type unable to be set<br/>
1419
+ - Fixed Telegram type unable to be set<br/>
1417
1420
  - Added node status for response (blue) and read (grey)<br/>
1418
1421
  </p>
1419
1422
  <p>
@@ -122,6 +122,12 @@ module.exports = (RED) => {
122
122
  if (nodeClient.hueDevice !== undefined) {
123
123
  const oHUEDevice = node.hueAllResources.filter((a) => a.id === nodeClient.hueDevice)[0];
124
124
  if (oHUEDevice !== undefined) {
125
+ // Add _Node to the clients array
126
+ nodeClient.setNodeStatusHue({
127
+ fill: "green",
128
+ shape: "ring",
129
+ text: "Ready :-)",
130
+ });
125
131
  nodeClient.currentHUEDevice = oHUEDevice;
126
132
  nodeClient.handleSendHUE(oHUEDevice);
127
133
  }
@@ -74,8 +74,8 @@ module.exports = (RED) => {
74
74
  help: `// KNX-Ultimate set as UNIVERSAL NODE
75
75
  // Example of a function that sends a message to the KNX-Ultimate
76
76
  msg.destination = "0/0/1"; // Set the destination
77
- msg.payload = false; // issues a write or response (based on the options Output Type above) to the KNX bus
78
- msg.event = "GroupValue_Write"; // "GroupValue_Write" or "GroupValue_Response", overrides the option Output Type above.
77
+ msg.payload = false; // issues a write or response (based on the options Telegram type above) to the KNX bus
78
+ msg.event = "GroupValue_Write"; // "GroupValue_Write" or "GroupValue_Response", overrides the option Telegram type above.
79
79
  msg.dpt = "1.001"; // for example "1.001", overrides the Datapoint option. (Datapoints can be sent as 9 , "9" , "9.001" or "DPT9.001")
80
80
  return msg;`,
81
81
  helplink: "https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki",
@@ -337,10 +337,7 @@
337
337
  <br />
338
338
 
339
339
  <label for="node-input-server">
340
- <span id="divknxsecure">
341
- <font color="green" size="4px"><i class="fa fa-shield" aria-hidden="true"></i></font>
342
- </span>&nbsp;<span><i class="fa fa-circle-o" aria-hidden="true"></i></font></span>
343
- <span data-i18n="knxUltimate.properties.node-input-server"></span>
340
+ <i class="fa fa-circle-o"></i> Gateway
344
341
  </label>
345
342
  <input type="text" id="node-input-server" />
346
343
  </div>
@@ -354,17 +351,16 @@
354
351
  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAB7CAAAewgFu0HU+AAAF6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDMtMjNUMTY6MjE6MDkrMDE6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg3YTdhODQ1LTEwOWMtNGQxMy04YTM5LTg5ZWE5MzIwNDRlYyIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyMTowOSswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyODoyNyswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+DGyPFQAAAE9JREFUKJG1UEEOACAIgub/v2yHalnJVoe4uIEKSgccJ9jroVmjA0+ujZtWku3DgZmgBiT4egN9CmmEAAfA/5HUW0OQu7dKmOCzmM3k9YYKZv8ZEZ/YgNsAAAAASUVORK5CYII="></img>
355
352
  <span data-i18n="knxUltimate.properties.node-input-topic"></span>
356
353
  </label>
357
- <input style="width:60%" type="text" id="node-input-topic" placeholder="Ex: 1/1/1" />
354
+ <input type="text" id="node-input-topic" placeholder="Sample: Dinning light" />
358
355
  </div>
359
356
  <div class="form-row">
360
357
  <label for="node-input-dpt">
361
358
  <img
362
359
  src="data:image/png;base64,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"></img>
363
- <span data-i18n="knxUltimate.properties.node-input-dpt"></span>
360
+ Datapoint
364
361
  </label>
365
- <select style="width:40%" id="node-input-dpt"></select>
362
+ <select id="node-input-dpt"></select>
366
363
  <span id="sampleCodeEditor" style="color:red;" />
367
-
368
364
  </div>
369
365
  </div>
370
366
  <div class="form-row">
@@ -395,45 +391,30 @@
395
391
 
396
392
  <div id="tabs">
397
393
  <ul>
398
- <li><a href="#tabs-1"><i class="fa fa-code"></i> Sample in Function</a></li>
399
- <li><a href="#tabs-2"><i class="fa fa-braille"></i> Advanced options</a></li>
400
- <li><a href="#tabs-3"><i class="fa fa-list-ol"></i> Format input</a></li>
394
+ <li><a href="#tabs-1"><i class="fa fa-braille"></i> Advanced options</a></li>
395
+ <li><a href="#tabs-2"><i class="fa fa-list-ol"></i> Format input</a></li>
396
+ <li><a href="#tabs-3"><i class="fa fa-code"></i> Payload Sample</a></li>
401
397
  </ul>
402
398
  <div id="tabs-1">
403
- <p>
404
- <div style="height:200px;min-height:150px;padding:0px;">
405
- <div style="height:100%;width:100%;padding:0px;" class="node-text-editor" id="example-editor"></div>
406
- </div>
407
- </p>
408
- </div>
409
-
410
- <div id="tabs-2">
411
- <p>
412
-
413
-
414
399
  <div class="form-row" style="padding:10px">
415
400
  <div class="form-row">
416
- <label style="width:230px" for="node-input-passthrough">
417
- <i class="fa fa-long-arrow-right"></i>
418
- <span data-i18n="knxUltimate.properties.node-input-passthrough"></span>
401
+ <label style="width:180px" for="node-input-passthrough">
402
+ <i class="fa fa-long-arrow-right"></i> Msg passthrough
419
403
  </label>
420
- <select style="width:92px" id="node-input-passthrough">
404
+ <select id="node-input-passthrough">
421
405
  <option value="no" data-i18n="knxUltimate.selectlists.passthrough_No"></option>
422
406
  <option value="yes" data-i18n="knxUltimate.selectlists.passthrough_Leave"></option>
423
407
  <option value="yesownprop" data-i18n="knxUltimate.selectlists.passthrough_OwnProp"></option>
424
408
  </select>
425
409
  </div>
426
- <br />
427
410
  <div class="form-row">
428
411
  <dt>
429
- <i class="fa fa-arrow-right"></i>|
430
- <span data-i18n="knxUltimate.advanced.OUTPUT"></span>
412
+ <i class="fa fa-arrow-right"></i> CONTROL (payload to KNX bus)
431
413
  </dt>
432
414
  </div>
433
415
  <div class="form-row">
434
- &nbsp;&nbsp;<label for="node-input-outputtype">
435
- <i class="fa fa-paper-plane-o"></i>
436
- <span data-i18n="knxUltimate.properties.node-input-outputtype"></span>
416
+ <label style="width:180px" for="node-input-outputtype">
417
+ <i class="fa fa-paper-plane-o"></i> Telegram type
437
418
  </label>
438
419
  <select id="node-input-outputtype">
439
420
  <option value="write" data-i18n="knxUltimate.selectlists.Output_write"></option>
@@ -443,25 +424,23 @@
443
424
  </select>
444
425
  </div>
445
426
  <div class="form-row" id="divOutputRBE">
446
- &nbsp;&nbsp;<input type="checkbox" id="node-input-outputRBE"
427
+ <input type="checkbox" id="node-input-outputRBE"
447
428
  style="display:inline-block; width:auto; vertical-align:top;" />
448
429
  <label style="width:85%" for="node-input-outputRBE">
449
- <i class="fa fa-filter"></i>
450
- <span data-i18n="knxUltimate.properties.node-input-outputRBE"></span>
430
+ <i class="fa fa-filter"></i> Send payload to KNX only if changed (RBE filter)
451
431
  </label>
452
432
  </div>
453
433
  <br />
454
434
  <div class="form-row">
455
435
  <dt>
456
- |<i class="fa fa-arrow-right"></i>
457
- <span data-i18n="knxUltimate.advanced.INPUT"></span>
436
+ |<i class="fa fa-arrow-right"></i> STATUS (payload from KNX BUS)
458
437
  </dt>
459
438
  </div>
460
439
  <div class="form-row" id="divNode-input-initialread">
461
- &nbsp;&nbsp;<label style="width:50%" for="node-input-initialread">
462
- <i class="fa fa-question-circle-o"></i> Read status upon connection
440
+ <label style="width:180px" for="node-input-initialread">
441
+ <i class="fa fa-question-circle-o"></i> Read status on start
463
442
  </label>
464
- <select style="width:100px" id="node-input-initialread">
443
+ <select id="node-input-initialread">
465
444
  <option value=0 data-i18n="knxUltimate.properties.node-input-initialread0"></option>
466
445
  <option value=1 data-i18n="knxUltimate.properties.node-input-initialread1"></option>
467
446
  <option value=2 data-i18n="knxUltimate.properties.node-input-initialread2"></option>
@@ -470,42 +449,38 @@
470
449
 
471
450
  </div>
472
451
  <div class="form-row" id="divInputRBE">
473
- &nbsp;&nbsp;<input type="checkbox" id="node-input-inputRBE"
452
+ <input type="checkbox" id="node-input-inputRBE"
474
453
  style="display:inline-block; width:auto; vertical-align:top;" />
475
454
  <label style="width:85%" for="node-input-inputRBE">
476
- <i class="fa fa-filter"></i>
477
- <span data-i18n="knxUltimate.properties.node-input-inputRBE"></span>
455
+ <i class="fa fa-filter"></i> React only by changed payload (RBE filter)
478
456
  </label>
479
457
  </div>
480
458
  <div class="form-row">
481
- &nbsp;&nbsp;<input type="checkbox" id="node-input-notifywrite"
459
+ <input type="checkbox" id="node-input-notifywrite"
482
460
  style="display:inline-block; width:auto; vertical-align:top;" />
483
461
  <label style="width:85%" for="node-input-notifywrite">
484
- <i class="fa fa-sign-in"></i>
485
- <span data-i18n="knxUltimate.properties.node-input-notifywrite"></span>
462
+ <i class="fa fa-sign-in"></i> React to write telegrams
486
463
  </label>
487
464
  </div>
488
465
  <div class="form-row">
489
- &nbsp;&nbsp;<input type="checkbox" id="node-input-notifyresponse"
466
+ <input type="checkbox" id="node-input-notifyresponse"
490
467
  style="display:inline-block; width:auto; vertical-align:top;" />
491
468
  <label style="width:85%" for="node-input-notifyresponse">
492
- <i class="fa fa-sign-in"></i>
493
- <span data-i18n="knxUltimate.properties.node-input-notifyresponse"></span>
469
+ <i class="fa fa-sign-in"></i> React to response telegrams
494
470
  </label>
495
471
  </div>
496
472
  <div class="form-row">
497
- &nbsp;&nbsp;<input type="checkbox" id="node-input-notifyreadrequest"
473
+ <input type="checkbox" id="node-input-notifyreadrequest"
498
474
  style="display:inline-block; width:auto; vertical-align:top;" />
499
475
  <label style="width:85%" for="node-input-notifyreadrequest">
500
- <i class="fa fa-sign-in"></i>
501
- <span data-i18n="knxUltimate.properties.node-input-notifyreadrequest"></span>
476
+ <i class="fa fa-sign-in"></i> React to read telegrams
502
477
  </label>
503
478
  </div>
504
479
 
505
480
  <div id="divnotifyreadrequestautoreact">
506
481
  <dd>
507
482
  <div class="form-row">
508
- &nbsp;&nbsp;<input type="checkbox" id="node-input-notifyreadrequestalsorespondtobus"
483
+ <input type="checkbox" id="node-input-notifyreadrequestalsorespondtobus"
509
484
  style="display:inline-block; width:auto; vertical-align:top;" />
510
485
  <label style="width:85%" for="node-input-notifyreadrequestalsorespondtobus">
511
486
  <span
@@ -513,7 +488,7 @@
513
488
  </label>
514
489
  </div>
515
490
  <div class="form-row">
516
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<label style="width:auto">
491
+ &nbsp;<label style="width:auto">
517
492
  <span
518
493
  data-i18n="knxUltimate.properties.node-input-notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized"></span>
519
494
  </label>
@@ -524,11 +499,9 @@
524
499
  </dd>
525
500
  </div>
526
501
  </div>
527
-
528
- </p>
529
502
  </div>
530
- <div id="tabs-3">
531
- <p>
503
+
504
+ <div id="tabs-2">
532
505
  <div class="form-row" style="padding:10px">
533
506
  <div class="form-row">
534
507
  <dt>
@@ -577,7 +550,12 @@
577
550
  </select>
578
551
  </div>
579
552
  </div>
580
- </p>
553
+
554
+ </div>
555
+ <div id="tabs-3">
556
+ <div style="height:200px;min-height:150px;padding:0px;">
557
+ <div style="height:100%;width:100%;padding:0px;" class="node-text-editor" id="example-editor"></div>
558
+ </div>
581
559
  </div>
582
560
  </div>
583
561
 
@@ -607,13 +585,13 @@
607
585
  | Universal mode (listen to all Group Addresses) | By setting this, the node will read and control ALL group addresses. |
608
586
  | Sample Function | This will give it a hint on what to write in a function, if you want to control the node via a Node-Red function node. |
609
587
  | Input msg passthrough | If set, you can pass the input mgs to the output msg. |
610
- | Output Type | *write* to send write telegram (usually, you want that), otherwise you can choose the telegram's type to react to. |
611
- | Send payload to BUS only if changed (RBE filter) | *Report by change* filter. If set, only the msg input (from the Flow) having different values each time, will be sent to the KNX bus. If you intend to send everytime the same value, turn it off. |
612
- | Read status upon connection | Read group address status, every time Node-Red starts and at every reconnection to the KNX Gateway. The node stores all group address values to a file, so you can choose wether to read from file or from the KNX bus. |
613
- | React only if payload from BUS is changed (RBE filter) | *Report by change* filter. If set, only the msg output (to KNX bus) having different values each time, will be sent to the msg output's flow. If you intend to send everytime the same value, leave it off. |
614
- | React to event GroupValue write | The node will react (will send a msg to the flow) each time it receives a *write* telegram from the KNX bus. Usually, you want that. |
615
- | React to event GroupValue response | The node will react (will send a msg to the flow) each time it receives a *response* telegram from the KNX bus. Usually, you want that for particular scenarios. |
616
- | React to event GroupValue read | The node will react (will send a msg to the flow) each time it receives a *read* telegram from the KNX bus. Usually, you want that if you're want to send a custom value to the KNX BUS. |
588
+ | Telegram type | *write* to send write telegram (usually, you want that), otherwise you can choose the telegram's type to react to. |
589
+ | Send payload to KNX only if changed (RBE filter) | *Report by change* filter. If set, only the msg input (from the Flow) having different values each time, will be sent to the KNX bus. If you intend to send everytime the same value, turn it off. |
590
+ | Read status on start | Read group address status, every time Node-Red starts and at every reconnection to the KNX Gateway. The node stores all group address values to a file, so you can choose wether to read from file or from the KNX bus. |
591
+ | React only by changed payload (RBE filter) | *Report by change* filter. If set, only the msg output (to KNX bus) having different values each time, will be sent to the msg output's flow. If you intend to send everytime the same value, leave it off. |
592
+ | React to write telegrams | The node will react (will send a msg to the flow) each time it receives a *write* telegram from the KNX bus. Usually, you want that. |
593
+ | React to response telegrams | The node will react (will send a msg to the flow) each time it receives a *response* telegram from the KNX bus. Usually, you want that for particular scenarios. |
594
+ | React to read telegrams | The node will react (will send a msg to the flow) each time it receives a *read* telegram from the KNX bus. Usually, you want that if you're want to send a custom value to the KNX BUS. |
617
595
  | Format input | Allow you to format numeric values received from the KNX Bus. |
618
596
 
619
597
  <br/>
@@ -146,7 +146,7 @@ module.exports = function (RED) {
146
146
  node.inputmessage = RED.util.cloneMessage(msg); // 28/03/2020 Store the message to be passed through.
147
147
  }
148
148
 
149
- // 25/07/2019 if payload is read or the output type is set to "read", do a read, otherwise, write to the bus
149
+ // 25/07/2019 if payload is read or the Telegram type is set to "read", do a read, otherwise, write to the bus
150
150
  if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true) || node.outputtype === 'read') {
151
151
  // READ: Send a Read request to the bus
152
152
  let grpaddr = '';
@@ -156,7 +156,7 @@ module.exports = function (RED) {
156
156
  // 29/12/2020 Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
157
157
  if (msg.hasOwnProperty('knx')) {
158
158
  if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Response' || msg.knx.event === 'GroupValue_Read'))) {
159
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/output type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
159
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
160
160
  const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
161
161
  node.setNodeStatus({
162
162
  fill: 'red', shape: 'ring', text: `DISABLED due to a circulare reference while READ (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
@@ -178,7 +178,7 @@ module.exports = function (RED) {
178
178
  // 29/12/2020 Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
179
179
  if (msg.hasOwnProperty('knx')) {
180
180
  if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Response' || msg.knx.event === 'GroupValue_Read'))) {
181
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-2. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/output type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
181
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-2. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
182
182
  const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
183
183
  node.setNodeStatus({
184
184
  fill: 'red', shape: 'ring', text: `DISABLED due to a circulare reference while READ-2 (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
@@ -201,7 +201,7 @@ module.exports = function (RED) {
201
201
  // 29/12/2020 Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
202
202
  if (msg.hasOwnProperty('knx')) {
203
203
  if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Response' || msg.knx.event === 'GroupValue_Read'))) {
204
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-3. Node ${node.id} The read request hasn't been sent. Two nodes with same group address and reaction/output type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
204
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-3. Node ${node.id} The read request hasn't been sent. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
205
205
  node.setNodeStatus({
206
206
  fill: 'red', shape: 'ring', text: `NOT SENT due to a circulare reference while READ-3 (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
207
207
  });
@@ -322,7 +322,7 @@ module.exports = function (RED) {
322
322
  // Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
323
323
  if (msg.hasOwnProperty('knx')) {
324
324
  if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Write' && outputtype === 'write') || (msg.knx.event === 'GroupValue_Response' && outputtype === 'response') || (msg.knx.event === 'GroupValue_Response' && outputtype === 'read') || (msg.knx.event === 'GroupValue_Read' && outputtype === 'read'))) {
325
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection. The node ${node.id} has been temporarely disabled. Two nodes with same group address and reaction/output type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
325
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection. The node ${node.id} has been temporarely disabled. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
326
326
  const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
327
327
  node.setNodeStatus({
328
328
  fill: 'red', shape: 'ring', text: `DISABLED due to a circulare reference (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
@@ -54,233 +54,233 @@ module.exports = function (RED) {
54
54
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
55
55
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
56
56
  node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
57
- } catch (error) {
58
- }
57
+ } catch (error) {
59
58
  }
59
+ }
60
60
 
61
61
  // Used to call the status update from the config node.
62
62
  node.setLocalStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
63
- const dDate = new Date()
64
- // 30/08/2019 Display only the things selected in the config
65
- GA = (typeof GA === 'undefined' || GA == '') ? '' : '(' + GA + ') '
66
- devicename = devicename || ''
67
- dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
68
- try {
69
- node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
70
- } catch (error) {
71
- }
63
+ const dDate = new Date()
64
+ // 30/08/2019 Display only the things selected in the config
65
+ GA = (typeof GA === 'undefined' || GA == '') ? '' : '(' + GA + ') '
66
+ devicename = devicename || ''
67
+ dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
68
+ try {
69
+ node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
70
+ } catch (error) {
72
71
  }
72
+ }
73
73
 
74
- // This function is called by the knx-ultimate config node, to output a msg.payload.
75
- node.handleSend = msg => {
76
- try {
77
- if (!msg.knx.dpt.startsWith('1.')) return
78
- } catch (error) {
79
- return
80
- }
81
- let bFound = false // 24/04/2021 true if the cycle below found a match, otherwise false
74
+ // This function is called by the knx-ultimate config node, to output a msg.payload.
75
+ node.handleSend = msg => {
76
+ try {
77
+ if (!msg.knx.dpt.startsWith('1.')) return
78
+ } catch (error) {
79
+ return
80
+ }
81
+ let bFound = false // 24/04/2021 true if the cycle below found a match, otherwise false
82
82
 
83
- // Update the node.rules with the values taken from the file, if any, otherwise leave the default value
84
- for (let i = 0; i < node.rules.length; i++) {
85
- // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
86
- var rule = node.rules[i]
87
- if (msg.topic === rule.topic) {
88
- if (msg.payload == true) {
89
- bFound = true
90
- // Add the device to the array of alertedDevices
91
- const oTrovato = node.alertedDevices.find(a => a.topic === rule.topic)
92
- if (oTrovato === undefined) {
93
- node.alertedDevices.unshift({ topic: rule.topic, devicename: rule.devicename, longdevicename: rule.longdevicename }) // Add to the begin of array
94
- if (node.whentostart === 'ifnewalert') node.send([null, null, node.getThirdPinMSG()])
95
- }
96
- node.setLocalStatus({ fill: 'red', shape: 'dot', text: 'Alert', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
97
- } else {
98
- // Remove the device from the array
99
- node.alertedDevices = node.alertedDevices.filter(a => a.topic !== msg.topic)
100
- node.setLocalStatus({ fill: 'green', shape: 'dot', text: 'Restore', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
83
+ // Update the node.rules with the values taken from the file, if any, otherwise leave the default value
84
+ for (let i = 0; i < node.rules.length; i++) {
85
+ // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
86
+ var rule = node.rules[i]
87
+ if (msg.topic === rule.topic) {
88
+ if (msg.payload == true) {
89
+ bFound = true
90
+ // Add the device to the array of alertedDevices
91
+ const oTrovato = node.alertedDevices.find(a => a.topic === rule.topic)
92
+ if (oTrovato === undefined) {
93
+ node.alertedDevices.unshift({ topic: rule.topic, devicename: rule.devicename, longdevicename: rule.longdevicename }) // Add to the begin of array
94
+ if (node.whentostart === 'ifnewalert') node.send([null, null, node.getThirdPinMSG()])
101
95
  }
96
+ node.setLocalStatus({ fill: 'red', shape: 'dot', text: 'Alert', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
97
+ } else {
98
+ // Remove the device from the array
99
+ node.alertedDevices = node.alertedDevices.filter(a => a.topic !== msg.topic)
100
+ node.setLocalStatus({ fill: 'green', shape: 'dot', text: 'Restore', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
102
101
  }
103
102
  }
104
-
105
- // If there's some device to alert, stop current timer and restart
106
- // This allow the last alerted device to be outputted immediately
107
- if (bFound && node.whentostart === 'ifnewalert' && node.alertedDevices.length > 0) {
108
- clearTimeout(node.timerSend)
109
- // Send directly the second and third message PIN
110
- node.send([null, node.getSecondPinMSG(), null])
111
- node.curIndexAlertedDevice = 0 // Restart form the beginning
112
- node.startTimer()
113
- }
114
103
  }
115
104
 
116
- // Get the msg to be outputted on second PIN
117
- node.getSecondPinMSG = () => {
118
- if (node.alertedDevices.length > 0) {
119
- const msg = {}
120
- let sRet = ''
121
- let sRetLong = ''
122
- let sTopic = ''
123
- node.alertedDevices.forEach(function (item) {
124
- sTopic += item.topic + ', '
125
- if (item.devicename !== undefined && item.devicename !== '') sRet += item.devicename + ', '
126
- if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong += item.longdevicename + ', '
127
- })
128
- sTopic = sTopic.slice(0, -2)
129
- if (sRet.length > 2) sRet = sRet.slice(0, -2)
130
- if (sRetLong.length > 2) sRetLong = sRetLong.slice(0, -2)
131
- msg.topic = sTopic
132
- msg.devicename = sRet
133
- msg.longdevicename = sRetLong
134
- msg.count = node.alertedDevices.length
135
- msg.payload = true
136
- return msg
137
- }
105
+ // If there's some device to alert, stop current timer and restart
106
+ // This allow the last alerted device to be outputted immediately
107
+ if (bFound && node.whentostart === 'ifnewalert' && node.alertedDevices.length > 0) {
108
+ clearTimeout(node.timerSend)
109
+ // Send directly the second and third message PIN
110
+ node.send([null, node.getSecondPinMSG(), null])
111
+ node.curIndexAlertedDevice = 0 // Restart form the beginning
112
+ node.startTimer()
138
113
  }
114
+ }
139
115
 
140
- // Get the msg to be outputted on third PIN
141
- node.getThirdPinMSG = () => {
142
- if (node.alertedDevices.length > 0) {
143
- const msg = {}
144
- let sRet = ''
145
- let sRetLong = ''
146
- let sTopic = ''
147
- const item = node.alertedDevices[0] // Pick the last alerted device
148
- sTopic = item.topic
149
- if (item.devicename !== undefined && item.devicename !== '') sRet = item.devicename
150
- if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong = item.longdevicename
151
- msg.topic = sTopic
152
- msg.devicename = sRet
153
- msg.longdevicename = sRetLong
154
- msg.count = node.alertedDevices.length
155
- msg.payload = true
156
- return msg
157
- }
116
+ // Get the msg to be outputted on second PIN
117
+ node.getSecondPinMSG = () => {
118
+ if (node.alertedDevices.length > 0) {
119
+ const msg = {}
120
+ let sRet = ''
121
+ let sRetLong = ''
122
+ let sTopic = ''
123
+ node.alertedDevices.forEach(function (item) {
124
+ sTopic += item.topic + ', '
125
+ if (item.devicename !== undefined && item.devicename !== '') sRet += item.devicename + ', '
126
+ if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong += item.longdevicename + ', '
127
+ })
128
+ sTopic = sTopic.slice(0, -2)
129
+ if (sRet.length > 2) sRet = sRet.slice(0, -2)
130
+ if (sRetLong.length > 2) sRetLong = sRetLong.slice(0, -2)
131
+ msg.topic = sTopic
132
+ msg.devicename = sRet
133
+ msg.longdevicename = sRetLong
134
+ msg.count = node.alertedDevices.length
135
+ msg.payload = true
136
+ return msg
158
137
  }
138
+ }
159
139
 
160
- // 24/04/2021 perform a read on all GA in the rule list. Called both from node.on("input") and knxUltimate-config
161
- node.initialReadAllDevicesInRules = () => {
162
- if (node.server) {
163
- let grpaddr = ''
164
- for (let i = 0; i < node.rules.length; i++) {
165
- // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
166
- const rule = node.rules[i]
167
- // READ: Send a Read request to the bus
168
- grpaddr = rule.topic
169
- try {
170
- // Check if it's a group address
171
- // const ret = Address.KNXAddress.createFromString(grpaddr, Address.KNXAddress.TYPE_GROUP)
172
- node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Read', payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
173
- node.server.writeQueueAdd({ grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id })
174
- } catch (error) {
175
- node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Not a KNX GA ' + error.message, payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
176
- }
177
- }
178
- } else {
179
- node.setLocalStatus({ fill: 'red', shape: 'ring', text: 'No gateway selected. Unable to read from KNX bus', payload: '', GA: '', dpt: '', devicename: '' })
180
- }
140
+ // Get the msg to be outputted on third PIN
141
+ node.getThirdPinMSG = () => {
142
+ if (node.alertedDevices.length > 0) {
143
+ const msg = {}
144
+ let sRet = ''
145
+ let sRetLong = ''
146
+ let sTopic = ''
147
+ const item = node.alertedDevices[0] // Pick the last alerted device
148
+ sTopic = item.topic
149
+ if (item.devicename !== undefined && item.devicename !== '') sRet = item.devicename
150
+ if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong = item.longdevicename
151
+ msg.topic = sTopic
152
+ msg.devicename = sRet
153
+ msg.longdevicename = sRetLong
154
+ msg.count = node.alertedDevices.length
155
+ msg.payload = true
156
+ return msg
181
157
  }
158
+ }
182
159
 
183
- node.on('input', function (msg) {
184
- if (typeof msg === 'undefined') return
185
- if (msg.hasOwnProperty('start')) {
186
- clearTimeout(node.timerSend)
187
- node.curIndexAlertedDevice = 0 // Restart form the beginning
188
- if (node.alertedDevices.length > 0) {
189
- node.send([null, node.getSecondPinMSG(), node.getThirdPinMSG()])
190
- node.startTimer()
191
- } else {
192
- // Nothing more to output
193
- node.sendNoMoreDevices()
160
+ // 24/04/2021 perform a read on all GA in the rule list. Called both from node.on("input") and knxUltimate-config
161
+ node.initialReadAllDevicesInRules = () => {
162
+ if (node.server) {
163
+ let grpaddr = ''
164
+ for (let i = 0; i < node.rules.length; i++) {
165
+ // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
166
+ const rule = node.rules[i]
167
+ // READ: Send a Read request to the bus
168
+ grpaddr = rule.topic
169
+ try {
170
+ // Check if it's a group address
171
+ // const ret = Address.KNXAddress.createFromString(grpaddr, Address.KNXAddress.TYPE_GROUP)
172
+ node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Read', payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
173
+ node.server.writeQueueAdd({ grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id })
174
+ } catch (error) {
175
+ node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Not a KNX GA ' + error.message, payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
194
176
  }
195
- return
196
- }
197
-
198
- // 24/04/2021 if payload is read or the output type is set to "read", do a read
199
- if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
200
- node.initialReadAllDevicesInRules()
201
- return
202
- }
203
-
204
- if (msg.topic === undefined) {
205
- node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide a msg.topic', payload: '', GA: '', dpt: '', devicename: '' })
206
- return
207
177
  }
208
- if (msg.payload === undefined) {
209
- node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide payload (true/false)', payload: '', GA: '', dpt: '', devicename: '' })
210
- return
211
- }
212
- msg.knx = { dpt: '1.001' }
213
- node.handleSend(msg)
214
- })
178
+ } else {
179
+ node.setLocalStatus({ fill: 'red', shape: 'ring', text: 'No gateway selected. Unable to read from KNX bus', payload: '', GA: '', dpt: '', devicename: '' })
180
+ }
181
+ }
215
182
 
216
- node.on('close', function (done) {
183
+ node.on('input', function (msg) {
184
+ if (typeof msg === 'undefined') return
185
+ if (msg.hasOwnProperty('start')) {
217
186
  clearTimeout(node.timerSend)
218
- if (node.server) {
219
- node.server.removeClient(node)
220
- }
221
- done()
222
- })
223
-
224
- node.handleTimer = () => {
187
+ node.curIndexAlertedDevice = 0 // Restart form the beginning
225
188
  if (node.alertedDevices.length > 0) {
226
- const count = node.alertedDevices.length
227
- if (node.curIndexAlertedDevice > count - 1) {
228
- node.curIndexAlertedDevice = 0
229
- if (node.whentostart === 'manualstart') {
230
- node.curIndexAlertedDevice = 0 // Restart form the beginning
231
- return
232
- }
233
- }
234
- // Create output message
235
- try {
236
- const curDev = node.alertedDevices[node.curIndexAlertedDevice] // is { topic: rule.topic, devicename: rule.devicename }
237
- const msg = {}
238
- msg.topic = curDev.topic
239
- msg.count = count
240
- msg.devicename = curDev.devicename
241
- msg.longdevicename = curDev.longdevicename
242
- msg.payload = true
243
- node.send([msg, null, null])
244
- } catch (error) {
245
- }
246
- node.curIndexAlertedDevice += 1
247
- // Restart timer
189
+ node.send([null, node.getSecondPinMSG(), node.getThirdPinMSG()])
248
190
  node.startTimer()
249
191
  } else {
250
192
  // Nothing more to output
251
193
  node.sendNoMoreDevices()
252
194
  }
195
+ return
253
196
  }
254
197
 
255
- // Start timer
256
- node.startTimer = () => {
257
- clearTimeout(node.timerSend)
258
- node.timerSend = setTimeout(() => {
259
- node.handleTimer()
260
- }, node.timerinterval * 1000)
198
+ // 24/04/2021 if payload is read or the Telegram type is set to "read", do a read
199
+ if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
200
+ node.initialReadAllDevicesInRules()
201
+ return
261
202
  }
262
203
 
263
- // As soon as there no more devices..
264
- node.sendNoMoreDevices = () => {
265
- const msg = {}
266
- msg.topic = ''
267
- msg.count = 0
268
- msg.devicename = ''
269
- msg.longdevicename = ''
270
- msg.payload = false
271
- node.send([msg, msg, msg])
204
+ if (msg.topic === undefined) {
205
+ node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide a msg.topic', payload: '', GA: '', dpt: '', devicename: '' })
206
+ return
272
207
  }
208
+ if (msg.payload === undefined) {
209
+ node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide payload (true/false)', payload: '', GA: '', dpt: '', devicename: '' })
210
+ return
211
+ }
212
+ msg.knx = { dpt: '1.001' }
213
+ node.handleSend(msg)
214
+ })
273
215
 
274
- // Init
275
- node.sendNoMoreDevices()
276
-
277
- // On each deploy, unsubscribe+resubscribe
216
+ node.on('close', function (done) {
217
+ clearTimeout(node.timerSend)
278
218
  if (node.server) {
279
219
  node.server.removeClient(node)
280
- if (node.topic !== '' || node.topicSave !== '') {
281
- node.server.addClient(node)
220
+ }
221
+ done()
222
+ })
223
+
224
+ node.handleTimer = () => {
225
+ if (node.alertedDevices.length > 0) {
226
+ const count = node.alertedDevices.length
227
+ if (node.curIndexAlertedDevice > count - 1) {
228
+ node.curIndexAlertedDevice = 0
229
+ if (node.whentostart === 'manualstart') {
230
+ node.curIndexAlertedDevice = 0 // Restart form the beginning
231
+ return
232
+ }
233
+ }
234
+ // Create output message
235
+ try {
236
+ const curDev = node.alertedDevices[node.curIndexAlertedDevice] // is { topic: rule.topic, devicename: rule.devicename }
237
+ const msg = {}
238
+ msg.topic = curDev.topic
239
+ msg.count = count
240
+ msg.devicename = curDev.devicename
241
+ msg.longdevicename = curDev.longdevicename
242
+ msg.payload = true
243
+ node.send([msg, null, null])
244
+ } catch (error) {
282
245
  }
246
+ node.curIndexAlertedDevice += 1
247
+ // Restart timer
248
+ node.startTimer()
249
+ } else {
250
+ // Nothing more to output
251
+ node.sendNoMoreDevices()
252
+ }
253
+ }
254
+
255
+ // Start timer
256
+ node.startTimer = () => {
257
+ clearTimeout(node.timerSend)
258
+ node.timerSend = setTimeout(() => {
259
+ node.handleTimer()
260
+ }, node.timerinterval * 1000)
261
+ }
262
+
263
+ // As soon as there no more devices..
264
+ node.sendNoMoreDevices = () => {
265
+ const msg = {}
266
+ msg.topic = ''
267
+ msg.count = 0
268
+ msg.devicename = ''
269
+ msg.longdevicename = ''
270
+ msg.payload = false
271
+ node.send([msg, msg, msg])
272
+ }
273
+
274
+ // Init
275
+ node.sendNoMoreDevices()
276
+
277
+ // On each deploy, unsubscribe+resubscribe
278
+ if (node.server) {
279
+ node.server.removeClient(node)
280
+ if (node.topic !== '' || node.topicSave !== '') {
281
+ node.server.addClient(node)
283
282
  }
284
283
  }
285
- RED.nodes.registerType('knxUltimateAlerter', knxUltimateAlerter)
286
284
  }
285
+ RED.nodes.registerType('knxUltimateAlerter', knxUltimateAlerter)
286
+ }
@@ -22,6 +22,7 @@ module.exports = function (RED) {
22
22
  node.formatmultiplyvalue = 1;
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
+ node.hueDevice = config.hueDevice;
25
26
 
26
27
  // Used to call the status update from the config node.
27
28
  node.setNodeStatus = ({
@@ -83,11 +84,7 @@ module.exports = function (RED) {
83
84
  }
84
85
  if (node.serverHue) {
85
86
  node.serverHue.removeClient(node);
86
- // I must get the object, to store read the battery status
87
- // I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
88
- if (node.serverHue !== null && node.serverHue.hueManager !== null) {
89
- node.serverHue.addClient(node);
90
- }
87
+ node.serverHue.addClient(node);
91
88
  }
92
89
 
93
90
  node.on('input', (msg) => {
@@ -26,6 +26,7 @@ module.exports = function (RED) {
26
26
  node.formatdecimalsvalue = 2;
27
27
  node.short_releaseValue = false;
28
28
  node.isTimerDimStopRunning = false;
29
+ node.hueDevice = config.hueDevice;
29
30
 
30
31
  // Used to call the status update from the config node.
31
32
  node.setNodeStatus = ({
@@ -58,7 +58,7 @@ module.exports = function (RED) {
58
58
  node.handleSend = (msg) => {
59
59
  if (node.currentHUEDevice === undefined) {
60
60
  node.setNodeStatusHue({
61
- fill: "grey",
61
+ fill: "red",
62
62
  shape: "ring",
63
63
  text: "Currently not ready.",
64
64
  payload: "",
@@ -621,13 +621,7 @@ module.exports = function (RED) {
621
621
  }
622
622
  if (node.serverHue) {
623
623
  node.serverHue.removeClient(node);
624
- if (node.serverHue !== null && node.serverHue.hueManager !== null) {
625
- try {
626
- node.serverHue.addClient(node);
627
- } catch (err) {
628
- RED.log.error(`Errore knxUltimateHueLight node.currentHUEDevice ${err.message}`);
629
- }
630
- }
624
+ node.serverHue.addClient(node);
631
625
  }
632
626
 
633
627
  node.on("input", (msg) => { });
@@ -22,6 +22,7 @@ module.exports = function (RED) {
22
22
  node.formatmultiplyvalue = 1;
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
+ node.hueDevice = config.hueDevice;
25
26
 
26
27
  // Used to call the status update from the config node.
27
28
  node.setNodeStatus = ({ fill, shape, text, payload }) => {
@@ -76,11 +77,7 @@ module.exports = function (RED) {
76
77
  }
77
78
  if (node.serverHue) {
78
79
  node.serverHue.removeClient(node);
79
- // I must get the object, to store read the status
80
- // I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
81
- if (node.serverHue !== null && node.serverHue.hueManager !== null) {
82
- node.serverHue.addClient(node);
83
- }
80
+ node.serverHue.addClient(node);
84
81
  }
85
82
 
86
83
  node.on('input', function (msg) {
@@ -22,6 +22,7 @@ module.exports = function (RED) {
22
22
  node.formatmultiplyvalue = 1;
23
23
  node.formatnegativevalue = "leave";
24
24
  node.formatdecimalsvalue = 2;
25
+ node.hueDevice = config.hueDevice;
25
26
 
26
27
  // Used to call the status update from the config node.
27
28
  node.setNodeStatus = ({ fill, shape, text, payload }) => { };
@@ -24,6 +24,7 @@ module.exports = function (RED) {
24
24
  node.formatmultiplyvalue = 1;
25
25
  node.formatnegativevalue = 'leave';
26
26
  node.formatdecimalsvalue = 2;
27
+ node.hueDevice = config.hueDevice;
27
28
 
28
29
  // Used to call the status update from the config node.
29
30
  node.setNodeStatus = ({ fill, shape, text, payload }) => {
@@ -25,6 +25,7 @@ module.exports = function (RED) {
25
25
  node.formatdecimalsvalue = 2;
26
26
  node.brightnessState = 0;
27
27
  node.isTimerDimStopRunning = false;
28
+ node.hueDevice = config.hueDevice;
28
29
 
29
30
  // Used to call the status update from the config node.
30
31
  node.setNodeStatus = ({
@@ -22,6 +22,7 @@ module.exports = function (RED) {
22
22
  node.formatmultiplyvalue = 1;
23
23
  node.formatnegativevalue = 'leave';
24
24
  node.formatdecimalsvalue = 2;
25
+ node.hueDevice = config.hueDevice;
25
26
 
26
27
  // Used to call the status update from the config node.
27
28
  node.setNodeStatus = ({
@@ -84,9 +85,7 @@ module.exports = function (RED) {
84
85
  }
85
86
  if (node.serverHue) {
86
87
  node.serverHue.removeClient(node);
87
- if (node.serverHue !== null && node.serverHue.hueManager !== null) {
88
- node.serverHue.addClient(node);
89
- }
88
+ node.serverHue.addClient(node);
90
89
  }
91
90
 
92
91
  node.on('input', (msg) => {
@@ -334,7 +334,7 @@ module.exports = function (RED) {
334
334
  node.send({ topic: node.name || node.topic, operation: 'Enabled', payload: node.sheddingStage })
335
335
  }
336
336
 
337
- // 24/04/2021 if payload is read or the output type is set to "read", do a read
337
+ // 24/04/2021 if payload is read or the Telegram type is set to "read", do a read
338
338
  if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
339
339
  node.initialReadAllDevicesInRules()
340
340
  }
@@ -8,21 +8,21 @@
8
8
  "node-input-topic": "Group Addr.",
9
9
  "node-input-outputtopic": "Topic",
10
10
  "node-input-dpt": "Datapoint",
11
- "node-input-initialread": "Read status upon connection",
11
+ "node-input-initialread": "Read status on start",
12
12
  "node-input-initialread0": "No",
13
- "node-input-initialread1": "Read from KNX BUS (to receive the response from BUS, enable also -React to event GroupValue response-)",
13
+ "node-input-initialread1": "Read from KNX BUS (to receive the response from BUS, enable also -React to response telegrams-)",
14
14
  "node-input-initialread2": "Read the last value saved to file prior to disconnection",
15
- "node-input-initialread3": "Read the last value saved to file prior to disconnection. If the file is missing, read from KNX BUS (to receive the response from BUS, enable also -React to event GroupValue response-)",
16
- "node-input-notifyreadrequest": "React to event GroupValue read",
17
- "node-input-notifyresponse": "React to event GroupValue response",
18
- "node-input-notifywrite": "React to event GroupValue write",
15
+ "node-input-initialread3": "Read the last value saved to file prior to disconnection. If the file is missing, read from KNX BUS (to receive the response from BUS, enable also -React to response telegrams-)",
16
+ "node-input-notifyreadrequest": "React to read telegrams",
17
+ "node-input-notifyresponse": "React to response telegrams",
18
+ "node-input-notifywrite": "React to write telegrams",
19
19
  "node-input-notifyreadrequestalsorespondtobus": "Auto send node value as response to the BUS",
20
20
  "node-input-notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized": "If value is undefined, send",
21
21
  "node-input-listenallga": "Universal mode (listen to all Group Addresses)",
22
22
  "node-input-name": "Node Name",
23
- "node-input-outputtype": "Output Type",
24
- "node-input-outputRBE": "Send payload to BUS only if changed (RBE filter)",
25
- "node-input-inputRBE": "React only if payload from BUS is changed (RBE filter)",
23
+ "node-input-outputtype": "Telegram type",
24
+ "node-input-outputRBE": "Send payload to KNX only if changed (RBE filter)",
25
+ "node-input-inputRBE": "React only by changed payload (RBE filter)",
26
26
  "node-input-formatmultiplyvalue": "Multiply",
27
27
  "node-input-formatnegativevalue": "Negatives",
28
28
  "node-input-formatdecimalsvalue": "Decimals",
@@ -36,8 +36,8 @@
36
36
  "Advancedoptions": "Advanced options",
37
37
  "Formatting": "Format INPUT (datagram coming from the KNX BUS)",
38
38
  "Operations": "NUMERIC VALUES (operations are performed in order)",
39
- "OUTPUT": "OUTPUT (sends datagram to the KNX BUS)",
40
- "INPUT": "INPUT (listen to datagram from the KNX BUS)",
39
+ "OUTPUT": "CONTROL (payload to KNX bus)",
40
+ "INPUT": "STATUS (payload from KNX BUS)",
41
41
  "NUMERICVALUES": "NUMERIC VALUES (operations are performed in order)",
42
42
  "noETSWarning": "You haven't imported the ETS csv file. <br/> The node will work as blind transmitter/receiver. <a href=\"https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/2.-Node-Configuration\" target='_blank'>Click here for help about that</a>.",
43
43
  "notify-DPT3007": "You selected a relative DIM. Please <a target='_blank' href='https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/-Sample---Dimming'>click here to view this sample</a> and learn how to handle such payload.",
@@ -11,7 +11,7 @@
11
11
  <table style="font-size:12px">
12
12
  <tr>
13
13
  <td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greendot.png"></img></td>
14
- <td>React to event GroupValue write</td>
14
+ <td>React to write telegrams</td>
15
15
  </tr>
16
16
  <tr>
17
17
  <td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greenring.png"></img></td>
@@ -19,7 +19,7 @@
19
19
  </tr>
20
20
  <tr>
21
21
  <td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/bluedot.png"></img></td>
22
- <td>React to event GroupValue response.</td>
22
+ <td>React to response telegrams.</td>
23
23
  </tr>
24
24
  <tr>
25
25
  <td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/bluering.png"></img></td>
@@ -27,7 +27,7 @@
27
27
  </tr>
28
28
  <tr>
29
29
  <td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greudot.png"></img></td>
30
- <td>React to event GroupValue read.</td>
30
+ <td>React to read telegrams.</td>
31
31
  </tr>
32
32
  <tr>
33
33
  <td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greyring.png"></img></td>
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "2.2.4",
6
+ "version": "2.2.5",
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",