Control your home with a Raspberry Pi and a mobile phone

In this post I will show how I have used a Raspberry Pi as a relay server that can be controlled via a web app on e.g. a mobile phone or via REST calls. The system consists of:

  • A Raspberry Pi 2 with Raspbian
  • A set of relays connected via the GPIO pins on the RPi
  • Flask running a Python WebAPI on the RPi
  • A Single Page Application made with HTML5, JavaScript and AngularJS where you can control the relays via the WebAPI

There are many inexpensive kits available for controlling voltage outlets at home, but making your own is an opportunity for learning and tinkering, so let’s go!

The hardware

I used an HUI KE relay board for my experiment.

relay

It has two relays and can operate in NC or NO mode. Which one you decide to use depends on if you want the relay circuit to be closed or open when no control signal is applied. If you have an electrical component that will be turned on most of the time, it makes sense to use NC (as no control current is consumed when the component is turned on). On the other hand, if you have something like a “welcome home” light that is only turned on short periods of time, NO is a better alternative. http://pcbheaven.com/wikipages/How_Relays_Work/ has an excellent description of how relays work.

The relay board needs 5V to operate, and from what I initially thought, 5V as control signals. As the Raspberry GPIO pins only gives 3.3V I thought I needed to build a level shifter or use my Arduino between the RPi and the relay. But my first tests showed that 3.3V as control signal was sufficient for triggering the relays. So, at least for this relay brand, the setup with RPi was very simple.

rpi_relay

Note: This experiment only shows how to trigger the relays. If you are going to control 220/110V appliances with the relays, you really need to know what you are doing and isolate the relay board and the connected cables in a proper way!

The software

I wanted my relay controlling software to be implemented as a WebAPI so that it could be used in many different ways (via a web-, mobile- or desktop app). I opted for Flask, which is a web framework for Python.

I have used Python 3.4.2 in this experiment. I really like Python as a programming language – the only major drawback is the mismatch between Python 2 and 3 and that “Python” normally means Python 2.X if you have several versions installed. Thus, in the snippets below, pip3 and python3 is used to call up the correct version of Python.

Installing Flask

The Flask library is installed with pip (a package manager for Python). If you don’t have pip installed already, you can get it for Python 3 by:

sudo apt-get install python3-pip

Then to install Flask:

sudo pip3 install flask

Creating a WebAPI

The definitions of the relays are kept in a separate Python file, relaydefinitions.py. It contains a list of relays objects with the properties for each relay. There is also a separate dictionary that maps the id of the relay to the GPIO pin number on the Raspberry (so that we will not expose the pin number outside of the API).

The actual WebAPI is defined in webrelay.py. It starts with the import statements that are needed and some helper methods. Each http request is handled by a method decorated with @app.route. The decorator also defines what URL should be handled and what method (GET, PUT, POST). The methods should return JSON data, and there is a convenient method jsonify that can transform the Python objects into JSON for this purpose.

 

Start the web server

To start the web server, you simply execute webrelay.py with Python 3:

sudo python3 webrelay.py runserver

Test the API with Curl

With Curl, you can send http requests via the terminal and thus test the WebAPI. If you run your RPi on your local LAN, you can run Curl on a different computer and access the API hosted on the RPi (replace myraspberry below with the local ip of your RPi).

To get a list with information about the defined relays:

curl -i http://myraspberry:80/WebRelay/api/relays

To get information about a specific relay:

curl -i http://myraspberry:80/WebRelay/api/relays/1

To alter the state of a specific relay:

curl -i -H "Content-Type: application/json" -X PUT -d '{"state":"off"}' http://localhost:80/WebRelay/api/relays/1

Creating a SPA front-end with AngularJS

Now that we have Flask up and running and serving http requests with JSON responses, we can also return html to create a GUI for our API. You do this by returning the result from render_template() in an @app.route decorated method:

render_template() will look in a subfolder templates for the specified html file and return it to the caller. So if you are making the call from a web browser, you will get a web page back.

To get data into the html, Flask supports templating html with Jinja2. I wanted to use an AngularJS SPA front-end for a more dynamic user experience and it turns out that it is fully possible with a few quirks:

  • The html will be parsed as Jinja2 by Flask. Jinja2 uses {{}} for inserting values into the html, which is the same characters that AngularJS uses for binding data. The solution is to configure AngularJS to use a different syntax by setting start- and end symbols on $interpolationprovider. I have used [[]] as symbols.
  • The html file that is used by Flask’s render_template() must reside in the templates sub folder. Files that are referenced from the html files (like javascript, images and css) must reside in a different subfolder called static.

Given these pre-requisites, we can create our simple AngularJS app with a html file and a controller in JavaScript to handle the actions.

The final web app looks like the screen shot below and the controls are big enough to be handled on a mobile phone connected to your local home WiFi.

webrelay_app

The complete code for this project is available on GitHub at:

https://github.com/LarsBergqvist/WebRelay

 

Advertisements

5 thoughts on “Control your home with a Raspberry Pi and a mobile phone

  1. hi Lars, Thankyou soo much for this great raspbian work. I need further help, i’m not getting how you linked the web to the RPi.

    Like

    1. Hi Awais, I’m not sure that I understand your question, maybe you can specify your problem in more detail? The Raspberry Pi runs a web server that acts on the GPIO pins depending on the http put requests sent. The web server also supplies a web page where pressing a button makes a http put requests that turns a specified GPIO pin on or off. To access the web application you have to be on the same LAN network as the Raspberry Pi or use port forwarding in your router to access it outside the LAN.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s