| <a href="http://eepurl.com/gJm095" target="_blank">Subscribe to my channel.</a> Only news about my nodes, no spam, no ads. I'm a github developer, not a merchant. | <a href="http://eepurl.com/gJm095" target="_blank">Subscribe to my channel.</a> Only news about my nodes, no spam, no ads. I'm a github developer, not a merchant. | ||||
| <p> | |||||
| <b>Version 1.0.17</b> May 2020<br/> | |||||
| - Interruptflowultimete: msg.play = true sends the current payload See the README on github for an example.</br> | |||||
| </p> | |||||
| <p> | <p> | ||||
| <b>Version 1.0.16</b> May 2020<br/> | <b>Version 1.0.16</b> May 2020<br/> | ||||
| - BlinkerUltimate: if you set the interval while the blinker is running, yet the new interval is applied immediately.</br> | - BlinkerUltimate: if you set the interval while the blinker is running, yet the new interval is applied immediately.</br> |
| </code> | </code> | ||||
| </details> | </details> | ||||
| <br/> | |||||
| In this other example, you can see the property "play" in action. This property allow you to replay the last previously stored message.<br/> | |||||
| This allow to save the state of a node and then replay it back whenever you want. | |||||
| <img src='https://raw.githubusercontent.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/master/img/if1.png' width='60%'> | |||||
| <details><summary>CLICK HERE, copy and paste it into your flow</summary> | |||||
| <code> | |||||
| [{"id":"9839dd47.81b2c8","type":"InterruptFlowUltimate","z":"1b769f85.fba14","name":"Interrupt Flow","triggertopic":"trigger","x":520,"y":260,"wires":[["d371d690.1e2fe8"]]},{"id":"568deb73.394fb4","type":"comment","z":"1b769f85.fba14","name":"1) Push buttons to change values","info":"","x":130,"y":100,"wires":[]},{"id":"e1c9f10a.0ba518","type":"inject","z":"1b769f85.fba14","name":"ALLOW","topic":"trigger","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":70,"y":320,"wires":[["9839dd47.81b2c8"]]},{"id":"82ba24f9.0f0bd8","type":"inject","z":"1b769f85.fba14","name":"INTERRUPT","topic":"trigger","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":280,"wires":[["9839dd47.81b2c8"]]},{"id":"23ba4f9c.86de9","type":"comment","z":"1b769f85.fba14","name":"2) Push INTERRUPT, then try again to change value (1)","info":"","x":200,"y":240,"wires":[]},{"id":"24671ef2.4519e2","type":"inject","z":"1b769f85.fba14","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":70,"y":140,"wires":[["9839dd47.81b2c8"]]},{"id":"d371d690.1e2fe8","type":"debug","z":"1b769f85.fba14","name":"Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":690,"y":260,"wires":[]},{"id":"409ec415.735d74","type":"inject","z":"1b769f85.fba14","name":"REPLAY","topic":"trigger","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":80,"y":420,"wires":[["6653ed0.7186014"]]},{"id":"6653ed0.7186014","type":"change","z":"1b769f85.fba14","name":"Play","rules":[{"t":"set","p":"play","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":210,"y":420,"wires":[["9839dd47.81b2c8"]]},{"id":"e957a069.0ac458","type":"inject","z":"1b769f85.fba14","name":"","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":70,"y":180,"wires":[["9839dd47.81b2c8"]]},{"id":"8f0af608.8fb45","type":"comment","z":"1b769f85.fba14","name":"3) Replay last message stored by the node","info":"","x":160,"y":380,"wires":[]},{"id":"46e6f455.0023ac","type":"comment","z":"1b769f85.fba14","name":"You can use Interruptflow, to save the state of a node, and then replay the last state as you want.","info":"","x":330,"y":60,"wires":[]}] | |||||
| </code> | |||||
| </details> | |||||
| # INVERT ULTIMATE | # INVERT ULTIMATE | ||||
| Outputs the inverted input. For example true -> false<br /> | Outputs the inverted input. For example true -> false<br /> |
| <div class="form-row"> | <div class="form-row"> | ||||
| <label for="node-input-triggertopic"><i class="icon-tag"></i> Trigger by topic</label> | <label for="node-input-triggertopic"><i class="icon-tag"></i> Trigger by topic</label> | ||||
| <input type="text" id="node-input-triggertopic" placeholder="Name"> | <input type="text" id="node-input-triggertopic" placeholder="Name"> | ||||
| <div><i>Whenever the node receives a payload = false from this topic, it stops output messages to the flow. As soon it receives payload = true from this topic, the output messages start to flow out again.</i></div> | |||||
| <div><i>Whenever the node receives a payload = false from this topic,<br/> it stops output messages to the flow.<br/>As soon it receives payload = true from this topic,<br/>the output messages start to flow out again. | |||||
| <br/>The node will output the current stored message<br/>plus an added property "isReplay = true",<br/>as soon as it receives a "play" = true from this topic. | |||||
| </i></div> | |||||
| </div> | </div> | ||||
| </script> | </script> | ||||
| <a href="http://eepurl.com/gJm095" target="_blank">Subscribe to my channel</a> for news about my nodes. | <a href="http://eepurl.com/gJm095" target="_blank">Subscribe to my channel</a> for news about my nodes. | ||||
| </p> | </p> | ||||
| <p>The meaning of this node is to interrupt/reactivate flow messages.<br/> | <p>The meaning of this node is to interrupt/reactivate flow messages.<br/> | ||||
| <p>The node will stop output messages, if it receives a payload = false from the specified topic.<br/> | |||||
| The node will resume output messages, if it receives a payload = true from the specified topic.<br/> | |||||
| Normally, passes the input messages to the output. If you send a payload with a specific topic (you can set it on the node properties), the node stops sending output messages.<br/> | |||||
| It can also save the last message received and play later. This is useful if you wish to restore previous state to, for example, a light actuator.<br/> | |||||
| Please see the <a href="https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate" target="_blank">README</a> on github for examples. | |||||
| </p> | |||||
| <p> | |||||
| The node will stop output messages, if it receives a payload = false <b>from the specified topic</b>.<br/> | |||||
| The node will resume output messages, if it receives a payload = true <b>from the specified topic</b>.<br/> | |||||
| Other that that, as soon as you send payload = false <b>from the specified topic</b>, the node stores the last received payload internally | |||||
| The node will output the current stored message plus an added property <b>isReplay</b> = true, if it receives a <b>play</b> = true from the specified topic.<br/> | |||||
| </p> | </p> | ||||
| <a href="https://www.paypal.me/techtoday" target="_blank"><img src='https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square' width='30%'></a> | <a href="https://www.paypal.me/techtoday" target="_blank"><img src='https://img.shields.io/badge/Donate-PayPal-blue.svg?style=flat-square' width='30%'></a> | ||||
| module.exports = function(RED) { | |||||
| function InterruptFlowUltimate(config) { | |||||
| RED.nodes.createNode(this,config); | |||||
| module.exports = function (RED) { | |||||
| function InterruptFlowUltimate(config) { | |||||
| RED.nodes.createNode(this, config); | |||||
| this.config = config; | this.config = config; | ||||
| var node = this; | var node = this; | ||||
| setNodeStatus({ fill: "green", shape: "ring", text: "-> pass" }); | |||||
| node.bInviaMessaggio = true; // Send the message or not | |||||
| setNodeStatus({ fill: "green", shape: "ring", text: "-> pass" }); | |||||
| node.bInviaMessaggio = true; // Send the message or not | |||||
| node.currentMsg = {}; // Stores current payload | |||||
| node.sTriggerTopic = node.config.triggertopic.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '') || "trigger"; // Topic controlling the bInviaMessaggio | |||||
| this.on('input', function (msg) { | this.on('input', function (msg) { | ||||
| var sTriggerTopic = node.config.triggertopic.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '') || "trigger"; // Topic controlling the bInviaMessaggio | |||||
| var sIncomingTopic = ""; | var sIncomingTopic = ""; | ||||
| if (msg.hasOwnProperty("topic")) { | if (msg.hasOwnProperty("topic")) { | ||||
| // 06/11/2019 | // 06/11/2019 | ||||
| sIncomingTopic = msg.topic.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ''); // Cut unwanted Characters | sIncomingTopic = msg.topic.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ''); // Cut unwanted Characters | ||||
| if (sIncomingTopic == sTriggerTopic && ToBoolean(msg.payload) === true) { | |||||
| node.bInviaMessaggio = true; | |||||
| setNodeStatus({ fill: "green", shape: "dot", text: "-> pass" }); | |||||
| return; | |||||
| } else if (sIncomingTopic==sTriggerTopic && ToBoolean(msg.payload)===false){ | |||||
| node.bInviaMessaggio = false; | |||||
| setNodeStatus({ fill: "red", shape: "dot", text: "|| stop" }); | |||||
| return; | |||||
| } | |||||
| } | |||||
| if (node.bInviaMessaggio) node.send(msg); | |||||
| }); | |||||
| function setNodeStatus({fill, shape, text}) | |||||
| { | |||||
| if (sIncomingTopic == node.sTriggerTopic) { | |||||
| if (msg.hasOwnProperty("play")) { | |||||
| node.currentMsg.isReplay = true; | |||||
| setNodeStatus({ fill: "yellow", shape: "dot", text: "-> replay" }); | |||||
| // Restore previous status | |||||
| setTimeout(() => { | |||||
| if (node.bInviaMessaggio) { | |||||
| setNodeStatus({ fill: "green", shape: "dot", text: "-> pass" }); | |||||
| } else { | |||||
| setNodeStatus({ fill: "red", shape: "dot", text: "|| stop (stored last msg)" }); | |||||
| } | |||||
| }, 1000) | |||||
| node.send(node.currentMsg); | |||||
| return; | |||||
| } else if (ToBoolean(msg.payload) === true) { | |||||
| node.bInviaMessaggio = true; | |||||
| setNodeStatus({ fill: "green", shape: "dot", text: "-> pass" }); | |||||
| return; | |||||
| } else if (ToBoolean(msg.payload) === false) { | |||||
| node.bInviaMessaggio = false; | |||||
| setNodeStatus({ fill: "red", shape: "dot", text: "|| stop (stored last msg)" }); | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (node.bInviaMessaggio) { | |||||
| node.currentMsg = msg; | |||||
| node.send(msg); | |||||
| } | |||||
| }); | |||||
| function setNodeStatus({ fill, shape, text }) { | |||||
| var dDate = new Date(); | var dDate = new Date(); | ||||
| node.status({fill: fill,shape: shape,text: text + " (" + dDate.getDate() + ", " + dDate.toLocaleTimeString() + ")"}) | |||||
| node.status({ fill: fill, shape: shape, text: text + " (" + dDate.getDate() + ", " + dDate.toLocaleTimeString() + ")" }) | |||||
| } | } | ||||
| function ToBoolean( value ) { | |||||
| function ToBoolean(value) { | |||||
| var res = false; | var res = false; | ||||
| if (typeof value === 'boolean') { | if (typeof value === 'boolean') { | ||||
| res = value; | res = value; | ||||
| } | |||||
| else if( typeof value === 'number' || typeof value === 'string' ) { | |||||
| } | |||||
| else if (typeof value === 'number' || typeof value === 'string') { | |||||
| // Is it formated as a decimal number? | // Is it formated as a decimal number? | ||||
| if( decimal.test( value ) ) { | |||||
| var v = parseFloat( value ); | |||||
| if (decimal.test(value)) { | |||||
| var v = parseFloat(value); | |||||
| res = v != 0; | res = v != 0; | ||||
| } | } | ||||
| else { | else { | ||||
| res = value.toLowerCase() === "true"; | res = value.toLowerCase() === "true"; | ||||
| } | } | ||||
| } | } | ||||
| return res; | return res; | ||||
| }; | }; | ||||
| } | |||||
| } | |||||
| RED.nodes.registerType("InterruptFlowUltimate",InterruptFlowUltimate); | |||||
| RED.nodes.registerType("InterruptFlowUltimate", InterruptFlowUltimate); | |||||
| } | } |
| { | { | ||||
| "name": "node-red-contrib-boolean-logic-ultimate", | "name": "node-red-contrib-boolean-logic-ultimate", | ||||
| "version": "1.0.16", | |||||
| "description": "A set of Node-RED enhanced boolean logic, with persisten values after reboot and more", | |||||
| "version": "1.0.17", | |||||
| "description": "A set of Node-RED enhanced boolean logic node, flow interruption node, blinker node, invert node, filter node, with persisten values after reboot and more.", | |||||
| "author": "Supergiovane (https://github.com/Supergiovane)", | "author": "Supergiovane (https://github.com/Supergiovane)", | ||||
| "dependencies": { | "dependencies": { | ||||
| "fs": "0.0.1-security" | "fs": "0.0.1-security" |