Tag Archives: node-red

Auto Launch Webpages full screen on Android

While waiting for Amazon to get round to reviewing my Node-RED Alexa Smart Home Skill I’ve needed something to hack on.

I’ve been keeping an eye on what folk have been doing with Node-RED Dashboard and a common use case keeps coming up. That is running the UI on a Android tablet mounted on a wall as a way to keep track of and control things around the house. This got me thinking about how to set something like this up.


For the best results you really want to run this totally full screen, there are ways to get this to happen with Chrome, but it’s a bit convoluted. Sure you can add it as a shortcut on the home screen but I thought there had to be a easier/better way.

So I started to have a bit of a play and came up with a new app. It’s basically just a full screen Activity with a WebView, with a few of extra features.

  • Set URL – Pick a URL to load when the phone boots, or the app is launched.
  • Launch on boot – The app can be configured to start up as soon as the phone finishes booting.
  • Take Screen Lock – This prevents the screen from powering off or locking so the page is always visible.

You can change the URL by swiping from the left hand edge of the screen, this will cause the action bar to appear, from this you can select “Settings”.

Set URL to Load
Set URL to Load

The app is in the Google Play store here, the code is on Github here

Alexa Home Skill for Node-RED

Following on from my last post this time I’m looking at how to implement Alexa Home Skills for use with Node-RED.

Home Skills provide ON/OFF, Temperature, Percentage control for devices which should map to most home automation tasks.

To implement a Home Skill there are several parts that need to created.

Skill Endpoint

Unlike normal skills which can be implemented as either HTTP or Lambda endpoints, Home Skills can only be implemented as a Lambda function. The Lambda function can be written in one of three languages, Javascript, Python and Java. I’ve chosen to implement mine in Javascript.

For Home Skills the request is passed in a JSON object and can be one of three types of message:

  • Discovery
  • Control
  • System


These messages are triggered when you say “Alexa, discover devices”. The reply this message is when the skill has the chance to tell the Echo what devices are available to control and what sort of actions they support. Each device section includes it’s name and a description to be shown in the Alexa phone/tablet application.

The full list of supported actions:

  • setTargetTemperature
  • incrementTargetTemperature
  • decrementTargetTemperature
  • setPercentage
  • incrementPercentage
  • decrementPercentage
  • turnOff
  • turnOn


These are the actual control messages, triggered by something like “Alexa, set the bedroom lights to 20%”. It contains one of the actions listed earlier and the on/off or value of the change.


This is the Echo system checking that the skill is all healthy.

Linking Accounts

In order for the skill to know who’s echo is connecting we have to arrange a way to link an Echo to an account in the Skill. To do this we have to implement a oAuth 2.0 system. There is a nice tutorial on using passport to provide oAuth 2.0 services here, I used this to add the required HTTP endpoints needed.

Since there is a need to set up oAuth and to create accounts in order to authorise the oAuth requests this means that is makes sense to only do this once and to run it as a shared service for everybody (just got to work out where to host it and how to pay for it).

A Link to the Device

For this the device is actually Node-RED which is probably going to be running on people’s home network. This means something that can connect out to the Skill is probably best to allow or traversing NAT routers. This sounds like a good usecase for MQTT (come on, you knew it was coming). Rather than just use the built in MQTT nodes we have a custom set of nodes that make use of some of the earlier sections.

Firstly a config node that uses the same authentication details as account linking system to create oAuth token to be used to publish device details to the database and to authenticate with the MQTT broker.

Secondly a input node that pairs with the config node. In the input node settings a device is defined and the actions it can handle are listed.

Hooking it all together

At this point the end to end flow looks something like this:

Alexa -> Lambda -> HTTP to Web app -> MQTT to broker -> MQTT to Node-RED

At this point I’ve left the HTTP app in the middle, but I’m looking at adding direct database access to the Lambda function so it can publish control messages directly via MQTT.

Enough talk, how do I get hold of it!

I’m beta testing it with a small group at the moment, but I’ll be opening it up to everybody in a few days. In the mean time the code is all on github, the web side of all of this can be found here, the Lambda function is here and the Node-RED node is here, I’ll put it on npm as soon as the skill is public.

Alexa Skills with Node-RED

I had a Amazon Echo Dot delivered on release day. I was looking forward to having a voice powered butler around the flat.

Amazon advertise WeMo support, but unfortunately they only support WeMo Sockets and I have a bunch of WeMo bulbs that I’d love to get to work

Alexa supports 2 sorts of skills:

  • Normal Skills
  • Home Skills

Normal Skills are triggered by a key word prefixed by either “Tell” or “Ask”. These are meant for information retrieval type services, e.g. you can say “Alexa, ask Network Rail what time the next train to London leaves Southampton Central”, which would retrieve train time table information. Implementing these sort of skills can be as easy as writing a simple REST HTTP endpoint that can handle the JSON format used by Alexa. You can also use AWS Lambda as an endpoint.

Home Skills are a little trickier, these only support Lambda as the endpoint. This is not so bad as you can write Lambda functions in a bunch of languages like Java, Python and JavaScript. As well as the Lambda function you also need to implement a website to link some sort of account for each user to their Echo device and as part of this you need to implement OAuth2.0 authentication and authorisation which can be a lot more challenging.

First Skill

The first step to create a skill is to define it in the Amazon Developer Console. Pick the Alexa tab and then the Alexa Skill Kit.

Defining a new Alexa Skill
Defining a new Alexa Skill

I called my skill Jarvis and set the keyword that will trigger this skill also to Jarvis.

On the next tab you define the interaction model for your skill. This is where the language processing gets defined. You outline the entities (Slots in Alexa parlance) that the skill will interact with and also the sentence structure to match for each Intent. The Intents are defined in a simple JSON format e.g.

  "intents": [
      "intent": "TVInput",
      "slots": [
          "name": "room",
          "type": "LIST_OF_ROOMS"
          "name": "input",
          "type": "LIST_OF_INPUTS"
      "intent": "Lights",
      "slots": [
          "name": "room",
          "type": "LIST_OF_ROOMS"
          "name": "command",
          "type": "LIST_OF_COMMANDS"
          "name": "level",
          "type": "AMAZON.NUMBER"

Slots can be custom types that you define on the same page or can make use of some built in types like AMAZON.NUMBER.

Finally on this page you supply the sample sentences prefixed with the Intent name and with the Slots marked.

TVInput set {room} TV to {input}
TVInput use {input} on the {room} TV
TVInput {input} in the {room}
Lights turn {room} lights {command}
Lights {command} {room} lights {level} percent

The next page is used to setup the endpoint that will actually implement this skill. As a first pass I decided to implement a HTTP endpoint as it should be relatively simple for Node-RED. There is a contrib package called node-red-contrib-alexa that supplies a collection of nodes to act as HTTP endpoints for Alexa skills. Unfortunately is has a really small bug that stops it working on Bluemix so I couldn’t use straight away. I’ve submitted a pull request that should fix things, so hopefully I’ll be able to give it a go soon.

The reason I want to run this on Bluemix is because endpoints need to have a SSL certificate and Bluemix has a wild card certificate for everything deployed on the .mybluemix.net domain which makes things a lot easier. (Update: When configuring the SSL section of the skill in the Amazon Developer Console, pick “My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority” when using Bluemix)

Alexa Skill Flow
Alexa Skill Flow

The key parts of the flow are:

  • The HTTP-IN & HTTP-Response nodes to handle the HTTP Post from Alexa
  • The first switch node filters the type of request, sending IntentRequests for processing and rejecting other sorts
  • The second switch picks which of the 2 Intents defined earlier (TV or Lights)

      "type": "IntentRequest",
      "requestId": "amzn1.echo-api.request.4ebea9aa-3730-4c28-9076-99c7c1555d26",
      "timestamp": "2016-10-24T19:25:06Z",
      "locale": "en-GB",
      "intent": { 
        "name": "TVInput", 
        "slots": { 
          "input": { 
            "name": "input",
            "value": "chromecast"
          "room": {
            "name": "room",
            "value": "bedroom"
  • The Lights Function node parses out the relevant slots to get the command and device to control
  • The commands are output to a MQTT out node which published to a shared password secured broker where they are picked up by a second instance of Node-RED running on my home network and sent to the correct WeMo node to carry out the action
  • The final function node formats a response for Alexa to say (“OK”) when the Intent has been carried out

    rep = {};
    rep.version  = '1.0';
    rep.sessionAttributes = {};
    rep.response = {
        outputSpeech: {
            type: "PlainText",
            text: "OK"
        shouldEndSession: true
    msg.payload = rep;
    msg.headers = {
        "Content-Type" :"application/json;charset=UTF-8"
    return msg;

It could do with some error handling and the TV Intent needs a similar MQTT output adding.

This works reasonably well, but having to say “Alexa, ask Jarvis to turn the bedroom light on” is a little long winded compared to just “Alexa turn on the bedroom light”, in order to use the shorter form you need to write a Home Skill.

I’ve started work on a Home Skill service and a matching Node-RED Node to go with it. When I’ve got it working I’ll post a follow up with details.

Tinkerforge Node-RED nodes

For a recent project I’ve been working on a collection of different Node-RED nodes. Part of this set is a group of nodes to interact with Tinkerforge Bricks and Bricklets.

Tinkerforge is a platform of stackable devices and sensors/actuators that can be connected to via USB or can be attached directly to the network via Ethernet or Wifi.

Tinkerforge Stack

Collections of sensors/actuators, known as bricklets, are grouped together round a Master Brick. Each Master Brick can host up to 4 sensors/actuators but multiple Master Brick’s can be stacked to add more capacity. The Master Brick also has a Micro USB socket which can be used to connect to a host machine running a deamon called brickd. The host runs a daemon that handles discovering the attached devices and exposes access to them via an API. There are also Ethernet (with and without PoE) and WiFi bricks which allow you to link the stack directly to the network.

As well as the Master Brick there is a RED Brick which contains a ARM Cortex A8 processor, SD card, USB socket and micro HDMI adapter. This runs a small Linux distribution (based on Debian) and hosts a copy of brickd.

There are bindings for the API in a number of languages including:

  • C/C++
  • C#
  • Delphi
  • Java
  • Javascript
  • PHP
  • Perl
  • Python
  • Ruby

For the Node-RED nodes I took the Javascript bindings and wrapped them as Node-RED nodes. So far the following bricklets are supported:

Adding others shouldn’t be hard, but these were the ones I had access to in order to test.

All the nodes share a config node which is configured to point to the instance of the brickd the sensors are linked and it then provides a filtered list of available bricklets for each node.

Node-RED - Google Chrome_004

The code for the nodes can be found here and is available on npmjs.org here

OwnTracks Encrypted Location Node-RED Node

OwnTracks Logo
OwnTracks Logo

At the weekend I ran the London Marathon, while I’m glad I did it, I have no desire to do it again (ask me again in 6 months).

My folks came down to watch me and to help them work out where on the course I was I ran with a phone strapped to my arm running OwnTracks. This was pointing at the semi public broker running on my machine on the end of my broadband. In order to keep some degree of privacy I had enabled the symmetric encryption facility.

As well as my family using the data I had run up a very simple logging script with the mosquitto_sub command to record my progress (I was also tracking it with my Garmin watch, but wanted to see how Owntracks did in comparison).

# mosquitto_sub -t 'owntracks/Ben/#' > track.log

Before I started I hadn’t looked at what sort of encryption was being used, but a little bit of digging in the src and a pointer in the right direction from Jan-Piet Mens got me to the libsodium library. I found a nodejs implementation on npm and hacked up a quick little script to decode the messages.

var readline = require('readline').createInterface({
  input: require('fs').createReadStream('track.json')

var sodium = require('libsodium-wrappers');

var StringDecoder = require('string_decoder').StringDecoder;
var decoder = new StringDecoder('utf8');

  var msg = JSON.parse(line);
  if (msg._type == 'encrypted') {
    var cypherText = new Buffer(msg.data, 'base64');
    var nonce = cypherText.slice(0,24);
    var key = new Buffer(32);
    var clearText = sodium.crypto_secretbox_open_easy(cypherText.slice(24),nonce,key,"text");

Now I had the method worked out it made sense to turn it into a Node-RED node so encrypted location streams could easily be consumed. I also added a little extra functionality, it copied the lat & lon values into a msg.location objects so they can easily be consumed by my node-red-node-geofence node and Dave’s worldmap node. The original decrypted location is left in the msg.payload field.

Owntracks node

The source for the node can be found on github here and the package is on npm here.

To install run the following in your ~/.node-red

npm install node-red-contrib-owntracks

New WeMo Nodes for Node-RED

Based on my previous playing with a set of Belkin WeMo sockets and lightbulbs I decided to have a go at improving support in Node-RED.

I’ve built 2 new nodes, control and event nodes.

WeMo Control Node
WeMo Control Node

The control node accepts the following values in the msg.payload

  • on/off
  • 1/0
  • true/false
  • A JSON object like this
      state: 'on'
      brightness: 255
      color: '255,0,0'
WeMo Event node
WeMo Event node

The input (event) node now uses uPNP events rather than polling status from the devices every 2 seconds. This means you won’t get the “nc” no change messages but you will get events when lights change brightness or colour as well as on/off messages.

Both nodes use a shared config node that uses uPNP discovery to locate WeMo devices on your local network so you don’t have to work out what IP address and port number they are using.

WeMo Device discovery
WeMo Device discovery

Discovery runs once a minute to ensure all devices are found and any change in IP address or port number are quickly picked up. First discovery may take a little while so please allow a little time if you don’t see all the devices you expect listed when you look in the config node.

All the code is up on github here, I’ll push them to npmjs after people have given them a bit more of a test and I’ll have a chat with the Node-RED guys about maybe swapping out the original WeMo node. There is basic backwards compatibility with the original WeMo node, but the nodes work better if after upgrading you use the configuration dialog to pick a discovered device from the list.

Update to node-red-node-ldap

I’ve updated the node-red-node-ldap node to use the ldapjs node rather than the LDAP node.

Node-RED LDAP node

The LDAP node was a NodeJS wrapper round the OpenLDAP libraries which meant there was an external native dependancy and limited the number of platforms that node could be deployed on.

The ldapjs node is all pure Javascript so should run everywhere.

Everything should be backward compatible but raise issues on github if you find problems.

Version 0.0.2 can be found on npmjs here and on github here

GPIO buttons – Demo stand

I recently got asked to help out building a demo for one of the projects the team has been working on.

The project uses situational awareness to vary the level of authentication needed to carry out different tasks. Rather than make the person using the demo run all over the place to change location or log in and out of various systems we have stubbed out the inputs and needed a way to toggle them locally. The demo runs on a tablet so we wanted something that could sit near by and allow the inputs to be varied.

To do this I thought I’d have a play with a Raspberry Pi and the GPIO pins. The plan was to attach 5 buttons to the toggle the state of the inputs, the buttons have lights that will show the state.

This would have been a perfect use case for the new Raspberry Pi Zero as it only needs 1 USB port and the GPIO pins, but I couldn’t convince any of the guys on the team lucky enough to grab one to give it up.

The chosen buttons where 5 of these:


I’d uses something very similar in the past for the MQTT Powered Video Walls in IBM Southbank Client Centre.

The first single button prototype worked nicely after I’d worked out what was needed with pull-up resistors for the buttons and current limiting resistors for the LEDs.

Button prototype

Node-RED was set up to read the state of the buttons from the GPIO pints and to update toggle the LED output the same way.

YouTube Preview Image
Node-RED flow to read buttons
Node-RED flow to read buttons

To make the demo totally standalone the rPi acts as a WiFi access point that the tablet connects to. It uses this connection to load the demo and to read the updates from the buttons via MQTT over Websockets.

The USB WiFi adapter available was a Edimax EW-7811UN, The default Linux driver for this doesn’t support HostAPD, luckily there is a page with instructions and a github project with a functional version.

Mosquitto 1.4.2 was installed to act as the the MQTT broker and to support MQTT over websockets so the web app could connect directly to get the button updates.

Having finished off the wiring and configuring the rPi the whole thing was mounted in a display board put together by Andy Feltham.

And ended up looking like this, all ready for a overlay with a description and instructions.

Completed Board

Securing Node-RED

Node-RED added some new authentication/authorisation code in the 0.10 release that allows for a plugable scheme. In this post I’m going to talk about how to use this to make Node-RED use a LDAP server to look up users.


First of all, to do this properly we will need to enable HTTPS to ensure the communication channel between the browser and Node-RED is properly protected. This is done by adding a https value to the settings.js file like this:

https: {
  key: fs.readFileSync('privkey.pem'),
  cert: fs.readFileSync('cert.pem')

You also need to un-comment the var fs = require(‘fs’); line at the top of settings.js.

You can generate the privkey.pem and cert.pem with the following commands in your node-red directory:

pi@raspberrypi ~/node-red $ openssl genrsa -out privkey.pem
Generating RSA private key, 1024 bit long modulus
e is 65537 (0x10001)
pi@raspberrypi ~/node-red $ openssl req -new -x509 -key privkey.pem -out cert.pem -days 1095
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:Hampshire
Locality Name (eg, city) []:Eastleigh
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Node-RED
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:raspberrypi.local
Email Address []:

The important bit is the Common Name value, this needs to match either the name or IP address that you will use to access your Node-RED console. In my case I have avahi enabled so I can access my pi using it’s host name raspberrypi with .local as the domain, but you may be more used to using an IP address like

Since this is a self signed certificate your browser will reject it the first time you try to connect with a warning like this:

Chrome warning about unsafe cert.
Chrome warning about unsafe cert.

This is because your certificate is not signed by one of the trusted certificate authorities, you can get past this error by clicking on Advanced then Proceed to raspberrypi.local (unsafe). With Chrome this error will be shown once every time you access the page, you can avoid this by copying the cert.pem file to your client machine and import it into Chrome:

  1. Open Chrome settings page chrome://settings
  2. Scroll to the bottom of page and click on the “+Show advanced settings” link
  3. Scroll to the HTTPS/SSL and click on “Manage certificates…”
  4. Select the Servers tab and select import
  5. Select the cert.pem you copied from your Raspberry Pi

Usernames and Passwords

In previous Node-RED releases you could set a single username and password for the admin interface, any static content or one that covered bh. This was done by adding a object to the settings.js file containing the user name and password. This was useful but could be a little limited. Since the 0.10 release there is now a pluggable authentication interface that also includes support for things like read only access to the admin interface. Details of these updates can be found here.

To implement a authentication plugin you need to create a NodeJS module based on this skeleton:

var when = require("when");

module.exports = {
   type: "credentials",
   users: function(username){
      //returns a promise that checks the authorisation for a given user
      return when.promise(function(resolve) {
         if (username == 'foo') {
            resolve({username: username, permissions: "*"});
         } else {
   authenticate: function(username, password) {
      //returns a promise that completes when the user has been authenticated
      return when.promise(function(resolve) {
         if (username == 'foo' && password == 'bar' ) {
            resolve({username: username, permissions: "*"});
         } else {
   default: function() {
      // Resolve with the user object for the default user.
      // If no default user exists, resolve with null.
      return when.promise(function(resolve) {

This comprises on 3 functions, one to authenticate a user against the backend, one to check the level of authorisation (used by Node-REDs built in oAuth mechanism once a user has been authenticated), and finally default which matches unauthenticated users.

For my LDAP example I’m not going to implement different read only/write levels of authorisation to make things a little easier.

The source for the module can be found here or on npmjs here. The easiest way to install it is with:

npm install -g node-red-contrib-ldap-auth

Then edit the Node-RED settings.js to include the following:

adminAuth: require('node-red-contrib-ldap-auth').setup({
    base: 'ou=group,o=company.com', 
    filterTemplate: 'mail={{username}}'

The filterTemplate is a mustache template to use to search the LDAP for the username, in this case the username is mail address.

Once it’s all up and running Node-RED should present you with something that looks like this:

Node-RED asking for credentials
Node-RED asking for credentials