Overview Node-RED is a highly graphical programming environment however there are some things which cannot be done using the out-of-the-box nodes. Using the Function Node is one way to get around this but if you want to make that re-usable then it is a good idea to turn that function into a Node in its own right. You can then re-use that Node from the palette or even make that Node available for others to use. Note that you cannot define new Nodes directly on the Watson IoT Platform so instead in this lab you will install a local copy of Node-RED, define a new Node and then re-use it in the IoT Platform. Task 1. Install Node-RED In this task you will install a local copy of Node-RED. 1. Download Node-RED: a. Download the appropriate Node-RED support package from here: http://nodered.org/docs/getting-started/installation 2. Install the support package a. Double-click the downloaded package to install it 3. Upgrade the package manager: a. On Mac, open a terminal and type: sudo npm install -g npm@2.x b. On Windows, open a command line and type: npm install -g npm@2.x 4. Install Node-RED a. On Mac, in the terminal type sudo npm install -g --unsafe-perm node-red b. On Windows, in the command line window type npm install -g --unsafe-perm node-red 5. Run Node-RED: a. In the terminal window / command line window, type node-red Copyright IBM Corp. 2017
b. Open a web browser and navigate to http://localhost:1880: Task 2. Define a New To Lower Case Node In this task you will define a new Node. Nodes consist of a pair of files: a JavaScript (.js) file that defines what the Node does, and a HTML file that defines the properties, edit dialog and help text for the Node. These files are usually stored in the Node-RED user directory (node-red/nodes) but they can be located in any folder so long as that folder is added to the nodesdir setting. Note that (a) the.node-red folder may Defining New Node-RED Nodes - 2 Copyright IBM Corp. 2017
be hidden and (b) you will need to create the nodes sub-folder 1. Write and test the function: a. Before wrapping your function as a node it is best to make sure it works by creating a regular Function node in a node red flow. Take this simple example which takes the input and turns it into lower case on the output: msg.payload = msg.payload.tolowercase(); node.send(msg); b. Use the function in a flow and confirm its operation: 2. Wrap the function code: a. Now your function may be wrapped in the necessary java script to turn it into a node b. Create a text file tolowercase.js c. Add the node module skeleton code: module.exports = function(red) { function LowerCaseNode(config) { RED.nodes.createNode(this,config); RED.nodes.registerType("lower-case",LowerCaseNode); The node is wrapped inside a node module. When the Node.js runtime loads the node on startup it calls a function exported by the module (in this case function(red)). The RED argument provides the module access to the Node-RED runtime api. The Node itself is defined by a function (LowerCaseNode) this function is called whenever a new instance of the node is created. The config argument contains all of the properties the user entered in the node-editor when the node was added to the flow. RED.nodes.createNode initializes the features shared by all nodes. Any node-specific code will be inserted after that call. Copyright IBM Corp. 2017 Defining New Node-RED Nodes - 3
Lastly the node function (LowerCaseNode) is registered with the runtime using the name for the node (lower-case) d. Add node-specific code: module.exports = function(red) { function LowerCaseNode(config) { RED.nodes.createNode(this,config); var node = this; this.on('input', function(msg) { msg.payload = msg.payload.tolowercase(); node.send(msg); ); RED.nodes.registerType("lower-case",LowerCaseNode); The node-specific code in this case registers a listener to the input event which gets called whenever a message arrives at the node. 3. Create the HTML file a. Examine the HTML file included with this workbook. Note that there are three sections: b. The Edit Template: c. The Main Node Definition: Defining New Node-RED Nodes - 4 Copyright IBM Corp. 2017
d. The Help Text: 4. Deploy and test: a. Locate your.node-red folder On Mac use Finder and the menu Go > Goto Folder: /Users/yourUserName/.node-red b. Create a nodes subfolder c. Paste in the html and.js files: Copyright IBM Corp. 2017 Defining New Node-RED Nodes - 5
d. Shutdown and restart Node-Red e. Your new node should now be available on the palette: Task 3. Define a New Threshold Node In this task you will examine a second example. Imagine a flow where you are measuring temperature and when the temperature rises above a specific threshold you want to generate an alert but only when the threshold is crossed (not every time a temperature comes in that is too high). You will start by importing the Watson IoT Node so that you can receive messages from the IoT Quickstart Simulated Sensor. You will then create a regular function node that reports when the threshold has been crossed and then finally turn it into a re-usable node definition and publish it. 1. Import Watson-IOT: a. Shutdown Node-RED b. In a terminal/command line, change the working directory to your Node-RED user directory (/.node-red) c. Type: npm install node-red-contrib-scx-ibmiotapp d. If the installation was successful, you will see an extra node module in your file system: Defining New Node-RED Nodes - 6 Copyright IBM Corp. 2017
e. Restart Node-RED 2. Create a flow: a. Create a simple flow that takes the input for the IOT Quickstart Sensor (http://bit.ly/iot_sensor) and displays it: b. Add a change node and add a checkvalue attribute to the payload Here you are setting that value to the temperature from the quickstart sensor - using an attribute like this makes the node more flexible 3. Create the threshold function and insert it such that the payload is only passed on when the threshold is crossed: Copyright IBM Corp. 2017 Defining New Node-RED Nodes - 7
if (msg.payload.checkvalue > 10) { if (context.get('status')!='alert') { context.set('status','alert'); node.send(msg); else context.set('status','ok'); 4. Test the flow using the simulated sensor and confirm that the temperature is only displayed when the threshold is crossed 5. Create the javascript file: module.exports = function(red) { function ThresholdNode(config) { RED.nodes.createNode(this,config); var node = this; this.on('input', function(msg) { var context = this.context(); var t = config.thresholdvalue; if (msg.payload.checkvalue > t) { Defining New Node-RED Nodes - 8 Copyright IBM Corp. 2017
if (context.get('status')!='alert') { context.set('status','alert'); node.send(msg); else context.set('status','ok'); ); RED.nodes.registerType("threshold",ThresholdNode); Note that the previous fixed value of 10 has been replaced with the thresholdvalue this is an attribute of the node that you will define in the html file 6. Create the HTML file: <script type="text/javascript"> RED.nodes.registerType('threshold',{ category: 'function', color: '#a6bbcf', defaults: { name: {value:"", thresholdvalue: {value:"10",required:true, inputs:1, outputs:1, icon: "alert.png", label: function() { return this.name "threshold"; ); </script> <script type="text/x-red" data-template-name="threshold"> <div class="form-row"> </div> <label for="node-input-name"><i class="icon-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="name"> <div class="form-row"> Copyright IBM Corp. 2017 Defining New Node-RED Nodes - 9
<label for="node-input-thresholdvalue"><i class="icon-tag"></i> Threshold</label> </div> <input type="text" id="node-input-thresholdvalue" placeholder="threshold"> </script> <script type="text/x-red" data-help-name="threshold"> <p>a node that only passes a message when a specific threshold has been crossed</p> </script> 7. Restart Node-RED: a. Copy the files into the nodes folder b. Restart Node-RED c. Your new node should now appear on the palette and work just like the previous function node: Task 4. Package the Node for Re-Use and Publish In order to make the node available to other node-red installations such as the one in IoT Platform the node must be packaged as a module and published to the npm repository. The package may be created and tested locally before actually publishing it for wider re-use. In this task you will create the package and test it on your local installation. In this simple example all of the files required will be placed in the same directory see the Node-RED documentation for alternative directory structures (http://nodered.org/docs/creating-nodes/packaging) 1. Move the files: a. In your nodes folder, create a sub-folder for the package (Threshold) b. Create a sub-folder inside the Threshold folder (Nodes) to hold the node definitions and move the two threshold files into it: Defining New Node-RED Nodes - 10 Copyright IBM Corp. 2017
2. Create the JSON file: a. Create a new text file in the Threshold package folder - package.json: { "name" : "iotbcal0505-threshold", "version" : "0.0.1", "description" : "A sample node created in the IoT Bootcamp", "dependencies": {, "node-red" : { "nodes": { "threshold": "nodes/threshold.js" The name should be prefixed node-red-contrib- to indicate that the node is not a Node-RED maintained one. Alternatively, you may use any name that does not have a node-red prefix. In this sample we have used our own prefix of iotbc along with your initials and month/day of birth In this sample we have deliberately omitted an entry for node-red keywords that make it searchable this keyword should only be added once you are happy that the package has been sufficiently tested and documented. 3. Add a readme a. Add another text file README.md This file should describe what the node does and any pre-requisites. You may also include additional information such as a sample node to demonstrate its use. The file should be marked up using GitHub flavored markdown: https://help.github.com/articles/basic-writing-and-formatting-syntax/ 4. Test the package locally: Copyright IBM Corp. 2017 Defining New Node-RED Nodes - 11
a. In the command line/terminal window change the working directory to the folder containing the package.json file b. Type: sudo npm link c. In the command line/terminal window change the working directory to the Node-RED home folder (usually /.node-red) d. Type: npm link <name of node module> Remember the name of your module is your equivalent of iotbcal0505-threshold 5. Add a user account: a. In a command line/terminal window, type npm adduser b. Follow the prompts to create a new user in the npm repository 6. Publish the package: a. Change the working directory to the Threshold package folder b. Type npm publish 7. Add the new node to Bluemix a. Edit the package.json file for an existing node-red instance on Bluemix to import your new node: b. Redeploy the application and open Node-RED: Defining New Node-RED Nodes - 12 Copyright IBM Corp. 2017
If you intend to publish the node for others to use then review the notes here: https://docs.npmjs.com/misc/developers (also remember to name the node node-red-contrib-xxxx) Adding node-red in the keywords property will make the node visible to searches: Copyright IBM Corp. 2017 Defining New Node-RED Nodes - 13