Projects

Part 2: Connecting the Dots

Mike Lewis

Issue 15, September 2018

This article includes additional downloadable resources.
Please log in to access.

Log in

We take Node-RED to the cloud, for powerful, worldwide access to your IoT dashboard.

BUILD TIME: 90 MINUTES
DIFFICULTY RATING: INTERMEDIATE

While many of us are first introduced to Node-RED on the Raspberry Pi, you don’t actually need any physical hardware to run Node-RED and monitor your IoT devices.

In Part 1 (Issue 13), we took you through the process of setting up Node-RED on a Raspberry Pi.

This time we’ll explore how to host Node-RED in the Cloud. We will then enhance our applications using public API’s and setting up HTTP routes and responses to display the results.

While you won’t need any hardware to follow along with this tutorial we will show you some great tools and methods that you can then use in your IoT projects.

It’s helpful if you followed Part 1 so that you are familiar with the basics of Node-RED, although not required.

Why The Cloud?

I know what you’re thinking - why put it in the cloud when I have a perfectly good Raspberry Pi for the job? And indeed, the answer isn’t quite clear cut. It really depends on your application, and how you want to be able to access your dashboard.

By setting up Node-RED in the cloud, you instantly overcome the firewall / routing issues that you can have when trying to access a private device publicly. Sure, we’ve shown you how to do this securely using VPN (see Issue 14), but having it on a cloud service makes things much easier to access for anyone, with no additional setup required.

Clearly, things like password security come into play here, as with any publicly-accessible system, but you gain unobstructed access to your dashboard from anywhere!

WHAT ARE THE DOWNSIDES?

Obviously, you don’t have GPIO hardware access in the cloud. So your dashboarding is limited to monitoring over standard protocols. But that’s really not a downside and is easily accommodated.

If you simply want Node-RED to monitor your house-plants for watering and need direct GPIO access without any real need for world access, then you probably won’t benefit from having your dashboard in the cloud.

However, there’s no reason you can’t have your in-house hardware transmit the data via MQTT or another service, to then include it in your cloud dashboard. Even if you do require some VPN tunnelling, you can configure it on the cloud server and still access everything publicly. This is quite a secure methodology and overcomes many issues.

Node-RED Cloud Providers

First up we’ll need to select a cloud provider. There are lots to choose from and it may come down to personal preference. Below is a comparison table of some of the popular choices.

We have chosen IBM Bluemix for this tutorial because it’s a good starting point since they have a Node-RED boilerplate application making setup quick and easy.

ProviderSetupCredit Card requiredNotes
IBM BluemixAutomatedFree lite plan: App will sleep after 10 days of development inactivity.
SenseTecnic FREDAutomated Quickest to set up but has the most limitations on the free plan. Great if you just want to have a quick play with Node-RED. Free plan limited to 50 nodes and only runs for 24h after you log out. Integrated MQTT on paid tiers.
Amazon Web ServicesManualMy personal preferred cloud provider. 12 months free tier includes EC2 micro server instance 750 hours per month.
Google CloudManual 1 free f1-micro instance per month.
Microsoft AzureManual12 months free tier includes B1S virtual machine - 750 hours per month.

IBM Bluemix Setup

Head to https://console.bluemix.net/ and sign up for an account.

Once you've signed up and logged in:

  • Select Catalog
  • Search "Node-RED"
  • Select the Node-RED Starter

The lite badge indicates that this instance is using a lite plan (free, with no time restrictions). Give your app a unique name. For the region we will have to accept the default of US South, as this is a restriction of the free plan. To be eligible for the free plan also select Lite for SDK for Node.js and Cloudant.

create

Select Create. It will take a few minutes for the app to be created then you will be redirected to the app’s dashboard.

dashboard

On my first attempt the app’s service failed to start (Maybe I wasn’t patient enough), but a simple restart of the service got it running.

Once the app is running select Visit App URL. You should see the Node-RED setup screen. Select Next to get started.

Since we’re running node-red in the cloud we definitely want to secure access with a username and password. Create a username and password and select Next.

welcome

We don’t need any extensions right now so we can just select Next, then finally select Finish to complete the setup. If you would like to install extensions later, you can always do so from the Node-RED admin.

Now you can either select “Go to your Node-RED flow editor” or navigate to https://(app-name).mybluemix.net/red/replacing (app-name) with the application name that you specified.

Now that we have our Node-RED dashboard ready, let’s build something!

Build 1:

APIs and HTTP Endpoints

API stands for Application Programming Interface. To try and explain it simply, in web development an API is a service that can be called upon to retrieve information or do a task.

For this build we will use Node-RED to easily reach out to an external API and do something with the data we receive. For inspiration, there’s a list of free public API’s available: https://github.com/toddmotto/public-apis/

How can we go past the RandomDog pictures API? There’s also a RandomCat API but the internet has enough cat images already.

Let’s make a call to their API and use the returned URL to display the image on a web page.

Here’s an overview of the steps we need to take:

  • Setup a HTTP Endpoint
  • Retrieve data from an external API
  • Use the fetched API data on a HTML web page
  • Return a HTTP response containing the HTML

To get things started, open Node-RED and drag a HTTP input onto the workspace.

http node

Double-click the newly created HTTP node to edit and enter the URL /dogs, this will be our endpoint.

request node

Next, create a HTTP request node. Enter the API’s endpoint for the URL field: https://random.dog/woof.json?filter=mp4,webm (We’ve added a query string parameter to exclude videos)

For the Return field select “a parsed JSON object”. This will convert the fetched string into a JSON object ready for us to work with.

JSON

Before we continue building the application, let’s take a quick detour to test the API and examine the received JSON object to ensure everything is working as expected. Drag in an inspect node and a debug node onto the workspace and wire the inspect, HTTP request and debug nodes together in that order then select the Deploy button.

deploy

Select the blue button on the Inspect node which will trigger our program to run once. Now, under the debug sidebar you should be able to explore the JSON object stored on the msg object as the payload property (msg.payload). The object should look like the example below:

msg {
  payload {
    url: "https://random.dog/9e66-fd9eece96.jpg"
  }
}

Hopefully, everything so far is going to plan! Ok, back to our project. Let’s clean up by deleting the inspect and debug nodes. You can optionally leave them in place if you prefer to assist in future troubleshooting.

Now it’s time to write the HTML code that will be served, we’ll also make use of the URL property from the JSON object data that we received from the API call and insert it into an HTML image element. Drag in a template node and edit.

Enter the following HTML code:

<html>
  <head>
    <title>Dogs!</title>
    <style>
    img {
      display: block;
      max-width: 300px;
      }
    </style>
  </head>
  <body>
    <h1>Random Dog Picture</h1>
    <img src="{{payload.url}}" />
    <a href="/dogs">Show me another!</a>
  </body>
</html>

You may notice one section of this code is not actually HTML - {{payload.url}}.

By default, Node-RED templates use Mustache formatting. This allows us to easily insert our object data. With Mustache formatting, you can also apply very simple logic similar to if and loop statements. Read more about Mustache at: https://mustache.github.io/mustache.5.html

Finally, create an HTTP response node and wire the four nodes together and select Deploy.

nodes

To see the results, point your browser to https://.mybluemix.net/dogs

search results

You might be thinking dogs are great but why would we bother with Node-RED?

What we’ve successfully done here is aggregated data from a URL. This has far-reaching applications and can easily be implemented in all sorts of ways. You could be requesting images from a Raspberry Pi Camera, photo library, or non-image data too! This is merely a fun example to play with and get used to HTTP requests from remote servers.

Build 2:

Weather API

First, to keep things neat, create a new tab to store our weather flow logic.

weather tab

Create an HTTP in node. Edit and give it the URL /report.

get report

Now, before creating the next request node we’ll need to select a weather API to use.

We have decided to use OpenWeatherMap for its simplicity and it’s free! To access this service we will need to sign up for an API key. Head over to https://home.openweathermap.org/users/sign_up and create a free account.

Once you’ve signed up, navigate to home.openweathermap.org/api_keys and take note of your API key, that’s all! It takes about 10 minutes for your key to be activated before you can use it. You should receive an email when it’s ready.

api key

While you’re waiting, let’s continue building our application. Back in Node-RED, create a HTTP request node. For the URL, enter the following, ensuring to enter your API key at the end: api.openweathermap.org/data/2.5/weather?q=sydney,au&units=metric&APPID=your-api-key

Note: We’ve adjusted this query to return metric results. Read the documentation on OpenWeatherMap’s website to learn how to customise these calls to suits your needs.

Also make sure to select “a parsed JSON object” under return, as we’re expecting to receive a JSON response.

json object

Now let’s test it. Create a debug node and wire all nodes together and select Deploy.

nodes

In another browser window, navigate to https://(app-name).mybluemix.net/report

The page will not load because we have not yet set up an HTTP response, however, we should be able to see a log of the API data that we received.

Back in Node-RED, open the debug sidebar. This is where you’ll be able to explore the response object and see what data is available for us to use. The data we are interested in is:

msg.payload.main.temp
msg.payload.wind.deg

From here we could display the temperature and wind data onto a web page, but let’s make things a little more interesting and use some logic on the data. One of the great things about Node-RED is the option of computation on the received data to help interpret results into something meaningful.

We’ll make a surf report that finds good waves for surfers in Sydney. Good waves depend on the wind direction and the direction that the beach is facing. We’ll just ignore all the other factors that help to make great waves (swell, tide, wind speed, the number of sharks, etc.) but let us know if someone expands on this demo, I’d love to try it out!

After making a call to the weather API we’ll then run this data through a series of functions to get the desired results.

From the fetched JSON response object, we have access to the wind direction in degrees (0-360), let’s convert this integer into an easy to read string such as “N” for North.

Drag in a function node and edit. Use “Wind direction” for the name of the function then add the following JavaScript code:

const degree = msg.payload.wind.deg;
function windDirection(degree) {
  if (degree>337.5) return "N";
  if (degree>292.5) return "NW";
  if (degree>247.5) return "W";
  if (degree>202.5) return "SW";
  if (degree>157.5) return "S";
  if (degree>122.5) return "SE";
  if (degree>67.5) return "E";
  if (degree>22.5) return "NE";
  return "N";
}
msg.wind_direction = windDirection(degree);
return msg;

We’re creating a property called wind_direction on the msg object and storing the result to use later.

wind direction

Next, we'll add in some of the popular beaches in Sydney and use a switch statement to match the current wind direction to the ideal conditions for each beach.

Drag another function node into play and edit. We’ll call this one “Find a good surf beach”. Then, enter the following JavaScript code:

let beach;
switch (msg.wind_direction) {
  case "SW":
    beach = "Manly";
    break;     
  case "W":
    beach = "Palm Beach";
    break;
  case "NW":
    beach = "Bondi";
    break;  
}
msg.beach_found = beach;
return msg;

Now, we’ll prepare the report to use on our HTML page storing the results as a string on the msg.report property. Create one last function node. Name this one “Surf report” and add the following JavaScript code:

const temp = msg.payload.main.temp;
let report;
if (msg.beach_found){
    report = msg.beach_found + " is pumping!";
    if (temp < 20) {
      report += " Bring your wetsuit!";
    }
} else {
    report = "No decent waves, it’s maker time!";
}
msg.report = report;
return msg;

This will check if a suitable beach was found in our previous function by looking up the msg.beach_found property.

If found we can return the name of the beach. We’ll also add a condition to check the temperature and if it’s less than 20°C we'll add some text onto the string with a message to bring a wetsuit (yes, I’m a wuss). Otherwise we can let the user know there's no decent waves found at the moment.

With the logic now sorted we can write the HTML for our data to be displayed. Create a template node and add the following HTML code:

<html>
  <head>
    <title>Surf Report</title>
  </head>
  <body>
    <h1>Surf Report</h1>
    <p>
      Temp: {{payload.main.temp}} ℃
      <br /> 
      Wind: {{wind_direction}}
    </p>
    <p>{{report}}</p>
    </body>
</html>

Finally, create an HTTP response node to serve the HTML page back to the user. Connect all the nodes together like so:

nodes

Select Deploy, then browse to https://.mybluemix.net/report to view the page.

WHERE TO FROM HERE?

You could send the data back to your IoT device(s) to use, via MQTT or HTTP endpoints to return a JSON file (creating an API of your own!). One use case could be to have your surf report displayed on a LED matrix mounted to the wall inside your house. Perhaps broadcast to multiple locations so your friends can meet you there!

If you’re not into surfing, perhaps a surf report is not very useful. However, we’ve shown how we can harness the power of Node-RED when dealing with responses to aggregate, and also perform some logic to humanise the responses somewhat.

If you’re aggregating temperature data or water levels for an array of sensors, you can transform them into different colours based on the reported ranges, and so much more.

surfs up

PART 1