node-red-contrib-knx-ultimate 4.1.21 → 4.1.23

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/nodes/knxUltimate-config.html +88 -42
  3. package/nodes/knxUltimate.html +68 -12
  4. package/nodes/knxUltimate.js +67 -8
  5. package/nodes/knxUltimateMultiRouting.html +2 -1
  6. package/nodes/knxUltimateRouterFilter.html +2 -1
  7. package/nodes/locales/de/knxUltimate-config.json +8 -1
  8. package/nodes/locales/de/knxUltimate.html +3 -1
  9. package/nodes/locales/de/knxUltimate.json +4 -2
  10. package/nodes/locales/de/knxUltimateMultiRouting.json +10 -0
  11. package/nodes/locales/de/knxUltimateRouterFilter.json +10 -0
  12. package/nodes/locales/en/knxUltimate-config.json +8 -1
  13. package/nodes/locales/en/knxUltimate.html +3 -1
  14. package/nodes/locales/en/knxUltimate.json +4 -2
  15. package/nodes/locales/en/knxUltimateMultiRouting.json +10 -0
  16. package/nodes/locales/en/knxUltimateRouterFilter.json +10 -0
  17. package/nodes/locales/es/knxUltimate-config.json +8 -1
  18. package/nodes/locales/es/knxUltimate.html +3 -1
  19. package/nodes/locales/es/knxUltimate.json +4 -2
  20. package/nodes/locales/es/knxUltimateMultiRouting.json +10 -0
  21. package/nodes/locales/es/knxUltimateRouterFilter.json +10 -0
  22. package/nodes/locales/fr/knxUltimate-config.json +8 -1
  23. package/nodes/locales/fr/knxUltimate.html +3 -1
  24. package/nodes/locales/fr/knxUltimate.json +4 -2
  25. package/nodes/locales/fr/knxUltimateMultiRouting.json +10 -0
  26. package/nodes/locales/fr/knxUltimateRouterFilter.json +10 -0
  27. package/nodes/locales/it/knxUltimate-config.json +8 -1
  28. package/nodes/locales/it/knxUltimate.html +3 -1
  29. package/nodes/locales/it/knxUltimate.json +4 -2
  30. package/nodes/locales/it/knxUltimateMultiRouting.json +10 -0
  31. package/nodes/locales/it/knxUltimateRouterFilter.json +10 -0
  32. package/nodes/locales/zh-CN/knxUltimate-config.json +8 -1
  33. package/nodes/locales/zh-CN/knxUltimate.html +3 -1
  34. package/nodes/locales/zh-CN/knxUltimate.json +4 -2
  35. package/nodes/locales/zh-CN/knxUltimateMultiRouting.json +10 -0
  36. package/nodes/locales/zh-CN/knxUltimateRouterFilter.json +10 -0
  37. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -6,7 +6,16 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
- **Version 4.1.21** - January 2026<br/>
9
+ **Version 4.1.23** - February 2026<br/>
10
+
11
+ - CHANGE: **KNX Gateway config**: persisted GA cache is no longer deleted automatically when opening the editor.<br/>
12
+ - NEW: **KNX Gateway config**: added an explicit **Clear persisted GA cache** button in the Utility tab.<br/>
13
+ - NEW: **KNX Device**: added **Periodic send stored value** option (cyclic write) with configurable interval (disabled in Universal mode).<br/>
14
+ - UI: **KNX Gateway config**: added a **Node Status** section label above status-related options.<br/>
15
+ - i18n: unified manual button labels across locales: **KNX Read** and **Toggle boolean**.<br/>
16
+ - Docs/help/wiki: updated Gateway configuration and Device pages in all supported languages to document the new options.<br/>
17
+
18
+ **Version 4.1.22** - February 2026<br/>
10
19
 
11
20
  - NEW: **KNX Multi Routing**: added KNX routing counter (hop count) handling to prevent telegram loops: optional **Respect routing counter (drop if 0)** and **Decrement routing counter when routing**.<br/>
12
21
  - FIX: **KNX Multi Routing**: improved behaviour with rewritten telegrams by relying on coherent cEMI; `knx.routingCounter` is exposed based on `knx.cemi.hex`.<br/>
@@ -958,8 +958,8 @@
958
958
  try { updateSecureModeAvailability(); } catch (e) { }
959
959
 
960
960
 
961
- // 14/08/2021 Elimino il file delle persistenze di questo nodo
962
- $.getJSON("deletePersistGAFile?serverId=" + node.id, (data) => { });
961
+ // NOTE: Do not auto-delete persisted GA cache on editor open.
962
+ // Users can explicitly clear it from the Utility tab.
963
963
 
964
964
  // 06/07/2023 Tabs
965
965
  // *****************************
@@ -991,6 +991,41 @@
991
991
  $("#debugText").val(sRetDebugText); // Store the config-node);
992
992
  });
993
993
 
994
+ $("#clearpersistga").click(function () {
995
+ try {
996
+ const confirmText = node._("knxUltimate-config.utility.clear_persist_confirm");
997
+ const okText = node._("knxUltimate-config.utility.clear_persist_ok");
998
+ const cancelText = node._("knxUltimate-config.utility.clear_persist_cancel");
999
+ const doneText = node._("knxUltimate-config.utility.clear_persist_done");
1000
+ const failText = node._("knxUltimate-config.utility.clear_persist_fail");
1001
+
1002
+ var dlg = RED.notify(confirmText, {
1003
+ modal: true,
1004
+ fixed: true,
1005
+ type: "warning",
1006
+ buttons: [
1007
+ {
1008
+ text: cancelText,
1009
+ click: function () { dlg.close(); }
1010
+ },
1011
+ {
1012
+ text: okText,
1013
+ class: "primary",
1014
+ click: function () {
1015
+ dlg.close();
1016
+ $.getJSON("deletePersistGAFile?serverId=" + node.id, (data) => {
1017
+ RED.notify(doneText, { type: "success", timeout: 2500 });
1018
+ }).fail(function (jqXHR, textStatus, errorThrown) {
1019
+ const err = (errorThrown || textStatus || "").toString();
1020
+ RED.notify(failText + (err ? (": " + err) : ""), { type: "error", timeout: 5000 });
1021
+ });
1022
+ }
1023
+ }
1024
+ ]
1025
+ });
1026
+ } catch (e) { }
1027
+ });
1028
+
994
1029
 
995
1030
 
996
1031
  },
@@ -1388,27 +1423,32 @@
1388
1423
  <input type="number" id="node-config-input-delaybetweentelegrams" style="width:20%">
1389
1424
  </div>
1390
1425
 
1391
- <div class="form-row">
1392
- <label for="node-config-input-loglevel">
1393
- <i class="fa fa-question-circle"></i>
1394
- <span data-i18n="knxUltimate-config.advanced.log_level"></span>
1395
- </label>
1396
- <select id="node-config-input-loglevel" style="width:40%;">
1397
- <option value="disable" data-i18n="knxUltimate-config.advanced.select_silent"></option>
1398
- <option value="error" data-i18n="knxUltimate-config.advanced.select_error"></option>
1399
- <option value="warn" data-i18n="knxUltimate-config.advanced.select_warning"></option>
1400
- <option value="info" data-i18n="knxUltimate-config.advanced.select_info"></option>
1401
- <option value="debug" data-i18n="knxUltimate-config.advanced.select_debug"></option>
1402
- </select>
1403
- <!-- <// DEBUG LEVELS: success < debug < info < warn < error < disable
1404
- </div> -->
1405
- </div>
1406
-
1407
- <div class="form-row">
1408
- <label for="node-config-input-statusUpdateThrottle">
1409
- <i class="fa fa-clock-o"></i>
1410
- <span data-i18n="knxUltimate-config.advanced.status_throttle"></span>
1411
- </label>
1426
+ <div class="form-row">
1427
+ <label for="node-config-input-loglevel">
1428
+ <i class="fa fa-question-circle"></i>
1429
+ <span data-i18n="knxUltimate-config.advanced.log_level"></span>
1430
+ </label>
1431
+ <select id="node-config-input-loglevel" style="width:40%;">
1432
+ <option value="disable" data-i18n="knxUltimate-config.advanced.select_silent"></option>
1433
+ <option value="error" data-i18n="knxUltimate-config.advanced.select_error"></option>
1434
+ <option value="warn" data-i18n="knxUltimate-config.advanced.select_warning"></option>
1435
+ <option value="info" data-i18n="knxUltimate-config.advanced.select_info"></option>
1436
+ <option value="debug" data-i18n="knxUltimate-config.advanced.select_debug"></option>
1437
+ </select>
1438
+ <!-- <// DEBUG LEVELS: success < debug < info < warn < error < disable
1439
+ </div> -->
1440
+ </div>
1441
+
1442
+ <div class="form-row">
1443
+ <label> <span style="font-weight:bold">Node Status</span>
1444
+ </label>
1445
+ </div>
1446
+
1447
+ <div class="form-row">
1448
+ <label for="node-config-input-statusUpdateThrottle">
1449
+ <i class="fa fa-clock-o"></i>
1450
+ <span data-i18n="knxUltimate-config.advanced.status_throttle"></span>
1451
+ </label>
1412
1452
  <select id="node-config-input-statusUpdateThrottle" style="width:40%;">
1413
1453
  <option value="0" data-i18n="knxUltimate-config.advanced.status_throttle_none"></option>
1414
1454
  <option value="1" data-i18n="knxUltimate-config.advanced.status_throttle_1s"></option>
@@ -1485,26 +1525,32 @@
1485
1525
  </p>
1486
1526
  </div>
1487
1527
 
1488
- <div id="tabs-4">
1489
- <p>
1490
- <div class="form-row">
1491
- <label><i class="fa fa-sign-in"></i> <span data-i18n="knxUltimate-config.utility.gather_debug"></span></label>
1492
- <input type="button" id="getinfocam" class="ui-button ui-corner-all ui-widget"
1493
- style="background-color:#AEE1FF;width:150px" data-i18n="[value]knxUltimate-config.utility.read_button">
1494
- </div>
1495
- <div class="form-row">
1496
- <label><i class="fa fa-sign-in"></i> <span data-i18n="knxUltimate-config.utility.get_all_used_ga"></span></label>
1497
- <input type="button" id="getallgaused" class="ui-button ui-corner-all ui-widget"
1498
- style="background-color:#AEE1FF;width:150px" data-i18n="[value]knxUltimate-config.utility.read_button">
1499
- </div>
1500
-
1501
- <div class="form-row" id="divDebugText" style="display: none;">
1502
- <textarea rows="10" id="debugText" style="width:100%"></textarea>
1503
- </div>
1504
- </p>
1505
- </div>
1528
+ <div id="tabs-4">
1529
+ <p>
1530
+ <div class="form-row">
1531
+ <label><i class="fa fa-sign-in"></i> <span data-i18n="knxUltimate-config.utility.gather_debug"></span></label>
1532
+ <input type="button" id="getinfocam" class="ui-button ui-corner-all ui-widget"
1533
+ style="background-color:#AEE1FF;width:150px" data-i18n="[value]knxUltimate-config.utility.read_button">
1534
+ </div>
1535
+ <div class="form-row">
1536
+ <label><i class="fa fa-sign-in"></i> <span data-i18n="knxUltimate-config.utility.get_all_used_ga"></span></label>
1537
+ <input type="button" id="getallgaused" class="ui-button ui-corner-all ui-widget"
1538
+ style="background-color:#AEE1FF;width:150px" data-i18n="[value]knxUltimate-config.utility.read_button">
1539
+ </div>
1540
+
1541
+ <div class="form-row">
1542
+ <label><i class="fa fa-trash"></i> <span data-i18n="knxUltimate-config.utility.clear_persist_label"></span></label>
1543
+ <input type="button" id="clearpersistga" class="ui-button ui-corner-all ui-widget"
1544
+ style="background-color:#FFD2D2;width:150px" data-i18n="[value]knxUltimate-config.utility.clear_persist_button">
1545
+ </div>
1546
+
1547
+ <div class="form-row" id="divDebugText" style="display: none;">
1548
+ <textarea rows="10" id="debugText" style="width:100%"></textarea>
1549
+ </div>
1550
+ </p>
1551
+ </div>
1506
1552
  </div>
1507
1553
 
1508
1554
  </div>
1509
1555
 
1510
- </script>
1556
+ </script>
@@ -37,7 +37,9 @@
37
37
  buttonEnabled: { value: true },
38
38
  buttonMode: { value: "toggle" },
39
39
  buttonStaticValue: { value: "" },
40
- buttonToggleInitial: { value: "false" }
40
+ buttonToggleInitial: { value: "false" },
41
+ periodicSend: { value: false },
42
+ periodicSendInterval: { value: 60 }
41
43
  },
42
44
  inputs: 1,
43
45
  outputs: 1,
@@ -54,17 +56,19 @@
54
56
  return ((this.outputRBE === "true" || this.outputRBE === true) ? "|rbe| " : "") + functionSendMsgToKNXCode + (this.name || this.topic || "KNX Device") + (this.setTopicType === 'str' || this.setTopicType === undefined ? '' : ' [' + (this.setTopicType === 'listenAllGA' ? 'Universal' : this.setTopicType) + ']') + functionreceiveMsgFromKNXCode + ((this.inputRBE === "true" || this.inputRBE === true) ? " |rbe|" : "")
55
57
  },
56
58
  paletteLabel: "KNX DEVICE",
57
- button: {
58
- enabled: function () {
59
- return !this.changed;
60
- },
61
- visible: function () {
62
- return this.buttonEnabled === true || this.buttonEnabled === "true";
63
- },
64
- onclick: function () {
65
- const node = this;
66
- const mode = node.buttonMode || 'read';
67
- const request = { id: node.id, mode };
59
+ button: {
60
+ enabled: function () {
61
+ return !this.changed;
62
+ },
63
+ visible: function () {
64
+ const isUniversal = this.setTopicType === 'listenAllGA' || this.listenallga === true || this.listenallga === 'true';
65
+ if (isUniversal) return false;
66
+ return this.buttonEnabled === true || this.buttonEnabled === "true";
67
+ },
68
+ onclick: function () {
69
+ const node = this;
70
+ const mode = node.buttonMode || 'read';
71
+ const request = { id: node.id, mode };
68
72
  if (mode === 'value') {
69
73
  request.value = node.buttonStaticValue;
70
74
  }
@@ -679,6 +683,14 @@
679
683
  }
680
684
  })
681
685
 
686
+ $("#node-input-periodicSend").on('change', function () {
687
+ if ($("#node-input-periodicSend").is(":checked")) {
688
+ $("#divPeriodicSendInterval").show()
689
+ } else {
690
+ $("#divPeriodicSendInterval").hide()
691
+ }
692
+ })
693
+
682
694
  // Set the group address type
683
695
  if (node.setTopicType === undefined) {
684
696
  node.setTopicType = 'str';
@@ -790,6 +802,12 @@
790
802
  $("#divNode-input-initialread").show();
791
803
  $("#divOutputRBE").show()
792
804
  $("#divInputRBE").show()
805
+ $("#divPeriodicSend").show()
806
+ if ($("#node-input-periodicSend").is(':checked')) {
807
+ $("#divPeriodicSendInterval").show()
808
+ } else {
809
+ $("#divPeriodicSendInterval").hide()
810
+ }
793
811
  } else if ($("#node-input-setTopicType").val() === 'listenAllGA') {
794
812
  $("#node-input-topic").hide();
795
813
  $("#divDatapointSelection").hide()
@@ -797,6 +815,9 @@
797
815
  $("#node-input-outputRBE").val("false")
798
816
  $("#divInputRBE").hide()
799
817
  $("#node-input-inputRBE").val("false")
818
+ $("#divPeriodicSend").hide()
819
+ $("#divPeriodicSendInterval").hide()
820
+ $("#node-input-periodicSend").prop('checked', false)
800
821
  $("#divnotifyreadrequestautoreact").hide();
801
822
  $("#divTopic").hide()
802
823
  $("#divNode-input-initialread").hide();
@@ -811,6 +832,12 @@
811
832
  $("#divOutputRBE").show()
812
833
  $("#divInputRBE").show()
813
834
  $("#divTopic").show()
835
+ $("#divPeriodicSend").show()
836
+ if ($("#node-input-periodicSend").is(':checked')) {
837
+ $("#divPeriodicSendInterval").show()
838
+ } else {
839
+ $("#divPeriodicSendInterval").hide()
840
+ }
814
841
  if ($("#node-input-notifyreadrequest").is(":checked")) {
815
842
  $("#divnotifyreadrequestautoreact").show();
816
843
  } else {
@@ -881,6 +908,22 @@
881
908
  $("#node-input-setTopicType").val('listenAllGA');
882
909
  }
883
910
 
911
+ // Periodic send UI sync (avoid triggering setTopicType change handler that clears fields)
912
+ try {
913
+ if ($("#node-input-setTopicType").val() === 'listenAllGA') {
914
+ $("#divPeriodicSend").hide()
915
+ $("#divPeriodicSendInterval").hide()
916
+ $("#node-input-periodicSend").prop('checked', false)
917
+ } else {
918
+ $("#divPeriodicSend").show()
919
+ if ($("#node-input-periodicSend").is(':checked')) {
920
+ $("#divPeriodicSendInterval").show()
921
+ } else {
922
+ $("#divPeriodicSendInterval").hide()
923
+ }
924
+ }
925
+ } catch (e) { }
926
+
884
927
  // 19/02/2020 Used to alert the user if the CSV file has not been loaded and to get the server sooner als deploy
885
928
  // ###########################
886
929
  $("#node-input-server").change(function () {
@@ -1144,6 +1187,19 @@
1144
1187
  <option value="false" data-i18n="knxUltimate.selectlists.RBE_out_disable"></option>
1145
1188
  </select>
1146
1189
  </div>
1190
+ <div class="form-row" id="divPeriodicSend">
1191
+ <input type="checkbox" id="node-input-periodicSend"
1192
+ style="display:inline-block; width:auto; vertical-align:top;" />
1193
+ <label style="width:85%" for="node-input-periodicSend">
1194
+ <i class="fa fa-repeat"></i> <span data-i18n="knxUltimate.properties.node-input-periodicSend"></span>
1195
+ </label>
1196
+ </div>
1197
+ <div class="form-row" id="divPeriodicSendInterval">
1198
+ <label style="width:180px" for="node-input-periodicSendInterval">
1199
+ <i class="fa fa-clock-o"></i> <span data-i18n="knxUltimate.properties.node-input-periodicSendInterval"></span>
1200
+ </label>
1201
+ <input type="number" id="node-input-periodicSendInterval" style="width:120px" min="1">
1202
+ </div>
1147
1203
  <hr>
1148
1204
  <div class="form-row">
1149
1205
  <dt>
@@ -342,6 +342,7 @@ module.exports = function (RED) {
342
342
  if (node.inputRBE === false) node.inputRBE = 'false'
343
343
 
344
344
  node.currentPayload = '' // Current value for the RBE input and for the .previouspayload msg
345
+ node._hasCurrentPayload = false // True once we have a meaningful stored value
345
346
  node.icountMessageInWindow = 0 // Used to prevent looping messages
346
347
  node.messageQueue = [] // 01/01/2020 All messages from the flow to the node, will be queued and will be sent separated by 60 milliseconds each. Use uf the underlying api "minimumDelay" is not possible because the telegram order isn't mantained.
347
348
  node.formatmultiplyvalue = (typeof config.formatmultiplyvalue === 'undefined' ? 1 : config.formatmultiplyvalue)
@@ -355,12 +356,52 @@ module.exports = function (RED) {
355
356
  node.buttonStaticValue = config.buttonStaticValue || ''
356
357
  node.buttonToggleInitial = coerceBoolean(config.buttonToggleInitial)
357
358
  node._buttonToggleState = node.buttonToggleInitial
359
+ node.periodicSend = coerceBoolean(config.periodicSend)
360
+ node.periodicSendInterval = Number(config.periodicSendInterval)
361
+ if (!Number.isFinite(node.periodicSendInterval) || node.periodicSendInterval <= 0) node.periodicSendInterval = 0
362
+ node.timerPeriodicSend = null
358
363
 
359
364
  const syncButtonToggleState = (value) => {
360
365
  if (node.buttonMode === 'toggle' && /^1\./.test(node.dpt || '')) {
361
366
  node._buttonToggleState = coerceBoolean(value)
362
367
  }
363
368
  }
369
+
370
+ const clearPeriodicSendTimer = () => {
371
+ if (node.timerPeriodicSend !== null) {
372
+ try { clearInterval(node.timerPeriodicSend) } catch (e) { /* noop */ }
373
+ node.timerPeriodicSend = null
374
+ }
375
+ }
376
+
377
+ const startPeriodicSendTimer = () => {
378
+ clearPeriodicSendTimer()
379
+ if (node.listenallga === true) return
380
+ if (node.periodicSend !== true) return
381
+ if (!Number.isFinite(node.periodicSendInterval) || node.periodicSendInterval <= 0) return
382
+
383
+ const intervalMs = Math.max(1000, Math.round(node.periodicSendInterval * 1000))
384
+ node.timerPeriodicSend = setInterval(() => {
385
+ try {
386
+ if (node._hasCurrentPayload !== true) return
387
+ if (!node.serverKNX || node.serverKNX.linkStatus !== 'connected') return
388
+ if (!node.serverKNX.knxConnection) return
389
+ if (node.listenallga === true) return
390
+ if (typeof node.topic !== 'string' || node.topic === '') return
391
+ if (typeof node.dpt !== 'string' || node.dpt === '' || node.dpt === 'auto') return
392
+
393
+ node.serverKNX.sendKNXTelegramToKNXEngine({
394
+ grpaddr: node.topic,
395
+ payload: node.currentPayload,
396
+ dpt: node.dpt,
397
+ outputtype: 'write',
398
+ nodecallerid: node.id
399
+ })
400
+ } catch (error) {
401
+ try { node.sysLogger?.debug(`Periodic send failed: ${error.message}`) } catch (e) { /* noop */ }
402
+ }
403
+ }, intervalMs)
404
+ }
364
405
  try {
365
406
  const baseLogLevel = (node.serverKNX && node.serverKNX.loglevel) ? node.serverKNX.loglevel : 'error'
366
407
  node.sysLogger = new loggerClass({ loglevel: baseLogLevel, setPrefix: node.type + ' <' + (node.name || node.id || '') + '>' })
@@ -480,6 +521,16 @@ module.exports = function (RED) {
480
521
  }
481
522
  } catch (error) { }
482
523
 
524
+ // Update stored value from KNX telegrams (used for RBE, button toggle sync and optional periodic send).
525
+ try {
526
+ const evt = msg && msg.knx ? msg.knx.event : undefined
527
+ if ((evt === 'GroupValue_Write' || evt === 'GroupValue_Response') && Object.prototype.hasOwnProperty.call(msg, 'payload')) {
528
+ node.currentPayload = msg.payload
529
+ node._hasCurrentPayload = true
530
+ syncButtonToggleState(msg.payload)
531
+ }
532
+ } catch (error) { /* noop */ }
533
+
483
534
  // #region "Inject the msg to the JS code, then output msg to the flow"
484
535
  // -+++++++++++++++++++++++++++++++++++++++++++
485
536
  if (node.receiveMsgFromKNXCode !== undefined) {
@@ -531,6 +582,7 @@ module.exports = function (RED) {
531
582
  // *********************************
532
583
  if (msg.hasOwnProperty('resetRBE')) {
533
584
  node.currentPayload = ''
585
+ node._hasCurrentPayload = false
534
586
  node.setNodeStatus({
535
587
  fill: 'grey', shape: 'ring', text: 'Reset RBE filter on this node.', payload: '', GA: '', dpt: '', devicename: ''
536
588
  })
@@ -775,6 +827,7 @@ module.exports = function (RED) {
775
827
  if (outputtype == 'response') {
776
828
  try {
777
829
  node.currentPayload = msg.payload// 31/12/2019 Set the current value (because, if the node is a virtual device, then it'll never fire "GroupValue_Write" in the server node, causing the currentPayload to never update)
830
+ node._hasCurrentPayload = true
778
831
  syncButtonToggleState(msg.payload)
779
832
  node.serverKNX.sendKNXTelegramToKNXEngine({
780
833
  grpaddr, payload: msg.payload, dpt, outputtype, nodecallerid: node.id
@@ -787,6 +840,7 @@ module.exports = function (RED) {
787
840
  // 05/01/2021 Updates only the internal currentPayload value.
788
841
  try {
789
842
  node.currentPayload = msg.payload
843
+ node._hasCurrentPayload = true
790
844
  syncButtonToggleState(msg.payload)
791
845
  node.serverKNX.sendKNXTelegramToKNXEngine({
792
846
  grpaddr, payload: msg.payload, dpt, outputtype, nodecallerid: node.id
@@ -798,6 +852,7 @@ module.exports = function (RED) {
798
852
  } else {
799
853
  try {
800
854
  node.currentPayload = msg.payload// 31/12/2019 Set the current value (because, if the node is a virtual device, then it'll never fire "GroupValue_Write" in the server node, causing the currentPayload to never update)
855
+ node._hasCurrentPayload = true
801
856
  syncButtonToggleState(msg.payload)
802
857
  node.setNodeStatus({
803
858
  fill: 'green', shape: 'dot', text: 'Writing', payload: msg.payload, GA: grpaddr, dpt, devicename: ''
@@ -814,6 +869,7 @@ module.exports = function (RED) {
814
869
 
815
870
  node.on('close', (done) => {
816
871
  if (node.timerTTLInputMessage !== null) clearTimeout(node.timerTTLInputMessage)
872
+ clearPeriodicSendTimer()
817
873
  node.inputmessage = {}
818
874
  if (node.serverKNX) {
819
875
  node.serverKNX.removeClient(node)
@@ -825,9 +881,9 @@ module.exports = function (RED) {
825
881
  })
826
882
 
827
883
  // On each deploy, add the node to the server list
828
- if (node.serverKNX) {
829
- node.serverKNX.addClient(node)
830
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`addClient: node id ${node.id}` || '' + ` with topic ${node.topic || ''} has been added to the server.`)
884
+ if (node.serverKNX) {
885
+ node.serverKNX.addClient(node)
886
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`addClient: node id ${node.id}` || '' + ` with topic ${node.topic || ''} has been added to the server.`)
831
887
  // 05/11/2021 if the node is set to read from bus, issue a read.
832
888
  // "node-input-initialread0": "No",
833
889
  // "node-input-initialread1": "Leggi dal BUS KNX",
@@ -840,8 +896,11 @@ module.exports = function (RED) {
840
896
  const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
841
897
  node.emit('input', { readstatus: true })
842
898
  }, 3000)
843
- }
844
- }
845
- }
846
- RED.nodes.registerType('knxUltimate', knxUltimate)
847
- }
899
+ }
900
+ }
901
+
902
+ // Start periodic send timer (optional)
903
+ startPeriodicSendTimer()
904
+ }
905
+ RED.nodes.registerType('knxUltimate', knxUltimate)
906
+ }
@@ -56,7 +56,8 @@
56
56
 
57
57
  <script type="text/html" data-template-name="knxUltimateMultiRouting">
58
58
  <div class="form-row">
59
- <b><span data-i18n="knxUltimateMultiRouting.title"></span></b>
59
+ <b><span data-i18n="knxUltimateMultiRouting.title"></span></b>&nbsp&nbsp<span style="color:red" &nbsp &nbsp<i class="fa fa-youtube"></i></span>&nbsp<a
60
+ target="_blank" href="https://youtu.be/fGT6BrkTkiM"><u><span data-i18n="common.youtube_sample"></span></u></a>
60
61
  <br/><br/>
61
62
  <label for="node-input-mode"><i class="fa fa-sliders"></i> <span data-i18n="knxUltimateMultiRouting.properties.mode"></span></label>
62
63
  <select id="node-input-mode">
@@ -59,7 +59,8 @@
59
59
 
60
60
  <script type="text/html" data-template-name="knxUltimateRouterFilter">
61
61
  <div class="form-row">
62
- <b><span data-i18n="knxUltimateRouterFilter.title"></span></b>
62
+ <b><span data-i18n="knxUltimateRouterFilter.title"></span></b>&nbsp&nbsp<span style="color:red" &nbsp &nbsp<i class="fa fa-youtube"></i></span>&nbsp<a
63
+ target="_blank" href="https://youtu.be/fGT6BrkTkiM"><u><span data-i18n="common.youtube_sample"></span></u></a>
63
64
  <br/><br/>
64
65
  </div>
65
66
 
@@ -126,7 +126,14 @@
126
126
  "gather_debug": "Debug und Log zur Fehlersuche sammeln",
127
127
  "get_all_used_ga": "Alle verwendeten GA für KNX-Routing-Filter abrufen",
128
128
  "read_button": "Lesen",
129
- "copy_ga_router": "Kopieren Sie diese Gruppenadressen in die Routing-Tabelle Ihres KNX/IP-Routers."
129
+ "copy_ga_router": "Kopieren Sie diese Gruppenadressen in die Routing-Tabelle Ihres KNX/IP-Routers.",
130
+ "clear_persist_label": "Persistenten GA-Cache für dieses Gateway löschen",
131
+ "clear_persist_button": "Löschen",
132
+ "clear_persist_confirm": "Dadurch wird die persistente GA-Cache-Datei für dieses Gateway gelöscht. Fortfahren?",
133
+ "clear_persist_ok": "Löschen",
134
+ "clear_persist_cancel": "Abbrechen",
135
+ "clear_persist_done": "Persistenter GA-Cache gelöscht.",
136
+ "clear_persist_fail": "Persistenter GA-Cache konnte nicht gelöscht werden"
130
137
  }
131
138
  }
132
139
  }
@@ -24,7 +24,7 @@ Im Editor kann pro Node ein kleiner Button angezeigt werden, über den du KNX-Te
24
24
  |Eigenschaft|Beschreibung|
25
25
  |--|--|
26
26
  | Manuellen Button anzeigen | Blendet den Button im Workspace und in der Knotenliste ein bzw. aus. |
27
- | Schaltflächenaktion | Legt fest, was beim Klick geschieht. **KNX-Leseanforderung senden** erzeugt ein normales Read-Telegramm. **Boolean umschalten (Schreiben)** steht bei DPT 1.x zur Verfügung und wechselt zwischen _true_ und _false_. **Benutzerdefinierten Wert schreiben** sendet den angegebenen Wert (muss zum eingestellten Datapoint passen). |
27
+ | Schaltflächenaktion | Legt fest, was beim Klick geschieht. **KNX Read senden** erzeugt ein normales Read-Telegramm. **Toggle boolean** steht bei DPT 1.x zur Verfügung und wechselt zwischen _true_ und _false_. **Benutzerdefinierten Wert schreiben** sendet den angegebenen Wert (muss zum eingestellten Datapoint passen). |
28
28
  | Initialer Toggle-Status | (Nur für boolesche Datapoints) Startwert der Toggle-Funktion. Der Zustand bleibt mit den ankommenden KNX-Telegrammen synchron. |
29
29
  | Benutzerdefinierter Wert | Wert für den Modus „Benutzerdefinierten Wert schreiben“. Erlaubt sind JSON-Literale wie `42`, `true`, `"Text"` oder `{ "red": 255 }`. |
30
30
 
@@ -44,6 +44,8 @@ Der Button wird nur eingeblendet, wenn die Option aktiv ist. Im Universalmodus i
44
44
  || **Vom Node-EINGANG zum KNX-BUS** |
45
45
  | Telegrammtyp | `write` zum Senden eines Schreib-Telegramms (üblich), alternativ Reaktion auf andere Typen. |
46
46
  | RBE-Filter | "Report by change". Wenn aktiv, sendet nur geänderte Werte zum BUS. Für identische Wiederholungen deaktivieren. Bei Aktivierung wird "rbe" dem Nodename hinzugefügt. |
47
+ | Periodisches Senden (gespeicherter Wert) | Wenn aktiv, sendet der Node den zuletzt gespeicherten Wert in festen Intervallen als _write_-Telegramm auf den KNX-Bus. Diese Option umgeht absichtlich den Output-RBE. |
48
+ | Intervall periodisches Senden | Intervall in Sekunden für das periodische Senden. |
47
49
  || **Vom KNX-BUS zum Node-AUSGANG** |
48
50
  | Status beim Start lesen | Liest den GA-Status bei Editorstart und jeder Wiederverbindung. Werte werden in einer Datei gepuffert, Quelle wählbar (Datei/BUS). |
49
51
  | RBE-Filter | Wie oben, aber für Ausgaben zum Flow. |
@@ -22,6 +22,8 @@
22
22
  "node-input-name": "Node Name",
23
23
  "node-input-outputtype": "Ausgabetyp",
24
24
  "node-input-outputRBE": "Payload nur bei Änderung an den KNX-BUS senden (RBE-Filter)",
25
+ "node-input-periodicSend": "Gespeicherten Wert periodisch an KNX senden (zyklisches Write)",
26
+ "node-input-periodicSendInterval": "Intervall (Sekunden)",
25
27
  "node-input-inputRBE": "Nur bei Änderungen vom KNX-Bus reagieren (RBE filter)",
26
28
  "node-input-formatmultiplyvalue": "Multiplizieren",
27
29
  "node-input-formatnegativevalue": "Negativ",
@@ -37,8 +39,8 @@
37
39
  "button": {
38
40
  "enable": "Schaltfläche für manuelle Befehle im Editor anzeigen",
39
41
  "mode": "Schaltflächenaktion",
40
- "mode_read": "KNX-Leseanforderung senden",
41
- "mode_toggle": "Boolean umschalten (Schreiben)",
42
+ "mode_read": "KNX Read senden",
43
+ "mode_toggle": "Toggle boolean",
42
44
  "mode_value": "Benutzerdefinierten Wert schreiben",
43
45
  "toggleInitial": "Initialer Toggle-Status",
44
46
  "toggleInitial_true": "Start mit EIN (true)",
@@ -24,5 +24,15 @@
24
24
  "outputs": {
25
25
  "raw": "RAW telegrams"
26
26
  }
27
+ },
28
+ "common": {
29
+ "ga": "GA",
30
+ "dpt": "DPT",
31
+ "name": "Name",
32
+ "youtube_sample": "YouTube-Beispiel",
33
+ "knx_gw": "KNX-Gateway",
34
+ "hue_bridge": "Hue Bridge",
35
+ "philips_hue": "Philips HUE",
36
+ "read": "Lesen"
27
37
  }
28
38
  }
@@ -36,5 +36,15 @@
36
36
  "passed": "Passed",
37
37
  "dropped": "Dropped"
38
38
  }
39
+ },
40
+ "common": {
41
+ "ga": "GA",
42
+ "dpt": "DPT",
43
+ "name": "Name",
44
+ "youtube_sample": "YouTube-Beispiel",
45
+ "knx_gw": "KNX-Gateway",
46
+ "hue_bridge": "Hue Bridge",
47
+ "philips_hue": "Philips HUE",
48
+ "read": "Lesen"
39
49
  }
40
50
  }
@@ -130,7 +130,14 @@
130
130
  "gather_debug": "Gather debug and log for troubleshoot",
131
131
  "get_all_used_ga": "Get all used GA for KNX routing filter",
132
132
  "read_button": "Read",
133
- "copy_ga_router": "Copy these group addresses in your routing table list of your KNX/IP router."
133
+ "copy_ga_router": "Copy these group addresses in your routing table list of your KNX/IP router.",
134
+ "clear_persist_label": "Clear persisted GA cache for this gateway",
135
+ "clear_persist_button": "Clear",
136
+ "clear_persist_confirm": "This deletes the persisted GA cache file for this gateway. Continue?",
137
+ "clear_persist_ok": "Delete",
138
+ "clear_persist_cancel": "Cancel",
139
+ "clear_persist_done": "Persisted GA cache deleted.",
140
+ "clear_persist_fail": "Unable to delete persisted GA cache"
134
141
  }
135
142
  }
136
143
  }
@@ -24,7 +24,7 @@ The editor can expose a per-node button that manually issues a KNX command witho
24
24
  |Property|Description|
25
25
  |--|--|
26
26
  | Show manual button | When enabled the small button appears on the node tile both in the palette and in the flow editor. |
27
- | Button action | Choose what happens when you click the button. **Send KNX read** issues a standard read telegram. **Toggle boolean (write)** is available for datapoint type 1.x and alternates between _true_ and _false_ each time you click the button. **Write custom value** sends the value you provide (the value must be compatible with the configured datapoint). |
27
+ | Button action | Choose what happens when you click the button. **Send KNX Read** issues a standard read telegram. **Toggle boolean** is available for datapoint type 1.x and alternates between _true_ and _false_ each time you click the button. **Write custom value** sends the value you provide (the value must be compatible with the configured datapoint). |
28
28
  | Initial toggle state | (Boolean datapoints only) Sets the starting value used by the toggle action. The state automatically keeps in sync with telegrams that the node receives from KNX. |
29
29
  | Custom value | The payload used by the custom value mode. You can enter any JSON literal: for example `42`, `true`, `"text"` or `{ "red": 255, "green": 0 }`. |
30
30
 
@@ -44,6 +44,8 @@ The button is only displayed when the option is enabled. If the node works in un
44
44
  || **From node's INPUT PIN to KNX BUS** |
45
45
  | Telegram type | _write_ to send write telegram (usually, you want that), otherwise you can choose the telegram's type to react to. |
46
46
  | 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. If enabled, "rbe" indication will be added to node's name.|
47
+ | Periodic send stored value | When enabled, the node sends the last stored value to the KNX bus at the given interval (as a _write_ telegram). This bypasses output RBE on purpose. |
48
+ | Periodic send interval | Interval in seconds for the periodic send. |
47
49
  || **From KNX BUS to node's ouput PIN** |
48
50
  | 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. |
49
51
  | 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. If enabled, "rbe" indication will be added to node's name. |
@@ -22,6 +22,8 @@
22
22
  "node-input-name": "Node Name",
23
23
  "node-input-outputtype": "Telegram type",
24
24
  "node-input-outputRBE": "Send payload to KNX only if changed (RBE filter)",
25
+ "node-input-periodicSend": "Periodically send the stored value to KNX (cyclic write)",
26
+ "node-input-periodicSendInterval": "Interval (seconds)",
25
27
  "node-input-inputRBE": "React only by changed payload (RBE filter)",
26
28
  "node-input-formatmultiplyvalue": "Multiply",
27
29
  "node-input-formatnegativevalue": "Negatives",
@@ -37,8 +39,8 @@
37
39
  "button": {
38
40
  "enable": "Show manual command button in editor",
39
41
  "mode": "Button action",
40
- "mode_read": "Send KNX read",
41
- "mode_toggle": "Toggle boolean (write)",
42
+ "mode_read": "Send KNX Read",
43
+ "mode_toggle": "Toggle boolean",
42
44
  "mode_value": "Write custom value",
43
45
  "toggleInitial": "Initial toggle state",
44
46
  "toggleInitial_true": "Start with ON (true)",
@@ -24,5 +24,15 @@
24
24
  "outputs": {
25
25
  "raw": "RAW telegrams"
26
26
  }
27
+ },
28
+ "common": {
29
+ "ga": "GA",
30
+ "dpt": "DPT",
31
+ "name": "Name",
32
+ "youtube_sample": "Youtube sample",
33
+ "knx_gw": "KNX GW",
34
+ "hue_bridge": "Hue Bridge",
35
+ "philips_hue": "Philips HUE",
36
+ "read": "Read"
27
37
  }
28
38
  }
@@ -36,5 +36,15 @@
36
36
  "passed": "Passed",
37
37
  "dropped": "Dropped"
38
38
  }
39
+ },
40
+ "common": {
41
+ "ga": "GA",
42
+ "dpt": "DPT",
43
+ "name": "Name",
44
+ "youtube_sample": "Youtube sample",
45
+ "knx_gw": "KNX GW",
46
+ "hue_bridge": "Hue Bridge",
47
+ "philips_hue": "Philips HUE",
48
+ "read": "Read"
39
49
  }
40
50
  }
@@ -130,7 +130,14 @@
130
130
  "gather_debug": "Reúna la depuración y el registro para la solución de problemas",
131
131
  "get_all_used_ga": "Obtenga todos los usos GA para el filtro de enrutamiento KNX",
132
132
  "read_button": "Leer",
133
- "copy_ga_router": "Copie estas direcciones de grupo en su lista de tabla de enrutamiento de su enrutador KNX/IP."
133
+ "copy_ga_router": "Copie estas direcciones de grupo en su lista de tabla de enrutamiento de su enrutador KNX/IP.",
134
+ "clear_persist_label": "Borrar caché persistente de GA de esta pasarela",
135
+ "clear_persist_button": "Borrar",
136
+ "clear_persist_confirm": "Esto elimina el archivo de caché persistente de GA para esta pasarela. ¿Continuar?",
137
+ "clear_persist_ok": "Eliminar",
138
+ "clear_persist_cancel": "Cancelar",
139
+ "clear_persist_done": "Caché persistente de GA eliminada.",
140
+ "clear_persist_fail": "No se puede eliminar la caché persistente de GA"
134
141
  }
135
142
  }
136
143
  }
@@ -24,7 +24,7 @@ El editor puede mostrar, para cada nodo, un pequeño botón que envía un comand
24
24
  | Propiedad | Descripción |
25
25
  |--|--|
26
26
  | Mostrar botón manual | Activa o desactiva la visualización del botón en el área de trabajo y en la lista de nodos. |
27
- | Acción del botón | Define la operación al hacer clic. **Enviar lectura KNX** emite un telegrama de lectura estándar. **Alternar booleano (escritura)** está disponible para datapoint 1.x y alterna los valores _true_/_false_ en cada pulsación. **Escribir valor personalizado** envía el valor indicado (debe ser coherente con el datapoint configurado). |
27
+ | Acción del botón | Define la operación al hacer clic. **Enviar KNX Read** emite un telegrama de lectura estándar. **Toggle boolean** está disponible para datapoint 1.x y alterna los valores _true_/_false_ en cada pulsación. **Escribir valor personalizado** envía el valor indicado (debe ser coherente con el datapoint configurado). |
28
28
  | Estado inicial del toggle | (Solo para datapoint booleanos) Establece el valor inicial que utiliza la acción de alternancia. El estado se sincroniza automáticamente con los telegramas recibidos desde el BUS. |
29
29
  | Valor personalizado | Payload utilizado por el modo “Escribir valor personalizado”. Se aceptan literales JSON como `42`, `true`, `"texto"` o `{ "red": 255 }`. |
30
30
 
@@ -44,6 +44,8 @@ El botón solo aparece cuando la opción está habilitada. En modo universal la
44
44
  || **Desde el pin de entrada del nodo hasta el bus KNX** |
45
45
  | Tipo de telegrama | _Write_ para enviar el telegrama de escritura (por lo general, desea eso), de lo contrario, puede elegir el tipo de telegrama para reaccionar. |
46
46
  | Filtro RBE | _Report por Change_ Filter. Si se establece, solo la entrada MSG (del flujo) que tiene diferentes valores cada vez, se enviará al bus KNX. Si tiene la intención de enviar cada vez el mismo valor, apáguelo. Si está habilitado, la indicación "RBE" se agregará al nombre del nodo. |
47
+ | Envío periódico del valor almacenado | Si está habilitado, el nodo envía al bus KNX el último valor almacenado a intervalos regulares (telegrama _write_). Esta opción omite intencionadamente el RBE de salida. |
48
+ | Intervalo de envío periódico | Intervalo en segundos del envío periódico. |
47
49
  || **Desde el bus KNX hasta el pin de ojera del nodo** |
48
50
  | Leer el estado al inicio | Lea el estado de la dirección de grupo, cada vez que el nodo-rojo comienza y en cada reconexión a la puerta de enlace KNX. El nodo almacena todos los valores de la dirección de grupo en un archivo, por lo que puede elegir Wether para leer desde el archivo o del bus KNX. |
49
51
  | Filtro RBE | _Report por Change_ Filter. Si se establece, solo la salida MSG (al bus KNX) que tiene valores diferentes cada vez, se enviará al flujo de la salida de MSG. Si tiene la intención de enviar cada vez el mismo valor, déjelo apagado. Si está habilitado, la indicación "RBE" se agregará al nombre del nodo. |
@@ -22,6 +22,8 @@
22
22
  "node-input-name": "Nombre de nodo",
23
23
  "node-input-outputtype": "Tipo de telegrama",
24
24
  "node-input-outputRBE": "Enviar carga útil a KNX solo si se cambia (filtro RBE)",
25
+ "node-input-periodicSend": "Enviar periódicamente el valor almacenado a KNX (escritura cíclica)",
26
+ "node-input-periodicSendInterval": "Intervalo (segundos)",
25
27
  "node-input-inputRBE": "Reaccionar solo por carga útil modificada (filtro RBE)",
26
28
  "node-input-formatmultiplyvalue": "Multiplicar",
27
29
  "node-input-formatnegativevalue": "Negativo",
@@ -37,8 +39,8 @@
37
39
  "button": {
38
40
  "enable": "Mostrar botón manual en el editor",
39
41
  "mode": "Acción del botón",
40
- "mode_read": "Enviar lectura KNX",
41
- "mode_toggle": "Alternar booleano (escritura)",
42
+ "mode_read": "Enviar KNX Read",
43
+ "mode_toggle": "Toggle boolean",
42
44
  "mode_value": "Escribir valor personalizado",
43
45
  "toggleInitial": "Estado inicial del toggle",
44
46
  "toggleInitial_true": "Iniciar en ON (true)",
@@ -24,5 +24,15 @@
24
24
  "outputs": {
25
25
  "raw": "RAW telegrams"
26
26
  }
27
+ },
28
+ "common": {
29
+ "ga": "Georgia",
30
+ "dpt": "DPT",
31
+ "name": "Nombre",
32
+ "youtube_sample": "Muestra de youtube",
33
+ "knx_gw": "KNX GW",
34
+ "hue_bridge": "Hue Bridge",
35
+ "philips_hue": "Tono Philips",
36
+ "read": "Leer"
27
37
  }
28
38
  }
@@ -36,5 +36,15 @@
36
36
  "passed": "Passed",
37
37
  "dropped": "Dropped"
38
38
  }
39
+ },
40
+ "common": {
41
+ "ga": "Georgia",
42
+ "dpt": "DPT",
43
+ "name": "Nombre",
44
+ "youtube_sample": "Muestra de youtube",
45
+ "knx_gw": "KNX GW",
46
+ "hue_bridge": "Hue Bridge",
47
+ "philips_hue": "Tono Philips",
48
+ "read": "Leer"
39
49
  }
40
50
  }
@@ -130,7 +130,14 @@
130
130
  "gather_debug": "Rassemblez le débogage et le journal pour le dépannage",
131
131
  "get_all_used_ga": "Obtenez tous les GA d'occasion pour le filtre de routage KNX",
132
132
  "read_button": "Lire",
133
- "copy_ga_router": "Copiez ces adresses de groupe dans votre liste de table de routage de votre routeur KNX / IP."
133
+ "copy_ga_router": "Copiez ces adresses de groupe dans votre liste de table de routage de votre routeur KNX / IP.",
134
+ "clear_persist_label": "Effacer le cache GA persistant de cette passerelle",
135
+ "clear_persist_button": "Effacer",
136
+ "clear_persist_confirm": "Cela supprime le fichier de cache GA persistant pour cette passerelle. Continuer ?",
137
+ "clear_persist_ok": "Supprimer",
138
+ "clear_persist_cancel": "Annuler",
139
+ "clear_persist_done": "Cache GA persistant supprimé.",
140
+ "clear_persist_fail": "Impossible de supprimer le cache GA persistant"
134
141
  }
135
142
  }
136
143
  }
@@ -24,7 +24,7 @@ L’éditeur peut afficher, pour chaque nœud, un petit bouton permettant d’en
24
24
  | Propriété | Description |
25
25
  |--|--|
26
26
  | Afficher le bouton manuel | Affiche ou masque le bouton dans l’espace de travail et dans la palette de nœuds. |
27
- | Action du bouton | Définit l’opération effectuée au clic. **Envoyer une lecture KNX** envoie un télégramme de lecture standard. **Basculer le booléen (écriture)** est disponible pour les datapoints 1.x et alterne les valeurs _true_/_false_. **Écrire une valeur personnalisée** envoie la valeur saisie (elle doit être compatible avec le datapoint configuré). |
27
+ | Action du bouton | Définit l’opération effectuée au clic. **Envoyer KNX Read** envoie un télégramme de lecture standard. **Toggle boolean** est disponible pour les datapoints 1.x et alterne les valeurs _true_/_false_. **Écrire une valeur personnalisée** envoie la valeur saisie (elle doit être compatible avec le datapoint configuré). |
28
28
  | État initial du basculement | (Datapoints booléens uniquement) Définit la valeur initiale utilisée par le mode bascule. L’état est automatiquement synchronisé avec les télégrammes reçus du BUS. |
29
29
  | Valeur personnalisée | Payload utilisé par le mode « Écrire une valeur personnalisée ». Vous pouvez saisir n’importe quel littéral JSON, par exemple `42`, `true`, `"texte"` ou `{ "red": 255 }`. |
30
30
 
@@ -44,6 +44,8 @@ Le bouton n’est visible que si l’option est activée. En mode universel, l
44
44
  || **De la broche d'entrée du nœud au bus KNX** |
45
45
  | Type de télégramme | _WRITE_ Pour envoyer un télégramme d'écriture (généralement, vous le souhaitez), sinon vous pouvez choisir le type du télégramme auquel réagir. |
46
46
  | Filtre RBE | _Report par filtre change_. S'il est défini, seule l'entrée MSG (du débit) ayant des valeurs différentes à chaque fois, sera envoyée au bus KNX. Si vous avez l'intention d'envoyer à chaque fois la même valeur, éteignez-la. Si vous êtes activé, l'indication "RBE" sera ajoutée au nom du nœud. |
47
+ | Envoi périodique de la valeur mémorisée | Si activé, le nœud envoie sur le bus KNX la dernière valeur mémorisée à intervalles réguliers (télégramme _write_). Cette option contourne volontairement le RBE de sortie. |
48
+ | Intervalle d'envoi périodique | Intervalle en secondes de l'envoi périodique. |
47
49
  || **De KNX BUS à la broche ouput de Node** |
48
50
  | Lire l'état au début | Lisez l'état de l'adresse du groupe, chaque fois que le Node-Red démarre et à chaque reconnexion à la passerelle KNX. Le nœud stocke toutes les valeurs d'adresse de groupe dans un fichier, afin que vous puissiez choisir wether à lire dans le fichier ou dans le bus KNX. |
49
51
  | Filtre RBE | _Report par filtre change_. S'il est défini, seule la sortie MSG (dans le bus KNX) ayant des valeurs différentes à chaque fois, sera envoyée au flux de la sortie MSG. Si vous avez l'intention d'envoyer à chaque fois la même valeur, laissez-la éteindre. Si vous êtes activé, l'indication "RBE" sera ajoutée au nom du nœud. |
@@ -22,6 +22,8 @@
22
22
  "node-input-name": "Nom de nœud",
23
23
  "node-input-outputtype": "Type de télégramme",
24
24
  "node-input-outputRBE": "Envoyez la charge utile à KNX uniquement si elle est modifiée (filtre RBE)",
25
+ "node-input-periodicSend": "Envoyer périodiquement la valeur mémorisée à KNX (écriture cyclique)",
26
+ "node-input-periodicSendInterval": "Intervalle (secondes)",
25
27
  "node-input-inputRBE": "Réagir uniquement par charge utile modifiée (filtre RBE)",
26
28
  "node-input-formatmultiplyvalue": "Multiplier",
27
29
  "node-input-formatnegativevalue": "Négatifs",
@@ -37,8 +39,8 @@
37
39
  "button": {
38
40
  "enable": "Afficher le bouton manuel dans l’éditeur",
39
41
  "mode": "Action du bouton",
40
- "mode_read": "Envoyer lecture KNX",
41
- "mode_toggle": "Basculer booléen (écriture)",
42
+ "mode_read": "Envoyer KNX Read",
43
+ "mode_toggle": "Toggle boolean",
42
44
  "mode_value": "Écrire une valeur personnalisée",
43
45
  "toggleInitial": "État initial du basculement",
44
46
  "toggleInitial_true": "Démarrer sur ON (true)",
@@ -24,5 +24,15 @@
24
24
  "outputs": {
25
25
  "raw": "RAW telegrams"
26
26
  }
27
+ },
28
+ "common": {
29
+ "ga": "Géorgie",
30
+ "dpt": "Dpt",
31
+ "name": "Nom",
32
+ "youtube_sample": "Échantillon YouTube",
33
+ "knx_gw": "KNX GW",
34
+ "hue_bridge": "Hue Bridge",
35
+ "philips_hue": "Hue Philips",
36
+ "read": "Lire"
27
37
  }
28
38
  }
@@ -36,5 +36,15 @@
36
36
  "passed": "Passed",
37
37
  "dropped": "Dropped"
38
38
  }
39
+ },
40
+ "common": {
41
+ "ga": "Géorgie",
42
+ "dpt": "Dpt",
43
+ "name": "Nom",
44
+ "youtube_sample": "Échantillon YouTube",
45
+ "knx_gw": "KNX GW",
46
+ "hue_bridge": "Hue Bridge",
47
+ "philips_hue": "Hue Philips",
48
+ "read": "Lire"
39
49
  }
40
50
  }
@@ -134,7 +134,14 @@
134
134
  "gather_debug": "Raccogli debug e log per assistenza",
135
135
  "get_all_used_ga": "Ottieni tutte le GA usate per il filtro di routing KNX",
136
136
  "read_button": "Leggi",
137
- "copy_ga_router": "Copia questi indirizzi di gruppo nella tabella di routing del tuo router KNX/IP."
137
+ "copy_ga_router": "Copia questi indirizzi di gruppo nella tabella di routing del tuo router KNX/IP.",
138
+ "clear_persist_label": "Cancella cache persistente GA di questo gateway",
139
+ "clear_persist_button": "Cancella",
140
+ "clear_persist_confirm": "Questo elimina il file di cache persistente delle GA per questo gateway. Continuare?",
141
+ "clear_persist_ok": "Elimina",
142
+ "clear_persist_cancel": "Annulla",
143
+ "clear_persist_done": "Cache persistente GA eliminata.",
144
+ "clear_persist_fail": "Impossibile eliminare la cache persistente GA"
138
145
  }
139
146
  }
140
147
  }
@@ -24,7 +24,7 @@ L’editor può mostrare, per ogni nodo, un pulsante che invia manualmente un co
24
24
  |Proprietà|Descrizione|
25
25
  |--|--|
26
26
  | Mostra pulsante manuale | Se attivo, il piccolo pulsante viene visualizzato sul nodo nel workspace e nel pannello dei nodi. |
27
- | Azione del pulsante | Definisce l’operazione eseguita al click. **Invia lettura KNX** invia un telegramma di lettura standard. **Inverti booleano (scrittura)** è disponibile per i datapoint di tipo 1.x e alterna i valori _true_/_false_ a ogni click. **Scrivi valore personalizzato** invia il valore inserito dall’utente (deve essere compatibile con il Datapoint configurato). |
27
+ | Azione del pulsante | Definisce l’operazione eseguita al click. **Invia KNX Read** invia un telegramma di lettura standard. **Toggle boolean** è disponibile per i datapoint di tipo 1.x e alterna i valori _true_/_false_ a ogni click. **Scrivi valore personalizzato** invia il valore inserito dall’utente (deve essere compatibile con il Datapoint configurato). |
28
28
  | Stato iniziale del toggle | (Solo datapoint booleani) Imposta il valore iniziale utilizzato dalla modalità toggle. Lo stato viene aggiornato automaticamente in base ai telegrammi che il nodo riceve dal BUS. |
29
29
  | Valore personalizzato | Payload utilizzato dalla modalità “Scrivi valore personalizzato”. È possibile inserire qualsiasi letterale JSON, ad esempio `42`, `true`, `"testo"` oppure `{ "red": 255 }`. |
30
30
 
@@ -44,6 +44,8 @@ Il pulsante è visibile soltanto se l’opzione è attiva. In modalità universa
44
44
  || **Dal PIN di INGRESSO del nodo verso il BUS KNX** |
45
45
  | Tipo telegramma | `write` per inviare un telegramma di scrittura (in genere è ciò che vuoi); in alternativa puoi scegliere a quale tipo di telegramma reagire. |
46
46
  | Filtro RBE | Filtro "Report by change”. Se attivo, invia al BUS solo messaggi di ingresso con valore diverso dal precedente. Se devi inviare sempre lo stesso valore, disattivalo. Se attivo, verrà aggiunta l'indicazione "rbe” al nome del nodo. |
47
+ | Invio periodico del valore memorizzato | Se attivo, il nodo invia sul BUS KNX il valore memorizzato ad intervalli regolari (telegramma di tipo _write_). Questa opzione bypassa volutamente l'RBE in uscita. |
48
+ | Intervallo invio periodico | Intervallo in secondi dell'invio periodico. |
47
49
  || **Dal BUS KNX verso il PIN di USCITA del nodo** |
48
50
  | Read status on start | Legge lo stato del GA ad ogni avvio di Node-RED e a ogni riconnessione al Gateway KNX. Il nodo memorizza i valori su file, quindi puoi scegliere se leggere da file o dal BUS KNX. |
49
51
  | Filtro RBE | Filtro "Report by change” sull'uscita: invia al flow solo quando il valore cambia. Se vuoi inviare anche valori ripetuti, lascialo disattivo. Se attivo, aggiunge "rbe” al nome del nodo. |
@@ -22,6 +22,8 @@
22
22
  "node-input-name": "Nome",
23
23
  "node-input-outputtype": "Tipo Output",
24
24
  "node-input-outputRBE": "Invia payload al bus KNX solo se modificato (filtro RBE)",
25
+ "node-input-periodicSend": "Invia periodicamente il valore memorizzato (scrittura ciclica)",
26
+ "node-input-periodicSendInterval": "Intervallo (secondi)",
25
27
  "node-input-inputRBE": "Reagisci solo se il payload del bus KNX cambia (filtro RBE)",
26
28
  "node-input-formatmultiplyvalue": "Moltiplica",
27
29
  "node-input-formatnegativevalue": "Negativi",
@@ -38,8 +40,8 @@
38
40
  "button": {
39
41
  "enable": "Mostra il pulsante manuale nell'editor",
40
42
  "mode": "Azione del pulsante",
41
- "mode_read": "Invia lettura KNX",
42
- "mode_toggle": "Inverti booleano (scrittura)",
43
+ "mode_read": "Invia KNX Read",
44
+ "mode_toggle": "Toggle boolean",
43
45
  "mode_value": "Scrivi valore personalizzato",
44
46
  "toggleInitial": "Stato iniziale del toggle",
45
47
  "toggleInitial_true": "Inizia con ON (true)",
@@ -24,5 +24,15 @@
24
24
  "outputs": {
25
25
  "raw": "Telegrammi RAW"
26
26
  }
27
+ },
28
+ "common": {
29
+ "ga": "GA",
30
+ "dpt": "DPT",
31
+ "name": "Nome",
32
+ "youtube_sample": "Esempio YouTube",
33
+ "knx_gw": "Gateway KNX",
34
+ "hue_bridge": "Hue Bridge",
35
+ "philips_hue": "Philips HUE",
36
+ "read": "Leggi"
27
37
  }
28
38
  }
@@ -36,5 +36,15 @@
36
36
  "passed": "Passati",
37
37
  "dropped": "Scartati"
38
38
  }
39
+ },
40
+ "common": {
41
+ "ga": "GA",
42
+ "dpt": "DPT",
43
+ "name": "Nome",
44
+ "youtube_sample": "Esempio YouTube",
45
+ "knx_gw": "Gateway KNX",
46
+ "hue_bridge": "Hue Bridge",
47
+ "philips_hue": "Philips HUE",
48
+ "read": "Leggi"
39
49
  }
40
50
  }
@@ -122,7 +122,14 @@
122
122
  "gather_debug": "收集调试信息和日志以便排查",
123
123
  "get_all_used_ga": "获取 KNX 路由过滤器使用的所有 GA",
124
124
  "read_button": "读取",
125
- "copy_ga_router": "将这些组地址复制到 KNX/IP 路由器的路由表中。"
125
+ "copy_ga_router": "将这些组地址复制到 KNX/IP 路由器的路由表中。",
126
+ "clear_persist_label": "清除该网关的持久化 GA 缓存",
127
+ "clear_persist_button": "清除",
128
+ "clear_persist_confirm": "这将删除该网关的持久化 GA 缓存文件。继续?",
129
+ "clear_persist_ok": "删除",
130
+ "clear_persist_cancel": "取消",
131
+ "clear_persist_done": "已删除持久化 GA 缓存。",
132
+ "clear_persist_fail": "无法删除持久化 GA 缓存"
126
133
  }
127
134
  }
128
135
  }
@@ -24,7 +24,7 @@
24
24
  |属性|说明|
25
25
  |--|--|
26
26
  | 显示手动按钮 | 在工作区和节点列表中显示/隐藏该按钮。|
27
- | 按钮动作 | 设置点击后的操作。**发送 KNX 读取** 会发送标准读取报文;**切换布尔值(写入)** 适用于 DPT 1.x,可在 _true_ / _false_ 之间切换;**写入自定义值** 会写入指定值(需与节点的 Datapoint 类型兼容)。|
27
+ | 按钮动作 | 设置点击后的操作。**发送 KNX Read** 会发送标准读取报文;**Toggle boolean** 适用于 DPT 1.x,可在 _true_ / _false_ 之间切换;**写入自定义值** 会写入指定值(需与节点的 Datapoint 类型兼容)。|
28
28
  | 切换初始状态 | (仅布尔型 Datapoint)定义切换模式的起始值。节点会根据接收到的 KNX 报文自动更新状态。|
29
29
  | 自定义值 | “写入自定义值” 模式所使用的载荷。支持任何 JSON 字面量,例如 `42`、`true`、`"文本"` 或 `{ "red": 255 }`。|
30
30
 
@@ -44,6 +44,8 @@
44
44
  || **节点输入 → KNX 总线** |
45
45
  | Telegram 类型 | `write` 发送写报文(常用);也可选择响应其他类型。|
46
46
  | RBE 过滤 | 按变化上报。启用后,仅当值变化时才发送到总线。需要重复发送相同值时请关闭。启用后在节点名中显示 "rbe”。|
47
+ | 周期发送已存储的值 | 启用后,节点会按设定间隔将最后一次存储的值作为 _write_ 报文周期发送到 KNX 总线。该功能会刻意绕过输出侧 RBE。|
48
+ | 周期发送间隔 | 周期发送的间隔(秒)。|
47
49
  || **KNX 总线 → 节点输出** |
48
50
  | 启动时读取状态 | 在 Node-RED 启动及每次重连时读取 GA 状态。节点会缓存值到文件,可选择从文件或总线读取。|
49
51
  | RBE 过滤 | 同上,但作用于输出到流程。|
@@ -22,6 +22,8 @@
22
22
  "node-input-name": "节点名字",
23
23
  "node-input-outputtype": "输出类型",
24
24
  "node-input-outputRBE": "只有数据改变的时候才发送到总线 (RBE 过滤器)",
25
+ "node-input-periodicSend": "周期发送已存储的值到 KNX(循环写入)",
26
+ "node-input-periodicSendInterval": "间隔(秒)",
25
27
  "node-input-inputRBE": "只有数据改变的时候才接收数据 (RBE 过滤器)",
26
28
  "node-input-formatmultiplyvalue": "乘",
27
29
  "node-input-formatnegativevalue": "负数",
@@ -37,8 +39,8 @@
37
39
  "button": {
38
40
  "enable": "在编辑器中显示手动命令按钮",
39
41
  "mode": "按钮操作",
40
- "mode_read": "发送 KNX 读取",
41
- "mode_toggle": "切换布尔值(写入)",
42
+ "mode_read": "发送 KNX Read",
43
+ "mode_toggle": "Toggle boolean",
42
44
  "mode_value": "写入自定义值",
43
45
  "toggleInitial": "初始切换状态",
44
46
  "toggleInitial_true": "初始值为 开 (true)",
@@ -24,5 +24,15 @@
24
24
  "outputs": {
25
25
  "raw": "RAW telegrams"
26
26
  }
27
+ },
28
+ "common": {
29
+ "ga": "组地址",
30
+ "dpt": "数据点类型",
31
+ "name": "名称",
32
+ "youtube_sample": "YouTube 示例",
33
+ "knx_gw": "KNX 网关",
34
+ "hue_bridge": "Hue Bridge",
35
+ "philips_hue": "飞利浦 HUE",
36
+ "read": "读取"
27
37
  }
28
38
  }
@@ -36,5 +36,15 @@
36
36
  "passed": "Passed",
37
37
  "dropped": "Dropped"
38
38
  }
39
+ },
40
+ "common": {
41
+ "ga": "组地址",
42
+ "dpt": "数据点类型",
43
+ "name": "名称",
44
+ "youtube_sample": "YouTube 示例",
45
+ "knx_gw": "KNX 网关",
46
+ "hue_bridge": "Hue Bridge",
47
+ "philips_hue": "飞利浦 HUE",
48
+ "read": "读取"
39
49
  }
40
50
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=20.18.1"
5
5
  },
6
- "version": "4.1.21",
6
+ "version": "4.1.23",
7
7
  "description": "Control your KNX and KNX Secure intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control, ETS group address importer, and KNX routing between interfaces. Easy to use and highly configurable.",
8
8
  "files": [
9
9
  "nodes/",
@@ -109,4 +109,4 @@
109
109
  "mocha": "^10.4.0",
110
110
  "marked": "^14.1.0"
111
111
  }
112
- }
112
+ }