node-red-contrib-knx-ultimate 2.5.0 → 3.0.0-beta1

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 (150) hide show
  1. package/.eslintrc.json +3 -2
  2. package/CHANGELOG.md +13 -0
  3. package/README.md +2 -1
  4. package/{KNXEngine → _JS_KNXEngine}/README.md +7 -7
  5. package/{KNXEngine → _JS_KNXEngine}/index.js +1 -1
  6. package/{KNXEngine → _JS_KNXEngine}/sample.js +5 -5
  7. package/{KNXEngine → _JS_KNXEngine}/sampleSecure.js +1 -1
  8. package/{KNXEngine → _JS_KNXEngine}/src/KNXClient.js +3 -3
  9. package/_JS_KNXEngine/src/dptlib/dpt60002.js +101 -0
  10. package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXConnectResponse.js +2 -0
  11. package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXConstants.js +1 -0
  12. package/nodes/commonFunctions.js +3 -3
  13. package/nodes/hue-config.html +2 -0
  14. package/nodes/knxUltimate-config.html +2 -0
  15. package/nodes/knxUltimate-config.js +226 -223
  16. package/nodes/knxUltimate.html +123 -56
  17. package/nodes/knxUltimate.js +100 -60
  18. package/nodes/knxUltimateAlerter.html +7 -12
  19. package/nodes/knxUltimateAlerter.js +2 -2
  20. package/nodes/knxUltimateGarageDoorBarrierOpener.html +7 -12
  21. package/nodes/knxUltimateGarageDoorBarrierOpener.js +2 -2
  22. package/nodes/knxUltimateGlobalContext.html +2 -0
  23. package/nodes/knxUltimateHueBattery.html +11 -14
  24. package/nodes/knxUltimateHueButton.html +27 -22
  25. package/nodes/knxUltimateHueButton.js +1 -1
  26. package/nodes/knxUltimateHueContactSensor.html +12 -8
  27. package/nodes/knxUltimateHueLight.html +32 -26
  28. package/nodes/knxUltimateHueLight.js +43 -6
  29. package/nodes/knxUltimateHueLightSensor.html +11 -14
  30. package/nodes/knxUltimateHueMotion.html +11 -14
  31. package/nodes/knxUltimateHueScene.html +24 -19
  32. package/nodes/knxUltimateHueScene.js +2 -1
  33. package/nodes/knxUltimateHueTapDial.html +11 -14
  34. package/nodes/knxUltimateHueTemperatureSensor.html +11 -14
  35. package/nodes/knxUltimateHueZigbeeConnectivity.html +11 -14
  36. package/nodes/knxUltimateLoadControl.html +4 -11
  37. package/nodes/knxUltimateLoadControl.js +1 -1
  38. package/nodes/knxUltimateLogger.html +3 -1
  39. package/nodes/knxUltimateSceneController.html +14 -15
  40. package/nodes/knxUltimateViewer.html +2 -0
  41. package/nodes/knxUltimateViewer.js +1 -1
  42. package/nodes/knxUltimateWatchDog.html +3 -1
  43. package/nodes/utils/payloadManipulation.js +49 -1
  44. package/nodes/utils/utils.js +4 -0
  45. package/package.json +4 -3
  46. package/resources/htmlUtils.js +27 -0
  47. /package/{KNXEngine → _JS_KNXEngine}/CHANGELOG.md +0 -0
  48. /package/{KNXEngine → _JS_KNXEngine}/LICENSE +0 -0
  49. /package/{KNXEngine → _JS_KNXEngine}/img/dpt 2.png +0 -0
  50. /package/{KNXEngine → _JS_KNXEngine}/img/dpt.png +0 -0
  51. /package/{KNXEngine → _JS_KNXEngine}/img/logo 2.png +0 -0
  52. /package/{KNXEngine → _JS_KNXEngine}/img/logo-big 2.png +0 -0
  53. /package/{KNXEngine → _JS_KNXEngine}/img/logo-big.png +0 -0
  54. /package/{KNXEngine → _JS_KNXEngine}/img/logo.png +0 -0
  55. /package/{KNXEngine → _JS_KNXEngine}/img/nodered 2.png +0 -0
  56. /package/{KNXEngine → _JS_KNXEngine}/img/nodered.png +0 -0
  57. /package/{KNXEngine → _JS_KNXEngine}/package.json +0 -0
  58. /package/{KNXEngine → _JS_KNXEngine}/simpleSample.js +0 -0
  59. /package/{KNXEngine → _JS_KNXEngine}/src/Curve25519.js +0 -0
  60. /package/{KNXEngine → _JS_KNXEngine}/src/KNXSocketOptions.js +0 -0
  61. /package/{KNXEngine → _JS_KNXEngine}/src/KNXsecureKeyring.js +0 -0
  62. /package/{KNXEngine → _JS_KNXEngine}/src/KnxLog.js +0 -0
  63. /package/{KNXEngine → _JS_KNXEngine}/src/cur.js +0 -0
  64. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt1.js +0 -0
  65. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt10.js +0 -0
  66. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt11.js +0 -0
  67. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt12.js +0 -0
  68. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt13.js +0 -0
  69. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt14.js +0 -0
  70. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt15.js +0 -0
  71. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt16.js +0 -0
  72. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt17.js +0 -0
  73. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt18.js +0 -0
  74. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt19.js +0 -0
  75. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt2.js +0 -0
  76. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt20.js +0 -0
  77. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt21.js +0 -0
  78. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt213.js +0 -0
  79. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt22.js +0 -0
  80. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt222.js +0 -0
  81. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt232.js +0 -0
  82. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt235.js +0 -0
  83. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt237.js +0 -0
  84. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt238.js +0 -0
  85. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt242.js +0 -0
  86. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt249.js +0 -0
  87. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt251.js +0 -0
  88. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt275.js +0 -0
  89. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt28.js +0 -0
  90. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt29.js +0 -0
  91. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt3.js +0 -0
  92. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt4.js +0 -0
  93. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt5.js +0 -0
  94. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt6.js +0 -0
  95. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt60001.js +0 -0
  96. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt7.js +0 -0
  97. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt8.js +0 -0
  98. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt9.js +0 -0
  99. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/dpt999.js +0 -0
  100. /package/{KNXEngine → _JS_KNXEngine}/src/dptlib/index.js +0 -0
  101. /package/{KNXEngine → _JS_KNXEngine}/src/errors/BufferLengthError.js +0 -0
  102. /package/{KNXEngine → _JS_KNXEngine}/src/errors/DateFormatError.js +0 -0
  103. /package/{KNXEngine → _JS_KNXEngine}/src/errors/DuplicateRequestError.js +0 -0
  104. /package/{KNXEngine → _JS_KNXEngine}/src/errors/InvalidValueError.js +0 -0
  105. /package/{KNXEngine → _JS_KNXEngine}/src/errors/NotImplementedError.js +0 -0
  106. /package/{KNXEngine → _JS_KNXEngine}/src/errors/RequestTimeoutError.js +0 -0
  107. /package/{KNXEngine → _JS_KNXEngine}/src/errors/index.js +0 -0
  108. /package/{KNXEngine → _JS_KNXEngine}/src/index.js +0 -0
  109. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/CRD.js +0 -0
  110. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/CRI.js +0 -0
  111. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/CRIFactory.js +0 -0
  112. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/DIB.js +0 -0
  113. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/DeviceInfo.js +0 -0
  114. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/HPAI.js +0 -0
  115. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/IPConfig.js +0 -0
  116. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/IPCurrentConfig.js +0 -0
  117. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXAddress.js +0 -0
  118. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXAddresses.js +0 -0
  119. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXConnectRequest.js +0 -0
  120. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXConnectionStateRequest.js +0 -0
  121. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXConnectionStateResponse.js +0 -0
  122. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXDataBuffer.js +0 -0
  123. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXDescriptionRequest.js +0 -0
  124. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXDescriptionResponse.js +0 -0
  125. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXDisconnectRequest.js +0 -0
  126. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXDisconnectResponse.js +0 -0
  127. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXHeader.js +0 -0
  128. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXPacket.js +0 -0
  129. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXProtocol.js +0 -0
  130. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXRoutingIndication.js +0 -0
  131. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXSearchRequest.js +0 -0
  132. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXSearchResponse.js +0 -0
  133. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXSecureSessionRequest.js +0 -0
  134. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXTunnelingAck.js +0 -0
  135. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXTunnelingRequest.js +0 -0
  136. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/KNXUtils.js +0 -0
  137. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/ServiceFamilies.js +0 -0
  138. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/TunnelCRI.js +0 -0
  139. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/AdditionalInfo.js +0 -0
  140. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/CEMIConstants.js +0 -0
  141. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/CEMIFactory.js +0 -0
  142. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/CEMIMessage.js +0 -0
  143. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/ControlField.js +0 -0
  144. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/LDataCon.js +0 -0
  145. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/LDataInd.js +0 -0
  146. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/LDataReq.js +0 -0
  147. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/NPDU.js +0 -0
  148. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/cEMI/TLVInfo.js +0 -0
  149. /package/{KNXEngine → _JS_KNXEngine}/src/protocol/index.js +0 -0
  150. /package/{KNXEngine → _JS_KNXEngine}/src/util/ipAddressHelper.js +0 -0
@@ -7,8 +7,9 @@ const fs = require("fs");
7
7
  const path = require("path");
8
8
  const net = require("net");
9
9
  const _ = require("lodash");
10
- const knx = require("../KNXEngine/src");
11
- const dptlib = require("../KNXEngine/src/dptlib");
10
+ const knx = require("knxultimate");
11
+ //const dptlib = require('knxultimate').dptlib;
12
+ const dptlib = require('knxultimate').dptlib;
12
13
 
13
14
  // const { Server } = require('http')
14
15
  const payloadRounder = require("./utils/payloadManipulation");
@@ -128,10 +129,9 @@ module.exports = (RED) => {
128
129
  }
129
130
 
130
131
  node.setAllClientsStatus = (_status, _color, _text) => {
131
- function nextStatus(_oClient) {
132
+ node.nodeClients.forEach((oClient) => {
132
133
  try {
133
- let oClient = RED.nodes.getNode(_oClient.id);
134
- oClient.setNodeStatus({
134
+ if (oClient.setNodeStatus !== undefined) oClient.setNodeStatus({
135
135
  fill: _color,
136
136
  shape: "dot",
137
137
  text: _status + " " + _text,
@@ -140,12 +140,10 @@ module.exports = (RED) => {
140
140
  dpt: "",
141
141
  devicename: "",
142
142
  });
143
- oClient = null;
144
143
  } catch (error) {
145
144
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.warn("Wow setAllClientsStatus error " + error.message);
146
145
  }
147
- }
148
- node.nodeClients.map(nextStatus);
146
+ });
149
147
  };
150
148
 
151
149
  // 21/01/2022 TTL Timer for clearung the node.telegramsQueue if the connection stays down for long time
@@ -251,8 +249,7 @@ module.exports = (RED) => {
251
249
  node.nodeClients
252
250
  .filter((_oClient) => _oClient.isWatchDog !== undefined && _oClient.isWatchDog === true)
253
251
  .forEach((_oClient) => {
254
- const oClient = RED.nodes.getNode(_oClient.id);
255
- oClient.signalNodeErrorCalledByConfigNode(_oError);
252
+ _oClient.signalNodeErrorCalledByConfigNode(_oError);
256
253
  });
257
254
  };
258
255
 
@@ -281,20 +278,11 @@ module.exports = (RED) => {
281
278
  devicename: "",
282
279
  });
283
280
  }
284
- // 05/04/2022 create the Json variable and add it to the list
285
- const jNode = {};
286
- jNode.id = _Node.id;
287
- jNode.topic = _Node.topic;
288
- if (_Node.hasOwnProperty("isWatchDog")) jNode.isWatchDog = _Node.isWatchDog;
289
- jNode.initialread = _Node.initialread;
290
- jNode.notifywrite = _Node.notifywrite;
291
- jNode.notifyresponse = _Node.notifyresponse;
292
- jNode.notifyreadrequest = _Node.notifyreadrequest;
293
- node.nodeClients.push(jNode);
281
+ node.nodeClients.push(_Node);
294
282
  }
295
283
  };
296
284
 
297
- node.removeClient = (_Node) => {
285
+ node.removeClient = async (_Node) => {
298
286
  // Remove the client node from the clients array
299
287
  try {
300
288
  node.nodeClients = node.nodeClients.filter((x) => x.id !== _Node.id);
@@ -303,7 +291,7 @@ module.exports = (RED) => {
303
291
  // If no clien nodes, disconnect from bus.
304
292
  if (node.nodeClients.length === 0) {
305
293
  try {
306
- node.Disconnect();
294
+ await node.Disconnect();
307
295
  } catch (error) { /* empty */ }
308
296
  }
309
297
  };
@@ -324,79 +312,78 @@ module.exports = (RED) => {
324
312
  .filter((_oClient) => _oClient.initialread === 2 || _oClient.initialread === 3)
325
313
  .filter((_oClient) => _oClient.hasOwnProperty("isWatchDog") === false)
326
314
  .forEach((_oClient) => {
327
- const oClient = RED.nodes.getNode(_oClient.id); // 05/04/2022 Get the real node
328
315
 
329
316
  if (node.linkStatus !== "connected") return; // 16/08/2021 If not connected, exit
330
317
 
331
318
  // 04/04/2020 selected READ FROM FILE 2 or from file then from bus 3
332
- if (oClient.listenallga === true) {
319
+ if (_oClient.listenallga === true) {
333
320
  // 13/12/2021 DA FARE
334
321
  } else {
335
322
  try {
336
323
  if (node.exposedGAs.length > 0) {
337
- const oExposedGA = node.exposedGAs.find((a) => a.ga === oClient.topic);
324
+ const oExposedGA = node.exposedGAs.find((a) => a.ga === _oClient.topic);
338
325
  if (oExposedGA !== undefined) {
339
326
  // Retrieve the value from exposedGAs
340
327
  const msg = buildInputMessage({
341
328
  _srcGA: "",
342
- _destGA: oClient.topic,
329
+ _destGA: _oClient.topic,
343
330
  _event: "GroupValue_Response",
344
331
  _Rawvalue: Buffer.from(oExposedGA.rawValue.data),
345
- _inputDpt: oClient.dpt,
346
- _devicename: oClient.name ? oClient.name : "",
347
- _outputtopic: oClient.outputtopic,
348
- _oNode: oClient,
332
+ _inputDpt: _oClient.dpt,
333
+ _devicename: _oClient.name ? _oClient.name : "",
334
+ _outputtopic: _oClient.outputtopic,
335
+ _oNode: _oClient,
349
336
  });
350
- oClient.previouspayload = ""; // 05/04/2021 Added previous payload
351
- oClient.currentPayload = msg.payload;
352
- oClient.setNodeStatus({
337
+ _oClient.previouspayload = ""; // 05/04/2021 Added previous payload
338
+ _oClient.currentPayload = msg.payload;
339
+ _oClient.setNodeStatus({
353
340
  fill: "grey",
354
341
  shape: "dot",
355
342
  text: "Update value from persist file",
356
- payload: oClient.currentPayload,
357
- GA: oClient.topic,
358
- dpt: oClient.dpt,
359
- devicename: oClient.name || "",
343
+ payload: _oClient.currentPayload,
344
+ GA: _oClient.topic,
345
+ dpt: _oClient.dpt,
346
+ devicename: _oClient.name || "",
360
347
  });
361
348
  // 06/05/2021 If, after the rawdata has been savad to file, the user changes the datapoint, the buildInputMessage returns payload null, because it's unable to convert the value
362
349
  if (msg.payload === null) {
363
350
  // Delete the exposedGA
364
- node.exposedGAs = node.exposedGAs.filter((item) => item.ga !== oClient.topic);
365
- oClient.setNodeStatus({
351
+ node.exposedGAs = node.exposedGAs.filter((item) => item.ga !== _oClient.topic);
352
+ _oClient.setNodeStatus({
366
353
  fill: "yellow",
367
354
  shape: "dot",
368
355
  text: "Datapoint has been changed, remove the value from persist file",
369
- payload: oClient.currentPayload,
370
- GA: oClient.topic,
371
- dpt: oClient.dpt,
372
- devicename: oClient.devicename || "",
356
+ payload: _oClient.currentPayload,
357
+ GA: _oClient.topic,
358
+ dpt: _oClient.dpt,
359
+ devicename: _oClient.devicename || "",
373
360
  });
374
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error("knxUltimate-config: DoInitialReadFromKNXBusOrFile: Datapoint may have been changed, remove the value from persist file of " + oClient.topic + " Devicename " + oClient.name + " Currend DPT " + oClient.dpt + " Node.id " + oClient.id);
361
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error("knxUltimate-config: DoInitialReadFromKNXBusOrFile: Datapoint may have been changed, remove the value from persist file of " + _oClient.topic + " Devicename " + _oClient.name + " Currend DPT " + _oClient.dpt + " Node.id " + _oClient.id);
375
362
  } else {
376
- if (oClient.notifyresponse) oClient.handleSend(msg);
363
+ if (_oClient.notifyresponse) _oClient.handleSend(msg);
377
364
  }
378
365
  } else {
379
- if (oClient.initialread === 3) {
366
+ if (_oClient.initialread === 3) {
380
367
  // Not found, issue a READ to the bus
381
- if (!readHistory.includes(oClient.topic)) {
382
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("KNXUltimate-config: DoInitialReadFromKNXBusOrFile 3: sent read request to GA " + oClient.topic);
383
- oClient.setNodeStatus({
368
+ if (!readHistory.includes(_oClient.topic)) {
369
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("KNXUltimate-config: DoInitialReadFromKNXBusOrFile 3: sent read request to GA " + _oClient.topic);
370
+ _oClient.setNodeStatus({
384
371
  fill: "grey",
385
372
  shape: "dot",
386
373
  text: "Persist value not found, issuing READ request to BUS",
387
- payload: oClient.currentPayload,
388
- GA: oClient.topic,
389
- dpt: oClient.dpt,
390
- devicename: oClient.devicename || "",
374
+ payload: _oClient.currentPayload,
375
+ GA: _oClient.topic,
376
+ dpt: _oClient.dpt,
377
+ devicename: _oClient.devicename || "",
391
378
  });
392
379
  node.writeQueueAdd({
393
- grpaddr: oClient.topic,
380
+ grpaddr: _oClient.topic,
394
381
  payload: "",
395
382
  dpt: "",
396
383
  outputtype: "read",
397
- nodecallerid: oClient.id,
384
+ nodecallerid: _oClient.id,
398
385
  });
399
- readHistory.push(oClient.topic);
386
+ readHistory.push(_oClient.topic);
400
387
  }
401
388
  }
402
389
  }
@@ -411,16 +398,15 @@ module.exports = (RED) => {
411
398
  .filter((_oClient) => _oClient.initialread === 1)
412
399
  .filter((_oClient) => _oClient.hasOwnProperty("isWatchDog") === false)
413
400
  .forEach((_oClient) => {
414
- const oClient = RED.nodes.getNode(_oClient.id); // 05/04/2022 Get the real node
415
401
 
416
402
  if (node.linkStatus !== "connected") return; // 16/08/2021 If not connected, exit
417
403
 
418
404
  // 04/04/2020 selected READ FROM BUS 1
419
- if (oClient.hasOwnProperty("isalertnode") && oClient.isalertnode) {
420
- oClient.initialReadAllDevicesInRules();
421
- } else if (oClient.hasOwnProperty("isLoadControlNode") && oClient.isLoadControlNode) {
422
- oClient.initialReadAllDevicesInRules();
423
- } else if (oClient.listenallga === true) {
405
+ if (_oClient.hasOwnProperty("isalertnode") && _oClient.isalertnode) {
406
+ _oClient.initialReadAllDevicesInRules();
407
+ } else if (_oClient.hasOwnProperty("isLoadControlNode") && _oClient.isLoadControlNode) {
408
+ _oClient.initialReadAllDevicesInRules();
409
+ } else if (_oClient.listenallga === true) {
424
410
  for (let index = 0; index < node.csv.length; index++) {
425
411
  const element = node.csv[index];
426
412
  if (!readHistory.includes(element.ga)) {
@@ -436,16 +422,16 @@ module.exports = (RED) => {
436
422
  }
437
423
  }
438
424
  } else {
439
- if (!readHistory.includes(oClient.topic)) {
425
+ if (!readHistory.includes(_oClient.topic)) {
440
426
  node.writeQueueAdd({
441
- grpaddr: oClient.topic,
427
+ grpaddr: _oClient.topic,
442
428
  payload: "",
443
429
  dpt: "",
444
430
  outputtype: "read",
445
- nodecallerid: oClient.id,
431
+ nodecallerid: _oClient.id,
446
432
  });
447
- readHistory.push(oClient.topic);
448
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("KNXUltimate-config: DoInitialReadFromKNXBusOrFile: sent read request to GA " + oClient.topic);
433
+ readHistory.push(_oClient.topic);
434
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("KNXUltimate-config: DoInitialReadFromKNXBusOrFile: sent read request to GA " + _oClient.topic);
449
435
  }
450
436
  }
451
437
  });
@@ -454,7 +440,7 @@ module.exports = (RED) => {
454
440
 
455
441
  // 01/02/2020 Dinamic change of the KNX Gateway IP, Port and Physical Address
456
442
  // This new thing has been requested by proServ RealKNX staff.
457
- node.setGatewayConfig = (
443
+ node.setGatewayConfig = async (
458
444
  /** @type {string} */ _sIP,
459
445
  /** @type {number} */ _iPort,
460
446
  /** @type {string} */ _sPhysicalAddress,
@@ -489,7 +475,7 @@ module.exports = (RED) => {
489
475
  );
490
476
 
491
477
  try {
492
- node.Disconnect();
478
+ await node.Disconnect();
493
479
  // node.setKnxConnectionProperties(); // 28/12/2021 Commented
494
480
  node.setAllClientsStatus("CONFIG", "yellow", "KNXUltimage-config:setGatewayConfig: disconnected by new setting...");
495
481
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("KNXUltimage-config:setGatewayConfig: disconnected by setGatewayConfig.");
@@ -498,7 +484,7 @@ module.exports = (RED) => {
498
484
 
499
485
  // 05/05/2021 force connection or disconnection from the KNX BUS and disable the autoreconenctions attempts.
500
486
  // This new thing has been requested by proServ RealKNX staff.
501
- node.connectGateway = (_bConnection) => {
487
+ node.connectGateway = async (_bConnection) => {
502
488
  if (_bConnection === undefined) return;
503
489
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(
504
490
  (_bConnection === true ? "Forced connection from watchdog" : "Forced disconnection from watchdog") +
@@ -513,7 +499,7 @@ module.exports = (RED) => {
513
499
  if (_bConnection === true) {
514
500
  // CONNECT AND ENABLE RECONNECTION ATTEMPTS
515
501
  try {
516
- node.Disconnect();
502
+ await node.Disconnect();
517
503
  node.setAllClientsStatus("CONFIG", "yellow", "Forced GW connection from watchdog.");
518
504
  node.autoReconnect = true;
519
505
  } catch (error) { }
@@ -521,7 +507,7 @@ module.exports = (RED) => {
521
507
  // DISCONNECT AND DISABLE RECONNECTION ATTEMPTS
522
508
  try {
523
509
  node.autoReconnect = false;
524
- node.Disconnect();
510
+ await node.Disconnect();
525
511
  const t = setTimeout(() => {
526
512
  // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
527
513
  node.setAllClientsStatus("CONFIG", "yellow", "Forced GW disconnection and stop reconnection attempts, from watchdog.");
@@ -618,12 +604,12 @@ module.exports = (RED) => {
618
604
  };
619
605
  // node.setKnxConnectionProperties(); 28/12/2021 Commented
620
606
 
621
- node.initKNXConnection = () => {
607
+ node.initKNXConnection = async () => {
622
608
  try {
623
609
  node.setKnxConnectionProperties(); // 28/12/2021 Added
624
610
  } catch (error) {
625
611
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error("knxUltimate-config: setKnxConnectionProperties: " + error.message);
626
- if (node.linkStatus !== "disconnected") node.Disconnect();
612
+ if (node.linkStatus !== "disconnected") await node.Disconnect();
627
613
  return;
628
614
  }
629
615
 
@@ -633,7 +619,7 @@ module.exports = (RED) => {
633
619
  try {
634
620
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info("knxUltimate-config: No nodes linked to this gateway " + node.name);
635
621
  try {
636
- if (node.linkStatus !== "disconnected") node.Disconnect();
622
+ if (node.linkStatus !== "disconnected") await node.Disconnect();
637
623
  } catch (error) { }
638
624
  return;
639
625
  } catch (error) { }
@@ -641,7 +627,7 @@ module.exports = (RED) => {
641
627
 
642
628
  try {
643
629
  // 02/01/2022 This is important to free the tunnel in case of hard disconnection.
644
- node.Disconnect();
630
+ await node.Disconnect();
645
631
  } catch (error) {
646
632
  // if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(error)
647
633
  }
@@ -662,8 +648,8 @@ module.exports = (RED) => {
662
648
 
663
649
  // Setting handlers
664
650
  // ######################################
665
- node.knxConnection.on(knx.KNXClient.KNXClientEvents.indication, handleBusEvents);
666
- node.knxConnection.on(knx.KNXClient.KNXClientEvents.error, (err) => {
651
+ node.knxConnection.on(knx.KNXClientEvents.indication, handleBusEvents);
652
+ node.knxConnection.on(knx.KNXClientEvents.error, (err) => {
667
653
  try {
668
654
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error("knxUltimate-config: received KNXClientEvents.error: " + (err.message === undefined ? err : err.message));
669
655
  } catch (error) {
@@ -681,11 +667,11 @@ module.exports = (RED) => {
681
667
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error("knxUltimate-config: Disconnected by: " + (err.message === undefined ? err : err.message));
682
668
  });
683
669
  // Call discoverCB when a knx gateway has been discovered.
684
- // node.knxConnection.on(knx.KNXClient.KNXClientEvents.discover, info => {
670
+ // node.knxConnection.on(knx.KNXClientEvents.discover, info => {
685
671
  // const [ip, port] = info.split(":");
686
672
  // discoverCB(ip, port);
687
673
  // });
688
- node.knxConnection.on(knx.KNXClient.KNXClientEvents.disconnected, (info) => {
674
+ node.knxConnection.on(knx.KNXClientEvents.disconnected, (info) => {
689
675
  node.startTimerClearTelegramQueue(); // 21/01/2022 Clear the telegram queue after a while
690
676
  if (node.linkStatus !== "disconnected") {
691
677
  node.linkStatus = "disconnected";
@@ -693,10 +679,10 @@ module.exports = (RED) => {
693
679
  node.Disconnect("Disconnected by event: " + info || "", "red"); // 11/03/2022
694
680
  }
695
681
  });
696
- node.knxConnection.on(knx.KNXClient.KNXClientEvents.close, (info) => {
682
+ node.knxConnection.on(knx.KNXClientEvents.close, (info) => {
697
683
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("knxUltimate-config: KNXClient socket closed.");
698
684
  });
699
- node.knxConnection.on(knx.KNXClient.KNXClientEvents.connected, (info) => {
685
+ node.knxConnection.on(knx.KNXClientEvents.connected, (info) => {
700
686
  if (node.timerClearTelegramQueue !== null) {
701
687
  clearTimeout(node.timerClearTelegramQueue); // Connected. Stop the timer that clears the telegrams queue.
702
688
  node.timerClearTelegramQueue = null;
@@ -721,7 +707,7 @@ module.exports = (RED) => {
721
707
  }, 500);
722
708
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info("knxUltimate-config: Connected to %o", info);
723
709
  });
724
- node.knxConnection.on(knx.KNXClient.KNXClientEvents.connecting, (info) => {
710
+ node.knxConnection.on(knx.KNXClientEvents.connecting, (info) => {
725
711
  node.linkStatus = "connecting";
726
712
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("knxUltimate-config: Connecting to" + info.ipAddr || "");
727
713
  node.setAllClientsStatus(info.ipAddr || "", "grey", "Connecting...");
@@ -740,7 +726,7 @@ module.exports = (RED) => {
740
726
  }
741
727
  } catch (error) {
742
728
  if (node.sysLogger !== undefined && node.sysLogger !== null) {
743
- node.sysLogger.error("KNXUltimate-config: Error in instantiating knxConnection " + error.message + " Node " + node.name);
729
+ node.sysLogger.error("KNXUltimate-config: Error in instantiating knxConnection " + error.stack + " Node " + node.name);
744
730
  node.error("KNXUltimate-config: Error in instantiating knxConnection " + error.message + " Node " + node.name);
745
731
  }
746
732
  node.linkStatus = "disconnected";
@@ -817,42 +803,41 @@ module.exports = (RED) => {
817
803
  node.nodeClients
818
804
  .filter((_input) => _input.notifywrite === true)
819
805
  .forEach((_input) => {
820
- const input = RED.nodes.getNode(_input.id); // 05/04/2022 Get the real node
821
806
 
822
807
  // 19/03/2020 in the middle of coronavirus. Whole italy is red zone, closed down. Scene Controller implementation
823
- if (input.hasOwnProperty("isSceneController")) {
808
+ if (_input.hasOwnProperty("isSceneController")) {
824
809
  // 12/08/2020 Check wether is a learn (save) command or a activate (play) command.
825
- if (_dest === input.topic || _dest === input.topicSave) {
810
+ if (_dest === _input.topic || _dest === _input.topicSave) {
826
811
  // Prepare the two messages to be evaluated directly into the Scene Controller node.
827
812
  new Promise((resolve) => {
828
- if (_dest === input.topic) {
813
+ if (_dest === _input.topic) {
829
814
  try {
830
815
  const msgRecall = buildInputMessage({
831
816
  _srcGA: _src,
832
817
  _destGA: _dest,
833
818
  _event: _evt,
834
819
  _Rawvalue: _rawValue,
835
- _inputDpt: input.dpt,
836
- _devicename: input.name ? input.name : "",
837
- _outputtopic: input.outputtopic,
820
+ _inputDpt: _input.dpt,
821
+ _devicename: _input.name ? _input.name : "",
822
+ _outputtopic: _input.outputtopic,
838
823
  _oNode: null,
839
824
  });
840
- input.RecallScene(msgRecall.payload, false);
825
+ _input.RecallScene(msgRecall.payload, false);
841
826
  } catch (error) { }
842
827
  } // 12/08/2020 Do NOT use "else", because both topics must be evaluated in case both recall and save have same group address.
843
- if (_dest === input.topicSave) {
828
+ if (_dest === _input.topicSave) {
844
829
  try {
845
830
  const msgSave = buildInputMessage({
846
831
  _srcGA: _src,
847
832
  _destGA: _dest,
848
833
  _event: _evt,
849
834
  _Rawvalue: _rawValue,
850
- _inputDpt: input.dptSave,
851
- _devicename: input.name ? input.name : "",
835
+ _inputDpt: _input.dptSave,
836
+ _devicename: _input.name || "",
852
837
  _outputtopic: _dest,
853
838
  _oNode: null,
854
839
  });
855
- input.SaveScene(msgSave.payload, false);
840
+ _input.SaveScene(msgSave.payload, false);
856
841
  } catch (error) { }
857
842
  }
858
843
  resolve(true); // fulfilled
@@ -864,9 +849,9 @@ module.exports = (RED) => {
864
849
  // 19/03/2020 Check and Update value if the input is part of a scene controller
865
850
  new Promise((resolve) => {
866
851
  // Check and update the values of each device in the scene and update the rule array accordingly.
867
- for (let i = 0; i < input.rules.length; i++) {
852
+ for (let i = 0; i < _input.rules.length; i++) {
868
853
  // rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, dpt:rowRuleDPT, send: rowRuleSend}
869
- const oDevice = input.rules[i];
854
+ const oDevice = _input.rules[i];
870
855
  if (typeof oDevice !== "undefined" && oDevice.topic == _dest) {
871
856
  const msg = buildInputMessage({
872
857
  _srcGA: _src,
@@ -874,12 +859,12 @@ module.exports = (RED) => {
874
859
  _event: _evt,
875
860
  _Rawvalue: _rawValue,
876
861
  _inputDpt: oDevice.dpt,
877
- _devicename: oDevice.name ? input.name : "",
862
+ _devicename: oDevice.name || "",
878
863
  _outputtopic: oDevice.outputtopic,
879
864
  _oNode: null,
880
865
  });
881
866
  oDevice.currentPayload = msg.payload;
882
- input.setNodeStatus({
867
+ _input.setNodeStatus({
883
868
  fill: "grey",
884
869
  shape: "dot",
885
870
  text: "Update dev in scene",
@@ -897,24 +882,17 @@ module.exports = (RED) => {
897
882
  .then(function () { })
898
883
  .catch(function () { });
899
884
  }
900
- } else if (input.hasOwnProperty("isLogger")) {
885
+ } else if (_input.hasOwnProperty("isLogger")) {
901
886
  // 26/03/2020 Coronavirus is slightly decreasing the affected numer of people. Logger Node
902
887
  // 24/03/2021 Logger Node, i'll pass cemiETS
903
888
  if (_cemiETS !== undefined) {
904
889
  // new Promise((resolve, reject) => {
905
- input.handleSend(_cemiETS);
890
+ _input.handleSend(_cemiETS);
906
891
  // resolve(true); // fulfilled
907
892
  // reject("error"); // rejected
908
893
  // }).then(function () { }).catch(function () { });
909
894
  }
910
- } else if (input.listenallga === true) {
911
- // Get the GA from CVS
912
- let oGA;
913
- if (node.csv !== undefined) {
914
- try {
915
- oGA = node.csv.filter((sga) => sga.ga == _dest)[0];
916
- } catch (error) { }
917
- }
895
+ } else if (_input.listenallga === true) {
918
896
 
919
897
  // 25/10/2019 TRY TO AUTO DECODE IF Group address not found in the CSV
920
898
  const msg = buildInputMessage({
@@ -922,23 +900,21 @@ module.exports = (RED) => {
922
900
  _destGA: _dest,
923
901
  _event: _evt,
924
902
  _Rawvalue: _rawValue,
925
- _inputDpt: typeof oGA === "undefined" ? null : oGA.dpt,
926
- _devicename: typeof oGA === "undefined" ? input.name || "" : oGA.devicename,
927
903
  _outputtopic: _dest,
928
- _oNode: input,
904
+ _oNode: _input
929
905
  });
930
- input.setNodeStatus({
906
+ _input.setNodeStatus({
931
907
  fill: "green",
932
908
  shape: "dot",
933
- text: typeof oGA === "undefined" ? "Try to decode" : "",
909
+ text: "",
934
910
  payload: msg.payload,
935
911
  GA: msg.knx.destination,
936
912
  dpt: msg.knx.dpt,
937
913
  devicename: msg.devicename,
938
914
  });
939
- input.handleSend(msg);
940
- } else if (input.topic == _dest) {
941
- if (input.hasOwnProperty("isWatchDog")) {
915
+ _input.handleSend(msg);
916
+ } else if (_input.topic == _dest) {
917
+ if (_input.hasOwnProperty("isWatchDog")) {
942
918
  // 04/02/2020 Watchdog implementation
943
919
  // Is a watchdog node
944
920
  } else {
@@ -947,14 +923,14 @@ module.exports = (RED) => {
947
923
  _destGA: _dest,
948
924
  _event: _evt,
949
925
  _Rawvalue: _rawValue,
950
- _inputDpt: input.dpt,
951
- _devicename: input.name ? input.name : "",
952
- _outputtopic: input.outputtopic,
953
- _oNode: input,
926
+ _inputDpt: _input.dpt,
927
+ _devicename: _input.name ? _input.name : "",
928
+ _outputtopic: _input.outputtopic,
929
+ _oNode: _input,
954
930
  });
955
931
  // Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload
956
- if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) {
957
- input.setNodeStatus({
932
+ if (!checkRBEInputFromKNXBusAllowSend(_input, msg.payload)) {
933
+ _input.setNodeStatus({
958
934
  fill: "grey",
959
935
  shape: "ring",
960
936
  text: "rbe block (" + msg.payload + ") from KNX",
@@ -965,18 +941,18 @@ module.exports = (RED) => {
965
941
  });
966
942
  return;
967
943
  }
968
- msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Added previous payload
969
- input.currentPayload = msg.payload; // Set the current value for the RBE input
970
- input.setNodeStatus({
944
+ msg.previouspayload = typeof _input.currentPayload !== "undefined" ? _input.currentPayload : ""; // 24/01/2020 Added previous payload
945
+ _input.currentPayload = msg.payload; // Set the current value for the RBE input
946
+ _input.setNodeStatus({
971
947
  fill: "green",
972
948
  shape: "dot",
973
949
  text: "",
974
950
  payload: msg.payload,
975
- GA: input.topic,
976
- dpt: input.dpt,
951
+ GA: _input.topic,
952
+ dpt: _input.dpt,
977
953
  devicename: "",
978
954
  });
979
- input.handleSend(msg);
955
+ _input.handleSend(msg);
980
956
  }
981
957
  }
982
958
  });
@@ -987,64 +963,56 @@ module.exports = (RED) => {
987
963
  node.nodeClients
988
964
  .filter((_input) => _input.notifyresponse === true)
989
965
  .forEach((_input) => {
990
- const input = RED.nodes.getNode(_input.id); // 05/04/2022 Get the real node
991
966
 
992
- if (input.hasOwnProperty("isLogger")) {
967
+ if (_input.hasOwnProperty("isLogger")) {
993
968
  // 26/03/2020 Coronavirus is slightly decreasing the affected numer of people. Logger Node
994
969
  // 24/03/2021 Logger Node, i'll pass cemiETS
995
970
  if (_cemiETS !== undefined) {
996
971
  // new Promise((resolve, reject) => {
997
- input.handleSend(_cemiETS);
972
+ _input.handleSend(_cemiETS);
998
973
  // resolve(true); // fulfilled
999
974
  // reject("error"); // rejected
1000
975
  // }).then(function () { }).catch(function () { });
1001
976
  }
1002
- } else if (input.listenallga === true) {
1003
- // Get the DPT
1004
- let oGA;
1005
- try {
1006
- oGA = node.csv.filter((sga) => sga.ga == _dest)[0];
1007
- } catch (error) { }
977
+ } else if (_input.listenallga === true) {
1008
978
 
1009
979
  const msg = buildInputMessage({
1010
980
  _srcGA: _src,
1011
981
  _destGA: _dest,
1012
982
  _event: _evt,
1013
983
  _Rawvalue: _rawValue,
1014
- _inputDpt: typeof oGA === "undefined" ? null : oGA.dpt,
1015
- _devicename: typeof oGA === "undefined" ? input.name || "" : oGA.devicename,
1016
984
  _outputtopic: _dest,
1017
- _oNode: input,
985
+ _oNode: _input
1018
986
  });
1019
- input.setNodeStatus({
987
+ _input.setNodeStatus({
1020
988
  fill: "blue",
1021
989
  shape: "dot",
1022
- text: typeof oGA === "undefined" ? "Try to decode" : "",
990
+ text: "",
1023
991
  payload: msg.payload,
1024
992
  GA: msg.knx.destination,
1025
993
  dpt: msg.knx.dpt,
1026
994
  devicename: msg.devicename,
1027
995
  });
1028
- input.handleSend(msg);
1029
- } else if (input.topic === _dest) {
996
+ _input.handleSend(msg);
997
+ } else if (_input.topic === _dest) {
1030
998
  // 04/02/2020 Watchdog implementation
1031
- if (input.hasOwnProperty("isWatchDog")) {
999
+ if (_input.hasOwnProperty("isWatchDog")) {
1032
1000
  // Is a watchdog node
1033
- input.watchDogTimerReset();
1001
+ _input.watchDogTimerReset();
1034
1002
  } else {
1035
1003
  const msg = buildInputMessage({
1036
1004
  _srcGA: _src,
1037
1005
  _destGA: _dest,
1038
1006
  _event: _evt,
1039
1007
  _Rawvalue: _rawValue,
1040
- _inputDpt: input.dpt,
1041
- _devicename: input.name ? input.name : "",
1042
- _outputtopic: input.outputtopic,
1043
- _oNode: input,
1008
+ _inputDpt: _input.dpt,
1009
+ _devicename: _input.name ? _input.name : "",
1010
+ _outputtopic: _input.outputtopic,
1011
+ _oNode: _input,
1044
1012
  });
1045
1013
  // Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload
1046
- if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) {
1047
- input.setNodeStatus({
1014
+ if (!checkRBEInputFromKNXBusAllowSend(_input, msg.payload)) {
1015
+ _input.setNodeStatus({
1048
1016
  fill: "grey",
1049
1017
  shape: "ring",
1050
1018
  text: "rbe INPUT filter applied on " + msg.payload,
@@ -1053,18 +1021,18 @@ module.exports = (RED) => {
1053
1021
  });
1054
1022
  return;
1055
1023
  }
1056
- msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Added previous payload
1057
- input.currentPayload = msg.payload; // Set the current value for the RBE input
1058
- input.setNodeStatus({
1024
+ msg.previouspayload = typeof _input.currentPayload !== "undefined" ? _input.currentPayload : ""; // 24/01/2020 Added previous payload
1025
+ _input.currentPayload = msg.payload; // Set the current value for the RBE input
1026
+ _input.setNodeStatus({
1059
1027
  fill: "blue",
1060
1028
  shape: "dot",
1061
1029
  text: "",
1062
1030
  payload: msg.payload,
1063
- GA: input.topic,
1031
+ GA: _input.topic,
1064
1032
  dpt: msg.knx.dpt,
1065
1033
  devicename: msg.devicename,
1066
1034
  });
1067
- input.handleSend(msg);
1035
+ _input.handleSend(msg);
1068
1036
  }
1069
1037
  }
1070
1038
  });
@@ -1074,25 +1042,19 @@ module.exports = (RED) => {
1074
1042
  node.nodeClients
1075
1043
  .filter((_input) => _input.notifyreadrequest === true)
1076
1044
  .forEach((_input) => {
1077
- const input = RED.nodes.getNode(_input.id); // 05/04/2022 Get the real node
1078
1045
 
1079
- if (input.hasOwnProperty("isLogger")) {
1046
+ if (_input.hasOwnProperty("isLogger")) {
1080
1047
  // 26/03/2020 Coronavirus is slightly decreasing the affected numer of people. Logger Node
1081
1048
  // if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info("BANANA isLogger", _evt, _src, _dest, _rawValue, _cemiETS);
1082
1049
  // 24/03/2021 Logger Node, i'll pass cemiETS
1083
1050
  if (_cemiETS !== undefined) {
1084
1051
  // new Promise((resolve, reject) => {
1085
- input.handleSend(_cemiETS);
1052
+ _input.handleSend(_cemiETS);
1086
1053
  // resolve(true); // fulfilled
1087
1054
  // reject("error"); // rejected
1088
1055
  // }).then(function () { }).catch(function () { });
1089
1056
  }
1090
- } else if (input.listenallga === true) {
1091
- // Get the DPT
1092
- let oGA;
1093
- try {
1094
- oGA = node.csv.filter((sga) => sga.ga == _dest)[0];
1095
- } catch (error) { }
1057
+ } else if (_input.listenallga === true) {
1096
1058
 
1097
1059
  // Read Request
1098
1060
  const msg = buildInputMessage({
@@ -1100,12 +1062,10 @@ module.exports = (RED) => {
1100
1062
  _destGA: _dest,
1101
1063
  _event: _evt,
1102
1064
  _Rawvalue: null,
1103
- _inputDpt: typeof oGA === "undefined" ? null : oGA.dpt,
1104
- _devicename: typeof oGA === "undefined" ? input.name || "" : oGA.devicename,
1105
1065
  _outputtopic: _dest,
1106
- _oNode: input,
1066
+ _oNode: _input
1107
1067
  });
1108
- input.setNodeStatus({
1068
+ _input.setNodeStatus({
1109
1069
  fill: "grey",
1110
1070
  shape: "dot",
1111
1071
  text: "Read",
@@ -1114,10 +1074,10 @@ module.exports = (RED) => {
1114
1074
  dpt: msg.knx.dpt,
1115
1075
  devicename: msg.devicename,
1116
1076
  });
1117
- input.handleSend(msg);
1118
- } else if (input.topic === _dest) {
1077
+ _input.handleSend(msg);
1078
+ } else if (_input.topic === _dest) {
1119
1079
  // 04/02/2020 Watchdog implementation
1120
- if (input.hasOwnProperty("isWatchDog")) {
1080
+ if (_input.hasOwnProperty("isWatchDog")) {
1121
1081
  // Is a watchdog node
1122
1082
  } else {
1123
1083
  // Read Request
@@ -1126,62 +1086,62 @@ module.exports = (RED) => {
1126
1086
  _destGA: _dest,
1127
1087
  _event: _evt,
1128
1088
  _Rawvalue: null,
1129
- _inputDpt: input.dpt,
1130
- _devicename: input.name ? input.name : "",
1131
- _outputtopic: input.outputtopic,
1132
- _oNode: input,
1089
+ _inputDpt: _input.dpt,
1090
+ _devicename: _input.name || "",
1091
+ _outputtopic: _input.outputtopic,
1092
+ _oNode: _input,
1133
1093
  });
1134
- msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Reset previous payload
1094
+ msg.previouspayload = typeof _input.currentPayload !== "undefined" ? _input.currentPayload : ""; // 24/01/2020 Reset previous payload
1135
1095
  // 24/09/2019 Autorespond to BUS
1136
- if (input.hasOwnProperty("notifyreadrequestalsorespondtobus") && input.notifyreadrequestalsorespondtobus === true) {
1137
- if (typeof input.currentPayload === "undefined" || input.currentPayload === "" || input.currentPayload === null) {
1096
+ if (_input.hasOwnProperty("notifyreadrequestalsorespondtobus") && _input.notifyreadrequestalsorespondtobus === true) {
1097
+ if (typeof _input.currentPayload === "undefined" || _input.currentPayload === "" || _input.currentPayload === null) {
1138
1098
  // 14/08/2021 Added || input.currentPayload === null
1139
1099
  node.writeQueueAdd({
1140
1100
  grpaddr: _dest,
1141
- payload: input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized,
1142
- dpt: input.dpt,
1101
+ payload: _input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized,
1102
+ dpt: _input.dpt,
1143
1103
  outputtype: "response",
1144
- nodecallerid: input.id,
1104
+ nodecallerid: _input.id,
1145
1105
  });
1146
- input.setNodeStatus({
1106
+ _input.setNodeStatus({
1147
1107
  fill: "blue",
1148
1108
  shape: "ring",
1149
1109
  text: "Read & Autorespond with default",
1150
- payload: input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized,
1151
- GA: input.topic,
1110
+ payload: _input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized,
1111
+ GA: _input.topic,
1152
1112
  dpt: msg.knx.dpt,
1153
1113
  devicename: "",
1154
1114
  });
1155
1115
  } else {
1156
1116
  node.writeQueueAdd({
1157
1117
  grpaddr: _dest,
1158
- payload: input.currentPayload,
1159
- dpt: input.dpt,
1118
+ payload: _input.currentPayload,
1119
+ dpt: _input.dpt,
1160
1120
  outputtype: "response",
1161
- nodecallerid: input.id,
1121
+ nodecallerid: _input.id,
1162
1122
  });
1163
- input.setNodeStatus({
1123
+ _input.setNodeStatus({
1164
1124
  fill: "blue",
1165
1125
  shape: "ring",
1166
1126
  text: "Read & Autorespond with default",
1167
- payload: input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized,
1168
- GA: input.topic,
1127
+ payload: _input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized,
1128
+ GA: _input.topic,
1169
1129
  dpt: msg.knx.dpt,
1170
1130
  devicename: "",
1171
1131
  });
1172
1132
  }
1173
1133
  } else {
1174
- input.setNodeStatus({
1134
+ _input.setNodeStatus({
1175
1135
  fill: "grey",
1176
1136
  shape: "dot",
1177
1137
  text: "Read",
1178
1138
  payload: msg.payload,
1179
- GA: input.topic,
1139
+ GA: _input.topic,
1180
1140
  dpt: msg.knx.dpt,
1181
1141
  devicename: "",
1182
1142
  });
1183
1143
  }
1184
- input.handleSend(msg);
1144
+ _input.handleSend(msg);
1185
1145
  }
1186
1146
  }
1187
1147
  });
@@ -1221,12 +1181,12 @@ module.exports = (RED) => {
1221
1181
  }
1222
1182
 
1223
1183
  // 26/12/2021 If the KNXEngine is busy waiting for telegram's ACK, exit
1224
- if (!node.knxConnection._getClearToSend()) {
1184
+ if (!node.knxConnection.clearToSend) {
1225
1185
  node.lockHandleTelegramQueue = false; // Unlock the function
1226
1186
  if (node.telegramsQueue.length > 0) {
1227
1187
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.warn(
1228
1188
  "knxUltimate-config: handleTelegramQueue: the KNXEngine is busy or is waiting for a telegram ACK with seqNumner " +
1229
- node.knxConnection._getSeqNumber() +
1189
+ node.knxConnection.getSeqNumber() +
1230
1190
  ". Delay handling queue.",
1231
1191
  );
1232
1192
  }
@@ -1291,7 +1251,6 @@ module.exports = (RED) => {
1291
1251
  // }
1292
1252
  try {
1293
1253
  node.nodeClients.forEach((_input) => {
1294
- const input = RED.nodes.getNode(_input.id); // 05/04/2022 Get the real node
1295
1254
 
1296
1255
  // 16/08/2021 If not connected, exit
1297
1256
  if (node.linkStatus !== "connected") {
@@ -1300,25 +1259,25 @@ module.exports = (RED) => {
1300
1259
  }
1301
1260
 
1302
1261
  // 19/03/2020 in the middle of coronavirus. Whole italy is red zone, closed down. Scene Controller implementation
1303
- if (input.hasOwnProperty("isSceneController")) {
1304
- } else if (input.hasOwnProperty("isLogger")) {
1262
+ if (_input.hasOwnProperty("isSceneController")) {
1263
+ } else if (_input.hasOwnProperty("isLogger")) {
1305
1264
  // 26/03/2020 Coronavirus is slightly decreasing the affected numer of people. Logger Node
1306
- } else if (input.listenallga === true) {
1307
- } else if (input.topic == oKNXMessage.grpaddr) {
1308
- if (input.hasOwnProperty("isWatchDog")) {
1265
+ } else if (_input.listenallga === true) {
1266
+ } else if (_input.topic == oKNXMessage.grpaddr) {
1267
+ if (_input.hasOwnProperty("isWatchDog")) {
1309
1268
  // 04/02/2020 Watchdog implementation
1310
1269
  // Is a watchdog node
1311
1270
  } else {
1312
1271
  const msg = {
1313
- topic: input.outputtopic,
1272
+ topic: _input.outputtopic,
1314
1273
  payload: oKNXMessage.payload,
1315
- devicename: input.name ? input.name : "",
1274
+ devicename: _input.name ? _input.name : "",
1316
1275
  event: "Update_NoWrite",
1317
1276
  eventdesc: "The value has been updated from another node and hasn't been received from KNX BUS",
1318
1277
  };
1319
1278
  // Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload
1320
- if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) {
1321
- input.setNodeStatus({
1279
+ if (!checkRBEInputFromKNXBusAllowSend(_input, msg.payload)) {
1280
+ _input.setNodeStatus({
1322
1281
  fill: "grey",
1323
1282
  shape: "ring",
1324
1283
  text: "rbe block (" + msg.payload + ") from KNX",
@@ -1330,18 +1289,18 @@ module.exports = (RED) => {
1330
1289
  node.lockHandleTelegramQueue = false; // Unlock the function
1331
1290
  return;
1332
1291
  }
1333
- msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Added previous payload
1334
- input.currentPayload = msg.payload; // Set the current value for the RBE input
1335
- input.setNodeStatus({
1292
+ msg.previouspayload = typeof _input.currentPayload !== "undefined" ? _input.currentPayload : ""; // 24/01/2020 Added previous payload
1293
+ _input.currentPayload = msg.payload; // Set the current value for the RBE input
1294
+ _input.setNodeStatus({
1336
1295
  fill: "green",
1337
1296
  shape: "dot",
1338
1297
  text: "",
1339
1298
  payload: msg.payload,
1340
- GA: input.topic,
1341
- dpt: input.dpt,
1299
+ GA: _input.topic,
1300
+ dpt: _input.dpt,
1342
1301
  devicename: "",
1343
1302
  });
1344
- input.handleSend(msg);
1303
+ _input.handleSend(msg);
1345
1304
  }
1346
1305
  }
1347
1306
  });
@@ -1353,6 +1312,9 @@ module.exports = (RED) => {
1353
1312
  } catch (error) {
1354
1313
  try {
1355
1314
  const oNode = RED.nodes.getNode(oKNXMessage.nodecallerid); // 05/04/2022 Get the real node
1315
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(
1316
+ "knxUltimate-config: node.knxConnection.write: Payload: " + oKNXMessage.payload + " GA:" + oKNXMessage.grpaddr + " DPT:" + oKNXMessage.dpt + " " + error.stack
1317
+ );
1356
1318
  oNode.setNodeStatus({
1357
1319
  fill: "red",
1358
1320
  shape: "dot",
@@ -1424,12 +1386,53 @@ module.exports = (RED) => {
1424
1386
  }
1425
1387
  }
1426
1388
 
1389
+
1427
1390
  function buildInputMessage({ _srcGA, _destGA, _event, _Rawvalue, _inputDpt, _devicename, _outputtopic, _oNode }) {
1428
1391
  let sPayloadmeasureunit = "unknown";
1429
1392
  let sDptdesc = "unknown";
1430
1393
  let sPayloadsubtypevalue = "unknown";
1431
1394
  let jsValue = null;
1432
1395
  let sInputDpt = "unknown";
1396
+ let gainfo = "unknown";
1397
+ let oGA;
1398
+
1399
+ // Construct the gainfo from _devicename ("(Ingressi logici->Sensori) Camera armadi lux")
1400
+ if (node.csv !== undefined) {
1401
+ try {
1402
+ oGA = node.csv.filter((sga) => sga.ga == _destGA)[0];
1403
+ const regexGA = /^(.*)\/(.*)\/(.*)$/;
1404
+ const regexName = /^\((.*)->(.*)\) (.*)$/;
1405
+ const matchGA = oGA.ga.match(regexGA);
1406
+ const matchName = oGA.devicename.match(regexName);
1407
+ gainfo = {
1408
+ maingroupname: matchName[1],
1409
+ middlegroupname: matchName[2],
1410
+ ganame: matchName[3],
1411
+ maingroupnumber: matchGA[1],
1412
+ middlegroupnumber: matchGA[2],
1413
+ ganumber: matchGA[3]
1414
+ }
1415
+ } catch (error) {
1416
+ // Dont' care
1417
+ }
1418
+ }
1419
+
1420
+ // 20/06/2024 set both if undefined
1421
+ if (_inputDpt === undefined) {
1422
+ try {
1423
+ _inputDpt = oGA === undefined ? null : oGA.dpt;
1424
+ } catch (error) {
1425
+ _inputDpt = null;
1426
+ }
1427
+
1428
+ }
1429
+ if (_devicename === undefined) {
1430
+ try {
1431
+ _devicename = oGA === undefined ? _oNode.name || "" : oGA.devicename;
1432
+ } catch (error) {
1433
+ _devicename = undefined;
1434
+ }
1435
+ }
1433
1436
 
1434
1437
  const errorMessage = {
1435
1438
  topic: _outputtopic,
@@ -1440,7 +1443,6 @@ module.exports = (RED) => {
1440
1443
  knx: {
1441
1444
  event: _event,
1442
1445
  dpt: "unknown",
1443
- //, details: dpt
1444
1446
  dptdesc: "",
1445
1447
  source: _srcGA,
1446
1448
  destination: _destGA,
@@ -1567,6 +1569,7 @@ module.exports = (RED) => {
1567
1569
  }
1568
1570
  }
1569
1571
  }
1572
+
1570
1573
  } else {
1571
1574
  // Don't care, it's a READ REQUEST
1572
1575
  }
@@ -1579,15 +1582,15 @@ module.exports = (RED) => {
1579
1582
  payload: jsValue,
1580
1583
  payloadmeasureunit: sPayloadmeasureunit,
1581
1584
  payloadsubtypevalue: sPayloadsubtypevalue,
1585
+ gainfo: gainfo,
1582
1586
  knx: {
1583
1587
  event: _event,
1584
1588
  dpt: sInputDpt,
1585
- //, details: dpt
1586
1589
  dptdesc: sDptdesc,
1587
1590
  source: _srcGA,
1588
1591
  destination: _destGA,
1589
- rawValue: _Rawvalue,
1590
- },
1592
+ rawValue: _Rawvalue
1593
+ }
1591
1594
  };
1592
1595
  // 11/11/2021 jsValue is null, as well as _Rawvalue, in case of READ REQUEST message.
1593
1596
  // if (jsValue !== null) finalMessage.payload = jsValue;
@@ -1884,7 +1887,7 @@ module.exports = (RED) => {
1884
1887
  }
1885
1888
  }, 4000);
1886
1889
 
1887
- node.Disconnect = (_sNodeStatus = "", _sColor = "grey") => {
1890
+ node.Disconnect = async (_sNodeStatus = "", _sColor = "grey") => {
1888
1891
  if (node.linkStatus === "disconnected") {
1889
1892
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("knxUltimate-config: Disconnect: already not connected:" + node.linkStatus + ", node.autoReconnect:" + node.autoReconnect);
1890
1893
  return;
@@ -1894,7 +1897,7 @@ module.exports = (RED) => {
1894
1897
  node.lockHandleTelegramQueue = false; // Unlock the telegram handling function
1895
1898
  if (node.timerDoInitialRead !== null) clearTimeout(node.timerDoInitialRead); // 17/02/2020 Stop the initial read timer
1896
1899
  try {
1897
- if (node.knxConnection !== null) node.knxConnection.Disconnect();
1900
+ if (node.knxConnection !== null) await node.knxConnection.Disconnect();
1898
1901
  } catch (error) {
1899
1902
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug(
1900
1903
  "knxUltimate-config: Disconnected: node.knxConnection.Disconnect() " + (error.message || "") + " , node.autoReconnect:" + node.autoReconnect,
@@ -1906,9 +1909,9 @@ module.exports = (RED) => {
1906
1909
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.debug("knxUltimate-config: Disconnected, node.autoReconnect:" + node.autoReconnect);
1907
1910
  };
1908
1911
 
1909
- node.on("close", function (done) {
1912
+ node.on("close", async function (done) {
1910
1913
  try {
1911
- node.Disconnect();
1914
+ await node.Disconnect();
1912
1915
  } catch (error) { /* empty */ }
1913
1916
  if (node.timerClearTelegramQueue !== null) clearTimeout(node.timerClearTelegramQueue);
1914
1917
  node.telegramsQueue = [];