Two guys from my team (Nick O’Leary and Dave Conway-Jones) at IBM released a very cool tool for wiring up IoT last week called Node-Red.
Node-Red lets you wire together a selection of inputs, things like MQTT messages, Twitter feeds, serial port and a whole lot more, perform transforms on them with Javascript functions before outputting them to a similar collection of options.
I’ve been playing with it to replace a couple things that used to be standalone scripts, but one of the things that was missing was the way to delay an action happening until a certain time after a message has arrived. For example if I want to set my Blink(1) clone to green when somebody mentions me in the tweet I may want to reset it to off 20 seconds later
To help with this I have written a new node called pause that delays passing on a given message by a configurable amount of time. Nodes are made up of 2 files and are placed in the node-red/nodes directory. As well as all the built in nodes there is a example node (99-sample) which you can use to
Each node is made up of 2 parts, the first is javascript file which controls how the node should behave and a html file which contains the descriptive text,
99-pause.js
... // Simple node to introduce a pause into a flow //Require main module var RED = require("../red/red"); function PauseNode(n) { RED.nodes.createNode(this,n); this.timeout = n.timeout * 1000; this.on("input", function(msg) { var node= this; setTimeout(function(){node.send(msg);}, node.timeout); }); } RED.nodes.registerType("pause",PauseNode);
You can see in the code above I’ve attached a small function to the ‘input’ event for the pause node, all it does setup a callback after the timeout expires to send the passed in message object to the next node in the flow.
99-pause.html
... <!-- First, the content of the edit dialog is defined. --> <script type="text/x-red" data-template-name="pause"> <div class="form-row"> <label for="node-input-topic"><i class="icon-tasks"></i> Pause</label> <input type="text" id="node-input-timeout" placeholder="Time"> </div> <div class="form-row"> <label for="node-input-name"><i class="icon-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> </script> <!-- Next, some simple help text is provided for the node. --> <script type="text/x-red" data-help-name="pause"> <p>Introduces a pause into a flow</p> <p>Default pause is 5 seconds but can be configured</p> </script> <!-- Finally, the node type is registered along with all of its properties --> <script type="text/javascript"> RED.nodes.registerType('pause',{ category: 'function', // the palette category color:"#E6E0F8", defaults: { // defines the editable properties of the node name: {value:""}, // along with default values. timeout: {value:"5", required:true, validate:RED.validators.number()} }, inputs:1, // set the number of inputs - only 0 or 1 outputs:1, // set the number of outputs - 0 to n icon: "arrow-in.png", // set the icon (held in public/icons) label: function() { // sets the default label contents return this.name||this.topic||"pause"; }, labelStyle: function() { // sets the class to apply to the label return this.name?"node_label_italic":""; } }); </script>
The HTML sets up configuration dialog for the node, the help text, the nodes look and behaviour and the default values for any properties the node has.
The configuration dialog for the pause node looks like this:
I’ve checked this new node into my fork of the Node-Red project here, but I’ll be submitting a pull request to get it included in the main project as soon as I get a chance to have a chat with Nick and Dave.
EDIT:
This is now a core node called delay and is also capable of rate limiting messages
One of the things that was missing was the way to delay.