node-red-contrib-knx-ultimate
Advanced tools
Comparing version
@@ -8,2 +8,7 @@ # node-red-contrib-knx-ultimate | ||
<p> | ||
<b>Version 1.1.26</b><br/> | ||
- New: Professional Watchdog Node added. Please <a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/7.-WatchDog-Configuration" target="_blank">consult the Wiki</a>.<br/> | ||
- Changed category (the node's list on left panel of node-red) to "KnxUltimate", to accomodate the Watchdog node.<br/> | ||
</p> | ||
<p> | ||
<b>Version 1.1.25</b><br/> | ||
@@ -10,0 +15,0 @@ - New: ability to programmatically change the KNX/IP interface or router's IP, Port, Physical Address and reset local ETH Interface Binding.<br/> |
@@ -8,3 +8,3 @@ const knx = require('knx') | ||
if (a[field] > b[field]) { return 1 } else { return -1 } | ||
} | ||
}; | ||
@@ -14,3 +14,3 @@ | ||
return kv[0].startsWith("DPT") | ||
} | ||
}; | ||
@@ -22,3 +22,3 @@ extractBaseNo = (kv) => { | ||
} | ||
} | ||
}; | ||
@@ -31,3 +31,3 @@ convertSubtype = (baseType) => (kv) => { | ||
} | ||
} | ||
}; | ||
@@ -42,3 +42,3 @@ | ||
return acc.concat(subtypes) | ||
} | ||
}; | ||
@@ -59,3 +59,3 @@ | ||
res.json(dpts) | ||
}) | ||
}); | ||
@@ -229,5 +229,3 @@ function knxUltimateConfigNode(config) { | ||
if (typeof _sPhysicalAddress !== "undefined" && _sPhysicalAddress !== "") node.physAddr = _sPhysicalAddress; | ||
if (typeof _sBindToEthernetInterface !== "undefined"){ | ||
if (_sBindToEthernetInterface === "Auto") node.KNXEthInterface = "Auto"; // Reset the interface to Auto; | ||
} | ||
if (typeof _sBindToEthernetInterface !== "undefined") node.KNXEthInterface = _sBindToEthernetInterface; | ||
setTimeout(() => node.setAllClientsStatus("CONFIG", "yellow", "Node's main config setting has been changed."), 1000); | ||
@@ -237,5 +235,5 @@ setTimeout(() => node.setAllClientsStatus("CONFIG", "green", "New config: IP " + node.host + " Port " + node.port + " PhysicalAddress " + node.physAddr + " BindToInterface " + node.KNXEthInterface), 2000) | ||
if (node.knxConnection) { | ||
node.initKNXConnection(); | ||
} | ||
} | ||
node.initKNXConnection(); | ||
}; | ||
}; | ||
@@ -285,4 +283,3 @@ node.initKNXConnection = () => { | ||
if (node.KNXEthInterface !== "Auto") | ||
{ | ||
if (node.KNXEthInterface !== "Auto") { | ||
var sIfaceName = ""; | ||
@@ -296,4 +293,3 @@ if (node.KNXEthInterface === "Manual") { | ||
} | ||
knxConnectionProperties.interface = sIfaceName; | ||
knxConnectionProperties.interface = sIfaceName; | ||
} else { | ||
@@ -307,3 +303,3 @@ RED.log.info("knxUltimate: Bind KNX Bus to interface (Auto)"); | ||
node.knxConnection.on("event", function (evt, src, dest, rawValue) { | ||
switch (evt) { | ||
switch (evt) { | ||
case "GroupValue_Write": { | ||
@@ -317,3 +313,3 @@ node.nodeClients | ||
try { | ||
oGA=node.csv.filter(sga => sga.ga == dest)[0]; | ||
oGA = node.csv.filter(sga => sga.ga == dest)[0]; | ||
} catch (error) { } | ||
@@ -325,38 +321,43 @@ | ||
// 25/10/2019 from v. 1.1.11, try to decode and output a datapoint. | ||
let msg = buildInputMessage(src, dest, evt, rawValue, tryToFigureOutDataPointFromRawValue(rawValue,dest), "") | ||
let msg = buildInputMessage(src, dest, evt, rawValue, tryToFigureOutDataPointFromRawValue(rawValue, dest), "") | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode", payload: msg.payload, GA: msg.knx.destination, dpt: "", devicename: "" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
input.send(msg) | ||
// -------------------------------- | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, oGA.dpt, oGA.devicename) | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "",payload: msg.payload, GA: msg.knx.destination, dpt:msg.knx.dpt, devicename:msg.devicename }); | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "", payload: msg.payload, GA: msg.knx.destination, dpt: msg.knx.dpt, devicename: msg.devicename }); | ||
input.send(msg) | ||
} | ||
} else if (input.topic == dest) { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, input.dpt, input.name ? input.name : "") | ||
// Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload | ||
if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) { | ||
input.setNodeStatus({fill: "grey", shape: "ring", text: "rbe block ("+msg.payload+") from KNX",payload: "", GA: "", dpt:"", devicename:""}) | ||
return; | ||
// 04/02/2020 Watchdog implementation | ||
if (input.hasOwnProperty("isWatchDog")) { | ||
// Is a watchdog node | ||
input.evalCalledByConfigNode("Write"); | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, input.dpt, input.name ? input.name : "") | ||
// Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload | ||
if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) { | ||
input.setNodeStatus({ fill: "grey", shape: "ring", text: "rbe block (" + msg.payload + ") from KNX", payload: "", GA: "", dpt: "", devicename: "" }) | ||
return; | ||
}; | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Added previous payload | ||
input.currentPayload = msg.payload;// Set the current value for the RBE input | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "", payload: msg.payload, GA: input.topic, dpt: input.dpt, devicename: "" }); | ||
input.send(msg); | ||
}; | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload: ""; // 24/01/2020 Added previous payload | ||
input.currentPayload = msg.payload;// Set the current value for the RBE input | ||
input.setNodeStatus({fill: "green", shape: "dot", text: "", payload: msg.payload, GA: input.topic, dpt:input.dpt, devicename:""}); | ||
input.send(msg) | ||
} | ||
}) | ||
}; | ||
}); | ||
break; | ||
} | ||
}; | ||
case "GroupValue_Response": { | ||
node.nodeClients | ||
.filter(input => input.notifyresponse==true) | ||
.filter(input => input.notifyresponse == true) | ||
.forEach(input => { | ||
if (input.listenallga==true) { | ||
if (input.listenallga == true) { | ||
// Get the DPT | ||
let oGA; | ||
try { | ||
oGA=node.csv.filter(sga => sga.ga == dest)[0]; | ||
oGA = node.csv.filter(sga => sga.ga == dest)[0]; | ||
} catch (error) { } | ||
@@ -367,6 +368,6 @@ | ||
if (typeof oGA === "undefined") { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, tryToFigureOutDataPointFromRawValue(rawValue,dest), "") | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode",payload: msg.payload, GA: msg.knx.destination, dpt:"", devicename:"" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
let msg = buildInputMessage(src, dest, evt, rawValue, tryToFigureOutDataPointFromRawValue(rawValue, dest), "") | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode", payload: msg.payload, GA: msg.knx.destination, dpt: "", devicename: "" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
@@ -377,28 +378,36 @@ } else { | ||
input.send(msg) | ||
} | ||
}; | ||
} else if (input.topic == dest) { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, input.dpt, input.name ? input.name : "") | ||
// Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload | ||
if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) { | ||
input.setNodeStatus({ fill: "grey", shape: "ring", text: "rbe INPUT filter applied on " + msg.payload }) | ||
return; | ||
// 04/02/2020 Watchdog implementation | ||
if (input.hasOwnProperty("isWatchDog")) { | ||
// Is a watchdog node | ||
input.evalCalledByConfigNode("Response"); | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, input.dpt, input.name ? input.name : "") | ||
// Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload | ||
if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) { | ||
input.setNodeStatus({ fill: "grey", shape: "ring", text: "rbe INPUT filter applied on " + msg.payload }) | ||
return; | ||
}; | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Added previous payload | ||
input.currentPayload = msg.payload; // Set the current value for the RBE input | ||
input.setNodeStatus({ fill: "blue", shape: "dot", text: "", payload: msg.payload, GA: input.topic, dpt: msg.knx.dpt, devicename: msg.devicename }); | ||
input.send(msg) | ||
}; | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload: ""; // 24/01/2020 Added previous payload | ||
input.currentPayload = msg.payload; // Set the current value for the RBE input | ||
input.setNodeStatus({ fill: "blue", shape: "dot", text: "", payload: msg.payload, GA: input.topic, dpt:msg.knx.dpt, devicename:msg.devicename }); | ||
input.send(msg) | ||
} | ||
}) | ||
}; | ||
}); | ||
break; | ||
} | ||
}; | ||
case "GroupValue_Read": { | ||
node.nodeClients | ||
.filter(input => input.notifyreadrequest==true) | ||
.filter(input => input.notifyreadrequest == true) | ||
.forEach(input => { | ||
if (input.listenallga==true) { | ||
if (input.listenallga == true) { | ||
// Get the DPT | ||
let oGA; | ||
try { | ||
oGA=node.csv.filter(sga => sga.ga == dest)[0]; | ||
oGA = node.csv.filter(sga => sga.ga == dest)[0]; | ||
} catch (error) { } | ||
@@ -410,41 +419,47 @@ | ||
// 25/10/2019 from v. 1.1.11, try to decode and output a datapoint. | ||
let msg = buildInputMessage(src, dest, evt, null, tryToFigureOutDataPointFromRawValue(rawValue,dest), "") | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode",payload: msg.payload, GA: msg.knx.destination, dpt:"", devicename:"" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
let msg = buildInputMessage(src, dest, evt, null, tryToFigureOutDataPointFromRawValue(rawValue, dest), "") | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode", payload: msg.payload, GA: msg.knx.destination, dpt: "", devicename: "" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, null, oGA.dpt, oGA.devicename) | ||
let msg = buildInputMessage(src, dest, evt, null, oGA.dpt, oGA.devicename); | ||
input.setNodeStatus({ fill: "grey", shape: "dot", text: "Read", payload: msg.payload, GA: msg.knx.destination, dpt: msg.knx.dpt, devicename: msg.devicename }); | ||
input.send(msg) | ||
input.send(msg); | ||
} | ||
} else if (input.topic == dest) { | ||
let msg = buildInputMessage(src, dest, evt, null, input.dpt, input.name ? input.name : ""); | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload: ""; // 24/01/2020 Added previous payload | ||
// 24/09/2019 Autorespond to BUS | ||
if (input.notifyreadrequestalsorespondtobus===true) { | ||
if (typeof input.currentPayload === "undefined" || input.currentPayload === "") { | ||
setTimeout(() => { | ||
node.knxConnection.respond(dest, input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized, input.dpt); | ||
input.setNodeStatus({ fill: "blue", shape: "ring", text: "Read & Autorespond with default", payload: input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized, GA: input.topic, dpt: msg.knx.dpt, devicename: "" }); | ||
}, 200); | ||
// 04/02/2020 Watchdog implementation | ||
if (input.hasOwnProperty("isWatchDog")) { | ||
// Is a watchdog node | ||
input.evalCalledByConfigNode("Read"); | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, null, input.dpt, input.name ? input.name : ""); | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Added previous payload | ||
// 24/09/2019 Autorespond to BUS | ||
if (input.notifyreadrequestalsorespondtobus === true) { | ||
if (typeof input.currentPayload === "undefined" || input.currentPayload === "") { | ||
setTimeout(() => { | ||
node.knxConnection.respond(dest, input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized, input.dpt); | ||
input.setNodeStatus({ fill: "blue", shape: "ring", text: "Read & Autorespond with default", payload: input.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized, GA: input.topic, dpt: msg.knx.dpt, devicename: "" }); | ||
}, 200); | ||
} else { | ||
setTimeout(() => { | ||
node.knxConnection.respond(dest, input.currentPayload, input.dpt); | ||
input.setNodeStatus({ fill: "blue", shape: "ring", text: "Read & Autorespond", payload: input.currentPayload, GA: input.topic, dpt: msg.knx.dpt, devicename: "" }); | ||
}, 200); | ||
}; | ||
} else { | ||
setTimeout(() => { | ||
node.knxConnection.respond(dest, input.currentPayload, input.dpt); | ||
input.setNodeStatus({ fill: "blue", shape: "ring", text: "Read & Autorespond", payload: input.currentPayload, GA: input.topic, dpt: msg.knx.dpt, devicename: "" }); | ||
}, 200); | ||
} | ||
} else { | ||
input.setNodeStatus({ fill: "grey", shape: "dot", text: "Read", payload: msg.payload, GA: input.topic , dpt:msg.knx.dpt, devicename:"" }); | ||
} | ||
input.send(msg) | ||
} | ||
}) | ||
input.setNodeStatus({ fill: "grey", shape: "dot", text: "Read", payload: msg.payload, GA: input.topic, dpt: msg.knx.dpt, devicename: "" }); | ||
}; | ||
input.send(msg); | ||
}; | ||
}; | ||
}); | ||
break; | ||
} | ||
}; | ||
default: return | ||
} | ||
}) | ||
} | ||
}; | ||
}); | ||
}; | ||
@@ -457,2 +472,3 @@ | ||
} | ||
function handleTelegramQueue() { | ||
@@ -459,0 +475,0 @@ if (node.knxConnection) { |
@@ -52,5 +52,7 @@ module.exports = function (RED) { | ||
// 01/02/2020 Dinamic change of the KNX Gateway IP, Port and Physical Address | ||
// DEPRECATED, USE THE WATCHDOG INSTEAD | ||
// This new thing has been requested by proServ RealKNX staff. | ||
if (msg.hasOwnProperty("setGatewayConfig")) { | ||
node.server.setGatewayConfig(msg.setGatewayConfig.IP, msg.setGatewayConfig.Port, msg.setGatewayConfig.PhysicalAddress, msg.setGatewayConfig.BindToEthernetInterface); | ||
RED.log.warn("knxUltimate: Node " + node.id + " setGatewayConfig is deprecated here. Use it with WatchDog node instead!"); | ||
return; | ||
@@ -208,3 +210,2 @@ } | ||
}, 1000); | ||
//node.server.removeClient(node); | ||
return; | ||
@@ -216,3 +217,2 @@ } | ||
node.currentPayload = msg.payload;// 31/12/2019 Set the current value (because, if the node is a virtual device, then it'll never fire "GroupValue_Write" in the server node, causing the currentPayload to never update) | ||
//node.server.knxConnection.respond(grpaddr, msg.payload, dpt); | ||
node.server.writeQueueAdd({ grpaddr: grpaddr, payload:msg.payload,dpt:dpt,outputtype:outputtype}) | ||
@@ -224,3 +224,2 @@ node.setNodeStatus({ fill: "blue", shape: "dot", text: "Responding",payload: msg.payload, GA: grpaddr, dpt:dpt, devicename:"" }); | ||
node.currentPayload = msg.payload;// 31/12/2019 Set the current value (because, if the node is a virtual device, then it'll never fire "GroupValue_Write" in the server node, causing the currentPayload to never update) | ||
//node.server.knxConnection.write(grpaddr, msg.payload, dpt); | ||
node.server.writeQueueAdd({ grpaddr: grpaddr, payload:msg.payload,dpt:dpt,outputtype:outputtype}) | ||
@@ -247,6 +246,4 @@ node.setNodeStatus({ fill: "green", shape: "dot", text: "Writing",payload: msg.payload, GA: grpaddr, dpt:dpt, devicename:"" }); | ||
node.server.removeClient(node); | ||
//node.setNodeStatus({ fill: "grey", shape: "ring", text: "Unsubscribed" }); | ||
if (node.topic || node.listenallga) { | ||
node.server.addClient(node); | ||
//(node.setNodeStatus({ fill: "green", shape: "ring", text: "Ready" }) | ||
} | ||
@@ -253,0 +250,0 @@ |
{ | ||
"name": "node-red-contrib-knx-ultimate", | ||
"version": "1.1.25", | ||
"version": "1.1.26", | ||
"description": "Single Node KNX IN/OUT with optional ETS group address importer. Easy to use and highly configurable.", | ||
@@ -11,3 +11,4 @@ "dependencies": { | ||
"knxUltimate": "knxUltimate.js", | ||
"knxUltimate-config": "knxUltimate-config.js" | ||
"knxUltimate-config": "knxUltimate-config.js", | ||
"knxUltimateWatchDog": "/Pro/knxUltimateWatchDog.js" | ||
} | ||
@@ -14,0 +15,0 @@ }, |
@@ -15,4 +15,5 @@ # node-red-contrib-knx-ultimate | ||
## DESCRIPTION | ||
Knx-ultimate is a powerfull device node, all-in-one. It acts as input device as well as output device at the same time. I'ts very SIMPLE TO USE thus very customizable.<br /> | ||
If you're here, you probably already have tried other knx nodes from npm. I hope you enjoy this one, because i've put big effort to do what i really needed, a copy/paste friendly node, with many functions and the possibility to use the ETS csv exported Group Addresses. | ||
**Knx-ultimate device node** is a powerfull device node, all-in-one. It acts as input device as well as output device at the same time. I'ts very SIMPLE TO USE thus very customizable.<br/> | ||
If you're here, you probably already have tried other knx nodes from npm. I hope you enjoy this one, because i've put big effort to do what i really needed, a copy/paste friendly node, with many functions and the possibility to use the ETS csv exported Group Addresses.<br /> | ||
**WatchDog node** is a professional oriented knx node for installers/companies. It allows notification (Email, Twitter, Telegram, Alexa, Siri, Sonos -with sonospollytts node- and so on) of KNX Bus connection errors, automatic or manual switchover to a backup KNX/IP router if the primary fails and allows you to programmatically change the config-node directly from a msg flow. | ||
@@ -28,2 +29,3 @@ [](https://www.paypal.me/techtoday) and <a href="http://eepurl.com/gJm095" target="_blank">subscribe to my channel.</a> Only news about my nodes, no spam, no ads.<br/>Please never put pineapple on an italian pizza! | ||
* Troubleshoot <a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/5.-FAQ-Troubleshoot">are here! Take a look.</a> | ||
* WatchDog node <a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/7.-WatchDog-Configuration" target="_blank">wiki is here.</a> | ||
<table> | ||
@@ -103,2 +105,7 @@ <tr> | ||
</details> | ||
<details><summary>WATCHDOG NODE FOR KNX CONNECTION BACKUP AND NOTIFICATION</summary> | ||
You can check the healty of your KNX Bus connection and switch over to anoter KNX/IP Router if the primary fails. | ||
</details> | ||
<details><summary>PROGRAMMATICALLY CHANGE THE KNX/IP INTERFACE/ROUTER CONFIG</summary> | ||
@@ -105,0 +112,0 @@ |
Sorry, the diff of this file is not supported yet
1998065
12.05%51
10.87%991
16.31%237
3.04%