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.
- package/CHANGELOG.md +19 -0
- package/KNXEngine/KNXClient.js +126 -151
- package/KNXEngine/KnxLog.js +2 -0
- package/KNXEngine/dptlib/dpt16.js +5 -2
- package/README.md +16 -5
- package/nodes/knxUltimate-config.html +1 -1
- package/nodes/knxUltimate-config.js +41 -33
- package/nodes/knxUltimate.js +7 -7
- package/nodes/knxUltimateGlobalContext.js +9 -2
- package/nodes/knxUltimateLoadControl.js +7 -7
- package/nodes/knxUltimateLogger.js +4 -2
- package/nodes/knxUltimateSceneController.js +11 -10
- package/nodes/knxUltimateWatchDog.js +2 -2
- package/nodes/locales/de/knxUltimateLoadControl.json +3 -3
- package/nodes/locales/zh-CN/knxUltimateLoadControl.json +1 -1
- package/package.json +1 -1
- package/knxultimate-api2/index.js +0 -22
- package/knxultimate-api2/src/Address.js +0 -116
- package/knxultimate-api2/src/Connection.js +0 -458
- package/knxultimate-api2/src/Datapoint.js +0 -143
- package/knxultimate-api2/src/FSM.js +0 -847
- package/knxultimate-api2/src/IpRoutingConnection.js +0 -83
- package/knxultimate-api2/src/IpTunnelingConnection.js +0 -65
- package/knxultimate-api2/src/KNXsecureKeyring.js +0 -575
- package/knxultimate-api2/src/KnxConstants.js +0 -261
- package/knxultimate-api2/src/KnxLog.js +0 -69
- package/knxultimate-api2/src/KnxProtocol.js +0 -1025
- package/knxultimate-api2/src/RawMod/CheckResourceAvailable.js +0 -9
- package/knxultimate-api2/src/RawMod/CustomMessageHandlerTemplates.js +0 -82
- package/knxultimate-api2/src/RawMod/CustomMsgHandlers.js +0 -148
- package/knxultimate-api2/src/RawMod/ErrorHandler.js +0 -108
- package/knxultimate-api2/src/RawMod/Errors.js +0 -93
- package/knxultimate-api2/src/RawMod/Handlers.js +0 -143
- package/knxultimate-api2/src/RawMod/KnxAddress.js +0 -374
- package/knxultimate-api2/src/RawMod/KnxDeviceResourceInformation.js +0 -7557
- package/knxultimate-api2/src/RawMod/KnxMessageTemplates.js +0 -204
- package/knxultimate-api2/src/RawMod/KnxNetProtocol.js +0 -201
- package/knxultimate-api2/src/RawMod/KnxNetProtocolExtra.js +0 -131
- package/knxultimate-api2/src/RawMod/KnxNetRebuildMessageBytes.js +0 -138
- package/knxultimate-api2/src/RawMod/KnxOperations/LoadStateMachine.js +0 -48
- package/knxultimate-api2/src/RawMod/KnxOperations/RestartDevice.js +0 -181
- package/knxultimate-api2/src/RawMod/KnxOperations/RunStateMachine.js +0 -48
- package/knxultimate-api2/src/RawMod/KnxParseTpci.js +0 -163
- package/knxultimate-api2/src/RawMod/RawMod.js +0 -88
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadApplicationID.js +0 -112
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDevMem.js +0 -340
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDeviceADC.js +0 -324
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDeviceAddress.js +0 -218
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadDeviceResource.js +0 -238
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadGroupAddrTblLoadstate.js +0 -84
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadGroupAssociationTblLoadstate.js +0 -84
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadManufacturerID.js +0 -96
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadMaskversion.js +0 -317
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadOrderNumber.js +0 -96
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadProgmodeStatus.js +0 -88
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadPropertyValue.js +0 -336
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/KnxReadSerialNumber.js +0 -99
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/__KnxReadResourceViaMemory.js +0 -12
- package/knxultimate-api2/src/RawMod/__KnxReadOperations/__KnxReadResourceViaProperty.js +0 -15
- package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxSetDeviceAddress.js +0 -150
- package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxSetProgmodeStatus.js +0 -73
- package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxWriteDevMem.js +0 -343
- package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxWriteDeviceResource.js +0 -204
- package/knxultimate-api2/src/RawMod/__KnxWriteOperations/KnxWritePropertyValue.js +0 -348
- package/knxultimate-api2/src/RawMod/__KnxWriteOperations/__KnxWriteResourceViaMemory.js +0 -11
- package/knxultimate-api2/src/RawMod/__KnxWriteOperations/__KnxWriteResourceViaProperty.js +0 -15
- package/knxultimate-api2/src/dptlib/dpt1.js +0 -201
- package/knxultimate-api2/src/dptlib/dpt10.js +0 -106
- package/knxultimate-api2/src/dptlib/dpt11.js +0 -84
- package/knxultimate-api2/src/dptlib/dpt12.js +0 -63
- package/knxultimate-api2/src/dptlib/dpt13.js +0 -77
- package/knxultimate-api2/src/dptlib/dpt14.js +0 -191
- package/knxultimate-api2/src/dptlib/dpt15.js +0 -24
- package/knxultimate-api2/src/dptlib/dpt16.js +0 -67
- package/knxultimate-api2/src/dptlib/dpt17.js +0 -25
- package/knxultimate-api2/src/dptlib/dpt18.js +0 -96
- package/knxultimate-api2/src/dptlib/dpt19.js +0 -62
- package/knxultimate-api2/src/dptlib/dpt2.js +0 -132
- package/knxultimate-api2/src/dptlib/dpt20.js +0 -52
- package/knxultimate-api2/src/dptlib/dpt213.js +0 -156
- package/knxultimate-api2/src/dptlib/dpt22.js +0 -145
- package/knxultimate-api2/src/dptlib/dpt222.js +0 -158
- package/knxultimate-api2/src/dptlib/dpt232.js +0 -58
- package/knxultimate-api2/src/dptlib/dpt237.js +0 -92
- package/knxultimate-api2/src/dptlib/dpt238.js +0 -73
- package/knxultimate-api2/src/dptlib/dpt242.js +0 -84
- package/knxultimate-api2/src/dptlib/dpt249.js +0 -87
- package/knxultimate-api2/src/dptlib/dpt251.js +0 -76
- package/knxultimate-api2/src/dptlib/dpt3.js +0 -90
- package/knxultimate-api2/src/dptlib/dpt4.js +0 -58
- package/knxultimate-api2/src/dptlib/dpt5.js +0 -70
- package/knxultimate-api2/src/dptlib/dpt6.js +0 -42
- package/knxultimate-api2/src/dptlib/dpt7.js +0 -150
- package/knxultimate-api2/src/dptlib/dpt8.js +0 -94
- package/knxultimate-api2/src/dptlib/dpt9.js +0 -212
- package/knxultimate-api2/src/dptlib/dpt999.js +0 -61
- package/knxultimate-api2/src/dptlib/index.js +0 -185
- package/knxultimate-api2/src/superKNX.js +0 -117
- 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/>
|
package/KNXEngine/KNXClient.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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(
|
|
168
|
+
conn._clientSocket.setMulticastInterface(conn._options.localIPAddress);
|
|
169
169
|
} catch (error) {
|
|
170
|
-
if (
|
|
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.
|
|
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
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
574
|
-
}
|
|
575
|
-
startDiscovery() {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
}
|
|
584
|
-
stopDiscovery() {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
}
|
|
591
|
-
getDescription(host, port) {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
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(
|
|
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)
|
|
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
|
-
//
|
|
706
|
-
|
|
707
|
-
|
|
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.
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
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;
|
package/KNXEngine/KnxLog.js
CHANGED
|
@@ -22,7 +22,8 @@ exports.formatAPDU = function (value) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
var buf = new Buffer.alloc(14);
|
|
25
|
-
buf.write(value, '
|
|
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('
|
|
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
|
-
|
|
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
|
-
##
|
|
46
|
+
## VOLUNTEER NEEDED FOR KNX SECURE
|
|
47
|
+
|
|
43
48
|
**************************************************
|
|
44
49
|
**************************************************
|
|
45
|
-
|
|
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
|
-
|
|
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
|
|
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">
|