node-red-contrib-knx-ultimate 4.0.8 → 4.0.9
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 +1 -1
- package/nodes/knxUltimate-config.js +81 -11
- package/nodes/knxUltimate.js +2 -1
- package/nodes/knxUltimateAutoResponder.js +2 -1
- package/nodes/knxUltimateHueScene.js +2 -1
- package/nodes/knxUltimateLoadControl.js +2 -1
- package/nodes/knxUltimateSceneController.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
-
**Version 4.0.
|
|
9
|
+
**Version 4.0.9** - September 2025<br/>
|
|
10
10
|
- KNX Config node: now the ethernet interface is automatically selected, based on the KNX Gateway's IP subnet.<br/>
|
|
11
11
|
- Added the details of keyring in clear text, when the loglevel is set to "debug".<br/>
|
|
12
12
|
|
|
@@ -393,17 +393,87 @@ module.exports = (RED) => {
|
|
|
393
393
|
sequenceNumber: typeof device.sequenceNumber === "number" ? device.sequenceNumber : "",
|
|
394
394
|
serialNumber: device.serialNumber || "",
|
|
395
395
|
}));
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
396
|
+
const lines = [];
|
|
397
|
+
lines.push("================ KNX Secure keyring debug dump ================");
|
|
398
|
+
lines.push(`Node: ${node.name || node.id || ""}`);
|
|
399
|
+
lines.push(`Created By: ${kr.getCreatedBy?.() || ""}`);
|
|
400
|
+
lines.push(`Created On: ${kr.getCreated?.() || ""}`);
|
|
401
|
+
lines.push(`Password (node credentials): ${node.credentials?.keyringFilePassword || ""}`);
|
|
402
|
+
lines.push("");
|
|
403
|
+
|
|
404
|
+
lines.push("Interfaces:");
|
|
405
|
+
if (interfaces.length === 0) {
|
|
406
|
+
lines.push(" (none)");
|
|
407
|
+
} else {
|
|
408
|
+
interfaces.forEach((iface, idx) => {
|
|
409
|
+
lines.push(` [${idx + 1}] ${iface.individualAddress || "(unknown)"} (${iface.type || ""})`);
|
|
410
|
+
lines.push(` Host: ${iface.host || ""}`);
|
|
411
|
+
lines.push(` User ID: ${iface.userId === "" ? "" : iface.userId}`);
|
|
412
|
+
lines.push(` Password (encoded): ${iface.password || ""}`);
|
|
413
|
+
lines.push(` Password (decoded): ${iface.decryptedPassword || ""}`);
|
|
414
|
+
lines.push(` Authentication (encoded): ${iface.authentication || ""}`);
|
|
415
|
+
lines.push(` Authentication (decoded): ${iface.decryptedAuthentication || ""}`);
|
|
416
|
+
if (!iface.groupAddresses || iface.groupAddresses.length === 0) {
|
|
417
|
+
lines.push(" Group Addresses: (none)");
|
|
418
|
+
} else {
|
|
419
|
+
lines.push(" Group Addresses:");
|
|
420
|
+
iface.groupAddresses.forEach((ga) => {
|
|
421
|
+
const senders = ga.senders && ga.senders.length > 0 ? ga.senders.join(", ") : "(none)";
|
|
422
|
+
lines.push(` - ${ga.address}: senders ${senders}`);
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
lines.push("");
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
lines.push("Backbones:");
|
|
430
|
+
if (backbones.length === 0) {
|
|
431
|
+
lines.push(" (none)");
|
|
432
|
+
} else {
|
|
433
|
+
backbones.forEach((backbone, idx) => {
|
|
434
|
+
lines.push(` [${idx + 1}] Multicast: ${backbone.multicastAddress || ""}`);
|
|
435
|
+
lines.push(` Latency: ${backbone.latency === "" ? "" : backbone.latency}`);
|
|
436
|
+
lines.push(` Key (encoded): ${backbone.key || ""}`);
|
|
437
|
+
lines.push(` Key (decoded hex): ${backbone.decryptedKey || ""}`);
|
|
438
|
+
lines.push("");
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
lines.push("Group Addresses:");
|
|
443
|
+
if (groupAddresses.length === 0) {
|
|
444
|
+
lines.push(" (none)");
|
|
445
|
+
} else {
|
|
446
|
+
groupAddresses.forEach((group, idx) => {
|
|
447
|
+
lines.push(` [${idx + 1}] ${group.address || ""}`);
|
|
448
|
+
lines.push(` Key (encoded): ${group.key || ""}`);
|
|
449
|
+
lines.push(` Key (decoded hex): ${group.decryptedKey || ""}`);
|
|
450
|
+
lines.push("");
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
lines.push("Devices:");
|
|
455
|
+
if (devices.length === 0) {
|
|
456
|
+
lines.push(" (none)");
|
|
457
|
+
} else {
|
|
458
|
+
devices.forEach((device, idx) => {
|
|
459
|
+
lines.push(` [${idx + 1}] ${device.individualAddress || ""}`);
|
|
460
|
+
lines.push(` Tool Key (encoded): ${device.toolKey || ""}`);
|
|
461
|
+
lines.push(` Tool Key (decoded hex): ${device.decryptedToolKey || ""}`);
|
|
462
|
+
lines.push(` Management Password (encoded): ${device.managementPassword || ""}`);
|
|
463
|
+
lines.push(` Management Password (decoded): ${device.decryptedManagementPassword || ""}`);
|
|
464
|
+
lines.push(` Authentication (encoded): ${device.authentication || ""}`);
|
|
465
|
+
lines.push(` Authentication (decoded): ${device.decryptedAuthentication || ""}`);
|
|
466
|
+
lines.push(` Sequence Number: ${device.sequenceNumber === "" ? "" : device.sequenceNumber}`);
|
|
467
|
+
lines.push(` Serial Number: ${device.serialNumber || ""}`);
|
|
468
|
+
lines.push("");
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
lines.push("Raw keyring (XML/base64 as provided):");
|
|
473
|
+
lines.push(node.keyringFileXML || "(empty)");
|
|
474
|
+
lines.push("================ End of keyring debug dump ================");
|
|
475
|
+
|
|
476
|
+
node.sysLogger?.debug(lines.join("\n"));
|
|
407
477
|
} catch (dumpError) {
|
|
408
478
|
node.sysLogger?.error("KNX Secure: unable to log keyring details: " + dumpError.message);
|
|
409
479
|
}
|
package/nodes/knxUltimate.js
CHANGED
|
@@ -121,7 +121,8 @@ module.exports = function (RED) {
|
|
|
121
121
|
node.inputmessage = {}; // Stores the input message to be passed through
|
|
122
122
|
node.timerTTLInputMessage = null; // The stored node.inputmessage has a ttl.
|
|
123
123
|
try {
|
|
124
|
-
|
|
124
|
+
const baseLogLevel = (node.serverKNX && node.serverKNX.loglevel) ? node.serverKNX.loglevel : 'error';
|
|
125
|
+
node.sysLogger = new loggerClass({ loglevel: baseLogLevel, setPrefix: node.type + " <" + (node.name || node.id || '') + ">" });
|
|
125
126
|
} catch (error) { console.log(error.stack) }
|
|
126
127
|
node.sendMsgToKNXCode = config.sendMsgToKNXCode || undefined;
|
|
127
128
|
node.receiveMsgFromKNXCode = config.receiveMsgFromKNXCode || undefined;
|
|
@@ -54,7 +54,8 @@ module.exports = function (RED) {
|
|
|
54
54
|
if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
|
|
55
55
|
|
|
56
56
|
try {
|
|
57
|
-
|
|
57
|
+
const baseLogLevel = (node.serverKNX && node.serverKNX.loglevel) ? node.serverKNX.loglevel : 'error';
|
|
58
|
+
node.sysLogger = new loggerClass({ loglevel: baseLogLevel, setPrefix: node.type + " <" + (node.name || node.id || '') + ">" });
|
|
58
59
|
} catch (error) { console.log(error.stack) }
|
|
59
60
|
// Used to call the status update from the config node.
|
|
60
61
|
node.setNodeStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
|
|
@@ -29,7 +29,8 @@ module.exports = function (RED) {
|
|
|
29
29
|
node.hueDevice = config.hueDevice;
|
|
30
30
|
node.initializingAtStart = false;
|
|
31
31
|
try {
|
|
32
|
-
|
|
32
|
+
const baseLogLevel = (node.serverKNX && node.serverKNX.loglevel) ? node.serverKNX.loglevel : 'error';
|
|
33
|
+
node.sysLogger = new loggerClass({ loglevel: baseLogLevel, setPrefix: node.type + " <" + (node.name || node.id || '') + ">" });
|
|
33
34
|
} catch (error) { console.log(error.stack) }
|
|
34
35
|
// Multi scene
|
|
35
36
|
config.GAsceneMulti = config.GAsceneMulti === undefined ? '' : config.GAsceneMulti;
|
|
@@ -38,7 +38,8 @@ module.exports = function (RED) {
|
|
|
38
38
|
node.totalWatt = 0 // Current total watt consumption
|
|
39
39
|
node.wattLimit = config.wattLimit === undefined ? 3000 : Number(config.wattLimit)
|
|
40
40
|
try {
|
|
41
|
-
|
|
41
|
+
const baseLogLevel = (node.serverKNX && node.serverKNX.loglevel) ? node.serverKNX.loglevel : 'error';
|
|
42
|
+
node.sysLogger = new loggerClass({ loglevel: baseLogLevel, setPrefix: node.type + " <" + (node.name || node.id || '') + ">" });
|
|
42
43
|
} catch (error) { console.log(error.stack) }
|
|
43
44
|
node.deviceList = []
|
|
44
45
|
for (let index = 1; index < 6; index++) {
|
|
@@ -29,7 +29,8 @@ module.exports = function (RED) {
|
|
|
29
29
|
node.isSceneController = true // Signal to config node, that this is a node scene controller
|
|
30
30
|
node.userDir = path.join(RED.settings.userDir, 'knxultimatestorage') // 09/03/2020 Storage of ttsultimate (otherwise, at each upgrade to a newer version, the node path is wiped out and recreated, loosing all custom files)
|
|
31
31
|
try {
|
|
32
|
-
|
|
32
|
+
const baseLogLevel = (node.serverKNX && node.serverKNX.loglevel) ? node.serverKNX.loglevel : 'error';
|
|
33
|
+
node.sysLogger = new loggerClass({ loglevel: baseLogLevel, setPrefix: node.type + " <" + (node.name || node.id || '') + ">" });
|
|
33
34
|
} catch (error) { console.log(error.stack) }
|
|
34
35
|
node.timerWait = null
|
|
35
36
|
node.icountMessageInWindow = 0
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=20.18.1"
|
|
5
5
|
},
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.9",
|
|
7
7
|
"description": "Control your KNX and KNX Secure intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control and ETS group address importer. Easy to use and highly configurable.",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"binary-parser": "2.2.1",
|