# node-red-contrib-boolean-logic-ultimate | # node-red-contrib-boolean-logic-ultimate | ||||
<p> | <p> | ||||
<b>Version 1.0.0 LTS</b><br/> | |||||
<b>Version 1.0.1</b><br/> | |||||
- Added "trigger mode" option<br/> | |||||
</p> | |||||
<p> | |||||
<b>Version 1.0.0</b><br/> | |||||
- Added Filter node<br/> | - Added Filter node<br/> | ||||
</p> | </p> | ||||
<p> | <p> |
The node can have a persistent input: the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload. | The node can have a persistent input: the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload. | ||||
## FUNCTIONS | |||||
## ADDITIONAL FUNCTIONS | |||||
* Filter ouput results (outputs only true or trye/false) | * Filter ouput results (outputs only true or trye/false) | ||||
* Trigger mode selection (Can output a payload only by single input's topic trigger and after evaluation ot other inputs, or can oputput a payload by change of every input) | * Trigger mode selection (Can output a payload only by single input's topic trigger and after evaluation ot other inputs, or can oputput a payload by change of every input) | ||||
</code> | </code> | ||||
<ol> | <ol> | ||||
<li>All topics: standard behaviour, the node will output <b>true</b> and <b>false</b> by evaluating all inputs. Each input change will trigger the node output.</li> | <li>All topics: standard behaviour, the node will output <b>true</b> and <b>false</b> by evaluating all inputs. Each input change will trigger the node output.</li> | ||||
<li>Single topic + eval: <u>only whenever the node receives a msg input with the <b>specified topic</b> (having payload = true)</u>, it starts the evaluation of all other inputs as well and outputs the evaluated payload. If the node receives a msg input other than the <b>specified topic</b>), it only retains it's value for the boolean evaluation.</li> | |||||
<li>Single topic + eval other inputs: <u>only whenever the node receives a msg input with the <b>specified topic</b> (having payload = true)</u>, it starts the evaluation of all other inputs as well and outputs the evaluated payload. If the node receives a msg input other than the <b>specified topic</b>), it only retains it's value for the boolean evaluation.</li> | |||||
</ol> | </ol> | ||||
<br/><br/> | |||||
Example of trigger mode = Single topic + eval other inputs | |||||
```js | |||||
[{"id":"4d2e4d1.4a02034","type":"BooleanLogicUltimate","z":"5635003e.2d70f","name":"","filtertrue":"both","persist":true,"triggertopic":"MotionSensor","outputtriggeredby":"onlyonetopic","inputCount":"3","topic":"result","x":460,"y":580,"wires":[["a9e93fa0.99508"],[],[]]},{"id":"b3a4633e.ff06c","type":"inject","z":"5635003e.2d70f","name":"","topic":"MotionSensor","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":560,"wires":[["4d2e4d1.4a02034"]]},{"id":"150ff8fd.8110e7","type":"inject","z":"5635003e.2d70f","name":"","topic":"Dusk","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":760,"wires":[["4d2e4d1.4a02034"]]},{"id":"6ecd73e1.9ac75c","type":"inject","z":"5635003e.2d70f","name":"","topic":"Rain","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":660,"wires":[["4d2e4d1.4a02034"]]},{"id":"350fb477.b0d484","type":"inject","z":"5635003e.2d70f","name":"","topic":"Dusk","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":800,"wires":[["4d2e4d1.4a02034"]]},{"id":"1118f46a.b967ac","type":"inject","z":"5635003e.2d70f","name":"","topic":"MotionSensor","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":600,"wires":[["4d2e4d1.4a02034"]]},{"id":"4e793dec.646b4c","type":"inject","z":"5635003e.2d70f","name":"","topic":"Rain","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":700,"wires":[["4d2e4d1.4a02034"]]},{"id":"a9e93fa0.99508","type":"debug","z":"5635003e.2d70f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":650,"y":580,"wires":[]},{"id":"8d44deef.e81d","type":"comment","z":"5635003e.2d70f","name":"Switch on the light only when it's raining and it's dusk. The trigger is someone entering in the Motion Sensor's area.","info":"Triggers only if someone enters \nin the motion sensor's area","x":410,"y":520,"wires":[]}] | |||||
``` | |||||
<br/><br/> | |||||
<b>Remember latest input values after reboot</b><br /> | <b>Remember latest input values after reboot</b><br /> | ||||
If checked, the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload.<br/> | If checked, the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload.<br/> |
icon: "serial.png", | icon: "serial.png", | ||||
label: | label: | ||||
function() { | function() { | ||||
var label = "Logic" + (this.filtertrue=="both" ? "" : " filtered" ) + " [" + this.inputCount + "]"; | |||||
let label = ""; | |||||
let filtered=this.filtertrue=="both" ? "" : " |TRUE" ; | |||||
let trigger=this.outputtriggeredby=="all" ? "" : " |TRIG:" + this.triggertopic; | |||||
label= this.inputCount + ((filtered+trigger)==""?" Boolean Logic":(filtered+trigger)); | |||||
if( this.name !== undefined && this.name.length > 0 ) { | if( this.name !== undefined && this.name.length > 0 ) { | ||||
label = label + " (" + this.name + ")"; | |||||
label += " (" + this.name + ")"; | |||||
} | } | ||||
return label; | return label; | ||||
}, | }, | ||||
<label for="node-input-outputtriggeredby"><i class="fa fa-filter"></i> Trigger mode</label> | <label for="node-input-outputtriggeredby"><i class="fa fa-filter"></i> Trigger mode</label> | ||||
<select type="text" id="node-input-outputtriggeredby" placeholder="Event"> | <select type="text" id="node-input-outputtriggeredby" placeholder="Event"> | ||||
<option value="all">All topics</option> | <option value="all">All topics</option> | ||||
<option value="onlyonetopic">Single topic + eval</option> | |||||
<option value="onlyonetopic">Single topic + only eval others</option> | |||||
</select> | </select> | ||||
</div> | </div> | ||||
<div class="form-row" id="triggertopic"> | <div class="form-row" id="triggertopic"> | ||||
</code> | </code> | ||||
<ol> | <ol> | ||||
<li>All topics: standard behaviour, the node will output <b>true</b> and <b>false</b> by evaluating all inputs. Each input change will trigger the node output.</li> | <li>All topics: standard behaviour, the node will output <b>true</b> and <b>false</b> by evaluating all inputs. Each input change will trigger the node output.</li> | ||||
<li>Single topic + eval: <u>only whenever the node receives a msg input with the <b>specified topic</b> (having payload = true)</u>, it starts the evaluation of all other inputs as well and outputs the evaluated payload. If the node receives a msg input other than the <b>specified topic</b>), it only retains it's value for the boolean evaluation.</li> | |||||
<li>Single topic + only eval others: <u>only whenever the node receives a msg input with the <b>specified topic</b> (having payload = true)</u>, it starts the evaluation of all other inputs as well and outputs the evaluated payload. If the node receives a msg input other than the <b>specified topic</b>), it only retains it's value for the boolean evaluation.</li> | |||||
</ol> | </ol> | ||||
Example of trigger mode = Single topic + eval other inputs: <b>SEE THE README FOR AN EXAMPLE</b> | |||||
<br/><br/> | <br/><br/> | ||||
<b>Remember latest input values after reboot</b><br /> | <b>Remember latest input values after reboot</b><br /> |
this.config = config; | this.config = config; | ||||
this.state = {}; | this.state = {}; | ||||
var node = this; | var node = this; | ||||
node.config = config; | |||||
var fs = require('fs'); | var fs = require('fs'); | ||||
var decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/ | var decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/ | ||||
if (!resOR) { resOR = null }; | if (!resOR) { resOR = null }; | ||||
if (!resXOR) { resXOR = null }; | if (!resXOR) { resXOR = null }; | ||||
} | } | ||||
SetResult(resAND,resOR,resXOR, node.config.topic); | |||||
// Operation mode evaluation | |||||
if (node.config.outputtriggeredby == "onlyonetopic") { | |||||
if (typeof node.config.triggertopic !== "undefined" | |||||
&& node.config.triggertopic !== "" | |||||
&& msg.hasOwnProperty("topic") && msg.topic !=="" | |||||
&& node.config.triggertopic === msg.topic) | |||||
{ | |||||
SetResult(resAND, resOR, resXOR, node.config.topic); | |||||
} | |||||
node.status({ fill: "grey", shape: "ring", text: " Saved " + msg.hasOwnProperty("topic") ? msg.topic : "empty input topic"}); | |||||
} else | |||||
{ | |||||
SetResult(resAND, resOR, resXOR, node.config.topic); | |||||
} | |||||
} | } | ||||
else if(keyCount > node.config.inputCount ) { | else if(keyCount > node.config.inputCount ) { | ||||
node.warn( | node.warn( |
{ | { | ||||
"name": "node-red-contrib-boolean-logic-ultimate", | "name": "node-red-contrib-boolean-logic-ultimate", | ||||
"version": "1.0.0", | |||||
"version": "1.0.1", | |||||
"description": "A set of Node-RED enhanced boolean logic, with persisten values after reboot and more", | "description": "A set of Node-RED enhanced boolean logic, with persisten values after reboot and more", | ||||
"author": "Supergiovane (https://github.com/Supergiovane)", | "author": "Supergiovane (https://github.com/Supergiovane)", | ||||
"dependencies": { | "dependencies": { |