This tutorial takes you through a step by step method to setup you Dash button hardware from RAK Wireless to work with Node-red Software. In this tutorial we will take our OpenHAB setup to control a bunch of appliances via the on board buttons on the RAk Dash button.
Dash button hardware:Here is a glimpse of the Dash Button from RAK wireless:
The Rak wireless Dash button consists of the following:
- 1) A RAK473 Ameba SDK based wifi module
- 2) 4 physical buttons
- 3) 4 rbg leds
The Button also provides a JTAG interface for programming, although you can program this with a RAK creator/creator pro base board (without the on-board RAK473 module)
Node Red:According to the website https://nodered.org/ :
Node-RED is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways.
It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.
Node-red is based on NodeJS and is a versatile GUI based tool to define your workflows for connecting physcial hardware to web services/software operations. It is completely browser based and provides tonnes of expandability options like creating custom nodes, importing nodes by other developers etc.
We will be looking into more on that in just a second. First lets get our base setup shall we :)
Setup your OpenHAB environment.To setup your OpenHAB environment and connecting your smart swirches(Sonoff, Belkin wemos etc) Please follow the extensive tutorial here:
https://www.hackster.io/naresh-krish/home-automation-using-wiscore-and-openhab-1ec6e4
By the end of the tutorial you will have your wifi enabled switch connected to a central server. Whats more, you can even connect the switches to alexa. Take the project for a spin and let me know your thoughts....on with the setup --->>>
Setup your node-red serverWe will install node red on the same Raspberry pi where we would have installed the OpenHAB server. Thought this is not a necessary step. You can have both of them run on completely different machines (PC or raspberry pis) just make sure that in the places that i caution about the service IP of the URL you make the necessary change to include the IP of the node-red or openhab server where appropriate:
There are two ways to get started with Node-RED on a Raspberry Pi.
- use the version preinstalled in Raspbian full image since November 2015.
- or manual install using an install script.
You can then start using the editor.
For the Raspbian pre-installed image please follow the tutorial here:
https://nodered.org/docs/hardware/raspberrypi
I'll cover the manual method below for better clarity and flexibility in setup. While installing manually, I would recommend using a more recent versions of node.js such as v8.x
The simplest way to install Node.js and other dependencies is
sudo apt-get install build-essential python-rpi.gpio
bash <(curl -sL
Accessing GPIO
If you plan to access the GPIO pins with Node-RED, you should verify which version of the Python RPi.GPIO libraries are installed.
Node-RED includes a Raspberry Pi specific script nrgpio
for interacting with the hardware GPIO pins. If you have installed as a global npm module, this script should be located at:
/usr/lib/node_modules/node-red/nodes/core/hardware/nrgpio ver
or
/usr/local/lib/node_modules/node-red/nodes/core/hardware/nrgpio ver
You must have at least 0.5.11 for the Pi2 or 0.5.8 for the original Pi. If you do not then the following commands will install the latest available:
sudo apt-get update && sudo apt-get install python-rpi.gpio
If you want to run as a user other than pi (or root), you will need either to add that user to the sudoers list - or maybe just access to python - for example by adding the following to sudoers using visudo.
NodeREDusername ALL=(ALL) NOPASSWD: /usr/bin/python
Starting Node-RED
Due to the constrained memory available on the Raspberry Pi, it is necessary to run Node-RED with the node-red-pi
command. This allows an additional argument to be provided that sets at what point Node.js will begin to free up unused memory.
When starting with the node-red-pi
script, the max-old-space-size
option should be specified:
node-red-pi --max-old-space-size=256
If you decide to run Node-RED using the node command directly, this option must appear between node and red.js.
node --max-old-space-size=256 red.js
This option limits the space it can use to 256MB before cleaning up. If you are running nothing else on your Pi you can afford to increase that figure to 512 and possibly even higher. The command free -h
will give you some clues as to how much memory is currently available.
Note: The pre-installed version of Node-RED on Raspbian that uses theAdding Autostart capability using SystemDnode-red-start
command also sets it to 256MB by default. If you do want to change that, the file you need to edit (as sudo) is/lib/systemd/system/nodered.service
The preferred way to autostart Node-RED on Pi is to use the built in systemd capability. The pre-installed version does this by using a nodered.service
file and start and stop scripts. You may install these by running the following commands
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/nodered.service -O /lib/systemd/system/nodered.service
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-start -O /usr/bin/node-red-start
sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-stop -O /usr/bin/node-red-stop
sudo chmod +x /usr/bin/node-red-st*
sudo systemctl daemon-reload
Info: These commands are run as root (sudo) - They download the three required files to their correct locations, make the two scripts executable and then reload the systemd daemon.
Node-RED can then be started and stopped by using the commands node-red-start
and node-red-stop
Once you install, point your browser (PC or device) to the ip of the raspberry and port 1880 to access the node-red UI like below:
Now that you have node-red also setup. Let dig into the Node-red IDE
Understanding Node-red operation:Node red is all about defining a flow of your actions as boxes and connecting lines. Each box or specifically a 'Node' is a block of js code that runs in the background to acheiev some putput based on some input.
Nodes ideally have one input and one output. Node can also have no input at all. Like the timer node that we will see shortly. Such nodes just generate events based on some internal operations.
In node-red a node is 'triggered' based on its input or internal operations. Once a node is triggered it can send what is called a message to the next node it connects to in its output.
Messages are nothing but javascript json objects that can be sent to other nodes as input objects for further processing. This way each node corresponds to a chain of operations that act on the original input data and return a processed data after doing operations.
Nodes:
From version 0.15 you can install nodes directly using the editor. To to this select Manage Palette
from the menu (top right), and then select the install
tab in the palette. You can now search for new nodes to install, update, and enable and disable existing nodes.
To install an npm-packaged node, you can either install it locally within your user data directory (by default, $HOME/.node-red
):
cd $HOME/.node-red
npm install <npm-package-name>
You will then need to stop and restart Node-RED for it to pick-up the new nodes.
Installing individual node filesDuring development it is also possible to install nodes by copying their .js
and .html
files into a nodes
directory within your user data directory. If these nodes have any npm dependencies, they must be also be installed within the user data directory. This is only really recommended for development purposes.
Adding the openhab2 node
OpenHAB provides a convenient node for controlling OpenHAB Items via the node-red IDE. Go to Palette and search for OpenHab2 and install it. Make sure you install the OpenHab2 version if you installed OpenHAB2 (which is the recommended version)
The node will look like this:
You would have to scroll down to the bottom of the left pane to see these nodes. Nodes are arranged alphabetically.
We will be concerned with a flow like this
DASH BUTTON pressed ----> HTTP GET REQUEST --->OPENHAB --->SWITCH OFF LIGHT 1
This part:
HTTP GET REQUEST --->OPENHAB --->SWITCH OFF LIGHT 1
Would be taken care by node-red as it defines a flow of actions, which can be explained like, "When we get an incoming HTTP GET response to node-red, access OpenHAB server and switch of a connected appliance"
The part:
DASH BUTTON pressed
Will be programmed on to the RAK Dash button. That will be covered shortly. Sooooo now lets design our workflow.
Design the workflow:For our workflow we need two main nodes:
- HTTP node
- OpenHAB2 node
The http node will handle the incoming GET request and will pass on the request to the openhab2 node which will toggle the lights based on the request parameters given to the http node.
Drag a http node to the work area and a openhab2 output node as well. Your workarea would look like this:
Connect them.
Connect the output grey square of the http node to the input grey square of the openhab2 out node. Like so:
Now this shows that a http get request would in turn trigger a openhab2 based output request to a connected devices.
Lets attach a dummy response object to the http request node. This is mandatory as any HTTP request that a client makes should result in a HTTP output. like so
Now to make sure your able to debug messages coming from the HTTP requsest object add a debug node to the HTTP request nodes output like so:
Now your test flow is almost complete. We just need to configure the nodes:
1) HTTP lights node (http request node)
Every request node needs to tell what kind of HTTP action can it support. Lets say our HTTP request object can handle HTTP GET operation. Double click the http node and it will shows a menu like so:
Here you Give a name to the node. Set the Method as GET and set the request URL to /togglelights. Lets see what this means:
The url section tells the node-red flow that this node can accept an HTTP GET request @ http://<ip of node-red server>:<port of server>/togglelights url.
Neat huh. with a few nodes, you have officially created a small HTTP service !!!
Now lets configure the openhab node. Double click on the node. It will show up like so:
Here again give a name to the node. But now you see a config called Controller with a pencil icon in it. This is called a configuration node. These nodes save a global configuration object related to the service you want to activate/trigger from your node. In our case it will be our OpenHAB2 server configuration. Click on the pencil icon. It will show a menu like so:
Give a name to your configuration so that you can access it in other openhab2 controller nodes. Set the protocol to http. In the host section. Either give the OPENHAB2 server IP or a host name if you have DNS setup. in port set 8080 or the port you assigned in your OpenHab2 setup config file.
Click update.
You will return to the previous node config menu, but this time, if your openhab config was right. You will be able to see your devices in the Item drop down like so:
Now You can select the switch you want to toggle when you press the DASH button. in the Topic section select ItemCommand as you want to send a command to the Item (ON, OFF etc). And in the PAYLOAD section put ON or OFF or TOGGLE based on the requirement. ON will turn the appliance on, OFF with switch off and TOGGLE will toggle on/off. Lets choose TOGGLE for now.
Now deploy this flow by clicking on deploy on the far top right of the tool. The flow is now deployed.
Note: If node-red complains about you mis-configuring any of the above nodes. Please review your node configuration and set them up as explained above. You shouldn't get an error during deployment to ensure proper workflow deployment
Now to test this flow. Try to send a GET request to the URL like shown below:
http://ip_node-red_host:1880/togglelights
this should show up as a request in the Debug panel in the right hand side panel. and you should see your appliance switching on/off on successive requests
Note: For sending/testing REST services. I would recommend the POSTMAN tool https://www.getpostman.com/appsSetting up you Dashbutton firmware:
Here is the fun part. Now you need to setup your dash button hardware to Try and call the above URL to control your OpenHAB lights. We will see how quickly this seemingly trivial flow can be enhanced to include more interesting stuff.
Without much ado, setup you RAM Ameba SDK based Arduino IDE by following the instruction below:
- Download the Arduino IDE.see the link https://www.arduino.cc/en/Main/Software
- Download the CREATOR Arduino library. Arduino IDE 1.6.5 support third party hardware by providing hardware configuration. You need add CREATOR's configuration in "File" -> "Preferences". And fill below URL in "Additional Boards Manager URLs:"
- I also suggest to enable "Show verbose output" options on "compilation" and "upload" in Preference.
- Open "Device Manager" in "Tools" -> "Board" -> "Board Manager". Wait for IDE update core configuration. Scroll down the menu, you will see RAK CREATOR in the list. Press "Install" at the right side.
- Select CREATOR in "Tools" -> "Board" -> "CREATOR RTL8711". Now you are able to develop Arduino code and upload image onto CREATOR.
Now upload the program below to your board:
#include <HttpClient.h>
#include <WiFi.h>
#include <WiFiClient.h>
#define LED1 0
#define LED2 1
#define LED3 2
#define LED4 3
#define RED 0
#define GREEN 1
#define BLUE 2
#define OFF 3
void printWifiStatus();
void led_off();
void http_get(char* str);
void led_ctrl(uint8_t led_num, uint8_t rgb);
char ssid[] = "RAK_2.4GHz_1"; // your network SSID (name)
char pass[] = "rakwireless205"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
// Name of the server we want to connect to
const char kHostname[] = "sonoff_switch_ip_here:port";
const char kPath[] = "/togglelights";
const int kHttpPort = 80;
// Number of milliseconds to wait without receiving any data before we give up
const int kNetworkTimeout = 30*1000;
// Number of milliseconds to wait if no data is available before trying again
const int kNetworkDelay = 1000;
int status = WL_IDLE_STATUS;
/* power enable */
int pwr_en = 15;
/* leds */
int led1_r = 25;
int led1_g = 24;
int led1_b = 19;
int led2_r = 0;
int led2_g = 2;
int led2_b = 6;
int led4_r = 12;
int led4_g = 11;
int led4_b = 13;
int led3_r = 22;
int led3_g = 21;
int led3_b = 1;
/* keys */
int key1 = 23;
int key2 = 14;
int key3 = 10;
int key4 = 20;
void setup()
{
Serial.begin(9600);
pinMode(pwr_en, OUTPUT);
digitalWrite(pwr_en, 1);
pinMode(led2_r, OUTPUT);
pinMode(led2_g, OUTPUT);
pinMode(led2_b, OUTPUT);
pinMode(led1_b, OUTPUT);
pinMode(led3_r, OUTPUT);
pinMode(led3_g, OUTPUT);
pinMode(led3_b, OUTPUT);
pinMode(led4_b, OUTPUT);
pinMode(key2, INPUT_PULLUP);
pinMode(key3, INPUT_PULLUP);
pinMode(key4, INPUT_PULLUP);
#if 1
/*
* Pin D21-D25 can not be used as digital IO ,when in debug mode(Enable JTAG).
* D21-D25 can be used as digital IO when in factory mode.(Disable JTAG)
*/
//D21-D25
pinMode(led4_g, OUTPUT);
pinMode(led4_r, OUTPUT);
pinMode(led1_g, OUTPUT);
pinMode(led1_r, OUTPUT);
pinMode(key1, INPUT_PULLUP);
#endif
led_off();
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
}
void loop()
{
led_off();
checkButtonStatus(key1);
delay(100);
}
void checkButtonStatus(int key){
if (digitalRead(key) == 0) {
delay(50);
if (digitalRead(key) == 0) {
led_ctrl(LED4,BLUE);
delay(500);
Serial.print(key + " was pressed");
http_get();
}
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
led_ctrl(LED1,RED);
led_ctrl(LED2,RED);
led_ctrl(LED3,RED);
led_ctrl(LED4,RED);
delay(500);
}
void led_off() {
led_ctrl(LED1,OFF);
led_ctrl(LED2,OFF);
led_ctrl(LED3,OFF);
led_ctrl(LED4,OFF);
}
void http_get() {
int err = 0;
WiFiClient c;
HttpClient http(c);
char path[100];
err = http.get(kHostname, kHttpPort, kPath);
Serial.println(path);
if (err == 0)
{
Serial.println("startedRequest ok");
err = http.responseStatusCode();
if (err >=0)
{
Serial.print("Got status code: ");
Serial.println(err);
}
else
{
Serial.print("Getting response failed: ");
Serial.println(err);
}
}
else
{
Serial.print("Connect failed: ");
Serial.println(err);
}
http.stop();
}
void http_post(char* data) {
int err = 0;
WiFiClient client;
while(1){
if (!client.connect("xxxxxxx", 8080)) { //port can be 8080 or as configured in the openhab config
Serial.println("Connect to server failed. Retry after 1s.");
client.stop();
delay(1000);
continue;
}else{
break;
}
}
Serial.println("connected to server");
// Make a HTTP request:
client.print("POST /rest/items/My_Item/");
client.print("OFF");
client.print("Host: ");
client.println("xxxxxxx"); //you open hab url in the form abc.xyz.com
client.println();
while (!client.available()) delay(100);
while (client.available()) {
char c = client.read();
Serial.write(c);
}
client.stop();
}
void led_ctrl(uint8_t led_num, uint8_t rgb)
{
switch (led_num) {
case LED1:
if (rgb == RED) {
digitalWrite(led1_r, 0);
digitalWrite(led1_g, 1);
digitalWrite(led1_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led1_r, 1);
digitalWrite(led1_g, 0);
digitalWrite(led1_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led1_r, 1);
digitalWrite(led1_g, 1);
digitalWrite(led1_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led1_r, 1);
digitalWrite(led1_g, 1);
digitalWrite(led1_b, 1);
}
break;
case LED2:
if (rgb == RED) {
digitalWrite(led2_r, 0);
digitalWrite(led2_g, 1);
digitalWrite(led2_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led2_r, 1);
digitalWrite(led2_g, 0);
digitalWrite(led2_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led2_r, 1);
digitalWrite(led2_g, 1);
digitalWrite(led2_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led2_r, 1);
digitalWrite(led2_g, 1);
digitalWrite(led2_b, 1);
}
break;
case LED3:
if (rgb == RED) {
digitalWrite(led3_r, 0);
digitalWrite(led3_g, 1);
digitalWrite(led3_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led3_r, 1);
digitalWrite(led3_g, 0);
digitalWrite(led3_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led3_r, 1);
digitalWrite(led3_g, 1);
digitalWrite(led3_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led3_r, 1);
digitalWrite(led3_g, 1);
digitalWrite(led3_b, 1);
}
break;
case LED4:
if (rgb == RED) {
digitalWrite(led4_r, 0);
digitalWrite(led4_g, 1);
digitalWrite(led4_b, 1);
}
else if (rgb == GREEN) {
digitalWrite(led4_r, 1);
digitalWrite(led4_g, 0);
digitalWrite(led4_b, 1);
}
else if (rgb == BLUE) {
digitalWrite(led4_r, 1);
digitalWrite(led4_g, 1);
digitalWrite(led4_b, 0);
}
else if (rgb == OFF) {
digitalWrite(led4_r, 1);
digitalWrite(led4_g, 1);
digitalWrite(led4_b, 1);
}
break;
default:
break;
}
}
A short explanation of the important parts:
1) Setup the buttons as digital input pins. These are defined like so:
#if 1
/*
* Pin D21-D25 can not be used as digital IO ,when in debug mode(Enable JTAG).
* D21-D25 can be used as digital IO when in factory mode.(Disable JTAG)
*/
//D21-D25
pinMode(led4_g, OUTPUT);
pinMode(led4_r, OUTPUT);
pinMode(led1_g, OUTPUT);
pinMode(led1_r, OUTPUT);
pinMode(key1, INPUT_PULLUP);
#endif
Now that you have setup key1. We proceed to define what happens when you press Key1. This happens in the checkButtonStatus function
void checkButtonStatus(int key){
if (digitalRead(key) == 0) {
delay(50);
if (digitalRead(key) == 0) {
led_ctrl(LED4,BLUE);
delay(500);
Serial.print(key + " was pressed");
http_get();
}
}
}
Here we check if the button is digital HIGH, trigger a HTTP GET function. Here we use the following function:
err = http.get(kHostname, kHttpPort, kPath);
where kHostName and KhttpPort are your node red host and port and kPath is nothing but /togglelights.
Now you should be all setup. Upload this code to your Ameba dash button. Once uploaded, click the button 1 on the Dash Button. This will trigger the node-red workflow you defined, and send a HTTP request object to trigger the OpenHab node. The OpenHab node will in turn hit your OpenHab2 server with the HTTP POST request to the item you specified in you configuration toggle it. NEATTTTTT !!!!!
For some server modifications:Now you may want to do the following small changes based on your setup:
- Node-red and Openhab on different servers. If your OpenHab and node-red are on same box you can specify the OpenHab IP in node-red configuration node as 127.0.0.1. But if they are on a different IP all together, make sure you specify the IP of DNS resolved name correctly in the configuration node.
- Making your setup secure: Its good to make sure your Node-red and Openhab 2 setups are behind https endpoints and not plain http as this is more secure. For this, i would advise putting node-red and openhab2 behind a nginx/apache webserver proxy setup
Openhab: http://docs.openhab.org/installation/security.html
Node-red: https://nodered.org/docs/configuration
When you make OpenHab behind a https endpoint, make sure you change the protocol configuration in the OpenHab configuration node as HTTPS.
- Securing access by adding Basic auth: You can make sure that your openhab2 server is behind a Basic auth setup as explained here:
http://docs.openhab.org/installation/security.html#authentication-and-access-control
Workflow modification:Since Node-red provides a drag-drop-draw functionality; you can literally change the workflow in any way you want. Just draw your flow !!!
For eg: here is a simple tutorial to add twitter access to your node:
After creating the twitter config, just connect you twitter node to your http request like so:
Now when ever your click the button, you would send out a tweet as well as switch off/on your appliance. COOOL !!!!
There are tonnes of other integration available via plugins in Node-red. You can mix and match these integration to your hearts desire and share your nodes as well:
Sharing your nodes/workflows:When you have finished your workflow and want to share it with your buddies. Its is quite easy, Select your node flow in its entirety by click and dragging the mouse to form a selection of your flow. Then in the top right menu, select Export -> Clipboard. This will give you a json like so:
[{"id":"55809f53.af20a","type":"openhab2-out","z":"7a5d96b3.1b2978","name":"ToggleOHLights","controller":"94b7105b.cc478","itemname":"Switch1","topic":"ItemCommand","payload":"TOGGLE","x":654,"y":874,"wires":[]},{"id":"fbf368e2.404b38","type":"http in","z":"7a5d96b3.1b2978","name":"toggle lights","url":"/togglelights","method":"get","upload":false,"swaggerDoc":"","x":416,"y":883,"wires":[["3493d584.f5ae0a","55809f53.af20a","ad2cd216.6c8ff","34da0c09.bcac54"]]},{"id":"3493d584.f5ae0a","type":"debug","z":"7a5d96b3.1b2978","name":"","active":true,"console":"false","complete":"payload","x":624,"y":789,"wires":[]},{"id":"ad2cd216.6c8ff","type":"http response","z":"7a5d96b3.1b2978","name":"","statusCode":"","headers":{},"x":639,"y":934,"wires":[]},{"id":"34da0c09.bcac54","type":"twitter out","z":"7a5d96b3.1b2978","name":"Tweet","x":692,"y":1001,"wires":[]},{"id":"94b7105b.cc478","type":"openhab2-controller","z":"","name":"MyOpenHab","protocol":"http","host":"ttn-gateway.local","port":"8080","path":"","username":"","password":""}]
You buddies can then import this json using the Settings - > import menu.
For creating you own nodes:For the Hard-CORE maker, Node-red provides a way to create your own node via the Node-red APIs. Check a sample tutorial here:
https://nodered.org/docs/creating-nodes/
API Reference for node-redNode-red provides a clean set of HTTP APIs for the following components:
- 1) Admin
- 2) Runtime
- 3) Storage
For details please visit:
https://nodered.org/docs/api/
For the impatient:And for the frantic maker in you. Node-red Cookbook provides pebuilt nodes/workflows for your to download and use with a few changes:
https://cookbook.nodered.org/
Comments
Please log in or sign up to comment.