node-red-contrib-boolean-logic-ultimate
Advanced tools
Comparing version
module.exports = function(RED) { | ||
function BooleanLogicUltimate(config) { | ||
RED.nodes.createNode(this,config); | ||
this.config = config; | ||
this.state = {}; | ||
RED.nodes.createNode(this, config); | ||
var node = this; | ||
node.config = config; | ||
node.jSonStates = {}; // JSON object with elements. It's not an array! Format: {"Rain":true,"Dusk":true,"MotionSensor":true} | ||
node.sInitializeWith = typeof node.config.sInitializeWith === "undefined" ? "WaitForPayload" : node.config.sInitializeWith; | ||
var fs = require('fs'); | ||
var decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/ | ||
// Helper for the config html, to be able to delete the peristent states file | ||
@@ -24,4 +23,4 @@ RED.httpAdmin.get("/stateoperation_delete", RED.auth.needsPermission('BooleanLogicUltimate.read'), function (req, res) { | ||
if (typeof contents !== 'undefined') { | ||
node.state = JSON.parse(contents); | ||
node.status({fill: "blue",shape: "ring",text: "Loaded persistent states (" + Object.keys(node.state).length + " total)."}); | ||
node.jSonStates = JSON.parse(contents); | ||
node.status({fill: "blue",shape: "ring",text: "Loaded persistent states (" + Object.keys(node.jSonStates).length + " total)."}); | ||
} | ||
@@ -36,2 +35,7 @@ } catch (error) { | ||
// 14/08/2019 If the inputs are to be initialized, create a dummy items in the array | ||
initUndefinedInputs(); | ||
this.on('input', function (msg) { | ||
@@ -43,13 +47,30 @@ | ||
if (topic !== undefined && payload !== undefined) { | ||
var value = ToBoolean( payload ); | ||
var state = node.state; | ||
// 14/08/2019 if inputs are initialized, remove a "dummy" item from the state's array, as soon as new topic arrives | ||
if(node.sInitializeWith !== "WaitForPayload") | ||
{ | ||
// Search if the current topic is in the state array | ||
if (typeof node.jSonStates[topic] === "undefined") | ||
{ | ||
// Delete one dummy | ||
for (let index = 0; index < node.config.inputCount; index++) { | ||
if (node.jSonStates.hasOwnProperty("dummy" + index)) { | ||
//RED.log.info(JSON.stringify(node.jSonStates)) | ||
delete node.jSonStates["dummy" + index]; | ||
//RED.log.info(JSON.stringify(node.jSonStates)) | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
// Add current attribute | ||
node.jSonStates[topic] = value; | ||
state[topic] = value; | ||
// Save the state array to a perisistent file | ||
if (this.config.persist == true) { | ||
if (node.config.persist == true) { | ||
try { | ||
if (!fs.existsSync("states")) fs.mkdirSync("states"); | ||
fs.writeFileSync("states/" + node.id.toString(),JSON.stringify(state)); | ||
fs.writeFileSync("states/" + node.id.toString(),JSON.stringify(node.jSonStates)); | ||
@@ -62,3 +83,3 @@ } catch (error) { | ||
// Do we have as many inputs as we expect? | ||
var keyCount = Object.keys(state).length; | ||
var keyCount = Object.keys(node.jSonStates).length; | ||
@@ -100,3 +121,3 @@ if( keyCount == node.config.inputCount ) { | ||
+ node.config.inputCount + " topics received, resetting. Will not output new value until " + node.config.inputCount + " new topics have been received."); | ||
node.state = {}; | ||
node.jSonStates = {}; | ||
DeletePersistFile(node.id); | ||
@@ -130,4 +151,21 @@ DisplayUnkownStatus(); | ||
} | ||
node.jSonStates = {}; // Resets inputs | ||
// 14/08/2019 If the inputs are to be initialized, create a dummy items in the array | ||
initUndefinedInputs(); | ||
} | ||
function initUndefinedInputs() { | ||
if (node.sInitializeWith !== "WaitForPayload") | ||
{ | ||
var nTotalDummyToCreate = Number(node.config.inputCount) - Object.keys(node.jSonStates).length; | ||
RED.log.info("BooleanLogicUltimate: Will create " + nTotalDummyToCreate + " dummy (" + node.sInitializeWith + ") values") | ||
for (let index = 0; index < nTotalDummyToCreate; index++) { | ||
node.jSonStates["dummy" + index] = node.sInitializeWith === "false" ? false : true; | ||
} | ||
if (nTotalDummyToCreate > 0) { | ||
setTimeout(() => { node.status({fill: "green",shape: "ring",text: "Initialized " + nTotalDummyToCreate + " undefined inputs with " + node.sInitializeWith});}, 4000) | ||
} | ||
} | ||
} | ||
function CalculateResult(_operation) { | ||
@@ -141,8 +179,8 @@ var res; | ||
// We need a starting value to perform AND and OR operations. | ||
var keys = Object.keys(node.state); | ||
res = node.state[keys[0]]; | ||
var keys = Object.keys(node.jSonStates); | ||
res = node.jSonStates[keys[0]]; | ||
for( var i = 1; i < keys.length; ++i ) { | ||
var key = keys[i]; | ||
res = PerformSimpleOperation( _operation, res, node.state[key] ); | ||
res = PerformSimpleOperation( _operation, res, node.jSonStates[key] ); | ||
} | ||
@@ -159,4 +197,4 @@ } | ||
for( var key in node.state ) { | ||
if( node.state[key] ) { | ||
for( var key in node.jSonStates ) { | ||
if( node.jSonStates[key] ) { | ||
trueCount++; | ||
@@ -205,12 +243,3 @@ } | ||
function DisplayStatus ( value ) { | ||
node.status( | ||
{ | ||
fill: value ? "green" : "red", | ||
shape: value ? "dot" : "ring", | ||
text: value ? "true" : "false" | ||
} | ||
); | ||
}; | ||
function DisplayUnkownStatus () { | ||
@@ -217,0 +246,0 @@ node.status( |
# node-red-contrib-boolean-logic-ultimate | ||
<p> | ||
<b>Version 1.0.4</b><br/> | ||
- Added the option to initialize the undefined inputs with true or false. Thanks to this, the node is immediately operative (will not wait until all topis arrives).<br/> | ||
</p> | ||
<p> | ||
<b>Version 1.0.3</b><br/> | ||
@@ -4,0 +8,0 @@ - Node status: cosmetic adjustments<br/> |
{ | ||
"name": "node-red-contrib-boolean-logic-ultimate", | ||
"version": "1.0.3", | ||
"version": "1.0.4", | ||
"description": "A set of Node-RED enhanced boolean logic, with persisten values after reboot and more", | ||
@@ -5,0 +5,0 @@ "author": "Supergiovane (https://github.com/Supergiovane)", |
@@ -8,4 +8,4 @@ # node-red-contrib-boolean-logic-ultimate | ||
[](https://standardjs.com) | ||
[](https://www.paypal.me/techtoday) | ||
## DESCRIPTION | ||
@@ -55,2 +55,10 @@ The node performs Boolean logic on the incoming payloads.<br/> | ||
<b>If input states are undefined</b><br /> | ||
Every time you create a node or modify the node, all inputs are set to undefined. This means that the node will wait the arrive of all topics (for example 3 topics, if you've selected 3 topics in the option), before it can output a payload. This can be a problem if your logic must be operative as soon as you deploy the flow. To overcome this problem, you can "initialize" all the undefined inputs with True or False. | ||
<ol> | ||
<li>Leave undefined: Standard behaviour, the node will wait all the "undefined" topics to arrive, then starts a flow with the result.</li> | ||
<li>True or False: The node is immediately operative, by force the initialization of the "undefined" inputs with "true" or "false".</li> | ||
</ol> | ||
<br/> | ||
Example of trigger mode = Single topic + eval other inputs | ||
@@ -57,0 +65,0 @@ ```js |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
35072
15.52%321
8.81%103
8.42%