This is it. The grand finale. In this tutorial, you will pull together everything you’ve done so far and finish the home automation system. In Part 1 and Part 2, I showed you how to set up the IoT hardware and how to build the software that controls the hardware in the home automation system. In this final part, I’ll show you how to build:

  • The Cloud IoT Application that sends messages between the mobile application and the home automation Controller Application
  • The Home Automation Controller Application, which resides in your home to control the devices
  • The Device Controller Application, a mobile application to control the system over the internet

The architecture of the overall solution looks like this:

Figure 1. The big picture
The big picture

So imagine you left the house in a hurry and forgot to arm the Alarm system. No problem. You just need to pull out your smartphone, open the Device Controller app, connect to the Cloud IoT Application, and send a message to your Home Automation System App: Arm. Alarm is now set.

In this tutorial, you’ll put all the remaining pieces in place. Let’s get started.

1

Set up the Cloud IoT app

In the video below, I show you how to create the Cloud IoT app by using IBM Cloud and Watson IoT Platform, which acts as the MQTT broker, how to register your Raspberry Pi as an IoT device, and how to create an API Key for authenticating the application code that runs on the Raspberry Pi.

That said, the concepts I’m presenting here are not locked into the IBM Cloud platform by any means. When you understand the basic ideas, you can use any MQTT server to broker requests between client applications (like mobile devices) and the IoT device controller application that runs in your home and controls the home automation system.

When you’re finished with the video, follow the steps in this section to set up the Cloud IoT Application component of your home automation system.

1a

Create the cloud IoT app

Log in to your IBM Cloud account. The first screen that you see after you’ve logged in is your Dashboard.

Click the Hamburger menu in the upper left corner of the page, and then select Internet Of Things. You’ll see a screen like this one, where you can create an IoT service:

IBM Cloud create an IoT Service

Click the Create IoT service button, and you’ll see a screen with the IoT Service offerings. At the time of this writing there is only one for the IBM Cloud Lite plan: the Internet of Things Platform

IBM Cloud Internet of Things Platform

The Internet of Things Platform card shows you a brief description of what it is, and provides a link to create the service (I know, it seems like there are a million screens, but you’re almost done, I promise). Click anywhere on the card, and you’ll see the final screen:

IBM Cloud create Watson IoT Platform app

Give your application a name like Home Automation Cloud Platform, and then click the Create button at the bottom of the screen and you’ll be taken to your Watson IoT Platform Dashboard welcome screen:

IBM Watson IoT Platform dashboard

Click the Launch button to go to your IoT Platform App Dashboard.

Now you’re ready to register your Raspberry Pi as an IoT device with the Watson IoT Platform.

1b

Register your Raspberry Pi as an IoT device

On the left side of the IBM Watson IoT Platform dashboard, there is a vertical navigation menu. Click the second option from the top, called Devices, and you’ll see this screen:

IBM Cloud IoT Platform application dashboard

The first step in registering an IoT device is to tell the Watson IoT Platform what type of device it is, called a Device Type. The device type defines a class of devices that share similar characteristics, from which you will register “instances” of that device type (borrowing from Object-oriented concepts).

From the tabbed menu at the top of the dashboard, select Device Types, and then select Add Device Type. You will see a screen that looks like this:

Create a device type

Choose Device, and then give the device type a name that is descriptive of its function (only alphanumeric, underscore, hyphen, and period characters, are allowed), such as HomeAutomationController, and an optional description. Click Next. You will see a screen that looks like this:

Device type metadata

You can enter lots of metadata for the device type, such as serial number, model, and manufacturer, if you want (or none at all, it’s up to you). The device type metadata is optional, and doesn’t make sense (to me anyway) for the home automation controller, so I’ll skip it. Click Next to create the device type.

Now you’ll need to register a device so it can be authenticated to use the Watson IoT Platform. Again, borrowing from object-oriented concepts, if the device type is the class, and then the device is the object. Go back to the Browse tab, and select Add Device, and you’ll see this screen:

Add an IoT device

Select the HomeAutomationController device type that you created earlier, and give the device a unique identifier (called the Device ID), such as Controller-1, and then click Next, and you’ll see the now familiar metadata screen.

IoT device metadata

Enter metadata for the device like you see above, and then click Next to create the device’s authentication token. You can either provide your own authentication token or let Watson IoT Platform generate one for you. I recommend the latter option. Click Next, and then click Done. You will see this screen:

Figure 2. IoT device credentials
IoT device credentials

Make sure to store the device credentials in a safe place because this is the only time you will see them. After you leave this screen, you will not be able to recover the credentials. For the purposes of the tutorial, I recommend that you take a screen capture.

Important: don’t use the Authentication token value that you see here because it works for my Org Id only!

Now you’re ready to create the authentication credentials for the home automation controller application that runs on the Raspberry Pi.

1c

Create the API key for the home automation controller

Just as IoT devices that use the Watson IoT Platform must be authenticated, so too must applications that talk to (and on behalf of) those devices. For applications, this mechanism is referred to as the API key and consists of the key and an authentication token.

From the menu on the left in your Watson IoT Platform dashboard, find Apps and select it. The API Key browse screen comes up. On that screen, click Generate API Key, and you’ll see this screen:

Create an API Key

Give the API key a description such as HomeAutomationControllerAPIKey (something unique you’ll recognize later, and will use for your Node-RED code in the next step), and an optional key expiration. I’m not going to give this key an expiration date. Click Next, and you’ll see this screen:

API Key description and expiration

From the Role drop-down list, select Device Application, and then click the Generate Key button.

Figure 3. API Key credentials
API Key credentials

Now you’ll see your new API key and auth token. On this screen is the only time you will ever see the token, so keep it some place safe like your password safe. If you lose the token, you’ll have to regenerate the API key.

For the purposes of the tutorial, I recommend that you take a screen capture, and the delete it later. Again, don’t use the API Key and Authentication token values you see here, as they work for my Org Id only!

The table below summarizes all of the information I’ll need in Step 3. I recommend that you create a table (like the one below) with the values specific to your Watson IoT Platform application (and keep it in a safe, secure place, of course).

Table 1. Authentication information
Element Value
Org Id qsj4yy
API Key a-qsj4yy-qed27cliyw
API Key Auth Token a@x@XyXf!9fZDrdcQO
Device Type Home Automation Controller
Device ID Controller-1
Device Auth Token ZOUW)4B BMLOnnPbCU

Now that you have an API key, it’s time to create the Home Automation Controller Application by using Node-RED.

2

Create the Home Automation Controller app using Node-RED

Node-RED uses a style of programming called flow-based programming, a programming paradigm where code is broken up into a network of processes. Data, in the form of information packets flows into and out of a process. Processes are connected to each other such that the flow of information through the packets in the network determines what the overall program (Flow) does.

Node-RED is a flow-based programming tool, where you build a flow that consists of processes called nodes and the information that flows between them.

Using Node-RED and a web browser, you’ll now build the Home Automation Controller app, which will use your newly generated API key to communicate with the IBM Cloud and the Watson IoT platform.

The application you’ll build will control three 433-MHz devices:

  • Two RF Outlets
  • Home Alarm system

In the video below, I show you how to set up your Node-RED environment and how to write the application code that controls the 433-MHz hardware that is connected to the Pi.

When you’re finished with the video, follow the steps in this section to write the Home Automation Controller component of your home automation system.

2a

Set up your Node-RED environment

If you installed Raspbian Stretch as I instructed in Part 1, Node-RED is already installed on your Raspberry Pi. If you installed some other OS on your Raspberry Pi, make sure to follow the instructions for that OS for installing Node-RED. You can find more information on installing Node-RED on the Node-RED website.

Before you start Node-RED on the Pi, you need to install a piece of software called Node Package Manager, or npm.

Open a new Terminal Window, and run these commands:


 sudo apt-get update
 sudo apt-get install npm
 

The first command makes sure that your Raspbian distro has the latest packages to install, and the second command installs npm. You should see output like this, indicating that npm was successfully installed:

Install npm

Now from a Terminal window, start Node-RED:

node-red-start

You’ll see output like this, where Node-RED successfully starts:

Start Node-RED

Now, open a browser and point it to the address shown in the output (in my case that’s http://10.0.0.8:1880). You’ll see a screen like this one, showing the node palette on the left side of the page, an empty flow called Flow 1 in the middle, and on the right is an information window:

Node-RED user interface

Node-RED is up and running now. You will need to install a node called node-red-contrib-scx-ibmiotapp that your home automation controller will use to communicate with the Watson IoT Platform as an application (as opposed to a device, which we will talk about shortly).

To install node-red-contrib-scx-ibmiotapp, go to the hamburger menu in Node-RED in the upper right corner, and choose Manage Palette. Click the Install tab, and in the search field type ibmiotapp, and you should see the contrib node in the results:

Install ibmiot node

Click Install, and follow the prompts to install the node. After it is installed, you will see it in the palette.

One final detail: remember the codesend program from Part 2? You will need to run this program to send a signal from your Home Automation Controller application, so go ahead and set up a symbolic link to it in /usr/local/bin like this:


 sudo ln -s /home/pi/HomeAutomation/433Utils/Rpi_utils/codesend codesend
 

This command assumes that your code is located in /home/pi/HomeAutomation as I suggested in Part 1. If not, you’ll need to modify it to accurately reflect the path to 433Utils.

When you’re setting up the Node-RED exec nodes to execute the codesend program in the next section, you’ll reference this path: codesend.

Now (finally!), you’re ready to start building the home automation controller application.

2b

Write the controller code for the Single RF outlet

With Node-RED open in your browser, drag an ibmiot node on to the flow, and then double-click it to open the node properties dialog. In the API Key drop-down list, select Add new ibmiot, and click the edit (pencil) icon.

Add the API key for the IoT app

I recommend that you give the key a name that matches the Description field of your API Key (that you set up in Step 1), such as HomeAutomationControllerAPIKey. Enter the API key information that you generated earlier in Step 1, and then click Add. You’re taken back to the node properties screen, where you should complete the remaining information:

  • Device Type = HomeAutomationController
  • DeviceId = Controller-1
  • Event = request
  • Format = json
  • Name = App Request Listener

    Add an ibmiot node to the flow

Click Done to finish configuring the node. The ibmiot node’s job is to listen for incoming device events that match the settings that you gave it.

Next, add two switch nodes, which are located under the Function section of the palette. Drag them onto the Flow as shown below:

Add a switch node to the flow

The switch node checks to see whether the message payload property called payload.d.deviceRequest.deviceId matches Outlet-1. If it does not match, it does nothing. If it matches, Node-RED passes the message as input to the second switch node, which you will configure as shown:

Add a second switch node to the flow

The second switch node checks to see whether the payload.d.deviceRequest.action property matches one of two values: on or off. If it does, the message is passed as either output 1 (if on) or 2 (if off). If it does not match, the node does nothing (the flow stops). Click Done to complete the configuration.

Now connect the App Request Listener node to the first switch node by clicking and dragging a “wire” between them. Then, connect the first switch node to the second. Now you’re ready to handle the on and off messages.

Let’s step back for a minute and ask, “What do we want the home automation controller to do if it gets an on message for Outlet-1? Obviously we want to send a signal to turn on RF Outlet 1, right? So how do we do that?

With an exec node! An exec node is used to execute (as in, exec-ute) a program (in this case codesend). Scroll down in the palette to Advanced, and drag two exec nodes onto the flow. Double-click the first exec node to configure it like this:

An an exec node to the flow

Now, connect the “on” output of the “Outlet-1-Router” node to this node. If the ibmiot node receives an on message for Outlet-1, it will be routed here, where the command codesend 1119539 170 will be sent, turning on the outlet. (Make sure that you use the on value for your outlet, not mine.)

Now, setup an exec node that turns off Outlet-1 just like you did for on (remember to use the encoded value for “off” for your outlet). Wire everything up, click Deploy, and unless you’ve made a configuration mistake, you should see something like this:

Flow for controlling the first RF outlet

So now you need to run a test. How exactly do you do that?

Node-RED provides a special node called an inject node that allows you to send a message into a node. In this case, we’ll set up an inject node that sends a JSON payload into a Watson IoT node that acts as a device. Under the input section of the palette, select the inject node and drop it onto the flow. Double-click it to configure it. Change the Payload option to JSON, and paste in this string (FYI, clicking the ellipsis brings up a nice little JSON editor):


 {
                    "deviceRequest": {
                        "deviceId": "Outlet-1",
                        "action": "on"
                    }
 }
 

Call the node Outlet-1 ON, and click Done.

Next, under the output section of your Node-RED palette, click and drag a Watson IoT node onto the flow. Select “Connect as” Device, and then click the Credentials edit button to add the device credentials that you set up earlier for the HomeAutomationController (called Controller-1, earlier in Step 1):

Add device authentication information to Watson IoT node

Click Add, and you’re taken back to the node configuration dialog, where you should complete the remaining information like this:

  • Event type = request
  • Format = json
  • Name = RequesterAdd device configuration information to the node

Next, add another inject node to turn Outlet-1 off using this JSON message:


 {
                    "deviceRequest": {
                        "deviceId": "Outlet-1",
                        "action": "off"
                    }
 }
 

Wire it into the Requester node, and you’re nearly ready to run a test.

One last thing: add debug nodes to your flow so that you can see the outgoing message from the Outlet-1 ONinject node that you just set up, and the incoming message to the App Request Listener node. debug nodes are super easy to set up: select one under the output section of the palette, drop it onto the flow, and wire its input to whatever node’s output you want to see.

When you’re done, click Deploy, and your flow should look like this:

Complete flow for controlling the second RF outlet

To test, click the Outlet-1 ONinject node. If the RF outlet is off, it should turn on. Next, click the Outlet-1 OFF node, and the RF outlet should turn off.

Not impressed? Well, think about it. In both cases, the messages that were sent from the inject nodes on your Pi (that is, Outlet-1 ON and Outlet-1 OFF) were sent to your Watson IoT Platform MQTT server, and then back to your Pi, where they were handled by the App Request Listener node. It might not look like it, but you just went to the IBM Cloud and back!

Don’t believe me? Check out your Watson IoT Platform dashboard. Select the Browse tab, select the device (HomeAutomationController), and then the State tab to see the most recent event.

Watson IoT App dashboard showing the latest event

As you can see, there is the JSON message that was created by the Outlet-1 OFFinject node and sent through the Requester node. Pretty cool, huh?

Now you’re ready to add a second RF Outlet. I’ll give you all the information that you need, but not nearly as many details as for the first outlet. Make sure that you refer to this section as you work through setting up the second RF outlet.

2c

Write the controller code for the Dual RF outlet

Grab a second RF outlet, plug it into the wall, along with a visual or auditory feedback device (such as a lamp or radio). Make sure that you sniff out the 433 MHz encoding for the outlet (see Part 2 if you need a refresher for running RFSniffer to do that) for both on and off.

To add the second RF Outlet to your Node-RED flow, you will need to complete these steps:

  • Modify the Device Routerswitch node to add another condition to check for Outlet-2
  • Add another switch node called Outlet-2-Router to handle on and off for Outlet-2 just like you did for Outlet-1.
  • Add an exec node called Outlet-2 ON to invoke codesend, along with the 433 MHz signal values, to turn on Outlet-2.
  • Add an exec node called Outlet-2 OFF to invoke codesend, along with the 433 MHz signal values, to turn off Outlet-2.
  • Connect the wires for the new nodes just like you did for Outlet-1
  • Add two inject nodes (call them Outlet-2 ON and Outlet-2 OFF) to test your code, and wire them into the existing Requester node.

The completed flow looks like this:

Completed flow for controlling the second RF outlet
2d

Write the controller code for the home alarm

The final IoT device in your home automation system is an alarm. Any 433-MHz alarm with a remote control should work fine, but I recommended the CPVan because it’s simple, and it has good reliability for the price. The CPVan Window and Door system is what I’ll be using for this section of the tutorial.

Grab the remote control, start RFSniffer on your Pi, and sniff out the codes for all four buttons on the remote. You’ll need those values for the exec nodes that you’ll set up to control the system in this section.

Below is a table of the values from running RFSniffer for my CPVan alarm system:

Table 2. CPVan Alarm encoding values ( yours will be different)
Function Encoded Signal Delay (microseconds)
Arm Away 12935172 434
Arm Stay 12935170 434
Alarm Off 12935169 434
Panic (SOS) 12935176 434

Next, in your Node-RED flow, make the following code changes:

  • Modify the Device Routerswitch node to add another condition to check for Alarm-1.
  • Add another switch node to handle the four actions: arm-away to arm the system when you leave your home (enables the motion sensors) arm-stay to arm the system while you’re at home or if you have pets (disables the motion sensors) off disables the alarm panic sounds the alarm
  • Add an exec node to invoke codesend (along with the 433 MHz signal values) to arm-away``Alarm-1.
  • Add an exec node to invoke codesend (along with the 433 MHz signal values) to arm-stay``Alarm-1.
  • Add an exec node to invoke codesend (along with the 433 MHz signal values) to turn off``Alarm-1.
  • Add an exec node to invoke codesend (along with the 433 MHz signal values) to trigger the panic for Alarm-1.
  • Connect the wires for the new nodes just like you did for Outlet-1 and Outlet-2.
  • Add four inject nodes to test your code, and wire them into a new Requester node (which you can easily create with copy/paste).

The completed flow looks like this (I’ve moved some of the nodes closer together so they’ll fit on one screen):

Completed flow for controlling the home alarm

Now you have a fully tested home automation system with two RF outlets and an alarm. At this point, you should have the knowledge and skill to build on what you’ve done to add more IoT devices to your home automation system.

Want to have some real fun? Of course you do! In the final section, you’ll bring it all together to control the home automation system from a mobile app!

Oh, I forgot to mention something: all of the flows are in GitHub for your reference. Go to makotogo/developerWorks in GitHub. So, if you have any trouble getting anything in the sections above to work, you can check out the solution that worked for me.

3

Create the Device Controller mobile app by using Android

I’ve chosen Android as the mobile application platform. That said, you are free to write the client application in any language and on any platform you choose, as long as it can communicate with the Watson IoT platform in the IBM Cloud.

Now that your Node-RED application is running on the Pi and connected to the IBM Cloud, you can write an MQTT application client to connect to it and control your home automation system. I’ve written one called Device Controller, and I’ll walk you through how to use it.

In the video below, I show you how to download the Device Controller Android app code from GitHub, import it into Android Studio, and run the app in the Android emulator to control your home automation system.

When you’re finished with the video, follow the steps in this section to use the home automation controller component of your home automation system.

3a

Download and install Android Studio

You’ll need to download and install Android Studio to continue with the rest of this tutorial. Installing Android Studio is super easy. Check out the Android Studio installation page for complete instructions for your platform.

I use a Mac, so that’s what you’ll see in the rest of the tutorial (and the video), but the instructions I present here should work fine for any platform that supports Android Studio, including Windows and Linux.

3b

Download the Device Controller app code from GitHub

I’ve written an Android app called Device Controller that you can download from GitHub and import into Android Studio.

If you’ve already cloned the developerWorks repository from the makotogo project in GitHub, you might already have the code. If not, open a Terminal window, and clone the code from GitHub:

git clone https://github.com/makotogo/developerWorks

Now open Android Studio and choose Import project, go to the location where you cloned the developerWorks/DeviceController code, and click Open.

After the code is imported, Android Studio will build it, which might take several minutes.

3c

Run the app in the emulator

From the Android Studio menu bar, click the Run button to run the app. Android Studio will ask you to choose a virtual device on which to run the app. If you have not created one and need help, check out this page for creating and managing virtual devices.

After the app comes up, you will be on the Home Screen, where you will need to enter your Org ID, API Key, auth token, and information about the HomeAutomationController device. For me, I’ll use the values from my table I created, and enter that information so that it looks like this:

Figure 4. Android IoT Device Controller app – Home Screen
Android IoT Device Controller app - Home View

Remember: the values of Org Id, API Key, and Auth Token will be different from those values you see above (which work for my IBM Cloud Lite account only)!

The app uses the Bottom Navigation material design pattern. Each of the four views in the app has an icon in the bottom navigation drawer. The views, from left-to-right, are:

  • Home — enter connection information
  • Devices Dashboard — control the IoT devices
  • Message Log — see messages from the system
  • Settings — enter settings for system information (you don’t need to worry about these settings for the app to work)

Now you should be oriented to the app. The two views I’ll show you in this tutorial are Home and Dashboard.

From the Home screen, after you’ve entered the information as you set it up in your Watson IoT Platform dashboard, click Connect to connect the application. If you’ve entered the information correctly, you should see a Toast message that tells you that you’re connected, and the Connection Status text field should say Connected (see ).

Now, to control your home automation system, touch the Devices Dashboard option in the bottom navigation drawer (it’s the icon just to the right of the Home icon.

Don’t see anything? That’s because the Android app works from a special message called the “discovery” message that is sent by the home automation controller Node-RED app that tells the requester (the Device Controller app in this case) all about the devices it manages.

That means you need to add another set of nodes to your Node-RED code, and I recommend that you add a new flow (just to keep things from getting cluttered in the browser).

Leave the Device Controller app running in the Android emulator, and make sure that your Node-RED Home Automation Controller app is running. Point your browser to it (at the same URL you used in Step 2). Near the top of the screen, you will see a plus (+) sign to add a new flow. Click that plus sign to add it (it will probably be called Flow 2).

In the new flow, add an App Request Listener node. You can copy this from Flow 1 and paste it onto Flow 2 without any changes.

Add a DeviceRouter node that listens for messages whose payload.d.deviceRequest.deviceId property is Controller-1. You can copy this from Flow 1, get rid of all but one of the == conditions and change the remaining one to Controller-1). Click Done to save your changes.

Add a Controller-1-Routerswitch node to accept messages whose payload.d.deviceRequest.action property value is discovery. Copy this from the Outlet-1-Router node in Flow 1. Delete one of its == conditions, and change the remaining comparison to discovery. Click Done to save your changes.

Add a function node (under function in the palette), and copy and paste the code listing below into the Function text area, and then click Done to save your changes.

Listing 1. JavaScript code for the discovery response message

                var discoveries = {
                  deviceId : "Controller-1",
                  deviceResponse : "discovery",    
                  devices : 
                    {             
                      deviceId : "Outlet-1",            
                      description : "433MHz RF Outlet",            
                      actions : [                
                        {                    
                          action : "on", 
                          description : "Turns the outlet on"                
                          
                        },                
                        {                    
                          action : "off", 
                          description : "Turns the outlet off"
                        }            
                      ]        
                    },        
                    {            
                      deviceId : "Outlet-2",            
                      description : "433MHz RF Outlet",            
                      actions : [                
                        {                    
                          action : "on", 
                          description : "Turns the outlet on"                
                          
                        },                
                        {                    
                          action : "off", 
                          description : "Turns the outlet off"              
                        }            
                      ]        
                    },        
                    {            
                      deviceId : "Alarm-1",            
                      description : "433MHz Home Alarm System",       
                      actions :                 
                        {                    
                          action : "arm-away",                    
                          description : "Arms the system in away mode (motion sensors active)"
                        },                
                        {                    
                          action : "arm-stay",
                          description : "Arms the system in stay mode (motion sensors inactive)"                
                        },                
                        {                    
                          action : "off",
                          description : "Disarms the system"                
                        },
                        {                    
                          action : "panic",                    
                          description : "Triggers the alarm siren (SOS)"
                        }
                                          }
                                  };
                msg.payload = discoveries;
                return msg;
                

You also want to test that the discovery response message was sent by the Requester in the main flow you just created. To do that, copy the App Request Listener node and paste it onto the new flow, double-click to edit it, and change its Event property from request to response. Click Done to save your changes.

Finally, add an inject node to generate a JSON discovery test message, and a Requester (copy this from Flow 1) to send it (don’t forget judiciously placed debug nodes to display the message payloads).

The completed flow should look something like this:

Node-RED discovery flow

Test your flow, and make sure that it works and that all messages are being sent and received. After they are received, go back to the Device Controller app, which is running in the Android Studio emulator. Go to the Devices Dashboard tab, and you should see the devices show up as shown below:

Device Controller app - Devices Dashboard View

To control a device, tap it in the Devices Dashboard, and a dialog opens that lets you initiate one of the actions that the device supports. For example, if I touch the Outlet-1 device, I see this dialog:

Device Controller app - control Outlet-1
3d

Install the app on your Android device

You can also install the Device Controller app on your Android device. Plug your Android device into your computer using a USB cable. You will need to configure your device to allow this (see this article for more information).

The application should look the same, but now you have it on your Android device. Have fun!

Conclusion to Part 3

In this series you’ve learned how to set up a Raspberry Pi and 433-MHz hardware and how to control it using the system software and some IoT and mobile apps. Now it’s up to you to build on that knowledge and those skills to add more devices and turn what you’ve built in this series into a home automation system that you can call your own. Good luck!

If you’ve caught the bug for IoT home automation projects, maybe you’ll want to try your hand at one of these IBM Code Patterns: