Home Assistant with Node-Red

Home Assistant is an open source home automation platform that can monitor and control smart home devices and it integrates with many of other common systems.

HA_demo

Home Assistant installation is targeted for Raspberry Pi’s but other hardware options are available.

I was very impressed how easy it was to install Home Assistant and get a basic home integration system up and running.

There is a huge number of integration solutions (1500+) that connect to most of the mainstream products. However if you want to do some custom Arduino or Raspberry Pi connections there isn’t an easy “out of the box” solution.  To solve this requirement Home Assistant has included Node-Red as an add-on.

Node-RED is a visual programming tool for wiring together hardware devices, APIs and online services.

I found that getting the Node-Red integration was a little tricky. This blog will show how to get Node-Red integration working and it includes a simple simulator circuit.

Getting Started

The installation instructions are very straightforward. I would recommend using a wired connection for your Raspberry Pi. A wireless network connection is 100% possible but it is not in the base installation directions.

After the basic installation is complete, add-ons can be installed under the Supervisor->Dashboard. I would recommend installing “File editor” and “Terminal & SSH” add-ons along with Node-Red.

ha_addons

I found that the Node-Red installed without any problems but it required some configuration changes before it would run.

In the Node Red add-on you will need to add a credential_secret and a password.

nodered_config

If Node-Red doesn’t start look at the log for errors (it’s at the bottom of the same page).

nodered_log

The base Node-Red installation has a very good selection of pre-installed nodes. If you wish to add more nodes see the “Manage Pallet” option that is accessed from the top right options icon.

At this stage Node-Red is somewhat standalone and it is not fully integrated with Home Assistant.

Integrating Node-Red with Home Assistant

The directions and files for Node-Red integration  can be downloaded to your PC.

ha_nr_int_files

Specifically you want to custom_components/nodered directory and files, which will need to be moved to the Raspberry Pi. The Home Assistant “File editor” add-on can be used to create Pi directories and move files from your PC.

nodered_files

The following directories and file should now exist:

/root/config/custom_components/nodered/__init__.py
/root/config/custom_components/nodered/__pycache__
/root/config/custom_components/nodered/binary_sensor.py
/root/config/custom_components/nodered/config_flow.py
/root/config/custom_components/nodered/const.py
/root/config/custom_components/nodered/discovery.py
/root/config/custom_components/nodered/manifest.json
/root/config/custom_components/nodered/save.txt
/root/config/custom_components/nodered/sensor.py
/root/config/custom_components/nodered/services.yaml
/root/config/custom_components/nodered/switch.py
/root/config/custom_components/nodered/websocket.py

/root/config/custom_components/nodered/.translations/en.json

Once this is complete Home Assistant will need to be restarted.

Including Node-Red Integrations

The next step is to create sensors and switches in Node-Red that can be accessed in Home Assistant. Below is a simple circuit that sends a random number (0-100) to a HA entity.

This logic uses a Big Timer node, that generates a pulse every minute from the middle output pin. An injector node allow you to force a new value. A random node will output a new random number whenever the Big Timer or Inject nodes are triggered.

nr_circuit

Double-click on the HA entity to configure the HA server and other properties.

nr_entity_config

Once the logic is complete click the “Deploy” button to make the logic active.

Node-Red integration is enabled by adding it in the Configuration->Integration page.

nr_new_int

nr_entities

Overview Dashboard with Node-Red Data

The final step is to modify the Overview Dashboard to include the Node-Red Entity.

For this example I added a gauge component using the Orange-Plus at the bottom right of this Configure UI page.

config_ui

On the live Overview page it is possible to click on the gauge card and get more information about this sensor.

HA_overview

Final Thoughts

Home Assistant is a very well structured home automation solution that offers a number of excellent approaches to bring in data.

Node-Red is a very flexible programming environment that help expands connectivity to Arduino, Raspberry Pi and other 3rd party services that are not in the base Home Assistant software.

For information on how to connect an Arduino module to Node-Red see:

https://funprojects.blog/2018/03/04/arduino-talking-mqtt-to-node-red/

https://funprojects.blog/2018/02/18/arduino-talking-to-node-red-and-python/

 

Micro:bits and Node-Red

BBC Micro Bit, (micro:bit) is an open source hardware ARM-based embedded system designed by the BBC for use in computer education in the UK. The device is half the size of a credit card and has an ARM Cortex-M0 processor, accelerometer and magnetometer sensors, Bluetooth and USB connectivity, a display consisting of 25 LEDs, and two programmable button.

Depending on where you purchase it the price ranges between $15-$20. So this is a very attractive module for the beginning programmer.

The micro:bit module has 2 buttons to interface to it and a small 5×5 LED screen. This is good for small tests but its a little limiting.

For the most part micro:bit is a standalone unit so in this blog I wanted to show how to put micro:bits information on to a Node-Red web dashboard that could be viewed from a smart phone, tablet or PC.

mp_nr_overview

Micro:bits Setup

The micro:bits has a USB connection that can be used for communications to PCs or Raspberry Pi’s. For my setup I used a Raspberry Pi Zero W, with a microUSB-to-USB adapter to connect into the micro:bit.

mp_pi_setup

The micro:bit can be programmed via a nice Web Interface, for details see: https://microbit.org/guide/quick/. For this application I programmed with blocks.

My logic had the temperature and light sensor values written out ever 10 seconds, in the format of: T=xxx, L=xxx, I used a comma separator between the data pieces. Button presses were sent as either A=1, or B=1, .

mp_usb_logic

 

Node-Red Setup

Node-Red is pre-install on the Raspberry Pi image, if you want to use a PC instead see the Node-Red installation documentation.

A Node-Red has a Serial port component (https://flows.nodered.org/node/node-red-node-serialport) that can be loaded manually or via the Palette Manager.

The first step is to insert a serial input node and define the serial interface. Double-click on the serial input node and edit the serial connection. The interface will vary with your setup but node-red will show a list of possible USB ports. The default baud rate of the micro:bits USB port is 115200. I used a timeout of 200ms to get the messages, but you could also look for a terminating character (the comma “,” could be used).

nr_serial_edit

The logic used 4 Javascript function nodes to parse the micro:bit message

nr_serial_logic

“Get Temp Value” Function:


// Pull out the temperature
//
var themsg = msg.payload;

if (themsg.indexOf("T=") > -1) {

var msgitems = themsg.split(",");

var temp = msgitems[0];
temp = temp.substring(2,4)
msg.payload = temp;
return msg;
}

“Get Light Value” Function:

// Pull out the Light Sensor Value
//
var themsg = msg.payload;</pre>
if (themsg.indexOf("T=") &gt; -1) {

var msgitems = themsg.split(",");

var light = msgitems[1];

light = light.substring(2,5)

msg.payload = light;

return msg;

}

“Check Button A” Function:

// If the message is Button A pressed
// "A=1,"
if (msg.payload == "A=1,") {
msg.payload =  1;
return msg;
}

“Check Button B” Function:

// If the message is Button B pressed
// "B=1,"
if (msg.payload == "B=1,") {
msg.payload =  1;
return msg;
}

Chart nodes are used to show the results. (Note: you’ll need to create a dashboard name).

For the button presses a 1-0 transition is needed after a button press, otherwise the chart will always show a value of 1. The 0-1 transition is done using a trigger node.

The final web dashboard is available at: http://your_node_red_ip:1880/UI.

mp_screen

Final Comments

The next step will be to add the ability to have Node-Red write values to the micro:bit. This would be done with the Node-Red serial output node. Micro:bit’s have a serial read function that would then process the command.

InfluxDB with Node-Red

There are a lot of excellent databases out there. Almost all databases can support time tagged information and if you have regularly sampled data everything works well. However if you have irregularly sampled data things can get a little more challenging.

InfluxDB is an open-source time series database (TSDB). It is written in Go and optimized for fast, high-availability storage and retrieval of time series data in fields such as operations monitoring, application metrics, Internet of Things sensor data, and real-time analytics.

InfluxDB has a number of great features:

  • when data is added, a time stamp is automatically added if it’s already incluced.
  • InfluxDB manages aggregation of times (i.e. means over the hour)
  • Open Source Web Trending packages like Grafana and Chronograf will talk directly to InfluxDB
  • an SQL language with a time based syntax

In this blog I wanted to document my notes on:

  • How to add sampled data from Node-Red to Influx
  • How to view Influx historical data in a Node-Red chart

Why Use Node-Red with Influx

With the great Web trending interfaces like Grafana and Chronograf why use Node-Red?

  • I really like Grafana, but I didn’t find it to be 100% mobile friendly, whereas Node-Red is designed for mobile use.
  • if you’re inputting data or doing logic in Node-Red it makes sense to keep the interface logic there also.

The downside of using Node-Red is that you will have to make your own charting controls.

Getting Started with InfluxDB

The official installation document  lists the various options based on your OS. For a simple Raspberry Pi or Ubuntu installation I used:

sudo apt-get install influxdb

The influxdb configuration/setup is modified by:

sudo nano /etc/influxdb/influxdb.conf

After configuration changes Influx can be restarted by:

sudo service influx restart

The Influx command line  interface (CLI) is useful for getting started and checking queries. It is started by entering: influx (Note: it might be slow to initially come up).

Below I’ve opened the influx CLI and created a new database called nrdb.

~$ influx
Connected to http://localhost:8086 version 1.7.9
InfluxDB shell version: 1.7.9
> create database nrdb
> show databases
name: databases
name
----
_internal
pidata
nrdb
>

Node-Red and Influx

Node-Red is pre-installed on Raspberry Pi. If you need to install Node-Red on a Window, MacOS or Linux node see the installation instructions.

For my testing I used the following definitions:

  1. nrdb – the InfluxDB database
  2. mytemps – the measurement variable for my temperatures
  3. Burlington, Hamilton – two locations for the temperatures
  4. temperatures – the actual temperatures

Two Node-Red libraries were installed:

These libraries can either be installed using npm or within Node-Red using the “Manage Pallet” option.

nr_pallet

For this project I create two sets of logic. The first set used the BigTimer to write a new simulated input every minute (via the middle output pin of BigTimer), or manual push in a value. The second part of the logic used a selected time to query the data and present it to a chart and table.

nr_influx_logic

The first step is to drop a InfluxDB outpt and then configure the Influx server, table and measurements.

influxdb_edit

A Javascript function node (“Simulate an Input”) is used to format the fields and values. The first passed item is the key item, and the second parameter is a tagged value. Note: there are a number of different ways to use this node.

nr_sim_input

The Big Timer middle output will send a value out every minute. I added an Inject Node (“Force Test”) so I could see more values.

To test that things are running, the influx cli can be used:

> use nrdb
Using database nrdb
> show measurements
name: measurements
name
----
mytemps
> select * from mytemps
name: mytemps
time location temperature
---- -------- -----------
1580584703785817412 Burlington 17
1580584706364427345 Burlington 5
1580584761862704310 Burlington 8

Show Influx Data in a Node-Red Dashboard

For a simple Dashboard I wanted to use a dropdown node (as a time selector), a chart and a table.

The drop down node has a selection of different times.

nr_dropdown

The payload from the dropdown node would be something like: 1m, 5m, 15m. A Javascript function node (“New Time Scale”) used this payload and created an InfluxDB query.

nr_timescales

This syntax can be tested in the influx cli:

> select time,temperature from mytemps where location='Burlington' and time > now() - 5m
name: mytemps
time temperature
---- -----------
1580588829859372644 12
1580588889896729245 6
1580588949931621672 17
1580589009972333308 8
1580589069980649689 12

The InfluxDB input node only has the InfluxDB server information. The query is passed in from the Javascript function node (“New Time Scale”) .

A Javascript function node (“Javascript function node (“Format Influx Results”) is used to put the msg.payload into a format that the chart node can use.


//
// Format the InfluxDB results to match the charts JSON format
//

var series = ["temp DegC"];
var labels = ["Data Values"];
var data = "[[";
var thetime;

for (var i=0; i < msg.payload.length; i++) {
    thetime = Number(msg.payload[i].time); // Some manipulation of the time may be required
    data += '{ "x":' + thetime + ', "y":' + msg.payload[i].temperature + '}';
    if (i < (msg.payload.length - 1)) {
        data += ","
    } else {
        data += "]]"
    }
}
var jsondata = JSON.parse(data);
msg.payload = [{"series": series, "data": jsondata, "labels": labels}];
msg.playload = data;
return msg;

Once all the logic has been updated, click on the Deploy button. The Node-Red dashboard can be accessed at: http://node-red_ip:1880/ui. Below is an example:

nr_influx_screen

Final Comments

This project was not 100% there are still some cleanup items to do, such as:

  • use real I/O
  • make the times a little cleaner in the table
  • a better time selections for the chart.

Also to better explain things I only used 1 location but multiple data points could be inserted, queried and charted.

Sqlite and Node-Red

Sqlite is an extremely light weight database that does not run a server component.

In this blog I wanted to document how I used Node-Red to create, insert and view SQL data on a Raspberry Pi. I also wanted to show how to reformat the SQL output so that it could be viewed in a Node-Red Dashboard line chart.

Installation

Node-Red is pre-installed on the Pi Raspian image. I wasn’t able to install the Sqlite node using the Node-Red palette manager. Instead I did a manual install as per the directions at: https://flows.nodered.org/node/node-red-node-sqlite .

cd ~/.node-red 
npm i --unsafe-perm node-red-node-sqlite 
npm rebuild

Create a Database and Table

It is possible to create a database and table structures totally in Node-Red.

I connected a manual inject node to a sqlite node.

sqlite_create_table

In the sqlite node an SQL create table command is used to make a new table. Note: the database file is automatically created.

For my example I used a 2 column table with a timestamp and a value

sqlite_db_config

Insert Data into Sqlite

Data can be inserted into Sqlite a number of different ways. A good approach for a Rasp Pi is to pass some parameters into an SQL statement.

sqlite_insert_flow

The sqlite node can use a “Prepared Statement” with a msg.params item to pass in data. For my example I created two variable $thetime and $thevalue.

sqlite_insert_conf

A function node can be used to format a msg.params item.


// Create a Params variable
// with a time and value component
//
msg.params = { $thetime:Date.now(), $thevalue:msg.payload }
return msg;

Viewing Sqlite Data

A “select” statement is used in an sqlite node to view the data.

A simple SQL statement to get all the data for all the rows in this example would be:

select * from temps;

A debug node can used to view the output.
sqlite_select

Custom Line Chart

Node-Red has a nice dashboard component that is well formatted for web pages on mobile devices.

To add the dashboard components use the Node-Red palette manager and search for: node-red-dashboard.

By default the chart node will create its own data vs. time storage. For many applications this is fine however if you want long term storage or customized historical plots then you will need to pass all the trend data to the chart node.

For some details on passing data into charts see: https://github.com/node-red/node-red-dashboard/blob/master/Charts.md#stored-data

Below is an example flow for creating a custom chart with 3 values with times.custom_chart_data

The JavaScript code needs to create a structure with: series, data and labels definitions


msg.payload = [{
"series": ["A"],
"data": [
[{ "x": 1577229315152, "y": 5 },
{ "x": 1577229487133, "y": 4 },
{ "x": 1577232484872, "y": 6 }
]
],
"labels": ["Data Values"]
}];

return msg;

This will create a simple chart:

custom_chart_image

For reference, below is an example of the data structure for three I/O points with timestamps:


// Data Structure for: Three data points with timestamps

msg.payload = [{
"series": ["A", "B", "C"],
"data": [
[{ "x": 1577229315152, "y": 5 },
{ "x": 1577229487133, "y": 4 },
{ "x": 1577232484872, "y": 2 }
],
[{ "x": 1577229315152, "y": 8 },
{ "x": 1577229487133, "y": 2 },
{ "x": 1577232484872, "y": 11 }
],
[{ "x": 1577229315152, "y": 15 },
{ "x": 1577229487133, "y": 14 },
{ "x": 1577232484872, "y": 12 }
]
],
"labels": ["Data Values"]
}];

Sqlite Data in a Line Chart

To manually update a line chart with some Sqlite data I used the following nodes:

sqlite_2_chartThe SQL select statement will vary based on which time period or aggregate data is required. For the last 8 values I used:

select * from temps LIMIT 8 OFFSET (SELECT COUNT(*) FROM temps)-8;

The challenging part is to format the SQL output to match the required format for the Line Chart. You will need to iterate over each data row (payload object) and format a JSON string.

 //  
 // Create a data variable   
 //  
 var series = ["temp DegC"];  
 var labels = ["Data Values"];  
 var data = "[[";  
   
 for (var i=0; i < msg.payload.length; i++) {  
   data += '{ "x":' + msg.payload[i].thetime + ', "y":' + msg.payload[i].thetemp + '}';  
   if (i < (msg.payload.length - 1)) {  
     data += ","  
   } else {  
     data += "]]"  
   }  
 }  
 var jsondata = JSON.parse(data);  
 msg.payload = [{"series": series, "data": jsondata, "labels": labels}];  
   
   
 return msg;  

 

To view the Node-Red Dashboard enter: http://pi_address:1880/ui

Screen_chart_sqlite

Final Comments

For a small standalone Raspberry Pi project using sqlite as a database is an excellent option. Because a Pi is limited in data storage I would need to include a function to limit the amount of data stored.

 

Apache Kafka with Node-Red

Apache Kafka is a distributed streaming and messaging system. There are a number of other excellent messaging systems such as RabbitMQ and MQTT. Where Kafka is being recognized is in the areas of high volume performance, clustering and reliability.

Like RabbitMQ and MQTT, Kafka messaging are defined as topics. Topics can be produced (published) and consumed (subscribed). Where Kafka differs is in the storage of messages. Kafka stores all produced topic messages up until a defined time out.

Node-Red is an open source visual programming tool that connects to Raspberry Pi hardware and it has web dashboards that can be used for Internet of Things presentations.

In this blog I would like to look at using Node-Red with Kafka for Internet of Things type of applications.

Getting Started

Kafka can be loaded on a variety of Unix platforms and Windows.  A Java installation is required for Kafka to run, and it can be installed on an Ubuntu system by:

apt-get install default-jdk

For Kafka downloads and installation instructions see: https://kafka.apache.org/quickstart. Once the software is installed and running there a number of command line utilities in the Kafka bin directory that allow you to do some testing.

To test writing messages to a topic called iot_test1, use the kafka-console-producer.sh  command and enter some data (use Control-C to exit):

bin/kafka-console-producer.sh --broker-list localhost:9092 --topic iot_test1
11
22
33

To read back and listen for messages:

 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic iot_test1 --from-beginning
11
22
33

The Kafka server is configured in the /config/server.properties  file. A couple of the things that I tweeked in this file were:

# advertised the Kafka server node ip
advertised.listeners=PLAINTEXT://192.168.0.116:9092
# allow topics to be deleted
delete.topic.enable=true

Node-Red

Node-Red is a web browser based visual programming tool, that allows users to create logic by “wiring” node blocks together.  Node-Red has a rich set of add-on components that includes things such as: Raspberry Pi hardware, Web Dash boards, email, Tweeter, SMS etc.

Node-Red has been pre-installed on Raspbian since 2015. For full installation instructions see:  https://nodered.org/#get-started

To add a Node-Red component select the “Palette Manager”, and in the Install tab search for kafka. I found that the node-red-contrib-kafka-manager component to be reliable (but there are others to try).

For my test example I wanted to create a dashboard input that could be adjusted. Then read back the data from the Kafka server and show the result in a gauge.

This logic uses:

  • Kafka Consumer Group – to read a topic(s) from a Kafka server
  • Dashboard Gauge – to show the value
  • Dashboard Slider – allows a user to select a numeric number
  • Kafka Producer – sends a topic message to the Kafka server

nodered_kafka Double-click on the Kafka nodes and in the ‘edit configuration’ dialog create and define a Kafka broker (or server). Also add the topic that you wish to read/write to.

kafka_consume

Double-click on the gauge and slider nodes and define a Dashboard group. Also adjust the labels, range and sizing to meet your requirements.

kafka_gauge

After the logic is complete hit the Deploy button to run the logic. The web dashboard is available at: http://your_node_red_ip:1880/ui.

kafka_phone

Final Comment

I found Node-Red and Kafka to be easy to use in a simple standalone environment. However when I tried to connect to a Cloud based Kafka service (https://www.cloudkarafka.com/) I quickly realized that there is a security component that needs to be defined in Node-Red. Depending on the cloud service that is used some serious testing will probably be required.

 

Raspberry Pi Internet Radio

Node-Red is graphical programming interface that allows logic to be created using nodes that are wired together. Node-Red has been pre-installed in the Raspian OS since 2015 and it has a very easy learning curve.

In this blog I wanted to show an example of Node-Red being used with a five button LCD faceplate to play Internet radio stations.

For this project I used a basic USB powered speaker, a Rasp Pi and a Pi 5-button LCD faceplate. The cost of the faceplates start at about $10.

pi_radio2

Getting Started with Internet Radio

There are a good number of Internet radio resources, https://www.internet-radio.com has a good selection of stations to choose from.

To find a URL of a radio station, look through the stations until you find what you like and then right click on the .pls link, and “Save Link as…”. Save this link as a file and then open the file in a text editor to get the URL.

radio_stations

 

MPD – Music Player Daemon

MPD is a Linux based music service that supports the playing of both music files and internet based radio stations. For command line operations that is also a MPD client application called mpc. To install both the service and client:

sudo apt-get install mpd mpc

Before I started building the node-red application I played with the mpc commands to ensure that I understood the basics.

Internet radio stations are added like a song list:

mpc add 'http://uk2.internet-radio.com:8062'
mpc add 'http://live.leanstream.co/CKNXFM'
mpc add 'http://66.85.88.2:7136'

Some key mpc control commands are:

mpc play  # play the current station
mpc play 3 # play radio station 3
mpc pause  # pause the music
mpc next  # play the next radio station
mpc prev  # play the previous radio station 

mpc volume 90 # set the volume to 90%
mpc volume +5 # increase the volume 5%
mpc volume -5 # decrease the volume 5%

The mpc status command will show the volume, what is playing along with the current station number and total number of stations:

$ mpc status
Comedy104 - A Star104.net Station: Doug Stanhope - To Tell You the Truth
[playing] #2/4 1:45/0:00 (0%)
volume: 75% repeat: off random: off single: off consume: off

Node-Red Logic

Node-Red can be started from the Raspberry Pi menus, or from the command line:

node-red-start &

To access the Node-Red web page, enter the Raspberry Pi ip address with port 1880, for example : http://192.168.0.121:1880

For this project two extra Node-Red components are needed, and they are for the LCD faceplate and the MPD music player. To add components use the “Palette Manager” option.

palette

For the LCD faceplate, search for Adafruit, and select the i2c-lcd-adafruit-sainsmart component.

adafruit_palette

Similarly search for mpd and add the node-red-contrib-mpd component.

mpd_palette To create logic select a node from the left node panel and drag it onto the center flow palette, and then “wire” the nodes together.

For the Internet music example I used four function nodes, and the two i2cLED and the two MPD nodes. (Comment nodes are only used to explain the logic).

node_red_radio

The first step is to double click on the MPD nodes and add an MPD server.

Select Button Logic

I used the select button to turn on and off the music player.

A context variable is created to save the current state of the player. Note: a context variable is only accessible for the node where it is defined..

The ic2_LCD_Input node message has a msg.button_name and msg.button_state item that is used to determine which button is pushed.

For the select button logic a group of messages was used to add the different radio stations.


// create an "is setup" variable
var issetup = context.get('issetup')||0;

if ((msg.button_name == "SELECT") && (msg.button_state == "pressed" )){
// if the setup hasn't been run, add a radio station playlist
if (issetup === 0) {
context.set('issetup',1);
var msg0 = { payload:"clear"};
var msg1 = { payload:"add http://185.33.21.112:11029" }; // 1.FM Trance
var msg2 = { payload:"add http://66.85.88.2:7136" }; // Comedy 104
var msg3 = { payload:"add http://live.leanstream.co/CKNXFM"}; // The One - Wingham
var msg4 = { payload:"add http://185.33.21.112:11269" }; // Baroque
var msg5 = { payload:"play" };
return [ [ msg0, msg1, msg2, msg3, msg4, msg5] ];
} else {
context.set('issetup',0);
msg0 = { payload:"pause"};
return msg0;
}
}

Up/Down Button Logic

The UP button will issue an MPD command equivalent to :

mpc volume +5

This will up the volume by 5%. The total volume will max at 100%.

The DOWN button will issue an MPD command equivalent to :

mpc volume -5

// Raise/Lower the volume
var msg1;
var thevolume = 5; //volume % increment to change

if ((msg.button_name == "UP") && (msg.button_state == "pressed" )){
// if the setup hasn't been run, add a radio station playlist
msg1 = { payload:"volume +" + thevolume };
return msg1;
}
if ((msg.button_name == "DOWN") && (msg.button_state == "pressed" )){
// if the setup hasn't been run, add a radio station playlist
msg1 = { payload:"volume -" + thevolume};
return msg1;
}

Current and Max Radio Station Logic

The ‘Current and Max Radio Stations’ node is updated from the MPD in node when there are any changes to the volume or when a new song or station is played.

This logic creates two flow variables (stnmax, stncnt) that are available in any node in this flow.  The station max (stnmax) and current radio station (stncnt) variables are used in the LEFT/RIGHT button logic to determine which station to change to.


// Get the max number of radio stations and the current radio statio
// Make context variables that can be used in other node, like the LEFT/RIGHT button

var msg1 = msg.payload.status ; //create a simplier message
var stnmax = msg1.playlistlength;
flow.set('stnmax',stnmax);
var stncur = msg1.nextsong;
if (isNaN(stncur)) {stncur = stnmax;} // ensure a valid station

flow.set('stncur',stncur);

return msg1; // only needed for possible debugging

While the code is running it is possible to view the context date.

context_flow

UP/DOWN Button Logic

The UP / DOWN logic changes between the radio stations using the mpc commands:

mpc next
mpc prev

It is important to not move past the range of the radio stations or MPD will hang. The stnmax and stncur variables are used to determine if the next or previous commands are to be allowed.


// Move left and right in radion stations
var stnmax = flow.get('stnmax');
var stncur = flow.get('stncur');
if ((msg.button_name == "LEFT") && (msg.button_state == "pressed" )){
// if the setup hasn't been run, add a radio station playlist
if (stncur > 1) {
var msg0 = {payload:"previous"};
return msg0;
}
}
if ((msg.button_name == "RIGHT") && (msg.button_state == "pressed" )){
// if the setup hasn't been run, add a radio station playlist
if (stncur < stnmax)
var msg1 = {payload:"next"};
return msg1;

}

Final Comments

The Pi LCD faceplate is an excellent hardware add-on for any Raspberry Pi project. However it important to know that clone hardware may work as expected. For my hardware I was not able to easily turn off the extra LED.

A future enhancement would be to add a Web interface so that you could change the volume or stations without using the 5 button Pi faceplate.

 

Pi Network Monitoring

There are some great full featured networking packages like Nagios and MRTG that can be loaded on Raspberry Pi’s. If, however, you are looking for something smaller scale that you can play with then Node-Red might be your answer. Node-Red is a visual programming environment that allows users to create applications by dragging and dropping blocks (nodes) on the screen. Logic flows are then created by connecting wires between the different blocks (nodes). Node-Red also comes with Web Dashboards, so you can view data or do control from your smart phone.

In this blog we’ll look at:

  • running some SNMP commands
  • setup NodeRed for SNMP
  • making read/write SNMP values on the Pi

 

Getting Started with SNMP

Simple Network Management Protocol (SNMP) is the standard for communicating and monitoring of network devices. Common device information is grouped into MIBs or Management Information Bases. Data items are called OIDs or Object Identifiers. OIDs are referenced by either their MIB name or by their OID numeric name. So for example the SNMP device name object could be queried by either its MIB name of: SNMPv2-MIB::sysName.0 or the object identifier number of: .1.3.6.1.2.1.1.5.0.

To install both the SNMP monitor and server on your Pi enter:

sudo apt-get update
sudo apt-get install snmp snmpd snmp-mibs-downloader

To show meaningful MIB names, you will need to modify the SNMP config file by:

sudo nano /etc/snmp/snmp.conf

The first line should be commented out, it should just read: #mibs .

There are many configuration options in the SNMP server agent that need to be considered. For a real/product system you will need to consider your user security but for a test system we can open up the Pi by:

sudo nano /etc/snmp/snmpd.conf

Then uncomment the agentAddress line so that all interfaces are open, and in the Access Control section comment out all the existing user access and add a new line with public access set to read/write (definitely not recommended in a real system):

# Listen for connections on all interfaces (both IPv4 *and* IPv6)
agentAddress udp:161,udp6:[::1]:161

# ACCESS CONTROL
#
# Set read/write access to public anywhere
#
rwcommunity public

After saving the changes to snmpd.conf, the service needs to be restarted:

sudo service snmpd restart

There are a number of useful SNMP command line programs, such as:

  • snmpget – gets a SNMP message for a specific OID
  • snmpset – sets a SNMP OID (OID needs to be writeable)
  • snmpwalk – gets multiple OID values in a MIB tree

The basic syntax for these commands is:

command -c community -v version node OID

To test that SNMP is working, enter the following:

pi@raspberrypi:~ $ snmpwalk -c public -v 1 localhost .1.3 

SNMPv2-MIB::sysDescr.0 = STRING: Linux raspberrypi 4.4.21-v7+ ...
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (319234) 0:53:12.34
SNMPv2-MIB::sysContact.0 = STRING: Me <me@example.org>
SNMPv2-MIB::sysName.0 = STRING: raspberrypi
...

If SNMP is working correctly a very long list of SNMP objects will be shown.

Get a Specific SNMP Result

There are thousands of SNMP results that can be read. Some of the more common and useful SNMP are:

1 minute CPU Load: .1.3.6.1.4.1.2021.10.1.3.1
5 minute CPU Load: .1.3.6.1.4.1.2021.10.1.3.2
15 minute CPU Load: .1.3.6.1.4.1.2021.10.1.3.3

Idle CPU time (%): .1.3.6.1.4.1.2021.11.11.0

Total RAM in machine: .1.3.6.1.4.1.2021.4.5.0
Total RAM used: .1.3.6.1.4.1.2021.4.6.0
Total RAM Free: .1.3.6.1.4.1.2021.4.11.0

Total disk/partion size(kBytes): .1.3.6.1.4.1.2021.9.1.6.1
Available space on the disk: .1.3.6.1.4.1.2021.9.1.7.1
Used space on the disk: .1.3.6.1.4.1.2021.9.1.8.1

An example to get the Idle CPU time with the SNMP command line tool would be:

$ snmpget -c public -v 1 localhost .1.3.6.1.4.1.2021.11.11.0

UCD-SNMP-MIB::ssCpuIdle.0 = INTEGER: 97

If the syntax is correct, a result is returned with the OID identifier, result type and the  result value.

Getting Started with NodeRed

NodeRed is pre-installed with the Raspbian images but it will need to have some SNMP and some support options loaded. At a terminal window enter the commands:

sudo apt-get update
sudo apt-get install npm
cd $HOME/.node-red
npm install node-red-node-snmp
npm install node-red-dashboard
npm install node-red-contrib-bigtimer

node-red-start &

Once Node-RED starts, you use a web browser to build applications. If you are working directly on your Pi, enter 127.0.0.1:1880 in the URL address box of your browser. You drop palettes from the left pane into the large flow window in the middle and wire them together in the correct order.

NodeRed Ping Monitor

A good starting program is to make a Web Dashboard that shows ping (node-to-node) delay times. The dashboards are defined in the right panel of Node-Red. A dashboard items are put into groups, and groups are put into tabs. Each tab will be shown as a separate page on your smart phone.

pinglogic

By double-clicking on the Ping node you can enter the different IP address.

pingnode

Similarly by double-clicking on the Chart node, you can define the label and look and feel of the chart.

chartnode

After the configuration is finished, click the Deploy button,  (top right on menu  bar). The Node-RED dashboard user interface is accessed by entering <IPaddress>:1880/ui (e.g., 192.168.1.102:1880/ui). Chart data values are shown by clicking on the chart line.

pingSS

NodeRed with SNMP Nodes

The ping node is quite simple and it returns just the ping value. The snmp node is more complex and it returns multiple pieces of information. To use snmp nodes in a Node-Red program you need some support nodes to parse/pass the payload messages. To send SNMP data to a chart dashboard, the following nodes are used:

  • Big Timer – to trigger the polling of data
  • snmp – gets SNMP/OID information
  • split – split the message into addressable variables
  • change – put the OID value into the message playload
  • chart – show the payload

snmplogic

The SNMP node configuration can get multiple values, a simple example to get the CPU free time is below (Note: the leading “.” is NOT included) :

snmpnode

The split node is used move the SNMP array data in a payload string. The change node is then used to move just the value into the payload.

changenode

The final step is to configure the charts to show the correct label information.

snmpSS

An SNMP Readable Pi Value

The Net-SNMP agent (snmpd) supports the creation of custom read/write objects (OIDs). The “Pass-through” MIB extension command in snmpd.conf allows for script files to be called.

Pass-through script files need to follow a few rules:

  • snmpget request passes a “-g” parameter (get)
  • the snmpget response needs to be 3 lines: OID, data type, and value
  • an snmpset request passes a “-s” parameter (set)

A simple example would be to define the Rasperry Pi board temperature as an SNMP object. The board temp is available by:

cat /sys/class/thermal/thermal_zone0/temp
46160

This returns the value in 1/1000s of a degree C. So to get just the Celsius temperature we can use:

echo $(($(cat /sys/class/thermal/thermal_zone0/temp) / 1000))
46

A SNMP bash script (/home/pi/pitemp), with our Pi CPU temp as OID  .1.3.6.1.4.1.8072.2.1 would be:

#!/bin/bash
if [ "$1" = "-g" ]
then
echo .1.3.6.1.4.1.8072.2.1
echo integer
echo $(($(cat /sys/class/thermal/thermal_zone0/temp) / 1000))
fi
exit 0

After the file is saved remember to make it executable (chmod +x pitemp).

In the “Pass-through” section of  /etc/snmp/snmpd.conf  a line is added to reference the new OID, shell and command:

#
# "Pass-through" MIB extension command
#
pass .1.3.6.1.2.1.8072.2.1 /bin/bash /home/pi/pitemp

After snmpd.conf is updated the snmpd service needs to restarted (sudo service snmpd restart), then our Pi temp OID can be accessed by:

snmpget -c public -v 1 localhost .1.3.6.1.2.1.8072.2.1
NET-SNMP-EXAMPLES-MIB::netSnmpExampleScalars = INTEGER: 47

Pi Writable SNMP GPIO Value

My goal was to use SNMP to turn on and off powered devices, so for this I used a PowerSwitch Tail II, however simple low cost relays could also be used.

The PowerSwitch Tail II ($26) is a power cord that is enabled/disabled with I/O pins. The PowerSwitch pins connect to the Pi pins 6 and 12.

pi_setup

The gpio tool is used to read and write to GPIO pins.  GPIO 1 is made writable by:

gpio mode 1 out

The SNMP script (/home/pi/powerswitch) to read and write to GPIO pin 1 (physical pin 12) is:

#!/bin/bash
if [ "$1" = "-g" ]
then
echo .1.3.6.1.2.1.8072.2.2
echo integer
gpio read 1
fi

if [ "$1" = "-s" ]
then
gpio write 1 $4
fi

exit 0

This new script file needs to made executable by: chmod +x powerswitch. The powerswitch script file is referenced in the SNMP server configuration file (/etc/snmp/snmpd.conf ):

#
# "Pass-through" MIB extension command
#
pass .1.3.6.1.2.1.8072.2.1 /bin/bash /home/pi/pitemp
pass .1.3.6.1.2.1.8072.2.2 /bin/bash /home/pi/powerswitch

Once again the smnpd needs to be restarted. Our read/write actions can be tested by:

$ snmpget -c public -v 1 localhost .1.3.6.1.2.1.8072.2.2
SNMPv2-SMI::mib-2.8072.2.2 = INTEGER: 0
$ snmpset -c public -v 1 localhost .1.3.6.1.2.1.8072.2.2 i 1
SNMPv2-SMI::mib-2.8072.2.2 = INTEGER: 1
$ snmpget -c public -v 1 localhost .1.3.6.1.2.1.8072.2.2
SNMPv2-SMI::mib-2.8072.2.2 = INTEGER: 1

NodeRed Setting SNMP Values

The exec node can be used to call the snmpset command.  A example with an ON and OFF button is:

gpio_logic

The configuration for the exec node is:

exec_node

And the web dashboard is:

gpioSS

Summary

Network monitoring and SNMP is huge topic, hopefully this will give you a good start.