Extending the Arduino IoT Cloud with FRED

Augment an Arduino-based weather station with external service notifications using the FRED Cloud-hosted Node-RED service.

Introduction

In this tutorial we’ll show you how to augment the Arduino Cloud service using the FRED cloud-hosted Node-RED service for some simple data processing and notifications. This is a common use-case for FRED and Arduino Cloud. Arduino cloud offers a basic data gathering and dashboard facility, and FRED is used as a general purpose programming system to add value to the Arduino cloud.

Once you master this basic pattern – of offloading processing from Arduino to FRED, you can use it for a variety of use cases, such as:

  • Adding sophisticated cloud processing such as complex event management or cloud based machine learning to analyse your sensor data
  • Leveraging third party service via FREDs easy nodes – eg IBM Watson, GE’s Predix or external DB services such as InfluxDB
  • Gathering and combining data from multiple locations and sensors, combining with public data like traffic or weather and building complex, interactive dashboards.

For this tutorial, we’ll create a connected temperature and humidity sensor using an Arduino MKR WiFi 1010 connected to a DHT11 sensor.  We’ll also add an external LED to indicate when the temperature is too high or low.

We’ll show you how to connect this device to the Arduino cloud service, create a ‘Thing’ in the service that exposes several properties corresponding to the sensors and LED.   We can then use the arduino-cloud dashboard to interact with the device.

Finally, we show how we can develop a simple processing flow in Node-RED, that uses the arduino-cloud nodes available on the FRED service to connect to the “Thing” on the arduino cloud and do some simple data processing as well as send data to an external notification service.  For this tutorial we’ll use the PushBullet service.

An overview of the set up is shown below.

Figure 1. Using FRED Service for processing and integration with IoT Cloud

This tutorial will talk you through the 4 main steps:

  1. Setting up the Arduino Weather Station Prototype board
  2. Connecting to the Arduino IoT Cloud
  3. Developing the Node-RED flow on FRED
  4. Connecting to the Pushbullet external notification service

The Weather Station Prototype

The prototype weather station device we’ll use is shown in Figure 2.

Figure 2. Prototype weather station with DHT11 temperature and humidity sensor and LED indicator light.

For this prototype you’ll need the following:

  • Arduino MKR Wifi 1010 with USB cable to connect to your PC
  • breadboard and jumper cables
  • An LED
  • 220 ohm and 10K ohm resistors

You can wire up the device as shown in Figure 3.

Figure 3. Breadboard diagram of prototype weather station.
Figure 4. Schematic for weather station.


Testing the Device Using a Local Sketch

To ensure the device works, we’ll upload a test program into the device that reads from the sensors and blinks the LED every two seconds.  The test program in the Appendix Listing 1 blinks the LED, reads the DHT11 sensor and sends the current readings to the serial monitor output.  

To upload this sketch, you’ll need to install and run the arduino editor and connect the device to your Mac or PC using a USB cable.  While you can download and run the arduino IDE locally, for this tutorial, we’ll use the arduino web-editor.  To get started see the Getting Started with Web Editor tutorial.   

To use the web editor, you need to create an Arduino account.  (You’ll need to do this to use the arduino cloud service later anyway so now is a good time to get that done.)  Once you have an account, you need to install a browser plugin.  Finally ensure your Arduino board plugged into the USB port is recognized by the computer.

Before you can upload the test sketch, you’ll need to include the DHT Sensor Library.  To find it, click on the Library Manager button on the web editor, and then search for DHT as shown in Figure 5.  It will likely be near the top as shown.  Click on the star to make it available in your favourites so you can use it in your sketches.

Figure 5. Search for DHT Sensor Library using the Library Manager.

You can then copy it to your editor and upload it to your board to ensure the board is working.  Once this is done you should see the onboard LED blinking on the board every second.  

Click on the Monitor tab to see the following in the monitor:

Humidity: 34.00%  Temperature: 18.00°C 64.40°F  Heat index: 16.74°C 62.14°F
turn LED on
Humidity: 34.00%  Temperature: 18.00°C 64.40°F  Heat index: 16.74°C 62.14°F
turn LED off
Humidity: 34.00%  Temperature: 18.00°C 64.40°F  Heat index: 16.74°C 62.14°F
turn LED on
Humidity: 34.00%  Temperature: 18.00°C 64.40°F  Heat index: 16.74°C 62.14°F
turn LED off

If you have any issues, ensure the DHT11 and LED are connected correctly, ensuring the correct pins are connected, and the polarity of the LED is correct.  If all goes well, congratulations, you’ve just built a prototype weather station!

Connecting the Device to IoT Cloud

Next we’ll connect our device to the arduino cloud service. This involves the following steps:

  • Adding a “thing” to represent our device and its properties.
  • Connecting our device to the IoT Cloud platform.
  • Associating the physical device with the thing.  This causes some code to be generated to handle the thing properties.
  • Updating the code needed to keep the thing properties are kept in sync with the real world weather station device sensor values and state of the LED.

To get started with Arduino Cloud you can follow the Getting started with the Arduino IoT Cloud.

We’ll go through the steps with our specific device.

Adding a Thing

In the IoT Cloud click on Things, and then the Create Thing button.

Figure 6. Creating a Thing in the IoT Cloud.

Name your thing appropriately.  We used Weather Station. Then, add variables that are associated with the DHT11 sensor and the LED by clicking on Add Variable as shown.

Figure 7. Weather Station Add Variable button.

Adding Variables to Things

Add the following variables:

humidityfloat type as shown.  You should configure it in the UI as Read Only, and update periodically every 2 seconds.

Figure 8. Adding humidity variable

temperature – create it as a CloudTemperature type, read-only and updated every 2 seconds.  The CloudTemperature type is in the Energy category of types.

Figure 9. Add temperature variable

red_led – boolean type.  This should be configured as Read & Write, and updated On change.

Figure 10. Add red_led variable

Now we have a Weather Station thing representing our device in the platform as shown.

Figure 11. Weather Station Thing with three variables.

Next, we need to connect our device to the IoT Cloud!

Connecting our Device

To add our device, you can click on the link/Select Device button and select an Arduino device.

Figure 12. Select Arduino device.

You must then wait for the platform to connect to your local device.  If all goes well the browser will display something similar to the following:

Figure 13. Arduino MKR WiFi 1010 configuration.

Click on configure, and give your device a name.

Figure 14. Naming your device.

Once this is done the platform will upload a new sketch into the device that has the code necessary to communicate with the Arduino IoT Cloud.  Click on Done and your device will be shown.

Figure 15. Device shown in the Devices list.

Note that if your device is not linked to a thing as shown you can click on the Things Tab and then click on the Associate Device on the Weather Station thing to link it to your device.

At this point, you have created a thing, added the device, and uploaded a sketch to the device to support communications with the IoT Cloud.  Next we’ll modify the sketch to support the DHT11 and the LED.

Update Sketch to Update Thing Properties

To update the sketch you can click on the Sketch tab as shown below.  Clock on the Open full editor button to modify the sketch and its configuration in the Web Editor.

Figure 16. IoT Cloud Sketch Tab

Your Editor will look something like the following.

Figure 17. Web Editor with generated weather station sketch.

Click on the Secret tab and ensure the SSID and password for your wifi network is set correctly.

Notice the template sketch provided by the platform (See Appendix Listing 2) provides placeholders for you to fill in the loop code and onRedLedChange() with your own code.  This is where we need to add the code to read our sensor and turn the LED on and off.

Before we can read the DHT11 we need to include the library.  Click on the Libraries tab and then your favourites for the DHT11 library, and then Include the DHT11 library.

Figure 18. Including the DHT11 Library.

Now, replace the sketch generated by the platform with the code in Appendix Listing 3 following (copy paste into the same file).  This will fill in the loop() and onRedLedChange() methods and set up the DHT11 sensor reading.

Click on the Upload and Save -> button to upload and save this new sketch into the Arduino.  If all goes well, your device will now keep the IoT platform thing variables up to date as shown.

Figure 19. Updated Thing variables shown.

Developing Node-RED Flow on FRED

Next we’ll create an API key on the IoT Cloud to connect to FRED to do additional processing and notifications.

First, click on the Integrations tab, and then click on Create API Key.  Give the API key a name such as FRED.

Figure 20. Creating an API key to connect to FRED

Setting up FRED

Create an account on the FRED system https://fred.sensetecnic.com/  You can sign up for a paid plan or free plan.

Once you’ve created an account and validated your email, you will be able to login and see a standard Node-RED instance for creating your flows.  Before we can create our flow we need to install the Arduino IoT Cloud nodes.  Click on the Add or Remove Nodes tab on the left as shown below.

If you are new to Node-RED, you can find several introductory tutorials on our developer site and a complete programming course at our Node-RED programming guide.

Figure 21. Adding Nodes to FRED instance.

Search for Arduio and install the Ardiuno-Iot-Cloud nodes.  For debugging and simple charts we’ll use the Dataviewer node, and the Pushbullet node for notifications; install those as well.

We’ll initially create a flow that connects to the IoT Cloud and displays information and controls the LED.

First, drag a property node, and a data viewer node to display the data in a chart in the flow as shown.

Figure 22. Simple flow to create a chart of a property.

Next, configure the property node by double-clicking on it.  You’ll get the following modal.

Figure 23. Configuring the property node

Create a new arduino-connection by clicking on the pencil icon and fill in your Client ID and Client Secret you recorded when you configured your integration.

Figure 24. Adding IoT Cloud configuration node

Click on Add.  Your property node is now configured.  The node will communicate with the IoT cloud to retrieve the Things and properties it can interact with.

Select the thing for the property, “Weather Station”, and the temperature property.

Deploy the simple two node flow, and if all goes well, temperature readings should begin to appear in the data viewer.  The current value also appears under the property node as shown.  To see the values themselves, you may add a debug node to the property output as well.

Figure 25. Temperature property displayed in data view node

Congratulations, you’ve connected FRED to the Arduino IoT Cloud!  Next, we’ll add the humidity and LED control nodes using the following flow.

Figure 26. Flow to display temperature, humidity and control the red LED.

The flow illustrated above is shown in Appendix Listing 4.  You can import this flow by Click on the hamburger icon in the top right, choosing Import and then copying and pasting this listing into the import dialog as described in the Node-RED documentation.  

Given a few seconds you should now see both the current temperature and humidity readings and have the ability to control the LED.

Going Further: Adding High Temperature Notifications

Let’s take this a bit further and create a flow that lights the LED and sends a notification when the temperature rises above 20 degrees. We’ll then extend this to send notifications via Pushbullet. First, we’ll create a flow to detect the temperature and light the LED.

Figure 27. Flow to detect high temperature and light the LED

The flow shown above can be imported from Appendix Listing 5.  Note that the function node here is very simple; it sends a true or false in the output message payload depending the value of the message payload received:

if (msg.payload > 20) {
    msg.payload = true;
} else {
    msg.payload = false;
}
return msg;

This can easily be extended to do additional processing, perhaps a dynamic threshold, or check that the temperature is below freezing.

Connecting to Pushbullet

Next, let’s connect Pushbullet for remote notifications.  To use this service, you’ll need to sign up, install Pushbullet on your phone or computer and then create an API key.

Figure 28. Creating an access token on Pushbullet.

Record the API key (access token) provided; this will be used to connect FRED to pushbullet.

Now, add a pushbullet node to your flow as shown.  Configure it to push to your devices by providing the API key.

Now, you can modify the flow to include a function node to send notifications to Pushbullet when the temperature test transitions to true as shown.

Figure 29. Flow to send notifications to Pushbullet when temperature is high

The associated flow can be imported from Appendix Listing 6.

Note that the send notification function node uses the Node-RED context feature to maintain state about whether a notification has been sent already.  For more information on how Node-RED context works see the associated documentation.

The function Setup code (in the function node Setup tab) is as follows:

if (context.get("notificationSent") === undefined) {
    context.set("notificationSent", false);
}

The function node code that sends the notification is as follows:

let notificationSent = context.get("notificationSent");

if (msg.payload) {
    if (!notificationSent) {
        msg.payload = "Temperature is too high!"
        context.set("notificationSent", true);
        return msg;   
    }
} else {
    context.set("notificationSent", false);
}

Now, when the temperature transitions more than 20 degrees, the LED will light, and you’ll get a Pushbullet notification on your device!

Note that free pushbullet accounts are limited to 500 notifications per month so do not leave this flow running otherwise you may exceed your limit!

Conclusion

The Arduino IoT Cloud makes it very easy to connect Arduino devices and visualize basic sensor data. However, if you want to create simple IoT applications for monitoring and control, then you need a general purpose service such as FRED. By combining FRED and the Arduino IoT Cloud, you get the ease of connectivity of Arduino and the power and flexibility of FRED – a winning combination!

Appendix

This appendix contains the Arduino device sketches and Node-RED flows hosted by FRED that needed for this tutorial.

Listing 1

Test program for the weather station prototype device

/*
  Test weather station sketch
*/
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 2
#define DHTTYPE DHT11

const int ALERT_LED = 8;      // the number of the LED pin
bool led_state = false;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  pinMode(ALERT_LED, OUTPUT);
  
  // initialize the DHT sensor
  dht.begin();

  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  
  // This delay gives the chance to wait for a Serial Monitor
  // without blocking if none is found
  delay(1500);
}

void loop() {
  delay(2000); 

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old'
  // (its a very slow sensor)
  float h = dht.readHumidity();

  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);
  
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(f);
  Serial.print(F("°F  Heat index: "));
  Serial.print(hic);
  Serial.print(F("°C "));
  Serial.print(hif);
  Serial.println(F("°F"));
  
  if (led_state) {
    Serial.println("turn LED on");
    digitalWrite(ALERT_LED, HIGH);
    led_state = false;
  } else {
    Serial.println("turn LED off");
    digitalWrite(ALERT_LED, LOW);
    led_state = true;
  }
}

Listing 2

Template sketch generated by the IoT Cloud to communicate with the IoT Cloud that provides placeholders to update variables.

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Weather Station"
  https://create.arduino.cc/cloud/things/xxx-xxx-xxx-xxx-xxx 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  bool red_led;
  float humidity;
  CloudTemperature temperature;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
  ArduinoCloud.update();
  // Your code here 
  
  
}

/*
  Since RedLed is READ_WRITE variable, onRedLedChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onRedLedChange()  {
  // Add your code here to act upon RedLed change
}

Listing 3

Weather station prototype sketch to update humidity, temperature based on DHT11 readings and turn the red LED and off based on the state of the red_led variable.

// DHT sensor library - Version: Latest 
#include <DHT.h>
#include <DHT_U.h>
#include "thingProperties.h"

const int ALERT_LED = 8;      // the number of the LED pin

#define DHTPIN 2
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ALERT_LED, OUTPUT);
  
  // initialize the DHT sensor
  dht.begin();

  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
  ArduinoCloud.update();
  // Your code here 
  delay(2000); 

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old'
  // (its a very slow sensor)
  float h = dht.readHumidity();

  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();

  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  temperature = t;
  humidity = h;
  
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(f);
  Serial.print(F("°F  Heat index: "));
  Serial.print(hic);
  Serial.print(F("°C "));
  Serial.print(hif);
  Serial.println(F("°F"));
}

/*
  Since RedLed is READ_WRITE variable, onRedLedChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onRedLedChange()  {
  // Add your code here to act upon RedLed change
  if (red_led) {
    Serial.println("red_led on");
    digitalWrite(ALERT_LED, HIGH); 
  } else {
    Serial.println("red_led off");
    digitalWrite(ALERT_LED, LOW);
  }
}

Listing 4

Flow to display temperature, humidity using data viewer nodes and control the red LED using inject nodes.

[
    {
        "id": "ad260a66.fea098",
        "type": "property in",
        "z": "bfbf6707.89c1e8",
        "connection": "f4c46bfe.1d2748",
        "thing": "bd56b98b-2b40-4787-aa3e-da76eb100cf9",
        "property": "920f2567-7df8-408a-9c93-814d76d34b35",
        "name": "temperature",
        "propname": "temperature",
        "defaultname": true,
        "variableName": "temperature",
        "x": 190,
        "y": 200,
        "wires": [
            [
                "a4e71cd0.afb4b"
            ]
        ]
    },
    {
        "id": "a4e71cd0.afb4b",
        "type": "data-view",
        "z": "bfbf6707.89c1e8",
        "name": "",
        "property": "payload",
        "fieldType": "msg",
        "width": 200,
        "height": 160,
        "points": 10,
        "active": true,
        "passthru": false,
        "hide": true,
        "outputs": 0,
        "x": 440,
        "y": 200,
        "wires": []
    },
    {
        "id": "f4808533.8eff58",
        "type": "property in",
        "z": "bfbf6707.89c1e8",
        "connection": "f4c46bfe.1d2748",
        "thing": "bd56b98b-2b40-4787-aa3e-da76eb100cf9",
        "property": "69cf78e4-8f87-4cea-8741-106b5ebec761",
        "name": "humidity",
        "propname": "humidity",
        "defaultname": true,
        "variableName": "humidity",
        "x": 190,
        "y": 460,
        "wires": [
            [
                "28d52b3f.d1d694"
            ]
        ]
    },
    {
        "id": "28d52b3f.d1d694",
        "type": "data-view",
        "z": "bfbf6707.89c1e8",
        "name": "",
        "property": "payload",
        "fieldType": "msg",
        "width": 200,
        "height": 160,
        "points": 10,
        "active": true,
        "passthru": false,
        "hide": true,
        "outputs": 0,
        "x": 450,
        "y": 460,
        "wires": []
    },
    {
        "id": "c59a0433.d9ee28",
        "type": "property out",
        "z": "bfbf6707.89c1e8",
        "connection": "f4c46bfe.1d2748",
        "thing": "bd56b98b-2b40-4787-aa3e-da76eb100cf9",
        "property": "08ef1d84-3d38-4541-bcf8-7155540f841d",
        "name": "red_led",
        "propname": "red_led",
        "defaultname": true,
        "x": 440,
        "y": 680,
        "wires": []
    },
    {
        "id": "e4731397.15691",
        "type": "inject",
        "z": "bfbf6707.89c1e8",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 180,
        "y": 660,
        "wires": [
            [
                "c59a0433.d9ee28"
            ]
        ]
    },
    {
        "id": "fa7575e9.2ca8f8",
        "type": "inject",
        "z": "bfbf6707.89c1e8",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 180,
        "y": 720,
        "wires": [
            [
                "c59a0433.d9ee28"
            ]
        ]
    },
    {
        "id": "f4c46bfe.1d2748",
        "type": "arduino-connection",
        "applicationname": "IoT Cloud"
    }
]

Listing 5

Flow to light the red LED when the temperature rises above 20 degrees.

[
    {
        "id": "93e44a06.81f868",
        "type": "property in",
        "z": "a8d29cdf.fe1dd",
        "connection": "f4c46bfe.1d2748",
        "thing": "bd56b98b-2b40-4787-aa3e-da76eb100cf9",
        "property": "920f2567-7df8-408a-9c93-814d76d34b35",
        "name": "temperature",
        "propname": "temperature",
        "defaultname": true,
        "variableName": "temperature",
        "x": 130,
        "y": 160,
        "wires": [
            [
                "86194a5b.fc3188",
                "b5175095.a84f5"
            ]
        ]
    },
    {
        "id": "86194a5b.fc3188",
        "type": "function",
        "z": "a8d29cdf.fe1dd",
        "name": "",
        "func": "if (msg.payload > 20) {\n    msg.payload = true;\n} else {\n    msg.payload = false;\n}\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 340,
        "y": 160,
        "wires": [
            [
                "f658a4f6.4d72f8"
            ]
        ]
    },
    {
        "id": "b5175095.a84f5",
        "type": "data-view",
        "z": "a8d29cdf.fe1dd",
        "name": "",
        "property": "payload",
        "fieldType": "msg",
        "width": 200,
        "height": 160,
        "points": 10,
        "active": true,
        "passthru": false,
        "hide": true,
        "outputs": 0,
        "x": 330,
        "y": 240,
        "wires": []
    },
    {
        "id": "f658a4f6.4d72f8",
        "type": "property out",
        "z": "a8d29cdf.fe1dd",
        "connection": "f4c46bfe.1d2748",
        "thing": "bd56b98b-2b40-4787-aa3e-da76eb100cf9",
        "property": "08ef1d84-3d38-4541-bcf8-7155540f841d",
        "name": "red_led",
        "propname": "red_led",
        "defaultname": true,
        "x": 540,
        "y": 160,
        "wires": []
    },
    {
        "id": "f4c46bfe.1d2748",
        "type": "arduino-connection",
        "applicationname": "IoT Cloud"
    }
]

Listing 6

Flow that sends notifications when the threshold rises above 20 degrees.

Note that you are limited to only 500 notifications per month, so do not leave this flow running too long!

[
    {
        "id": "93e44a06.81f868",
        "type": "property in",
        "z": "a8d29cdf.fe1dd",
        "connection": "f4c46bfe.1d2748",
        "thing": "bd56b98b-2b40-4787-aa3e-da76eb100cf9",
        "property": "920f2567-7df8-408a-9c93-814d76d34b35",
        "name": "temperature",
        "propname": "temperature",
        "defaultname": true,
        "variableName": "temperature",
        "x": 110,
        "y": 140,
        "wires": [
            [
                "86194a5b.fc3188",
                "b5175095.a84f5"
            ]
        ]
    },
    {
        "id": "86194a5b.fc3188",
        "type": "function",
        "z": "a8d29cdf.fe1dd",
        "name": "test temperature",
        "func": "if (msg.payload > 20) {\n    msg.payload = true;\n} else {\n    msg.payload = false;\n}\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 340,
        "y": 140,
        "wires": [
            [
                "f658a4f6.4d72f8",
                "1c64469f.67b679"
            ]
        ]
    },
    {
        "id": "b5175095.a84f5",
        "type": "data-view",
        "z": "a8d29cdf.fe1dd",
        "name": "",
        "property": "payload",
        "fieldType": "msg",
        "width": 200,
        "height": 160,
        "points": 10,
        "active": true,
        "passthru": false,
        "hide": true,
        "outputs": 0,
        "x": 330,
        "y": 240,
        "wires": []
    },
    {
        "id": "f658a4f6.4d72f8",
        "type": "property out",
        "z": "a8d29cdf.fe1dd",
        "connection": "f4c46bfe.1d2748",
        "thing": "bd56b98b-2b40-4787-aa3e-da76eb100cf9",
        "property": "08ef1d84-3d38-4541-bcf8-7155540f841d",
        "name": "red_led",
        "propname": "red_led",
        "defaultname": true,
        "x": 560,
        "y": 100,
        "wires": []
    },
    {
        "id": "432d96f7.6fb348",
        "type": "pushbullet",
        "z": "a8d29cdf.fe1dd",
        "config": "6af4f9cc.950b08",
        "pushtype": "note",
        "title": "",
        "chan": "",
        "name": "",
        "x": 690,
        "y": 280,
        "wires": []
    },
    {
        "id": "1c64469f.67b679",
        "type": "function",
        "z": "a8d29cdf.fe1dd",
        "name": "send notification message",
        "func": "let notificationSent = context.get(\"notificationSent\");\n\nif (msg.payload) {\n    if (!notificationSent) {\n        msg.payload = \"Temperature is too high!\"\n        context.set(\"notificationSent\", true);\n        return msg;   \n    }\n} else {\n    context.set(\"notificationSent\", false);\n}\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "if (context.get(\"notificationSent\") === undefined) {\n    context.set(\"notificationSent\", false);\n}\n",
        "finalize": "",
        "x": 580,
        "y": 180,
        "wires": [
            [
                "432d96f7.6fb348"
            ]
        ]
    },
    {
        "id": "f4c46bfe.1d2748",
        "type": "arduino-connection",
        "applicationname": "IoT Cloud"
    },
    {
        "id": "6af4f9cc.950b08",
        "type": "pushbullet-config",
        "name": "Mike Pushbullet"
    }
]

Connecting FRED (Cloud Node-RED) to Ubidots

Adding a cloud Node-Red service to Ubidots for extra processing capability

Using motion sensor data to control home heating

Overview:

This tutorial is an example of using the FRED (Cloud Node-Red) service to augment Ubidots with some more sophisticated cloud processing. It solves a need that some users may have when using Ubidots, i.e. keeping state and aggregating multiple data sources. In this tutorial, we will be sending data from a PIR motion sensor, connected to a wifi-enabled particle proton. Of course you can use any sensor device you wish.

What is Node RED?showcase-flow

Node-RED is a visual tool for wiring the Internet of Things developed by IBM Emerging Technology and the open source community. Using Node-RED, developers wire up input, output and processing nodes to create flows to process data, control things, or send alerts. It works by allowing you to wire up web services or custom “nodes” to each other, or to things, to do things like:

  • Send an email on a rainy weather forecast.
  • Push sensor data to services like Twitter.
  • Perform complex analysis on data with ease.

If you’re new to Node RED you might find our Introduction to Node RED tutorial helpful.

Overview of the setup

Once you are ready to go – let’s take a look at the overall setup of the demo. In the diagram below, you can see the overall flow of data. When movement is detected by the PIR motion sensor, it is passed to the particle board, and then sent over WiFi via the Particle.io service, to the Ubidots cloud.

When data arrives in Ubidots, the data is also pushed out to FRED (via MQTT) where it is processed. When FRED has finished, the data is sent back to Ubidots, and can then be used to update a Ubidots dashboard where it is graphed.

Our use case for this setup is heating control in the home. We wish to turn on the heating in the house when several rooms are occupied. To do this, we need to gather occupancy info from all rooms, and when we reach a threshold, we signal the heating system to start. This is a simple, but representative example of how we can use Cloud Node-Red (FRED) to augment ubidots.

Since Ubidots doesn’t allow users to easily manage state and to aggregate data, it’s a great use of an external logic facility to handle that – that’s why FRED is so helpful here! 

Tutorial

Steps in this demo

  • Step 1: Setup Ubidots variables for the PIR sensor data
  • Step 2: Configure a webhook in Particle Cloud to push sensor data to Ubidots
  • Step 3: Create the Node-RED flow on FRED to process the data and send the command to the home to turn on the heating when the threshold is reached

Step 1: Setup Ubidots variables for the PIR sensor data

Create a UbiDots device by using the add device facility. Choose the  Blank Device category and name it “particle”.

Then create five raw variables: PIR, PIR2, PIR3, PIR4, totalpir. These correspond to our four motion PIR sensors and a synthetic variable, totalpir, which is the count of how many active sensors are triggered, i.e how many rooms are occupied in our home.

You will need to note down the token generated by Ubidots – this is used throughout this example to link together the particle device, FRED and ubidots virtual devices. It is shown hidden in our screenshot below, so make it visible and copy for later use.

Step 2: Configure your Particle device to push sensor data to Ubidots

There are two main steps needed to setup your Particle device and publish data. In this example we are going to use the MQTT library for Ubidots  which is provided by Ubidots.

  1. Device Setup: this step allows you to register your device with the Particle IDE and setup the IDE to generate code for your specific device.
  2. PUBLISH Values to a Device: in this step, we adapt the generic code provided by the Particle IDE to send our PIR value to Ubidots (and make sure we use the correct token so it is directed to our Ubidots device)

A comprehensive tutorial on using Particle devices with Ubidots is available on the Ubidots website. If you need more information head over there and read through – it includes links to other tasks such as creating Ubidots devices and variables so is a great resource.

In the Particle’s Web IDE create a New App and set the name. For additional details to creating a New App, head over to this article and return once complete.

Then select the libraries tab in the Particle IDE and select the UBIDOTSMQTT library. Make sure to add the last version library.

Click on INCLUDE IN APP. And return to “MYAPP.ino

This library creates by default a new Device. The name of this device will be “Particle” by default, and his label will be your Particle Core ID.

The default code that the Particle IDE generates, now needs to be adapted for our use case. You will need to:

  1. Fill in the TOKEN that you noted down when you first created the device in Ubidots. This links your particle board to Ubidots so it knows which specific Ubidots device this particle board is associated with.
  2. Update the main loop code to add the PIR value and publish to Ubidots
client.add("PIR", pir); // Insert as first parameter your variable label
client.ubidotsPublish("particle"); // Insert your device label where the
                                   // values will be stored

Input this code into the Particle Cloud IDE, and then publish to your particle device from the IDE. The full code listing is reproduced below, you can copy this and replace it in your IDE.

Particle code:

// This #include statement was automatically added by the Particle IDE.

#include <UbidotsMQTT.h>

#ifndef TOKEN

#define TOKEN “BBFF-…”  // Add here your Ubidots TOKEN

#endif

void callback(char* topic, byte* payload, unsigned int length) {}

UbidotsMQTT client(TOKEN, callback);

void setup() {

    Serial.begin(115200);

    client.ubidotsSetBroker(“industrial.api.ubidots.com“);

    client.connect();

}

void loop() {

    if(!client.isConnected()){

        client.connect();

    }

    int pir = digitalRead(D0);

    // Publish routine, if the device and variables are not created they will be created

    Serial.println(“Sending value”);

    client.add(“PIR”, pir); // Insert as first parameter your variable label

    client.ubidotsPublish(“particle”); // Insert your device label where the values will be stored

    // Client loop for publishing and to maintain the connection

    client.loop();

    delay(10000);

}

Step 3: Create the Node-RED flow on FRED to process the data and send the command to the home to turn on the heating when the threshold is reached

Now that we have the particle board sensing data and sending it to Ubidots (via the particle cloud) let’s build the Node-Red flow on FRED which we need to process the data. 

Create a FRED Account

If you don’t already have an account on FRED (Cloud Node-RED), set one up now. It’s free for a demo account, which can be used for these tutorials and any other experiments you may have with Node-RED. Register for a free account at http://fred.sensetecnic.com.

After registering, make sure to activate your account via your email. You will not be able to log in until you validate your account.

Our final flow will look like the one below.

To get started, head over to your FRED account, create a new flow canvas, and begin by creating a Ubidots in Node. 

Once you have created the Ubidots in node, click on it and you will see the following configuration screen.

UbiDots node’s configuration:

Fill in the Token field using the authentication token shown when you first created the device in Ubidots (it is shown hidden in our screenshot back in step 1) and the names of the variables you created in Ubidots (pir, pir2 ……)

Once you have configured the node, drag a function node to the canvas, and wire the output of the Ubidots in node to this new function node. Then click on the function node, name it totalPir, and copy the following code into the function.

This code is fairly simple and pulls the PIR sensor values from the incoming message (line 3), then calculates the aggregate value for all sensors on line 9, which it places in the outgoing message.

Next wire the output of the function node to a ubidots out node – this will allow us to see the aggregate value (totalPir) in our ubidots dashboard. Then connect a switch node and a http request node.

Then find and drag a switch node onto the canvas, and connect it to the function node. Configure it for the threshold value you want to trigger the heating. For example, if you require 3 rooms to be occupied before you turn on the home heating then set its value to 3.

Lastly, create a http request node, and wire that to the switch node. We don’t show the details here because each home controller is different. We assume that your home heating control has a web interface that accepts http commands for control.

How you configure this node is dependent on your specific home controller, but for some examples of how the http request node is used, take a look at this tutorial.

Finally, to check that everything is working locally, drag a debug node to the canvas and wire it up to the function node so that you can see the output locally before it is sent to Ubidots.

Running the demo

Once the flow is set up, we can hit the deploy button in the top right of the screen in FRED so that it is running in the cloud and then take a look at the output. Firstly, if you look at the debug node you will see the following:

Once you are sure that is working OK, head over to Ubidots and take a look at the UbiDots totalPir variable. It should look something like the screenshot seen below:

As you can see, as the flow runs in FRED it keeps track of the total number of motion sensors that are active and shows that on Ubidots. 

Conclusion

This is a simple example of how you can use the FRED service to combine cloud Node-RED with Ubidots. This allows you to keep all the ease of use and simplicity of Ubidots, but when you need it, to augment Ubidots with a full processing engine. Although the example we show here is quite simple, it should be clear that once you link ubidots to FRED, you have a full programming environment at your disposal. More complex examples of Node-RED flows could be used to:

  • aggregate Ubidots data with external data from web sources or other APIs, eg weather, open data sources etc (see tutorial)
  • use IBM Watson to add AI capability to your flows (see tutorial)
  • carry out complex event processing such as Fast Fourier Transform (FFT) or anomaly detection (see tutorial)

In fact, since Node-RED is a full programming environment, there is no limit to what FRED allows you to develop. FRED plus Ubidots – power through simplicity.

More info

A general introduction to Node-RED programming – free online course

A comprehensive set of Node-RED tutorials

Tutorials, guides and other info for Ubidots

FRED (Cloud Node-RED) and cryptocurrencies

Accessing Cryptocurrency data via the STS Binance node

We’ve seen a few folks playing around with FRED to access – and in some cases – trade on cryptocurrencies, which we thought was a fun use of Node-RED. Our very own crypto expert, Ted, here at STS decided to jump in and develop a new Node for accessing and using the Binance cryptocurrency platform. Continue reading “FRED (Cloud Node-RED) and cryptocurrencies”

Tutorial: Using the OSIsoft PI Web API node with FRED (Cloud Node-RED)

OSIsoft PI System is an industrial data management system that is widely used to capture, process, analyze, and store any form of real-time data. With the flexibility and powerful features of FRED, users can add more values to their current OSIsoft PI System. Continue reading “Tutorial: Using the OSIsoft PI Web API node with FRED (Cloud Node-RED)”

Using FRED (Cloud Node-RED) with the MultiTech LoRaWAN gateway

LoRa wireless modulation is a very popular wireless communication technology for IoT development. Its long range and low power consumption features make it suitable for many IoT applications. After we tested out the LoRaWan network on a single channel gateway in our previous blog posts, Continue reading “Using FRED (Cloud Node-RED) with the MultiTech LoRaWAN gateway”

Monitor a Pi Zero-hosted security camera with Node-RED, FRED and STS-MQTT

The new Pi Zero W is a great hardware platform for creating all kinds of interesting hardware gadgets.  With built in bluetooth, wifi, and a camera connector, it seems like the ideal system for creating a security cam.  Of course one of the best things about the Pi Zero is that it runs Node-RED! Continue reading “Monitor a Pi Zero-hosted security camera with Node-RED, FRED and STS-MQTT”

Use FRED (Cloud Node-RED) with LoRa modulation (P2P connection)

LoRa wireless modulation is growing in popularity for IoT development. Its long range and low power consumption make it suitable for many IoT applications. This blog post will discuss the experience setting up a LoRa P2P network using the Adafruit Feather M0 Lora module board and Dragino Lora/GPS HAT on a Raspberry Pi. Continue reading “Use FRED (Cloud Node-RED) with LoRa modulation (P2P connection)”

Use FRED (Cloud Node-RED) with LoRaWAN

LoRa wireless modulation is a very popular wireless communication technology for IoT development. Its long range and low power consumption features make it suitable for many IoT applications. After we tested out the LoRa P2P network in our last blog post, this post will focus on setting up a network of LoRa devices following the LoRaWan protocol and sending data to the The Things Network. Continue reading “Use FRED (Cloud Node-RED) with LoRaWAN”

Detect Presence using a FitBit, Node-RED and FRED

By hosting node-red in the cloud, FRED can act as an intermediary between devices and cloud services.  To illustrate this, let’s create a system that send a notification when a user wearing a Fitbit Flex comes in range of a Bluetooth scanner.  We’ll distribute the job of discovering and filtering bluetooth devices between a device and a FRED-hosted node-red instance.  This will allow us to change how notifications are delivered, or make use of the scanner for other purposes without changing the device flow. Continue reading “Detect Presence using a FitBit, Node-RED and FRED”