node-red-contrib-knx-ultimate
Advanced tools
Comparing version
@@ -0,10 +1,17 @@ | ||
 | ||
 | ||
[](https://www.paypal.me/techtoday) and <a href="http://eepurl.com/gJm095" target="_blank">subscribe to my channel </a> for latest news about my nodes. | ||
<br/> | ||
<p> | ||
<b>Version 1.1.32</b> - Feb 2020<br/> | ||
- New: in the knx-ultimate, added the option to <a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/2.-Node-Configuration" target="_blank">format the msg.payload value</a>, if it's numeric.<br/> | ||
- Switched to knx.js API 2.3.7<br/> | ||
- Refractoring of some internal code to speed up things, whenever the node sends a "Read" request to the BUS.<br/> | ||
- Fix a message warning in the config page, if you not imported the ETS csv file.<br/> | ||
- Fix the "Universal Mode" setting wrongly reverting to false on newly added nodes, if you've not imported the ETS csv.<br/> | ||
- Devicename msg property is now populated with the node name, if the node is in Universal Mode and the ETS CSV file has not been imported (previoulsy was set to empty string).<br/> | ||
- Update the Wiki and node help, with the new "payload format" options.<br/> | ||
</p> | ||
<p> | ||
<b>Version 1.1.31</b> - Feb 2020<br/> | ||
@@ -246,2 +253,2 @@ - Rewritten the "Send a GrpValue read once on connection/reconnect" using the telegram queue.<br/> | ||
- Initial release<br/> | ||
</p> | ||
</p> |
@@ -1,3 +0,6 @@ | ||
const knx = require('knxultimate-api') | ||
const dptlib = require('knxultimate-api/src/dptlib') | ||
const knx = require('knx'); | ||
const dptlib = require('knx/src/dptlib'); | ||
// const knx = require('knxultimate-api'); | ||
// const dptlib = require('knxultimate-api/src/dptlib'); | ||
const oOS = require('os') | ||
@@ -83,3 +86,3 @@ | ||
node.csv = readCSV(config.csv); // Array from ETS CSV Group Addresses | ||
node.loglevel = config.loglevel !== undefined ? config.loglevel : "info"; // 06/02/2020 by Heleon19 Loglevel default info | ||
node.loglevel = config.loglevel !== undefined ? config.loglevel : "error"; // 18/02/2020 Loglevel default error | ||
@@ -359,16 +362,7 @@ // Endpoint for reading csv from the other nodes | ||
// 25/10/2019 TRY TO AUTO DECODE | ||
// -------------------------------- | ||
if (typeof oGA === "undefined") { | ||
// 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), "", dest); | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode", payload: msg.payload, GA: msg.knx.destination, dpt: "", devicename: "" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
// 25/10/2019 TRY TO AUTO DECODE IF Group address not found in the CSV | ||
let msg = buildInputMessage({ _srcGA: src, _destGA: dest, _event: evt, _Rawvalue: rawValue, _inputDpt: (typeof oGA === "undefined") ? null : oGA.dpt, _devicename: (typeof oGA === "undefined") ? input.name || "" : oGA.devicename, _outputtopic: dest, _oNode: input }); | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: (typeof oGA === "undefined") ? "Try to decode" : "", payload: msg.payload, GA: msg.knx.destination, dpt: msg.knx.dpt, devicename: msg.devicename }); | ||
input.send(msg) | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, oGA.dpt, oGA.devicename, dest); | ||
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) { | ||
@@ -380,3 +374,3 @@ // 04/02/2020 Watchdog implementation | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, input.dpt, input.name ? input.name : "", input.outputtopic) | ||
let msg = buildInputMessage({ _srcGA: src, _destGA: dest, _event: evt, _Rawvalue: rawValue, _inputDpt: input.dpt, _devicename: input.name ? input.name : "", _outputtopic: input.outputtopic, _oNode: input }) | ||
// Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload | ||
@@ -408,17 +402,8 @@ if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) { | ||
// 25/10/2019 TRY TO AUTO DECODE | ||
// -------------------------------- | ||
if (typeof oGA === "undefined") { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, tryToFigureOutDataPointFromRawValue(rawValue, dest), "", dest) | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode", payload: msg.payload, GA: msg.knx.destination, dpt: "", devicename: "" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
// 25/10/2019 TRY TO AUTO DECODE IF Group address not found in the CSV | ||
let msg = buildInputMessage({ _srcGA: src, _destGA: dest, _event: evt, _Rawvalue: rawValue, _inputDpt: (typeof oGA === "undefined") ? null : oGA.dpt, _devicename: (typeof oGA === "undefined") ? input.name || "" : oGA.devicename, _outputtopic: dest, _oNode: input }); | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: (typeof oGA === "undefined") ? "Try to decode" : "", payload: msg.payload, GA: msg.knx.destination, dpt: msg.knx.dpt, devicename: msg.devicename }); | ||
input.send(msg) | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, oGA.dpt, oGA.devicename, dest) | ||
input.setNodeStatus({ fill: "blue", 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) { | ||
// 04/02/2020 Watchdog implementation | ||
@@ -429,3 +414,3 @@ if (input.hasOwnProperty("isWatchDog")) { | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, rawValue, input.dpt, input.name ? input.name : "", input.outputtopic) | ||
let msg = buildInputMessage({ _srcGA: src, _destGA: dest, _event: evt, _Rawvalue: rawValue, _inputDpt: input.dpt, _devicename: input.name ? input.name : "", _outputtopic: input.outputtopic, _oNode: input }) | ||
// Check RBE INPUT from KNX Bus, to avoid send the payload to the flow, if it's equal to the current payload | ||
@@ -458,16 +443,7 @@ if (!checkRBEInputFromKNXBusAllowSend(input, msg.payload)) { | ||
// 25/10/2019 TRY TO AUTO DECODE | ||
// -------------------------------- | ||
if (typeof oGA === "undefined") { | ||
// 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), "", dest) | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: "Try to decode", payload: msg.payload, GA: msg.knx.destination, dpt: "", devicename: "" }); | ||
input.send(msg) | ||
// -------------------------------- | ||
// 25/10/2019 TRY TO AUTO DECODE IF Group address not found in the CSV | ||
let msg = buildInputMessage({ _srcGA: src, _destGA: dest, _event: evt, _Rawvalue: null, _inputDpt: (typeof oGA === "undefined") ? null : oGA.dpt, _devicename: (typeof oGA === "undefined") ? input.name || "" : oGA.devicename, _outputtopic: dest, _oNode: input }); | ||
input.setNodeStatus({ fill: "green", shape: "dot", text: (typeof oGA === "undefined") ? "Try to decode" : "", payload: msg.payload, GA: msg.knx.destination, dpt: msg.knx.dpt, devicename: msg.devicename }); | ||
input.send(msg) | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, null, oGA.dpt, oGA.devicename, dest); | ||
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); | ||
} | ||
} else if (input.topic == dest) { | ||
@@ -480,4 +456,4 @@ | ||
} else { | ||
let msg = buildInputMessage(src, dest, evt, null, input.dpt, input.name ? input.name : "", input.outputtopic); | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Added previous payload | ||
let msg = buildInputMessage({ _srcGA: src, _destGA: dest, _event: evt, _Rawvalue: null, _inputDpt: input.dpt, _devicename: input.name ? input.name : "", _outputtopic: input.outputtopic, _oNode: input }) | ||
msg.previouspayload = typeof input.currentPayload !== "undefined" ? input.currentPayload : ""; // 24/01/2020 Reset previous payload | ||
// 24/09/2019 Autorespond to BUS | ||
@@ -535,5 +511,30 @@ if (input.notifyreadrequestalsorespondtobus === true) { | ||
// 14/08/2019 If the node has payload same as the received telegram, return false | ||
checkRBEInputFromKNXBusAllowSend = (_node, _KNXTelegramPayload) => { | ||
if (_node.inputRBE !== true) return true; | ||
if (typeof _node.currentPayload === "undefined") return true; | ||
var curVal = _node.currentPayload.toString().toLowerCase(); | ||
var newVal = _KNXTelegramPayload.toString().toLowerCase(); | ||
if (curVal === "false") { | ||
curVal = "0"; | ||
} | ||
if (curVal === "true") { | ||
curVal = "1"; | ||
} | ||
if (newVal === "false") { | ||
newVal = "0"; | ||
} | ||
if (newVal === "true") { | ||
newVal = "1"; | ||
} | ||
if (curVal === newVal) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
// 26/10/2019 Try to figure out the datapoint type from raw value | ||
function tryToFigureOutDataPointFromRawValue(_rawValue) { | ||
// 25/10/2019 Try some Datapoints | ||
if (_rawValue === null) return "1.001"; | ||
if (_rawValue.length == 1) { | ||
@@ -579,52 +580,53 @@ if (_rawValue[0].toString() == "0" || _rawValue[0].toString() == "1") { | ||
// 14/08/2019 If the node has payload same as the received telegram, return false | ||
checkRBEInputFromKNXBusAllowSend = (_node, _KNXTelegramPayload) => { | ||
if (_node.inputRBE !== true) return true; | ||
if (typeof _node.currentPayload === "undefined") return true; | ||
var curVal = _node.currentPayload.toString().toLowerCase(); | ||
var newVal = _KNXTelegramPayload.toString().toLowerCase(); | ||
if (curVal === "false") { | ||
curVal = "0"; | ||
} | ||
if (curVal === "true") { | ||
curVal = "1"; | ||
} | ||
if (newVal === "false") { | ||
newVal = "0"; | ||
} | ||
if (newVal === "true") { | ||
newVal = "1"; | ||
} | ||
if (curVal === newVal) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
function buildInputMessage(src, dest, evt, value, inputDpt, _devicename, _outputtopic) { | ||
// Resolve DPT and convert value if available | ||
var dpt = dptlib.resolve(inputDpt); | ||
var jsValue = null | ||
if (dpt && value) { | ||
var jsValue = dptlib.fromBuffer(value, dpt) | ||
} | ||
function buildInputMessage({ _srcGA, _destGA, _event, _Rawvalue, _inputDpt, _devicename, _outputtopic, _oNode }) { | ||
var sPayloadmeasureunit = "unknown"; | ||
var sDptdesc = "unknown"; | ||
var sPayloadsubtypevalue = "unknown"; | ||
var jsValue = null; | ||
if (dpt.subtype !== undefined) { | ||
sPayloadmeasureunit = dpt.subtype.unit !== undefined ? dpt.subtype.unit : "unknown"; | ||
sDptdesc = dpt.subtype.desc !== undefined ? dpt.subtype.desc.charAt(0).toUpperCase() + dpt.subtype.desc.slice(1) : "unknown"; | ||
if (dpt.subtype.enc !== undefined) { | ||
try { | ||
if (!Boolean(jsValue)) sPayloadsubtypevalue = dpt.subtype.enc[0]; | ||
if (Boolean(jsValue)) sPayloadsubtypevalue = dpt.subtype.enc[1]; | ||
} catch (error) { | ||
} | ||
// Resolve DPT and convert value if available | ||
if (_Rawvalue !== null) { | ||
sInputDpt = (_inputDpt === null) ? tryToFigureOutDataPointFromRawValue(_Rawvalue) : _inputDpt; | ||
var dpt = dptlib.resolve(sInputDpt); | ||
if (dpt && _Rawvalue !== null) { | ||
var jsValue = dptlib.fromBuffer(_Rawvalue, dpt) | ||
} | ||
}; | ||
// Formatting the msg output value | ||
if (_oNode !== null && jsValue !== null) { | ||
if (typeof jsValue === "number") { | ||
// multiplier | ||
jsValue = jsValue * _oNode.formatmultiplyvalue; | ||
// Number of decimals | ||
if (_oNode.formatdecimalsvalue == 999) { | ||
// Leave as is | ||
} else { | ||
// Round | ||
jsValue = +(Math.round(jsValue + "e+" + _oNode.formatdecimalsvalue) + "e-" + _oNode.formatdecimalsvalue); | ||
} | ||
// leave, zero or abs | ||
if (jsValue < 0) { | ||
if (_oNode.formatnegativevalue == "zero") { | ||
jsValue = 0; | ||
} else if (_oNode.formatnegativevalue == "abs") { | ||
jsValue = Math.abs(jsValue); | ||
} | ||
} | ||
} | ||
} | ||
if (dpt.subtype !== undefined) { | ||
sPayloadmeasureunit = dpt.subtype.unit !== undefined ? dpt.subtype.unit : "unknown"; | ||
sDptdesc = dpt.subtype.desc !== undefined ? dpt.subtype.desc.charAt(0).toUpperCase() + dpt.subtype.desc.slice(1) : "unknown"; | ||
if (dpt.subtype.enc !== undefined) { | ||
try { | ||
if (!Boolean(jsValue)) sPayloadsubtypevalue = dpt.subtype.enc[0]; | ||
if (Boolean(jsValue)) sPayloadsubtypevalue = dpt.subtype.enc[1]; | ||
} catch (error) { | ||
} | ||
} | ||
}; | ||
} | ||
// Build final input message object | ||
@@ -639,9 +641,9 @@ return { | ||
{ | ||
event: evt | ||
, dpt: inputDpt | ||
event: _event | ||
, dpt: sInputDpt | ||
//, details: dpt | ||
, dptdesc: sDptdesc | ||
, source: src | ||
, destination: dest | ||
, rawValue: value | ||
, source: _srcGA | ||
, destination: _destGA | ||
, rawValue: _Rawvalue | ||
} | ||
@@ -648,0 +650,0 @@ }; |
@@ -22,2 +22,5 @@ module.exports = function (RED) { | ||
node.messageQueue = []; // 01/01/2020 All messages from the flow to the node, will be queued and will be sent separated by 60 milliseconds each. Use uf the underlying knx.js "minimumDelay" is not possible because the telegram order isn't mantained. | ||
node.formatmultiplyvalue = (typeof config.formatmultiplyvalue === "undefined" ? 1 : config.formatmultiplyvalue); | ||
node.formatnegativevalue = (typeof config.formatnegativevalue === "undefined" ? "leave" : config.formatnegativevalue); | ||
node.formatdecimalsvalue = (typeof config.formatdecimalsvalue === "undefined" ? 999 : config.formatdecimalsvalue); | ||
@@ -36,3 +39,3 @@ // Used to call the status update from the config node. | ||
if (node.server) { | ||
var oError = {nodeid:node.id,topic:node.outputtopic,devicename:_devicename,GA:_GA,text:text}; | ||
var oError = { nodeid: node.id, topic: node.outputtopic, devicename: _devicename, GA: _GA, text: text }; | ||
node.server.reportToWatchdogCalledByKNXUltimateNode(oError); | ||
@@ -42,3 +45,3 @@ }; | ||
} | ||
// Check if the node has a valid topic and dpt | ||
@@ -45,0 +48,0 @@ if (node.listenallga == false) { |
{ | ||
"name": "node-red-contrib-knx-ultimate", | ||
"version": "1.1.31", | ||
"version": "1.1.32", | ||
"description": "Single Node KNX IN/OUT with optional ETS group address importer. Easy to use and highly configurable. Control your KNX intallation via Node-Red!", | ||
"dependencies": { | ||
"knxultimate-api": "2.3.7", | ||
"knx": "2.3.6" | ||
"knx": "2.3.7" | ||
}, | ||
@@ -9,0 +9,0 @@ "node-red": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
1484656
0.36%1068
0.47%0
-100%