Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Node-RED

A Visual Tool for Wiring the Internet of Things

ben hardill • @hardillb

the Internet of Things

the Internet of Things

internet

gpio

usb devices

light-weight, edge of network, application builder

easy to use, drag and drop interface

allows the developer to focus on the task at hand

no more shaving

*pssst - do the first demo

{
"payload": "Hello World!"
"topic": "foo"
  ...
  ...
}

A long time ago in a galaxy far,
far away....

Inject node

Allows manual triggering of flows

Can be scheduled to automatically inject at fixed intervals

Debug node

Shows message content, either just payload or entire object in the debug sidebar

Function node

Runs user-defined js against the messages flowing past

Template node

Renders messages into a {{mustache}} template

TCP/UDP nodes

Connects out, or listens for incoming connections

HTTP nodes

Define http endpoints for incoming requests, or trigger gets of urls in the middle of a flow

MQTT Nodes

Publish and Subscribe nodes

Hardware nodes

Serial devices.

Raspberry Pi / BeagleBone Black GPIO pins

Storage nodes

MongoDB, Redis, local files

Social nodes

Twitter, irc, email, xmpp

Function Node

Uses vm.createScript under the covers to sandbox execution

console, util, Buffer included for convenience, but easy to add anything via settings

Function Node

Returning messages

 return msg;
 return [msg1, msg2, msg3];
 return [msg1, [msgA, msgB] ];

Function Context

Each function node has its own context object to save state between calls.

  context.count = (context.count||0);
  context.count += 1;
  var countMessage = { payload: context.count };
  return [msg, countMessage];

Function Global Context

in settings.js

  ...
  functionGlobalContext: {
      arDrone: require('ar-drone')
  }
  ...

then...

the first steps towards Node-RED-copter

  context.client = context.client||context.global.arDrone.createClient();
    
  if (msg.payload == "takeoff") {
      context.client.takeoff();
  } else if (msg.payload == "land") {
      context.client.land();
  }

Easy to wrap any npm module into a palette node*

* once we get the API documented

Each node defined in a pair of files:

.js : server-side behaviour
.html : appearance in editor & help

For example, sentiment*:

var sentiment = require('sentiment');
sentiment('Cats are stupid.',
    function (err, result) {
        console.dir(result); // Score: -2
    }
);

sentiment('Cats are totally amazing!',
    function (err, result) {
        console.dir(result); // Score: 4
    }
);
* https://github.com/thisandagain/sentiment
var RED = require("../../red/red");
var sentiment = require('sentiment');

function SentimentNode(n) {
    RED.nodes.createNode(this,n);

    this.on("input", function(msg) {
            var node = this;
            sentiment(msg.payload, function (err, result) {
                msg.sentiment = result;
                node.send(msg);
            });
    });
}

RED.nodes.registerType("sentiment",SentimentNode);

72-sentiment.js

<script type="text/javascript">
   RED.nodes.registerType('sentiment',{
       category: 'analysis-function',
       color:"#E6E0F8",
       defaults: {
           name: {value:""},
       },
       inputs:1,
       outputs:1,
       icon: "arrow-in.png",
       label: function() {
           return this.name||"sentiment";
       },
       labelStyle: function() {
           return this.name?"node_label_italic":"";
       }
   });
</script>
<script type="text/x-red" data-template-name="sentiment">
  <div class="form-row">
     <label for="node-input-name"> Name </label>
     <input type="text" id="node-input-name">
  </div>
</script>

72-sentiment.html

*pssst - do the next demo

-

       ...
       defaults: {
            server: {value:"server",required:true},
            port: {
                value:"",
                required: true,
                validate: RED.validators.number()
            },
            host: {
                value:"",
                validate: function(v) {
                    return (this.server == "server")||v.length > 0;
                }
            }
       }
       ...
       ...
       oneditprepare: function() {
          // called when the edit dialog is being built
       },
       oneditsave: function() {
          // called when the edit dialog has been closed (not cancelled)
      }
      ...

step 1 : add Eclipse Orion build files

<link rel="stylesheet" type="text/css" href="built-editor.css"/>
<script src="built-editor.min.js"></script>

step 2 : initialise the editor when editing function node

oneditprepare: function() {
   ...
    require(["orion/editor/edit"], function(edit) {
        edit({
            parent:document.getElementById('node-input-func-editor'),
            lang:"js",
            contents: $("#node-input-func").val()
        });
   ...
}

"My God, it's full of JSON"

[{"id": "3e4aa4b4.c1b55c", "type": "inject", "name": "", "topic": "", "payload": "Hello devWorks Days 2013", "repeat": "", "crontab": "", "once": false, "x": 98, "y": 174, "wires": [["b347e57e.4cb818"]]},  {"id": "b347e57e.4cb818", "type": "debug", "name": "", "active": true, "complete": false, "x": 358, "y": 211, "wires": []}]

What's next?

Go get it: http://nodered.org

Just added to npm - work in progress

 $ npm install node-red
 $ npm start node-red
 $ open http://localhost:1880

Online sharing of functions and flows - gist based

Allow individual nodes to be npm-installable

More Documentation (of course)

Questions?