emonPi, NodeRed and MQTT

Using the emonPi in it's default configuration works great to post data to Emoncms for logging and visualisation. However there may be times when you want some more flexibility and or ability to interface with other hardware.

Using a tool called Node-Red the emonPi can become a central hub for home automation, control and notification. Node-RED is a tool for wiring together hardware devices, APIs and online services in new and interesting ways. At the heart of Node-RED is a visual editor allowing complex data flows to be wired together with only a little coding skills.  Here are some of my ideas of things I might like to achieve with Node-RED, For more inspiration check out Martin's IoT Google hangout 29min in:


Install Node-RED on emonPi / emonHub / Raspberry Pi 

Make emonPi file-system RW:
$ rpi-rw

Install Node-RED (taken from node-RED RaspberryPi install guide):
$ curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash - 
$ sudo apt-get install -y build-essential python-dev python-rpi.gpio nodejs
$ sudo npm install -g --unsafe-perm node-red

Open up port 1880 so we can access Node-RED editor:
$ sudo iptables -A INPUT -p tcp -m tcp --dport 1880 -j ACCEPT

Open up port 1883 so we can access MQTT server:
$ sudo iptables -A INPUT -p tcp -m tcp --dport 1883 -j ACCEPT

Make iptables rules persistent
$ apt-get install iptables-persistent

Choose yes to save rules, if needed edit the persistent rules:
$ sudo nano /etc/iptables/rules.v4


Start Node-RED with:
$ node-red-pi --max-old-space-size=128

To view the node-RED graphical editor browse to:
http://emonpi:1880/ (or use IP address if this does not work)

To use Node-RED as a permanent setup you will want to set it up as a service to autostart at boot and enable secure authentication access to node-RED editor.

When you are done don't forget to put the emonPi back to read-only mode to preserve SD card lifespan:
$ rpi-ro

Getting data from the emonPi into Node-RED

There are two options to get our energy data into Node-RED:

1. Real-time data from emonHub using MQTT (see example below):

MQTT is a lightweight communication protocol for small web-connected devices. The latest version of emonHub as setup on the emonPi (and emonHub from July 15) uses MQTT as a link to Emoncms and also to provide data to the emonPi LCD script. Since MQTT is already running all we need to do is to point Node-RED MQTT input block to subscribe to the 'emonhub/rx/#' MQTT topic on port 1883. The '#' topic includes data received from all nodes. To subscribe to just one node use e.g. emonPi use: 'emonhub/5/values' or 'emonhub/10/values' for emonTx.

To subscribe the the emonPi's MQTT topics externally (if your running node-RED on another machine) you will need to open up the MQTT port on the emonPi:

$ sudo iptables -A INPUT -p tcp -m tcp --dport 1883 -j ACCEPT

2. Historic data from Emoncms using HTTP API: 

To pull historic data already logged to Emoncms (e.g KWh data) into Node-RED we can use Emoncms's API. Here is a simple example to pull in the latest value from the KWh feed, just enter your RW API key and feed ID:

http://emoncms.org/feed/value.json&apikey=APIKEY&id=FEED_ID

To view all Emoncms API see: http://emoncms.org/input/api

Node-RED example: send warning email when emonTH battery is low


Simple but useful example, use Node-RED connecting to emonPi in real-time data via MQTT (localhost) and sending email (via Gmail SMTP) if emonTH battery drops below 1.7V. Also in this flow as an example is a node to decode emonPi power data.


Here is the contents of each node: 
MQTT Node subscribing to emonhub mqtt topic on localhost (running node-RED on emonPi)
Separate node to split the MQTT data up into nodes based on ID: e.g emonTx = 10, emonPi = 5, emonTH = 19
CSV node to split up MQTT CSV string
If function node
email node, enter your Gmail (or otherwise) SMTP login

Node-RED flow export, import by copy and pasting into import>clipboard in Node-RED editor:

[{"id":"eb57a13e.14a86","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"44c7eefa.bb381","type":"mqtt in","name":"MQTT: emonhub/rx/#","topic":"emonhub/rx/#","broker":"eb57a13e.14a86","x":159,"y":386,"z":"fa6ca080.05936","wires":[["2c7fcc53.d38034","eb7e04d9.1481f8"]]},{"id":"2c7fcc53.d38034","type":"debug","name":"RAW MQTT output: emonhub/rx/#","active":false,"console":"false","complete":"topic","x":242,"y":461,"z":"fa6ca080.05936","wires":[]},{"id":"eb7e04d9.1481f8","type":"switch","name":"Seperate Nodes","property":"topic","rules":[{"t":"cont","v":"5"},{"t":"cont","v":"19"},{"t":"cont","v":"20"}],"checkall":"true","outputs":3,"x":343,"y":317,"z":"fa6ca080.05936","wires":[["b0618044.4f9e8"],["9077dea0.6f882"],[]]},{"id":"9077dea0.6f882","type":"csv","name":"emonTH 1: emonhub/19/values > Decode MQTT CSV","sep":",","hdrin":"","hdrout":"","multi":"one","ret":"\\n","temp":"temp,temp_external,humidity,battery,pulsecount","x":664,"y":373,"z":"fa6ca080.05936","wires":[["75ee731f.8a118c"]]},{"id":"b0618044.4f9e8","type":"csv","name":"emonPi: emonhub/5/values > Decode MQTT CSV","sep":",","hdrin":"","hdrout":"","multi":"one","ret":"\\n","temp":"power1,power2,power1_plus_2,Vrms,temp1,temp2,temp3,temp4,temp5,temp6,pulseCount","x":647,"y":236,"z":"fa6ca080.05936","wires":[["cda897fa.325768"]]},{"id":"cda897fa.325768","type":"debug","name":"Debug: emonPi Power1 output","active":false,"console":"false","complete":"payload.power1","x":1015,"y":235,"z":"fa6ca080.05936","wires":[]},{"id":"75ee731f.8a118c","type":"function","name":"If emonTH battery < 1.7V","func":"if (msg.payload.battery < 1.7) {\n   return {payload:'WARNING: emonTH battery low  '+msg.payload.battery+'V'  };\n}","outputs":1,"noerr":0,"x":1015,"y":363,"z":"fa6ca080.05936","wires":[["f8d8fd72.0727"]]},{"id":"f8d8fd72.0727","type":"delay","name":"Limit 1 email per day","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","rateUnits":"day","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":948,"y":447,"z":"fa6ca080.05936","wires":[["1d4154b2.e2beab"]]},{"id":"1d4154b2.e2beab","type":"e-mail","server":"smtp.gmail.com","port":"465","name":"","dname":"Send warning email","x":1198,"y":439,"z":"fa6ca080.05936","wires":[]}] To engage in discussion regarding this post, please post on our Community Forum.