node-red-contrib-knx-ultimate 1.3.31 → 1.3.34

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 (99) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/KNXEngine/KNXClient.js +126 -151
  3. package/KNXEngine/KnxLog.js +2 -0
  4. package/KNXEngine/dptlib/dpt16.js +5 -2
  5. package/README.md +16 -5
  6. package/nodes/knxUltimate-config.html +1 -1
  7. package/nodes/knxUltimate-config.js +41 -33
  8. package/nodes/knxUltimate.js +7 -7
  9. package/nodes/knxUltimateGlobalContext.js +9 -2
  10. package/nodes/knxUltimateLoadControl.js +7 -7
  11. package/nodes/knxUltimateLogger.js +4 -2
  12. package/nodes/knxUltimateSceneController.js +11 -10
  13. package/nodes/knxUltimateWatchDog.js +2 -2
  14. package/nodes/locales/de/knxUltimateLoadControl.json +3 -3
  15. package/nodes/locales/zh-CN/knxUltimateLoadControl.json +1 -1
  16. package/package.json +1 -1
  17. package/knxultimate-api2/index.js +0 -22
  18. package/knxultimate-api2/src/Address.js +0 -116
  19. package/knxultimate-api2/src/Connection.js +0 -458
  20. package/knxultimate-api2/src/Datapoint.js +0 -143
  21. package/knxultimate-api2/src/FSM.js +0 -847
  22. package/knxultimate-api2/src/IpRoutingConnection.js +0 -83
  23. package/knxultimate-api2/src/IpTunnelingConnection.js +0 -65
  24. package/knxultimate-api2/src/KNXsecureKeyring.js +0 -575
  25. package/knxultimate-api2/src/KnxConstants.js +0 -261
  26. package/knxultimate-api2/src/KnxLog.js +0 -69
  27. package/knxultimate-api2/src/KnxProtocol.js +0 -1025
  28. package/knxultimate-api2/src/RawMod/CheckResourceAvailable.js +0 -9
  29. package/knxultimate-api2/src/RawMod/CustomMessageHandlerTemplates.js +0 -82
  30. package/knxultimate-api2/src/RawMod/CustomMsgHandlers.js +0 -148
  31. package/knxultimate-api2/src/RawMod/ErrorHandler.js +0 -108
  32. package/knxultimate-api2/src/RawMod/Errors.js +0 -93
  33. package/knxultimate-api2/src/RawMod/Handlers.js +0 -143
  34. package/knxultimate-api2/src/RawMod/KnxAddress.js +0 -374
  35. package/knxultimate-api2/src/RawMod/KnxDeviceResourceInformation.js +0 -7557
  36. package/knxultimate-api2/src/RawMod/KnxMessageTemplates.js +0 -204
  37. package/knxultimate-api2/src/RawMod/KnxNetProtocol.js +0 -201
  38. package/knxultimate-api2/src/RawMod/KnxNetProtocolExtra.js +0 -131
  39. package/knxultimate-api2/src/RawMod/KnxNetRebuildMessageBytes.js +0 -138
  40. package/knxultimate-api2/src/RawMod/KnxOperations/LoadStateMachine.js +0 -48
  41. package/knxultimate-api2/src/RawMod/KnxOperations/RestartDevice.js +0 -181
  42. package/knxultimate-api2/src/RawMod/KnxOperations/RunStateMachine.js +0 -48
  43. package/knxultimate-api2/src/RawMod/KnxParseTpci.js +0 -163
  44. package/knxultimate-api2/src/RawMod/RawMod.js +0 -88
  45. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadApplicationID.js +0 -112
  46. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDevMem.js +0 -340
  47. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDeviceADC.js +0 -324
  48. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDeviceAddress.js +0 -218
  49. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDeviceResource.js +0 -238
  50. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadGroupAddrTblLoadstate.js +0 -84
  51. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadGroupAssociationTblLoadstate.js +0 -84
  52. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadManufacturerID.js +0 -96
  53. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadMaskversion.js +0 -317
  54. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadOrderNumber.js +0 -96
  55. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadProgmodeStatus.js +0 -88
  56. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadPropertyValue.js +0 -336
  57. package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadSerialNumber.js +0 -99
  58. package/knxultimate-api2/src/RawMod/__KnxReadOperations/__KnxReadResourceViaMemory.js +0 -12
  59. package/knxultimate-api2/src/RawMod/__KnxReadOperations/__KnxReadResourceViaProperty.js +0 -15
  60. package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxSetDeviceAddress.js +0 -150
  61. package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxSetProgmodeStatus.js +0 -73
  62. package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxWriteDevMem.js +0 -343
  63. package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxWriteDeviceResource.js +0 -204
  64. package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxWritePropertyValue.js +0 -348
  65. package/knxultimate-api2/src/RawMod/__KnxWriteOperations/__KnxWriteResourceViaMemory.js +0 -11
  66. package/knxultimate-api2/src/RawMod/__KnxWriteOperations/__KnxWriteResourceViaProperty.js +0 -15
  67. package/knxultimate-api2/src/dptlib/dpt1.js +0 -201
  68. package/knxultimate-api2/src/dptlib/dpt10.js +0 -106
  69. package/knxultimate-api2/src/dptlib/dpt11.js +0 -84
  70. package/knxultimate-api2/src/dptlib/dpt12.js +0 -63
  71. package/knxultimate-api2/src/dptlib/dpt13.js +0 -77
  72. package/knxultimate-api2/src/dptlib/dpt14.js +0 -191
  73. package/knxultimate-api2/src/dptlib/dpt15.js +0 -24
  74. package/knxultimate-api2/src/dptlib/dpt16.js +0 -67
  75. package/knxultimate-api2/src/dptlib/dpt17.js +0 -25
  76. package/knxultimate-api2/src/dptlib/dpt18.js +0 -96
  77. package/knxultimate-api2/src/dptlib/dpt19.js +0 -62
  78. package/knxultimate-api2/src/dptlib/dpt2.js +0 -132
  79. package/knxultimate-api2/src/dptlib/dpt20.js +0 -52
  80. package/knxultimate-api2/src/dptlib/dpt213.js +0 -156
  81. package/knxultimate-api2/src/dptlib/dpt22.js +0 -145
  82. package/knxultimate-api2/src/dptlib/dpt222.js +0 -158
  83. package/knxultimate-api2/src/dptlib/dpt232.js +0 -58
  84. package/knxultimate-api2/src/dptlib/dpt237.js +0 -92
  85. package/knxultimate-api2/src/dptlib/dpt238.js +0 -73
  86. package/knxultimate-api2/src/dptlib/dpt242.js +0 -84
  87. package/knxultimate-api2/src/dptlib/dpt249.js +0 -87
  88. package/knxultimate-api2/src/dptlib/dpt251.js +0 -76
  89. package/knxultimate-api2/src/dptlib/dpt3.js +0 -90
  90. package/knxultimate-api2/src/dptlib/dpt4.js +0 -58
  91. package/knxultimate-api2/src/dptlib/dpt5.js +0 -70
  92. package/knxultimate-api2/src/dptlib/dpt6.js +0 -42
  93. package/knxultimate-api2/src/dptlib/dpt7.js +0 -150
  94. package/knxultimate-api2/src/dptlib/dpt8.js +0 -94
  95. package/knxultimate-api2/src/dptlib/dpt9.js +0 -212
  96. package/knxultimate-api2/src/dptlib/dpt999.js +0 -61
  97. package/knxultimate-api2/src/dptlib/index.js +0 -185
  98. package/knxultimate-api2/src/superKNX.js +0 -117
  99. package/nodes/knxUltimate-config API2.js +0 -1829
package/CHANGELOG.md CHANGED
@@ -6,6 +6,25 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ <p>
10
+ <b>Version 1.3.34</b> - March 2022<br/>
11
+ - Reset handlers by removing/adding every time the connection is set by "new" directive.<br/>
12
+ - Fixed an issue causing glitches, when the disconnection is requested by the KNX interface instead of KNX-Ultimate.<br/>
13
+ - Fixed an issue occurring when the disconnection is started from KNX-Ultimate by the DISCONNECT_REQUEST, but the KNX Interface fails to send the DISCONNECT_RESPONSE to confirm the disconnection.<br/>
14
+ - Updated knxUltimate-config.js to actively disconnect and close the socket when the disconnection is requested by the KNX Interface. All other cases (disconnection by ethernet cable, disconnection by unreachable KNX Interface, disconnection by temporary out of access, disconnection by means of user intervention, disconnection by Watchdog node etc...) are not affected by this issue.<br/>
15
+ - Optimized memory allocation to allow the garbage collector to get rid of unref variables.<br/>
16
+ - Scene controller: fixed node status issues.<br/>
17
+ - Load control: code revision.<br/>
18
+ - Logger: code revision.<br/>
19
+ - Watchdog: code revision.<br/>
20
+ - Device node: code revision.<br/>
21
+ - Global Context: code revision.<br/>
22
+ - Wiki: merged Global Context node sample, into one single page for better readability.<br/>
23
+ </p>
24
+ <p>
25
+ <b>Version 1.3.32</b> - February 2022<br/>
26
+ - FIX Datapoint 16.001: fixed an issue with the ISO8859-1 encoding.<br/>
27
+ </p>
9
28
  <p>
10
29
  <b>Version 1.3.31</b> - February 2022<br/>
11
30
  - KNX Viewer node: now the payload is formatted depending on value type.<br/>
@@ -19,7 +19,7 @@ const ipAddressHelper = require("./util/ipAddressHelper");
19
19
  const KNXAddress = require("./protocol/KNXAddress").KNXAddress;
20
20
  const KNXDataBuffer = require("./protocol/KNXDataBuffer").KNXDataBuffer;
21
21
  const DPTLib = require('./dptlib');
22
- const KNXsecureKeyring = require("./KNXsecureKeyring.js");
22
+ //const KNXsecureKeyring = require("./KNXsecureKeyring.js");
23
23
  //const lodash = require("lodash");
24
24
 
25
25
  var STATE;
@@ -64,6 +64,9 @@ var KNXClientEvents;
64
64
  // connecting: "connecting"
65
65
  // };
66
66
 
67
+ // Contains the decrypted keyring file
68
+ var jKNXSecureKeyring = "";
69
+
67
70
  // options:
68
71
  const optionsDefaults = {
69
72
  physAddr: '15.15.200',
@@ -91,8 +94,8 @@ class KNXClient extends EventEmitter {
91
94
  super();
92
95
  this._clientTunnelSeqNumber = -1;
93
96
  this._options = options;//Object.assign(optionsDefaults, options);
94
- this._options.connectionKeepAliveTimeout = KNXConstants.KNX_CONSTANTS.CONNECTION_ALIVE_TIME,
95
- this._localPort = null;
97
+ this._options.connectionKeepAliveTimeout = KNXConstants.KNX_CONSTANTS.CONNECTION_ALIVE_TIME;
98
+ //this._localPort = null;
96
99
  this._peerHost = this._options.ipAddr;
97
100
  this._peerPort = this._options.ipPort;
98
101
  this._connectionTimeoutTimer = null;
@@ -104,7 +107,7 @@ class KNXClient extends EventEmitter {
104
107
  this._processInboundMessage = this._processInboundMessage.bind(this);
105
108
  this._clientSocket = null;
106
109
  this.sysLogger = null;
107
- this.jKNXSecureKeyring = this._options.jKNXSecureKeyring; // 28/12/2021 Contains the Keyring JSON object
110
+ jKNXSecureKeyring = this._options.jKNXSecureKeyring; // 28/12/2021 Contains the Keyring JSON object
108
111
  try {
109
112
  this.sysLogger = require("./KnxLog.js").get({ loglevel: this._options.loglevel }); // 08/04/2021 new logger to adhere to the loglevel selected in the config-window
110
113
  } catch (error) {
@@ -120,24 +123,28 @@ class KNXClient extends EventEmitter {
120
123
  throw (error);
121
124
  }
122
125
 
123
- let conn = this;
126
+ // 12/03/2022 Remove all listeners
127
+ this.removeAllListeners();
124
128
  // 07/12/2021 Based on protocol instantiate the right socket
125
129
  if (this._options.hostProtocol === "TunnelUDP") {
126
130
  this._clientSocket = dgram.createSocket({ type: 'udp4', reuseAddr: false });
131
+ this._clientSocket.removeAllListeners(); // 12/03/2022 Remove all listeners
127
132
  this._clientSocket.on(SocketEvents.message, this._processInboundMessage);
128
133
  this._clientSocket.on(SocketEvents.error, error => this.emit(KNXClientEvents.error, error));
129
134
  this._clientSocket.on(SocketEvents.close, info => this.emit(KNXClientEvents.close, info));
130
- this._clientSocket.bind({ address: this._options.localIPAddress, port: this._options._peerPort }, () => {
135
+ let conn = this;
136
+ this._clientSocket.bind({ address: this._options.localIPAddress, port: this._options._peerPort }, function () {
131
137
  try {
132
138
  conn._clientSocket.setTTL(128);
133
139
  } catch (error) {
134
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("UDP: Error setting SetTTL " + error.message || "");
140
+ if (conn.sysLogger !== undefined && conn.sysLogger !== null) conn.sysLogger.error("UDP: Error setting SetTTL " + error.message || "");
135
141
  }
136
142
  });
137
143
 
138
144
  } else if (this._options.hostProtocol === "TunnelTCP") {
139
145
  // TCP
140
146
  this._clientSocket = new net.Socket();
147
+ this._clientSocket.removeAllListeners(); // 12/03/2022 Remove all listeners
141
148
  //this._clientSocket.on(SocketEvents.data, this._processInboundMessage);
142
149
  this._clientSocket.on(SocketEvents.data, function (msg, rinfo, callback) {
143
150
  console.log(msg, rinfo, callback);
@@ -146,37 +153,39 @@ class KNXClient extends EventEmitter {
146
153
  this._clientSocket.on(SocketEvents.close, info => this.emit(KNXClientEvents.close, info));
147
154
 
148
155
  } else if (this._options.hostProtocol === "Multicast") {
149
- let conn = this;
150
156
  this._clientSocket = dgram.createSocket({ type: 'udp4', reuseAddr: true });
157
+ this._clientSocket.removeAllListeners(); // 12/03/2022 Remove all listeners
151
158
  this._clientSocket.on(SocketEvents.listening, function () {
152
- try {
153
- conn._clientSocket.addMembership(conn._peerHost, conn._options.localIPAddress);
154
- } catch (err) {
155
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("Multicast: cannot add membership (%s)", err);
156
- try {
157
- this.emit(KNXClientEvents.error, err);
158
- } catch (error) { }
159
- return;
160
- }
159
+
161
160
  });
161
+ let conn = this;
162
162
  this._clientSocket.on(SocketEvents.message, this._processInboundMessage);
163
163
  this._clientSocket.on(SocketEvents.error, error => this.emit(KNXClientEvents.error, error));
164
164
  this._clientSocket.on(SocketEvents.close, info => this.emit(KNXClientEvents.close, info));
165
- this._clientSocket.bind(this._peerPort, () => {
165
+ this._clientSocket.bind(this._peerPort, function () {
166
166
  try {
167
167
  conn._clientSocket.setMulticastTTL(128);
168
- conn._clientSocket.setMulticastInterface(this._options.localIPAddress);
168
+ conn._clientSocket.setMulticastInterface(conn._options.localIPAddress);
169
169
  } catch (error) {
170
- if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("Multicast: Error setting SetTTL " + error.message || "");
170
+ if (conn.sysLogger !== undefined && conn.sysLogger !== null) conn.sysLogger.error("Multicast: Error setting SetTTL " + error.message || "");
171
+ }
172
+ try {
173
+ conn._clientSocket.addMembership(conn._peerHost, conn._options.localIPAddress);
174
+ } catch (err) {
175
+ if (conn.sysLogger !== undefined && conn.sysLogger !== null) conn.sysLogger.error("Multicast: cannot add membership (%s)", err);
176
+ try {
177
+ conn.emit(KNXClientEvents.error, err);
178
+ } catch (error) { }
179
+ return;
171
180
  }
172
- this._localPort = this._clientSocket.address().port;// 07/12/2021 Get the local port used bu the socket
181
+ //this._localPort = this._clientSocket.address().port;// 07/12/2021 Get the local port used bu the socket
173
182
  });
174
183
  }
175
184
 
176
185
  this._clientTunnelSeqNumber = -1;
177
186
  this._channelID = null;
178
187
  this._connectionState = STATE.DISCONNECTED;
179
- this._tunnelReqTimer = null;
188
+ this._timerWaitingForACK = null;
180
189
  this._numFailedTelegramACK = 0; // 25/12/2021 Keep count of the failed tunnelig ACK telegrams
181
190
 
182
191
  }
@@ -228,21 +237,21 @@ class KNXClient extends EventEmitter {
228
237
  }
229
238
  return new KNXDataBuffer(adpu.data, IDataPoint);
230
239
  }
231
- bindSocketPortAsync(port = KNXConstants.KNX_CONSTANTS.KNX_PORT, host = '0.0.0.0') {
232
- return new Promise((resolve, reject) => {
233
- try {
234
- this._clientSocket.bind(port, host, () => {
235
- this._clientSocket.setMulticastInterface(host);
236
- this._clientSocket.setMulticastTTL(128);
237
- this._options.localIPAddress = host;
238
- resolve();
239
- });
240
- }
241
- catch (err) {
242
- reject(err);
243
- }
244
- });
245
- }
240
+ // bindSocketPortAsync(port = KNXConstants.KNX_CONSTANTS.KNX_PORT, host = '0.0.0.0') {
241
+ // return new Promise((resolve, reject) => {
242
+ // try {
243
+ // this._clientSocket.bind(port, host, () => {
244
+ // this._clientSocket.setMulticastInterface(host);
245
+ // this._clientSocket.setMulticastTTL(128);
246
+ // this._options.localIPAddress = host;
247
+ // resolve();
248
+ // });
249
+ // }
250
+ // catch (err) {
251
+ // reject(err);
252
+ // }
253
+ // });
254
+ // }
246
255
  send(knxPacket) {
247
256
 
248
257
  // Logging
@@ -309,10 +318,8 @@ class KNXClient extends EventEmitter {
309
318
 
310
319
  /**
311
320
  *
312
- * @param {KNXAddress} srcAddress
313
321
  * @param {KNXAddress} dstAddress
314
322
  * @param {KNXDataBuffer} data
315
- * @param {function} cb
316
323
  */
317
324
  // sendWriteRequest(dstAddress, data) {
318
325
  write(dstAddress, data, dptid) {
@@ -344,8 +351,7 @@ class KNXClient extends EventEmitter {
344
351
  cEMIMessage.control.priority = 3;
345
352
  cEMIMessage.control.addressType = 1;
346
353
  cEMIMessage.control.hopCount = 6;
347
- this._incSeqNumber(); // 26/12/2021
348
- const seqNum = this._getSeqNumber();
354
+ const seqNum = this._incSeqNumber(); // 26/12/2021
349
355
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
350
356
  if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
351
357
  //if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error("this._tunnelReqTimer "+ this._tunnelReqTimer.size);
@@ -390,8 +396,7 @@ class KNXClient extends EventEmitter {
390
396
  cEMIMessage.control.priority = 3;
391
397
  cEMIMessage.control.addressType = 1;
392
398
  cEMIMessage.control.hopCount = 6;
393
- this._incSeqNumber(); // 26/12/2021
394
- const seqNum = this._getSeqNumber();
399
+ const seqNum = this._incSeqNumber(); // 26/12/2021
395
400
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
396
401
  if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
397
402
  this.send(knxPacketRequest);
@@ -432,8 +437,7 @@ class KNXClient extends EventEmitter {
432
437
  cEMIMessage.control.priority = 3;
433
438
  cEMIMessage.control.addressType = 1;
434
439
  cEMIMessage.control.hopCount = 6;
435
- this._incSeqNumber(); // 26/12/2021
436
- const seqNum = this._getSeqNumber();
440
+ const seqNum = this._incSeqNumber(); // 26/12/2021
437
441
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
438
442
  if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
439
443
  this.send(knxPacketRequest);
@@ -446,55 +450,6 @@ class KNXClient extends EventEmitter {
446
450
  }
447
451
 
448
452
  }
449
- // writeRaw(dstAddress, _rawDataBuffer, bitlength) {
450
- // // bitlength is unused and only for backward compatibility
451
-
452
- // if (this._connectionState !== STATE.CONNECTED) throw new Error("The socket is not connected. Unable to access the KNX BUS");
453
-
454
- // if (!Buffer.isBuffer(_rawDataBuffer)) {
455
- // if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.error('KNXClient: writeRaw: Value must be a buffer! ');
456
- // return
457
- // }
458
-
459
- // // Transform the "data" into a KNDDataBuffer
460
- // let data = new KNXDataBuffer(_rawDataBuffer);
461
-
462
- // if (typeof dstAddress === "string") dstAddress = KNXAddress.createFromString(dstAddress, KNXAddress.TYPE_GROUP);
463
- // let srcAddress = this._options.physAddr;
464
- // if (this._options.hostProtocol === "Multicast") {
465
- // // Multicast
466
- // const cEMIMessage = CEMIFactory.CEMIFactory.newLDataIndicationMessage("write", srcAddress, dstAddress, data);
467
- // cEMIMessage.control.ack = 0;
468
- // cEMIMessage.control.broadcast = 1;
469
- // cEMIMessage.control.priority = 3;
470
- // cEMIMessage.control.addressType = 1;
471
- // cEMIMessage.control.hopCount = 6;
472
- // const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXRoutingIndication(cEMIMessage);
473
- // this.send(knxPacketRequest);
474
- // // 06/12/2021 Multivast automaticalli echoes telegrams
475
-
476
- // } else {
477
- // // Tunneling
478
- // const cEMIMessage = CEMIFactory.CEMIFactory.newLDataRequestMessage("write", srcAddress, dstAddress, data);
479
- // cEMIMessage.control.ack = this._options.suppress_ack_ldatareq ? 0 : 1;
480
- // cEMIMessage.control.broadcast = 1;
481
- // cEMIMessage.control.priority = 3;
482
- // cEMIMessage.control.addressType = 1;
483
- // cEMIMessage.control.hopCount = 6;
484
- // this._incSeqNumber(); // 26/12/2021
485
- // const seqNum = this._getSeqNumber();
486
- // const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
487
- // if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
488
- // this.send(knxPacketRequest);
489
- // // 06/12/2021 Echo the sent telegram. Last parameter is the echo true/false
490
- // try {
491
- // if (this._options.localEchoInTunneling) this.emit(KNXClientEvents.indication, knxPacketRequest, true);
492
- // } catch (error) {
493
- // }
494
-
495
- // }
496
-
497
- // }
498
453
 
499
454
  writeRaw(dstAddress, _rawDataBuffer, bitlength) {
500
455
  // bitlength is unused and only for backward compatibility
@@ -543,8 +498,7 @@ class KNXClient extends EventEmitter {
543
498
  cEMIMessage.control.priority = 3;
544
499
  cEMIMessage.control.addressType = 1;
545
500
  cEMIMessage.control.hopCount = 6;
546
- this._incSeqNumber(); // 26/12/2021
547
- const seqNum = this._getSeqNumber();
501
+ const seqNum = this._incSeqNumber(); // 26/12/2021
548
502
  const knxPacketRequest = KNXProtocol.KNXProtocol.newKNXTunnelingRequest(this._channelID, seqNum, cEMIMessage);
549
503
  if (!this._options.suppress_ack_ldatareq) this._setTimerWaitingForACK(knxPacketRequest);
550
504
  this.send(knxPacketRequest);
@@ -569,35 +523,35 @@ class KNXClient extends EventEmitter {
569
523
  clearTimeout(this._heartbeatTimer);
570
524
  }
571
525
  }
572
- isDiscoveryRunning() {
573
- return this._discovery_timer != null;
574
- }
575
- startDiscovery() {
576
- if (this.isDiscoveryRunning()) {
577
- throw new Error('Discovery already running');
578
- }
579
- this._discovery_timer = setTimeout(() => {
580
- this._discovery_timer = null;
581
- }, 1000 * KNXConstants.KNX_CONSTANTS.SEARCH_TIMEOUT);
582
- this._sendSearchRequestMessage();
583
- }
584
- stopDiscovery() {
585
- if (!this.isDiscoveryRunning()) {
586
- return;
587
- }
588
- if (this._discovery_timer !== null) clearTimeout(this._discovery_timer);
589
- this._discovery_timer = null;
590
- }
591
- getDescription(host, port) {
592
- if (this._clientSocket == null) {
593
- throw new Error('No client socket defined');
594
- }
595
- this._connectionTimeoutTimer = setTimeout(() => {
596
- this._connectionTimeoutTimer = null;
597
- }, 1000 * KNXConstants.KNX_CONSTANTS.DEVICE_CONFIGURATION_REQUEST_TIMEOUT);
598
- this._awaitingResponseType = KNXConstants.KNX_CONSTANTS.DESCRIPTION_RESPONSE;
599
- this._sendDescriptionRequestMessage(host, port);
600
- }
526
+ // isDiscoveryRunning() {
527
+ // return this._discovery_timer != null;
528
+ // }
529
+ // startDiscovery() {
530
+ // if (this.isDiscoveryRunning()) {
531
+ // throw new Error('Discovery already running');
532
+ // }
533
+ // this._discovery_timer = setTimeout(() => {
534
+ // this._discovery_timer = null;
535
+ // }, 1000 * KNXConstants.KNX_CONSTANTS.SEARCH_TIMEOUT);
536
+ // this._sendSearchRequestMessage();
537
+ // }
538
+ // stopDiscovery() {
539
+ // if (!this.isDiscoveryRunning()) {
540
+ // return;
541
+ // }
542
+ // if (this._discovery_timer !== null) clearTimeout(this._discovery_timer);
543
+ // this._discovery_timer = null;
544
+ // }
545
+ // getDescription(host, port) {
546
+ // if (this._clientSocket == null) {
547
+ // throw new Error('No client socket defined');
548
+ // }
549
+ // this._connectionTimeoutTimer = setTimeout(() => {
550
+ // this._connectionTimeoutTimer = null;
551
+ // }, 1000 * KNXConstants.KNX_CONSTANTS.DEVICE_CONFIGURATION_REQUEST_TIMEOUT);
552
+ // this._awaitingResponseType = KNXConstants.KNX_CONSTANTS.DESCRIPTION_RESPONSE;
553
+ // this._sendDescriptionRequestMessage(host, port);
554
+ // }
601
555
  Connect(knxLayer = TunnelCRI.TunnelTypes.TUNNEL_LINKLAYER) {
602
556
 
603
557
  if (this._clientSocket == null) {
@@ -644,20 +598,25 @@ class KNXClient extends EventEmitter {
644
598
  // TCP
645
599
  const timeoutError = new Error(`Connection timeout to ${this._peerHost}:${this._peerPort}`);
646
600
  let conn = this;
647
- this._clientSocket.connect({ port: this._peerPort, host: this._peerHost, localAddress: this._options.localAddress }, function () {
601
+ this._clientSocket.connect( this._peerPort, this._peerHost, function () {
648
602
  // conn._timer = setTimeout(() => {
649
603
  // conn._timer = null;
650
604
  // conn.emit(KNXClientEvents.error, timeoutError);
651
605
  // }, 1000 * KNXConstants.KNX_CONSTANTS.CONNECT_REQUEST_TIMEOUT);
652
606
  conn._awaitingResponseType = KNXConstants.KNX_CONSTANTS.CONNECT_RESPONSE;
653
607
  conn._clientTunnelSeqNumber = 0;
654
- if (conn._options.isSecureKNXEnabled) conn._sendSecureSessionRequestMessage(new TunnelCRI.TunnelCRI(knxLayer), conn.jKNXSecureKeyring);
608
+ if (conn._options.isSecureKNXEnabled) conn._sendSecureSessionRequestMessage(new TunnelCRI.TunnelCRI(knxLayer));
655
609
  });
656
610
 
657
611
  } else {
658
612
 
659
613
  // Multicast
660
614
  this._connectionState = STATE.CONNECTED;
615
+
616
+ // 16/03/2022 These two are referring to tunneling connection, but i set it here as well. Non si sa mai.
617
+ this._numFailedTelegramACK = 0; // 25/12/2021 Reset the failed ACK counter
618
+ this._clearToSend = true; // 26/12/2021 allow to send
619
+
661
620
  this._clientTunnelSeqNumber = -1;
662
621
  try {
663
622
  this.emit(KNXClientEvents.connected, this._options);
@@ -702,27 +661,25 @@ class KNXClient extends EventEmitter {
702
661
  this._connectionState = STATE.DISCONNECTING;
703
662
  this._awaitingResponseType = KNXConstants.KNX_CONSTANTS.DISCONNECT_RESPONSE;
704
663
  this._sendDisconnectRequestMessage(this._channelID);
705
- //this._timerTimeoutSendDisconnectRequestMessage = setTimeout(() => {
706
- this._setDisconnected("Called from KNXClient Disconnected");
707
- //}, 1000 * KNXConstants.KNX_CONSTANTS.CONNECT_REQUEST_TIMEOUT);
664
+ // 12/03/2021 Set disconnected if not already set by DISCONNECT_RESPONSE sent from the IP Interface
665
+ let t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
666
+ if (this._connectionState !== STATE.DISCONNECTED) this._setDisconnected("Forced call from KNXClient Disconnect() function, because the KNX Interface hasn't sent the DISCONNECT_RESPONSE in time.");
667
+ }, 2000);
708
668
  }
709
669
  isConnected() {
710
670
  return this._connectionState === STATE.CONNECTED;
711
671
  }
712
672
  _setDisconnected(_sReason = "") {
713
- if (this._timerTimeoutSendDisconnectRequestMessagetimer !== null) clearTimeout(this._timerTimeoutSendDisconnectRequestMessagetimer);
714
- this._timerTimeoutSendDisconnectRequestMessage = null;
715
- if (this._connectionTimeoutTimer !== null) clearTimeout(this._connectionTimeoutTimer);
716
- if (this._tunnelReqTimer !== null) clearTimeout(this._tunnelReqTimer);
717
- this.stopHeartBeat();
718
- this._connectionState = STATE.DISCONNECTED;
719
673
  try {
720
- this.emit(KNXClientEvents.disconnected, this._options.ipAddr + ":" + this._options.ipPort + " " + _sReason);
674
+ if (this.sysLogger !== undefined && this.sysLogger !== null) this.sysLogger.debug("KNXClient: called _setDisconnected " + this._options.ipAddr + ":" + this._options.ipPort + " " + _sReason);
721
675
  } catch (error) {
722
676
  }
723
-
677
+ this._connectionState = STATE.DISCONNECTED;
678
+ this.stopHeartBeat();
679
+ this._timerTimeoutSendDisconnectRequestMessage = null;
680
+ if (this._connectionTimeoutTimer !== null) clearTimeout(this._connectionTimeoutTimer);
681
+ if (this._timerWaitingForACK !== null) clearTimeout(this._timerWaitingForACK);
724
682
  this._clientTunnelSeqNumber = -1;
725
- this._clearToSend = true; // 26/12/2021 allow to send
726
683
  this._channelID = null;
727
684
 
728
685
  // 08/12/2021
@@ -730,11 +687,16 @@ class KNXClient extends EventEmitter {
730
687
  this._clientSocket.close();
731
688
  } catch (error) { }
732
689
 
690
+ try {
691
+ this.emit(KNXClientEvents.disconnected, this._options.ipAddr + ":" + this._options.ipPort + " " + _sReason);
692
+ } catch (error) {
693
+ }
694
+ this._clearToSend = true; // 26/12/2021 allow to send
733
695
  }
734
696
  _runHeartbeat() {
735
697
  if (this._heartbeatRunning) {
736
698
  this.getConnectionStatus();
737
- setTimeout(() => {
699
+ let t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
738
700
  this._runHeartbeat();
739
701
  }, 1000 * this._options.connectionKeepAliveTimeout);
740
702
  }
@@ -747,7 +709,7 @@ class KNXClient extends EventEmitter {
747
709
  return (this._clearToSend !== undefined ? this._clearToSend : true);
748
710
  }
749
711
 
750
- _incSeqNumber(seq) {
712
+ _incSeqNumber() {
751
713
  this._clientTunnelSeqNumber++;
752
714
  if (this._clientTunnelSeqNumber > 255) {
753
715
  this._clientTunnelSeqNumber = 0;
@@ -758,10 +720,10 @@ class KNXClient extends EventEmitter {
758
720
  // return cEMIMessage.dstAddress.toString();
759
721
  // }
760
722
  _setTimerWaitingForACK(knxTunnelingRequest) {
761
- const timeoutErr = new errors.RequestTimeoutError(`RequestTimeoutError seqCounter:${knxTunnelingRequest.seqCounter}, DestAddr:${knxTunnelingRequest.cEMIMessage.dstAddress.toString() || "Non definito"}, AckRequested:${knxTunnelingRequest.cEMIMessage.control.ack}, timed out waiting telegram acknowledge by ${this._options.ipAddr || "No Peer host detected"}`);
762
- if (this._tunnelReqTimer !== null) clearTimeout(this._tunnelReqTimer);
763
723
  this._clearToSend = false; // 26/12/2021 stop sending until ACK received
764
- this._tunnelReqTimer = setTimeout(() => {
724
+ const timeoutErr = new errors.RequestTimeoutError(`RequestTimeoutError seqCounter:${knxTunnelingRequest.seqCounter}, DestAddr:${knxTunnelingRequest.cEMIMessage.dstAddress.toString() || "Non definito"}, AckRequested:${knxTunnelingRequest.cEMIMessage.control.ack}, timed out waiting telegram acknowledge by ${this._options.ipAddr || "No Peer host detected"}`);
725
+ if (this._timerWaitingForACK !== null) clearTimeout(this._timerWaitingForACK);
726
+ this._timerWaitingForACK = setTimeout(() => {
765
727
  try {
766
728
  this._numFailedTelegramACK += 1;
767
729
  if (this._numFailedTelegramACK > 2) {
@@ -836,6 +798,12 @@ class KNXClient extends EventEmitter {
836
798
  this._setDisconnected("Connect response error " + knxConnectResponse.status);
837
799
  return;
838
800
  }
801
+
802
+ // 16/03/2022
803
+ if (this._timerWaitingForACK !== null) clearTimeout(this._timerWaitingForACK);
804
+ this._numFailedTelegramACK = 0; // 16/03/2022 Reset the failed ACK counter
805
+ this._clearToSend = true; // 16/03/2022 allow to send
806
+
839
807
  this._connectionState = STATE.CONNECTED;
840
808
  this._channelID = knxConnectResponse.channelID;
841
809
  try {
@@ -860,7 +828,7 @@ class KNXClient extends EventEmitter {
860
828
  } catch (error) {
861
829
  }
862
830
  }
863
- this._setDisconnected("Received Disconnect Response");
831
+ this._setDisconnected("Received DISCONNECT_RESPONSE from the KNX interface.");
864
832
  }
865
833
  else if (knxHeader.service_type === KNXConstants.KNX_CONSTANTS.DISCONNECT_REQUEST) {
866
834
 
@@ -875,7 +843,10 @@ class KNXClient extends EventEmitter {
875
843
 
876
844
  this._connectionState = STATE.DISCONNECTING;
877
845
  this._sendDisconnectResponseMessage(knxDisconnectRequest.channelID);
878
- this._setDisconnected("Received Disconnect Request");
846
+ // 12/03/2021 Added 1 sec delay.
847
+ let t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
848
+ this._setDisconnected("Received KNX packet: DISCONNECT_REQUEST, ChannelID:" + this._channelID + " Host:" + this._options.ipAddr + ":" + this._options.ipPort);
849
+ }, 1000);
879
850
  }
880
851
  else if (knxHeader.service_type === KNXConstants.KNX_CONSTANTS.TUNNELING_REQUEST) {
881
852
 
@@ -932,7 +903,7 @@ class KNXClient extends EventEmitter {
932
903
  // Check the received ACK sequence number
933
904
  if (!this._options.suppress_ack_ldatareq) {
934
905
  if (knxTunnelingAck.seqCounter === this._getSeqNumber()) {
935
- if (this._tunnelReqTimer !== null) clearTimeout(this._tunnelReqTimer);
906
+ if (this._timerWaitingForACK !== null) clearTimeout(this._timerWaitingForACK);
936
907
  this._numFailedTelegramACK = 0; // 25/12/2021 clear the current ACK failed telegram number
937
908
  this._clearToSend = true; // I'm ready to send a new datagram now
938
909
  try {
@@ -1032,7 +1003,7 @@ class KNXClient extends EventEmitter {
1032
1003
  this.send(KNXProtocol.KNXProtocol.newKNXDescriptionRequest(new HPAI.HPAI(this._options.localIPAddress)));
1033
1004
  }
1034
1005
  _sendSearchRequestMessage() {
1035
- this.send(KNXProtocol.KNXProtocol.newKNXSearchRequest(new HPAI.HPAI(this._options.localIPAddress, this._localPort)), KNXConstants.KNX_CONSTANTS.KNX_PORT, KNXConstants.KNX_CONSTANTS.KNX_IP);
1006
+ //this.send(KNXProtocol.KNXProtocol.newKNXSearchRequest(new HPAI.HPAI(this._options.localIPAddress, this._localPort)), KNXConstants.KNX_CONSTANTS.KNX_PORT, KNXConstants.KNX_CONSTANTS.KNX_IP);
1036
1007
  }
1037
1008
  _sendConnectRequestMessage(cri) {
1038
1009
  this.send(KNXProtocol.KNXProtocol.newKNXConnectRequest(cri));
@@ -1046,18 +1017,22 @@ class KNXClient extends EventEmitter {
1046
1017
  _sendDisconnectResponseMessage(channelID, status = KNXConstants.ConnectionStatus.E_NO_ERROR) {
1047
1018
  this.send(KNXProtocol.KNXProtocol.newKNXDisconnectResponse(channelID, status));
1048
1019
  }
1049
- _sendSecureSessionRequestMessage(cri, jKNXSecureKeyring) {
1020
+ _sendSecureSessionRequestMessage(cri) {
1050
1021
  let oHPAI = new HPAI.HPAI("0.0.0.0", 0, this._options.hostProtocol === "TunnelTCP" ? KNXConstants.KNX_CONSTANTS.IPV4_TCP : KNXConstants.KNX_CONSTANTS.IPV4_UDP);
1051
- this.send(KNXProtocol.KNXProtocol.newKNXSecureSessionRequest(cri, oHPAI, jKNXSecureKeyring));
1022
+ this.send(KNXProtocol.KNXProtocol.newKNXSecureSessionRequest(cri, oHPAI));
1052
1023
  }
1053
1024
  }
1054
1025
 
1026
+
1055
1027
  // module.exports = function KNXClientEvents() {
1056
1028
  // return KNXClientEvents;
1057
1029
  // }
1058
1030
  module.exports = {
1059
1031
  KNXClient: KNXClient,
1060
- KNXClientEvents: KNXClientEvents
1032
+ KNXClientEvents: KNXClientEvents,
1033
+ getDecodedKeyring: function () {
1034
+ return jKNXSecureKeyring;
1035
+ } // Contains the decoded keyring file
1061
1036
  };
1062
1037
  //exports.KNXClient = KNXClient;
1063
1038
  //exports.KNXClientEvents = KNXClientEvents;
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * (C) 2021 Supergiovane
3
3
  */
4
+ "use strict";
5
+
4
6
  const util = require('util')
5
7
  const possibleLEvels = ['silent', 'error', 'warn', 'info', 'debug', 'trace'];
6
8
  let logger
@@ -22,7 +22,8 @@ exports.formatAPDU = function (value) {
22
22
  }
23
23
 
24
24
  var buf = new Buffer.alloc(14);
25
- buf.write(value, 'ascii')
25
+ if (this.subtypeid === "001") buf.write(value, 'latin1');
26
+ if (this.subtypeid === "000") buf.write(value, 'ascii');
26
27
  return buf;
27
28
 
28
29
  }
@@ -33,7 +34,9 @@ exports.fromBuffer = function (buf) {
33
34
  knxLog.get().error("DPT6: Buffer should be 14 byte long, got", buf.length);
34
35
  return null;
35
36
  }
36
- return buf.toString('ascii');
37
+ if (this.subtypeid === "001") return buf.toString('latin1');
38
+ if (this.subtypeid === "000") return buf.toString('ascii');
39
+
37
40
 
38
41
  }
39
42
 
package/README.md CHANGED
@@ -21,7 +21,8 @@ payload = true // Turn light on
21
21
  payload = {red:255, green:200, blue:30} // Put some colors in our life
22
22
  ```
23
23
 
24
- ## DESCRIPTION
24
+
25
+ ## NODE LIST
25
26
 
26
27
  * **KNX-ULTIMATE node** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/2.-Node-Configuration), allow you to control your *KNX installation* via Node-Red. You can control all your KNX devices as well as create a *Virtual Device* in Node-Red, to link external *non KNX* devices, and make it compatible with your KNX installation. I'ts very SIMPLE TO USE thus very customizable.
27
28
  * **SCENE CONTROLLER node** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/SceneController-Configuration), The scene controller node can act as a real scene controller, with recall and save of the current scene.
@@ -32,6 +33,9 @@ payload = {red:255, green:200, blue:30} // Put some colors in our life
32
33
  * **LOAD CONTROL node** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/LoadControl-Configuration). Control your loads (Oven, Washing machine, etc..) and avoit shutting down the main voltage due to too high power consumption.
33
34
  * **VIEWER node** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/knxUltimateViewer). View all Group Addresses and values of your KNX BUS, in the Node-Red Dashboard.
34
35
 
36
+ <br>
37
+ <br>
38
+
35
39
  ## CHANGELOG
36
40
 
37
41
  * See <a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/blob/master/CHANGELOG.md">here the changelog</a>
@@ -39,18 +43,25 @@ payload = {red:255, green:200, blue:30} // Put some colors in our life
39
43
  <br>
40
44
  <br>
41
45
 
42
- ## SEARCHING FOR HELP _ VOLUNTEER NEEDED _
46
+ ## VOLUNTEER NEEDED FOR KNX SECURE
47
+
43
48
  **************************************************
44
49
  **************************************************
45
- *I need volunteer helping in development of KNX Secure. High knowledge of cryptography and KNX is needed.*
50
+
51
+ KNX-Secure is under development and **should** be ready by mid 2022.<br/>
52
+ Many users requested me to "extract" the baseline KNX API and make it accessible via npmjs. Here is it.<br/>
53
+ The API is named **KNXUltimate**. In the README page is well documented and there are also samples for unsecure and secure KNX connections.
54
+ * <a href="https://github.com/Supergiovane/KNXUltimate#readme">KNXUltimate API</a>
55
+
56
+ I need volunteer helping in development of KNX Secure.<br/>
57
+ High knowledge of cryptography and KNX is needed.
46
58
  **************************************************
47
59
  **************************************************
48
60
  <br>
49
61
  <br>
50
62
 
51
- ## KNX SECURE
52
63
 
53
- KNX-Secure is under development and **should** be ready by mid 2022. You can help me by clicking here [![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square)](https://www.paypal.me/techtoday)
64
+
54
65
 
55
66
  ## HELP, SAMPLES, TROUBLESHOOT, WIKI, FAQ, BEST PRACTICES
56
67
 
@@ -247,7 +247,7 @@
247
247
  </div>
248
248
  <div id="SecureKNX" style="margin: 5px 5px 5px 5px;" >
249
249
  <p>
250
- <p>WARNING: FUNCTION NOT ENABLED. KNX SECURE WILL BE ACTIVE ON EARLY 2022</p>
250
+ <p>WARNING: FUNCTION NOT ENABLED. KNX SECURE SHOULD BE READY ON MID 2022</p>
251
251
  <div class="form-row">
252
252
  <i class="fa fa-youtube"></i>
253
253
  <a href="https://youtu.be/OpR7ZQTlMRU" target="_blank">