Introduction: The Raspberry Pi-Arduino-SignalR Home Automation Hub

About: I'm a Mechanical Engineer turned IT Professional and Author. I came into the Information Technology world because someone challenged me to. But at heart, I'm still a grease monkey with no desire to lose touch …

Following a couple of my prelude IBLEs published here and here, this project takes the first step towards building a basic version of a functional Home Automation Hub.

I've used several different technologies in an effort to make sense of how I may be able to use all the things that I have learned in the past and the new things that I continue to learn as days progress.

Therefore, this Automation Hub is comprised of the following components:

A SQL Server 2012 database that:

  • stores a list of pre-determined Infrared (IR) codes in a table along with a unique "code key"
  • the code keys are intuitively named (by the user) so as to identify the purpose of their associated IR codes

A Real-time ASP.NET SignalR Hub Web Application that:

  • awaits and receives "code keys" as commands from a user facing HTML client
  • when received, connects to the SQL database and retrieves an IR Code using the supplied code key
  • relays the retrieved IR code to a Python SignalR client

A User facing HTML SignalR Dashboard client that:

  • communicates a unique code key to the Hub via the jQuery SignalR Client APIs
  • each button on the Dashboard will represent a unique code key recorded in the SQL database table

A Python SignalR background service application running on the Raspberry Pi 2.0 that:

  • receives IR codes as commands from the Hub
  • seeks out delimiters in the IR Code and breaks the very long code into segments
  • communicates over Serial port to Arduino and writes out each segment in succession

An Arduino IR Transmitter Sketch that:

  • awaits and receives each of the IR code segments over the Serial port
  • assembles the code segments into an IR Code buffer array
  • packages the buffer into an an IR Transmit command using the IRLib Arduino library

If the target appliance is in the vicinity of the IR Transmitter, then the appliance (may) react to the IR signal transmitted by the Arduino

NOTE

Although, the target appliance that I use in this demonstration does react to IR signals, you may want to read this section of my other IBLE for reasons why I say that the appliance (may) react to the IR signal .

Time to roll.

Step 1: What You Need, Before What You Need

This instructable takes off with some of the work done previously which also resulted in my last IBLE.

So, before we step into what we need for this IBLE, it's recommended that you read this instructable for some background on how :

  1. The Arduino IRLib Infrared Library was set up
  2. How IR codes used in this IBLE were captured using an IR Receiver
  3. How the captured IR codes were used to control the target appliance via an IR Transmitter

Following the completion of this IBLE, I deployed an ASP.NET IR Code Recorder web application that would:

  • Accept the captured IR Code along with an intuitively named code key as inputs through a web form
  • Break the very length IR code into segments less than 64 characters long to stay under the Serial buffer limit of the Arduino Uno
  • The last segment of codes would be pre-fixed with an "E" that indicates to the Arduino that it's received the last segment of code
  • Each segment would be separated by a pipe delimiter before being assembled back into a long string
  • Finally, the segmented IR Code along with its code key was stored into a SQL Server 2012 database

It's this SQL database that forms one of the components of the Home Automation Hub elaborated in this IBLE.

NOTE

The IR Code Recorder Web application does not form part of the discussion here for the following reasons:

  • You can manually capture codes using Arduino Sketch, split them into pipe-delimited sections and store them in the the database without having to build an elaborate Web Application
  • Unlike this IBLE, the IR Recorder focuses on reverse communication from Arduino to Raspberry Pi

Therefore details on this project would be a topic for another IBLE

Step 2: What You Need - the Hardware

A functioning Raspberry Pi 2.0 - I recommend installing Ubuntu Mate as it has a richer set of features including OpenLibre Office which by the way was indispensable in documenting this instructable, right there on the Raspberry Pi.

In addition, the Pi , you'll need the following externals:

  • The Arduino Uno prototyping platform or a clone
  • An IR transmitters LED - I used a brand named Three Legs from Amazon.com
  • 330 or a 220 Ohm resistors - I used the 220 (color code Red-Red-Brown) because I had several handy
  • The usual bread board, connectors, and a PC with the Arduino Environment installed
  • A test candidate - such as the ubiquitous Samsung LED Monitor with a remote

Step 3: What You Need - the Software

To get all of the pieces together, the following software setup will have to be installed and running:

On the Raspberry Pi, you will need to install the following:

  • The Arduino IDE - used to build the Sketch and flash it to the UNO
  • The Python module for Arduino - for Serial communication between the UNO and the Pi
  • The Python SignalR client library - You can refer to the instructions attached here

A Windows machine with the following development environment installed:

  • Free edition of Microsoft Visual Studio Express 2013 to build the SignalR Hub and Web client application
  • Free edition of the SQL Server 2012 Express to design and build the back-end database

A Windows Internet Information Server (IIS) Hosting environment:

  • Once the SignalR Hub and Web client is built and tested, it will need to be deployed to a local IIS Server
  • In my case, I plan to use an old laptop running Windows 7 with IIS on my home network

NOTE

All instructions are applicable to the Python 2.7.x version . Version 3.0 may require rewrites

Step 4: The SQL Server Database

The attached schematic shows the structure of a basic SQL Server database used in this application and contains just two tables.

Table AutoHubCode

The two important columns in this table are:

AutoCodeKey- stores the user-friendly name of the Code key

  • Each of the code keys is transmitted by an automation client - in our case, an HTML button from a Web page

AutoCodeVal- stores the raw IR Code sequence

  • This is the actual IR code that is transmitted back to the client in response by the SignalR Hub

In this case, a Python client in constant communication to the Hub receives the IR code sequence and transmits it over Serial Port to the Arduino UNO

Table AutoHubLog

  • Logs the code requested by the automation client .
  • This is a measure to track who and when used the system, and what code was requested

As mentioned, I've used SQL Server 2012 as my database platform of choice . You can recreate this simple design on a different database platform such as MySQL, Oracle, etc.

Nevertheless, the SQL Script to create this database has been attached here.

NOTE

  1. The code for the SignalR Hub is designed to connect to a SQL Server 2012 database
  2. Working with a different database would mean altering the Hub to use a different database driver

Step 5: The ASP.NET SignalR Hub Web Application

The ASP.NET SignalR Hub Web Application jointly comprises of the following components as indicated in the attached schematic:

Section 1 - The SignalR Hub that receives requests from and responds to client

Sections 2,4 - The HTML client web page and it's style sheet that collectively form the front end of the Automation system and issues commands to the Automation Hub

Section 3 - The jQuery SignalR APIs used by the HTML client to communicate to the Automation Hub

Section 5 - The SignalR Hub does not directly communicate to the database . It does so via intermediate classes generated using the Entity Framework

These classes abstract the database details from the front end application

Section 6 - The Database service class that helps perform the Read-Write operations on the SQL Database (described previously) by using Entity Framework classes

ASP.NET and SignalR are Microsoft technologies and this tutorial will walk you through on how a simple SignalR application is built and deployed.

What I've built here is based on the basics acquired from this tutorial. When deployed, the application should look similar to the web page shown in the second picture

NOTE ON THE CODE

A ZIP file containing a stripped down version of the code has been attached

The folder structure is as shown in the visual - however, all of the framework classes, and jQuery scripts have been removed to reduce the size of the attachment

The recommendation is that this code be used as a guide because when you create a new SignalR Web application by following the tutorial link above, the latest jQuery libraries and ASP.NET framework classes will be added automatically

Also, the references to the jQuery scripts in the index.html page will have to be changed to reflect the latest version of the jQuery SignalR client libraries that will be automatically added when you build your Web application.

Finally, the connection string will have to be changed to match your database in the files named like Web.config*

Step 6: The Python SignalR Service Client

While the HTML SignalR Client is a front facing User Interface, the Python Client is a back end service application whose main function is to receive the IR Code transmitted by the Hub and route it to the Arduino UNO over Serial communication.

The code attached is self-explanatory and is documented enough to describe its functionality.

As shown in the composite screen shot, the HTML Client and the Python Service client communicate through the SignalR Hub as follows:

  1. The user of the automation system issues a command to the Hub via a button click
  2. Each button is associated with the IR Key code and when clicked, this code is transmitted to the Hub
  3. The Hub receives this code, connects to the database and retrieve the raw IR Signal code and transmits it back to all connected clients
    • At the same time, the Hub logs an entry in the AutoHubLog database table recording the code and the date and time it was requested by remote clients
  4. The Python service client receives the IR Code and relays it to the Arduino UNO for further processing

Step 7: The Arduino UNO IR Transmission Sketch and Code

The Arduino circuit as shown in the visuals is pretty simple for this system and is therefore described briefly:

  • The colorless IR LED must be wired to Digital PIN 3 on the UNO - this is a requirement of the IRLib Arduino library
  • The reasons are described in my earlier IBLE on cloning a remote in the section related to the IRLib library
  • The Green LED connected to the Digital PIN 4 is a visual indicator that lights up when the UNO has received all sections of the IR Code from the Python client running on the Raspberry Pi.
  • Having this LED light up will confirm that the Serial communication between the Raspberry Pi and the UNO is working
  • To enable Serial communication, the UNO is connected to the Raspberry Pi via the USB Port
  • The attached Arduino Sketch is commented sufficiently to describe its function
  • The comments at the top of the code also describes how the circuit needs to be wired up

NOTE

In practice, the Arduino and the Pi could be jointly connected to a powered USB hub strong enough to drive the Pi, the Arduino and also transmit a strong signal via the IR LED

Step 8: Hooking Up and Testing the System

  1. Build and deploy the ASP.NET SignalR Hub, the HTML client along with the SQL Server 2012 database to an Internet Information Server (IIS) on your local home network
  2. Access the web application by opening the HTML SignalR client over HTTP
  3. Click a button on the control panel, and if the application has been deployed correctly, the Hub will respond by returning the IR Code and displaying it in the Gray panel adjoining the control panel
  4. Connect the Arduino to the Raspberry Pi over USB - open the Arduino IDE on the Pi and make sure that the UNO can establish connection with the Pi
  5. Open the Python code and make the following changes as applicable to your environment
  6. Lastly, open up the Arduino Sketch in the Arduino IDE on the Raspberry Pi and flash it to the UNO
  7. Position the bread board that holds the circuit in close proximity with the appliance to be controlled - the IR LED must have a clear line of vision with the IR receiver port of the appliance
  8. Start the Python program on the Raspberry Pi by pressing the F5 button on the Python IDLE tool bar
  9. Return to the Control panel on the HTML client program (Step 2) and click a button (such as Power On or Volume Up)

If the system has been set up correctly, then you should be able to bring up the HTML client page on your phone or tablet and control your appliance with the buttons on your HTML client page.

Step 9: The System in Action

The visuals above show the Home Automation System in action once it's setup.

Since publishing this IBLE, I've extended the interface by capturing a few IR Codes from my VIZIO LED TV

As shown side by side with the factory TV Remote in the first visual, few essential functions of this remote have been built into the Web UI accessed via my tablet

Subsequent visuals show the tablet in the foreground with the TV in the back responding to commands issued from the Web interface:

  1. Power OFF command - The TV turns off
  2. Power ON command - TV turns on and the "V" logo appears as the screen powers up
  3. Mute ON command - A horizontal bar comes up with the speaker muted

In all the tests, the Gray area alongside the dashboard on the tablet screen displays the command issued by the client, and the response sent back by the remote SignalR Hub

Step 10: Enhancing the Automation System and Related Fixes

This system can be extended by adding more codes captured from different systems. While this part is easy, there are two other factors that you will have to take into consideration.

Enhancement 1 (Quick) : Working with IR Signals of different lengths

  1. IR Codes of different systems come with different lengths, even between two products from the same manufacturer.
    • For example, in this case, the IR code array length for the LED TV is 67 whilst that of the Samsung Sound Bar is around 87.
  2. Which means, if I turned on the Sound Bar first, the the IR Buffer array in the Arduino sketch would be filled with an IR Code sequence that contains 87 codes
  3. Following this, if I turned on the LED TV, it would fill the IR Buffer array with just 67 codes, but the remaining 20 codes from the previous operation would still be around

The result? The LED TV does not turn on because the IR Code Buffer has been corrupted by the extra 20 codes not cleaned up from the previous operation!

Fix 1 (the easy way out ,not recommended)

Alter the Arduino Sketch as follows:

Change the following function calls in in the loop(){} function

transmitIRCode() ; 
to <br>transmitIRCode(c);

Make changes to the signature of the above function:

void transmitIRCode(int codeLen)<br>{<br>	//RAWBUF constant replaced with codeLen<br>	IRTransmitter.IRSendRaw::send(IRCodeBuffer, codeLen, 38);
}

While this is easy, the array never really gets completely cleared and therefore this is not a very clean solution

Fix 2 (Not hard, recommended)

Declare an additional variable at the very top of the Arduino Sketch, after the comments section:

unsigned int EMPTY_INT_VALUE;

Add this to the top of the setup() function:

//Capture the natural state of an empty unsigned integer variable<br>EMPTY_INT_VALUE = IRCodeBuffer[0];

Scroll down and add a new function to the sketch immediately after the transmitIRCode() function:

void clearIRCodeBuffer(int codeLen)<br>{<br>//Clear all codes from the array<br>//NOTE: setting the array elements to 0 is not the solution!<br>for(int i=1;i<=codeLen;i++)<br>{<br>IRCodeBuffer[i-1]=EMPTY_INT_VALUE;<br>}<br>}

Finally, call new function above at the following location in the loop() function:

...
//Reset - Resume reading Serial Port<br>clearIRCodeBuffer(c);<br>...

This is a more cleaner approach as it actually resets all the locations in the IR Buffer array that were populated by the most recent IR Code signal without leaving anything to chance.

Enhancement 2 (More involved): Repeating IR Signal Transmission for certain devices

  1. Some devices require the same signal be transmitted multiple times in order to respond
    Example: In this case, the Samsung Sound Bar requires the same code to be sent twice with a gap of 1 second

The Fix in Concept has been discussed here as it's a bit more involved and will need testing.

Adding the repeat functionality to the Ardunio Sketch will mean that you will have to flash the Sketch each time you add a new device to your Home Automation System

Instead, adding this fix to the HTML SignalR client and the Python SignalR Service application makes the solution a lot more flexible. And this could be achieved in principle as follows:

Modify the SignalR HTML client to transmit repeat information to the Hub

Open the index.html and embed the repeat value in the HTML button like so:

value="SMSNG-SB-PWR-ON" 

would become

value="SMSNG-SB-PWR-ON_2_1000"

Where, 2 is the repeat value and 1000 is the delay value in milliseconds between the two repeat signals

When you click on this button, the SignalR hub will receive the Key Code+Repeat_Spec

Modify the SignalR Server side methods to parse out only the Key Code:

  • Use the Key Code to retrieve the IR Code from the database as usual
  • Transmit the Key Code+Repeat_Spec and the IRCode to the SingalR Clients as usual

Modify the Python SignalR Service Application to transmit signals using the Repeat values:

Open the Python client and modify the following two functions:

def print_command_from_hub(buttonId, cmdSrc):

# parse the repeat code from the buttonId value
def transmitToArduino(IRSignalCode,delim,endPrefix): 

# set up a while or for loop to transmit the signal at the desired frequency
  • This way, the Arduino doesn't have to be flashed repeatedly
  • Any number of repeat frequencies could be built into this system
  • Besides, if you're using the UNO, there's a limit to the size your Sketch can grow to!

Step 11: Known Issues & Security Concerns

As is the case with systems built the very first time, this one has a couple of issues that came out during testing.

Issue 1: Firing commands in rapid succession with delays less than a second between button clicks caused the system to become unresponsive after responding for the first couple of times.

  • Restarting the Python SignalR client restores the system back to normal operations
  • Immediate resolutions may be is to remove unwanted Debug outputs in both, the Python SignalR Client and also the Arduino Sketch and repeat these tests
  • Another place to look into would be the Serial communication itself - would it be possible to add code to rapidly flush the buffer?

That said, I've noticed that my TV does not respond well to its factory remote - therefore the very nature of IR communication of my TV may be a contributing factor as well.

Issue 2: The HTML screen stops responding to button clicks after a long period of inactivity

  • Usually refreshing the page resolves this behavior - the cause for this behavior however is still unclear

SECURITY CONCERNS

This system has been designed for local (home) network use only and does not have the necessary security safeguards in place to be used over the internet!

Therefore it's recommended that the SignalR Hub be deployed to a local machine on your local/home network.

Thanks for reading my IBLE and I hope you have fun!