Integrating cloud analytics and a dashboard app into your IoT solutions

In the first article in this series, “Integrating LPWAN networking into your IoT solutions,” you learned how to monitor hay barns for humidity and temperature to identify dangerous conditions. You learned how to get sensor readings for temperature and humidity from NodeMCU devices to the IBM Watson IoT Platform. In this article, you learn how to preserve those readings in a database, how to display them in an IoT dashboard, and how to generate alerts.

What you’ll need to build your application

Because you are adding on to the IoT system that you built in the first tutorial in this series, you need to have completed the first tutorial before working on this one. To do that, you need:


Figure 1 shows the addition of the IoT cloud analytics system, including an IoT dashboard, to our overall IoT monitoring system (which also includes the IoT edge analytics system).

Architecture diagram


Create your IoT dashboard application

We will build our IoT dashboard application using Node-RED, and it will display the data that is sent to Watson IoT Platform and stored in a Cloudant database.

Create the IBM Cloud app

The easiest way to have a configured Node-RED, Cloudant, and IBM Watson IoT Platform is to create them together from a boilerplate.

  1. Log in to your IBM Cloud account.
  2. In the dashboard, click Create resource.
  3. Under the boilerplate heading, click Internet of Things Platform Starter.
  4. Name the application (the name should be unique, so haybale-< your name > is a good choice), and click Create.
  5. Wait until the application starts, and then click Visit App URL.
  6. Click Next.
  7. Configure a user name and a password for your Node-RED dashboard. I selected to let everybody view the editor because it’s a demonstration; you don’t have to do that.
  8. Click Next, and then click Finish.

Configure the IBM Watson IoT Platform

The next step is to configure the new IBM Watson IoT Platform.

  1. Return to the application’s console tab in the browser (the one where you were when you clicked Visit App URL).
  2. Scroll down to services, and click < your application name >-iotf-service. In it, click Launch.
  3. Configure the device type, and a device, as you did in the first article. Use the device ID tst to create a “device” for testing purposes. Use the authentication token testtest.
  4. Configure the security to allow unencrypted readings, as you did in the first article.
  5. Click test and then the Recent Events tab to see events.

Send MQTT messages to the Watson IoT Platform to verify it is receiving events

Now, we verify that the Watson IoT Platform is receiving events by using an MQTT client to send messages that mimic our sensor readings.

  1. Go to the HiveMQ client.
  2. Enter these parameters using the values from the credentials you set up when registering with Watson IoT Platform:
Parameter Value
Port 1883
Client ID d: :Hay-Sensor:tst
Username use-token-auth
Password testtest

Note that this MQTT library has a length limit on the client ID field, which is why we can’t call our device test: it is one character too long.

  1. Click Connect. Once the client is connected, the Publish panel opens. From now on, that is the part of the client you use.

  2. Publish to the topic iot-2/evt/sensorReading/fmt/JSON. Use the value {“temp”:0, “humidity”:0}.

  3. Go to the IBM Watson IoT Platform dashboard on the Recent Events tab to view the messages.
An event in the IBM Watson IoT Platform


Store the sensor data in the database

The next step is to receive the events in a Node-RED flow. This flow then formats the event messages and stores the information in a Cloudant database.

Follow these instructions to create the flow on your own. If you want to copy the flow and customize it as you follow along, copy the file JSON file from here to the clipboard and then in the Node-RED editor, click Import > Clipboard from the hamburger menu and paste the flow.

Create the flow to receive and store events

  1. Open the Node-RED editor at:
  2. Create a new flow:

    1. From the hamburger menu in the top right corner, select Flow > Add.
    2. Double-click the Flow 2 tab and rename it to IoT Flows. Change the status to Enabled. Click Done.
    3. Double-click the Flow 1 tab, the default flow, and change the status to Disabled (or delete it). Click Done.
    4. Click the IoT Flows tab.
  3. From the palette’s input section, drag the ibmiot into the main editor area.
  4. Double-click the IBM IoT node to configure it:

    1. Change the authentication to Bluemix Service to receive events from the IoT Platform that is already connected to our Node-RED application. The authentication is handled for you automatically.
    2. Click All for the device ID and for the format to see all the events.
    3. Click Done.
  5. From the palette’s output section, drag debug into the main editor area.
  6. Double-click msg.payload and change the output to complete msg object. Click Done.
  7. Draw a line between the IBM IoT node and the msg node, as shown in Figure 3.
IBM IoT node and the msg node


  1. Click Deploy > Full (you might need to log on first). When the application is deployed, the blue dots on the top right of the nodes disappear, and a connected message appears below the IBM IoT node.
  2. Use HiveMQ to send a few more messages to the IBM Watson IoT Platform.
  3. Return to the editor and view the debug tab in the right sidebar. Expand one of the messages; it should look similar to Figure 4.
Message on debug tab

Modify the messages

In the database, we want to have documents with the temperature and humidity as separate values, not part of a JSON string. Also, we’d want a timestamp. So, we need to reformat the messages we receive.

  1. In the Node-RED editor, from the palette’s the function section, drag the json node to the main editor area. Connect the IBM IoT node to the json node and then connect the json node to the msg node.
  2. Double-click the json node and select the action Always convert to JavaScript Object.
  3. Deploy the Node-RED application again, send another message, and see that msg.payload in the debug output is now a parsed object, not a string.
  4. In the Node-RED editor, from the palette’s function section, drag the function node to the editor. Connect the json node to the function node and the function node to the msg node.
  5. Name the function node add params.
  6. Write this function to add the device ID and time to the payload:

    msg.payload.time = new Date().getTime();
    msg.payload.deviceId = msg.deviceId;
    return msg;
  7. Deploy, test, and see that the msg.payload now has the time and deviceId.

Write the messages to the Cloudant database

Now that we have the message payload, we can write it to the database.

  1. In the Node-RED editor, from the palette’s storage section, drag the cloudant node to the editor.
  2. Double-click the cloudant node. Name the database events, and select Only store msg.payload object.
  3. Connect the new events node to the right side of add params node. Your flow now looks like Figure 5:
Connect new events node


  1. Deploy the Node-RED app. Then, send a few more events from the HiveMQ client.
  2. Return to the IBM Cloud Console.
  3. Open the -cloudantNoSQLDB database service under Cloud Foundry Services.
  4. Click LAUNCH.
  5. Click the databases icon on the left sidebar, and then the events database.
  6. Click Table to see the event information with all the parameters you entered, as shown in Figure 6.
See event information


Generate alerts

When either the temperature or the humidity exceeds a threshold, we want to issue an alert.

Looking at the article about hay bale fires, these are the alert conditions (assuming your system does not use the edge analytics in the second article in the series to deal with problems automatically):

Condition Alert
Humidity > 20% The hay is too wet, it needs to be dried (low priority).
Temperature (F) > 150 Entering danger zone, disassemble stacked hay bales to promote air circulation (medium priority).
Temperature (F) > 175 Call fire services about possible risk, stop all air movement to avoid fanning the flames (high priority).
Temperature (F) > 190 Remove hot hay with the help of fire services. Expect a fire (critical priority).

If your system does use edge analytics, the first two alert conditions do not require an alert. The edge analytics controls a heater and a fan to solve them automatically. You only need alerts when the temperature is above 175 ⁰F, because you need to call fire services.

Convert temperature sensor data from Celsius to Fahrenheit

The DHT11 that produces our temperature readings is Chinese. It uses Celsius. However, the article about hay bale fires presents its data in Fahrenheit. So, the first step is to add a node that calculates the Fahrenheit temperature.

  1. Return to the Node-RED editor.
  2. Drag a function node to the editor.
  3. Double-click the function node, name it CtoF, and use this function:

    msg.payload.tempF = msg.payload.temp*9/5+32;
    return msg;
  4. Connect the add params node’s left side to the CtoF node’s right side.

Calculate the status

Next, we calculate the status string. This is important, because we only want to generate alerts when the status changes.

  1. From the function section of the palette, drag the switch node, and name it tempAlerts.
  2. Double-click the switch node to configure it.

    1. Set the property to msg.payload.tempF.
    2. Set the top rule’s operator to >=, the data type to number, and the value 190.
    3. Click Add to create two more rules, both with the operator >= and the data type number. The first has the value 175, and the second 150.
    4. Click Add to create a fourth rule with the operator otherwise.
    5. Change the bottom value to stopping after first match.
Switch node configuration
  1. Click Done.
    1. From the function section, drag the template node to create a node with these parameters:
Parameter Value
Name On fire
Set property msg. payload.status
Format Plain text
Template Call fire services now! Fire expected!
  1. Copy and paste the template node you just created to create two more nodes, and change some parameters:
Parameter Template Node #2 Template Node #3
Name Stop air movement Start air movement
Template Fire likely, stop air movement to avoid fanning flames. Dangerously hot, promote air circulation.
  1. Connect the new nodes to the tempAlerts switch node’s right (output) side. The order is important: On fire on top, then Stop air movement, then Start air movement. The flow should now look something like Figure 8.
Order of the flow


  1. Create another switch node with these parameters:
Parameter Value
Name humidityAlert
Property msg.payload.humidity
Rule #1 >= 20
Rule #2 Otherwise
Type stopping after first match
  1. Connect the left (input) side of this humidityAlert switch node to the tempAlertsnode’s right side, to the bottom connector (for the “otherwise” case).
  2. Copy and paste the On fire node twice more to create these nodes:
Parameter Template Node #4 Template Node #5
Name Too humid Reduce humidity
Template Fine Everytime’s fine, no alert
  1. Connect the Too humid node to the top output of the humidityAlert node and the Fine node to the bottom one.

Create alerts

Finally, we can create alerts.

  1. From the function section of the palette, drag an rbe node. Set these parameters:
Parameter Value
Mode Block unless value changes
Property msg.payload.status
Name Report by Exception
  1. Connect the output of all five template nodes to the input for Report by Exception. This node stops the flow unless the property it watches changes. This prevents alerts for minor changes in temperature or humidity.
  2. For now, put a debug node after Report by Exception (with the default parameters). Disable the msg debug node above by clicking the checkbox at its right side.
  3. Your flow is now complete and can send alerts. Deploy your Node-RED app.
Deploy your Node-RED app


If you use edge analytics, there is no need for the Start air movement and Too humid nodes. Instead, you can just link to the input (left) side of the Fine node.


Of course, you can also not put the 150 value in tempAlerts and remove the humidityAlert node completely, going directly from tempAlerts to Fine — it is functionally the same. However, by keeping those values, we make it possible for the dashboard we create in the next step to show us when the fan or the heater should be on.

Send these messages using the HiveMQ client to verify that you get the correct alerts in the debug pane:

Message Expected result (in the debug tab of the right sidebar)
{“temp”:0, “humidity”:5} The status says that everything’s fine
{“temp”:0, “humidity”:15} Nothing, no change in status
{“temp”:0, “humidity”:25} New alert telling you to reduce humidify
{“temp”:50, “humidity”:25} Nothing, no change in status
{“temp”:70, “humidity”:25} New alert telling you to promote air circulation (remember, 70 Celsius is 158 Fahrenheit)
{“temp”:80, “humidity”:25} New alert telling you to stop air circulation
{“temp”:90, “humidity”:25} New alert telling you to call fire services
{“temp”:10, “humidity”:15} New alert telling you everything is fine

If you are using edge analytics, you can use the same messages. However, you will not get alerts telling you to reduce humidity or promote air circulation. You can skip messages 2 through 5 because they do not change the status.

Create a dashboard

Users of the Hay Barn Monitoring app want to have a dashboard to visualize and analyze the sensor data that the application collects and stores. In this step, we create that dashboard.

Create the initial dashboard

To create the initial dashboard, it is necessary to first import a Node-RED dashboard library.

  1. Click the hamburger icon on the top right.
  2. Click Manage palette.
  3. Click the Install tab. Type dashboard in the search field to reduce the number of results. Locate the node-red-dashboard library, and then click install. Click Install again.
  4. In the right sidebar, click the dashboard tab. Then, click the Layout tab. Click the dashboard > Layout tab in the right sidebar.
The Layout tab


  1. Click +tab to create a tab.
  2. Within Tab 1, click + group to create a new group.

Note: On a production system, you would have more meaningful names for tabs and groups.

Show the alert status

  1. From the palette’s dashboard section, drag text.
  2. Set these parameters:
Parameter Value
Group Group 1 [Tab 1]
Label Status
Value {{msg.payload.status}}
  1. Connect the Report by Exception node’s right side to the new Status node’s left side.
  2. Open a new browser tab and browse to http:///ui.
  3. Generate an alert.
  4. See that the browser tab now has the alert text, shown in Figure 12.
Browser tab with alert text


  1. Generate different alerts to see that the status changes.

Show the current readings

It could be useful to know what the current temperature and humidity values are. To do so:

  1. Create two dashboard > gauge nodes with these parameters:
Parameter Node #1 Node #2
Group Group 1 [Tab 1] Group 1 [Tab 1]
Type Gauge Gauge
Label Temperature Humidity
Value Format {{msg.payload.tempF}} {{msg.payload.humidity}}
Units F %
Range 32 – 212 0 – 100
Sectors 32… 150… 175 … 212 0… 20… 20… 100
  1. Connect both gauge nodes to CtoF. The new flow looks like Figure 13.
New flow


  1. Deploy the flow.
  2. Publish new values and see the temperature and humidity gauges show the values.

Show recent temperature chart

Now, we add to our dashboard a chart of recent temperatures.

  1. To start a new column, click the dashboard > Layout tab on the right sidebar. Select Tab 1 and click + group.
  2. Click edit on Group 2 and rename it to Recent History. Click Update.
  3. The chart node draws a chart of the message payload, with different series identified by msg.topic. To have the appropriate values, create a new function node after the CtoF node with these parameters:
Parameter Value
Name getTemp
Function msg.payload = msg.payload.tempF; msg.topic = msg.deviceId + ” temp”; return msg;
  1. Create a dashboard > chart node after the getTemp node with these parameters:
Parameter Value
Group Recent History [Tab 1]
Size 6 x 6
Label Temp
Type Line chart
X-axis last 1 hours
X-axis Label HH:mm:ss
Y-axis 0 – 240 (looks nicer than the actual range, 32-212)
Legend Show
Interpolate bezier
  1. Deploy and send some messages with different temperatures. The dashboard should look similar to Figure 14.
Dashboard with different temperatures


The URL for your dashboard will be https://<your application name>

Show the status of the fan and heater

If your system uses the edge analytics from the second article in the series to deal with problems automatically, it is useful to have an indication of whether the fan or the heater should be on. Here is how you create those indicators:

  1. Create a new function node, using these parameters:
Parameter Value
Name replicateEdgeAnalytics
Function = msg.payload.tempF >= 150 && msg.payload.tempF < 175; msg.payload.heater = msg.payload.humidity >= 20 && msg.payload.tempF < 150; return msg;

This node replicates the edge analytics, resulting in two Boolean values: if the fan should be turned on and msg.payload.heater if the heater should be on.

  1. Connect the output (right) side of CtoF to the input (left) side of replicateEdge Analytics.
  2. Create two dashboard > text nodes, with these parameters:
Parameter Value in the first text node Value in the second text node
Label Fan Heater
Value {{ ? “on” : “off”}} {{msg.payload.heater ? “on” : “off”}}

These nodes receive the values from replicateEdgeAnalytics and display them, using the ternary operator to display “on” or “off” as needed.

  1. Connect the output of replicateEdgeAnalytics to the inputs for Fan and Heater.
  2. Send different values to ensure you see the fan and heater on when appropriate.

Deployment considerations

In this example, the alerts go to the dashboard. That’s nice for testing purposes, but obviously it is not good enough in production. In a production application you would probably also use the IBM Push Notifications service for your alerts. With this service, you can send alerts by SMS. It also includes an API for writing alert applications for devices that do not have a cellular SMS number.

Another issue is dealing with multiple devices. The recent history chart, shown in Figure 15, automatically adjusts and shows multiple lines.

Recent history chart


Unfortunately, the gauges and alerts just rely on the latest information received. For the gauges, you can solve this by using a switch node and creating gauges for each, as shown in Figure 16.

Switch node with gauges


We could use a similar approach with the alerts, but then we’d have to replicate a fairly complicated workflow. A better solution would be to replace the Report by Exception node with a node that keeps a list of devices and their latest statuses and identifies whenever the status of a specific device changes.


With this tutorial, we added an IoT cloud analytics system, including an IoT dashboard that generates alerts to our IoT monitoring system. We stored the IoT sensor data in a Cloudant database, and we used Node-RED to generate alerts and create a dashboard for the user (a farmer) of our IoT solution. Throughout the series so far, we’ve explored integrating LPWAN networking and edge computing as well as pushing analytics out to the edge devices, and using the IoT data to generate alerts for the user of the IoT solution.

Ori Pomerantz