Home Automation with AngularJS and node.js on a Raspberry Pi

In this blog post I show how you can quickly setup and implement a control software for your switches at home with some modern JavaScript stuff. This project should primarily help me to get more in touch with these kinds of freaky scripting and this is maybe helpful for other Java Developers or people who want to play around with the Raspberry Pi. So I decided to share it with you. There is no line of old-fashioned Java code here, but maybe some really technical C++-code ;-). Please note, that this is not a tutorial for the usage of the frameworks. The tutorials that you can find in the internet are very good and I don’t want to repeat all of the basic fundamentals in this post. The complete code is also available at Github.

homepigui (1)

Prerequisites

You need the following Hardware to do it:

When you just want to play around with AngularJS and you have no Raspberry Pi, then you can skip the first steps and just use the mock implementation of the REST server at apiary.io.

Install the Raspberry Pi Hardware

Before we can start hacking we need to connect the 433 MHz Sender to the GPIO pins of the Raspberry Pi like in the following picture:

rpi_gpiopins

PIN 1 GND -> PIN 6 (GND)
PIN 2 Data in -> PIN 11 (GPIO17)
PIN 3 Vcc -> PIN 2 (5V)
PIN 4 -> Antenna

Install the Raspberry Pi Software

It’s easier to access the Pi over password-less ssh to setup the software environment . Make sure that you activated ssh in the raspberry-config and it’s up and running. When you don’t want to use ssh, than just skip this step.

ssh-keygen
cat ~/.ssh/id_rsa.pub | ssh pi@raspberrypi "mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys"

For easier handling during development I installed a Bonjour service on the Raspberry Pi. It’s now possible to directly access the Pi with the Finder (Mac required ;-)).

Install wiringPi

Please follow the instructions here to install the library for accessing the GPIO pins of the Pi or just run the following commands on the Pi:

sudo apt-get install git-core
sudo apt-get update
sudo apt-get upgrade
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

Install rcswitch-pi

The library was originally developed for the Arduino and was then ported to the Raspberry Pi. In the mean time the original library was extended with support for a special kind of switches from the company Rev. I forked the rcswitch-pi repo and added this functionality also to the Pi-lib, because I have them at home and also want to control these devices. Although I have made a pull request, which is not merged actually.

To install my version of the library just clone the git repo and compile the source code:

git clone https://github.com/denschu/rcswitch-pi
make

The following steps are highly dependent on the switches you have at home. To find out which protocol to use please have a look a this link. For my Elro devices I use this command to turn the first switch on:

#Turn Elro switch 1 on (Housecode="11111" -> means all dips on)
sudo ./send 11111 1 1

For my Rev-devices I added a sendRev-command to the Repo, which you can also use directly:

#Turn Rev switch 1 with Group B on
sudo ./sendRev B 1 1

Ok, at this point the basic stuff works and we are able to control our radio-controlled devices through the shell :-) Cool.

Install node.js

The setup of node.js is very easy, but takes some time. So start the compile process and get some coffee :-)

Get and extract it:

cd /usr/src
sudo wget http://nodejs.org/dist/v0.8.16/node-v0.8.16.tar.gz
sudo tar xvzf node-v0.8.16.tar.gz
cd node-v0.8.16

Compile it:

sudo ./configure
sudo make
sudo make install

Test it:

sudo make test

Don’t worry, when not all of the tests will pass. For more infos and basic testing of the installation check out this really good tutorial.

Start hacking – Create the REST Server

Design the API

For the design and documentation of a REST API I recommend apiary.io. It’s a web-based tool and brings you really cool features out-of-the-box, e.g. a Mock Server, an Inspector, a Test-Tool, etc. Actually it’s in beta and there are outstanding modifications on the API Blueprint Format. They want to switch to the more readable Markdown which is also used by Github.

I have designed the API completely with apiary.io. You can find it here:

http://docs.rcswitch.apiary.io/

Do some basic testing with curl

Make a GET-Request against the apiary-Mock-Server:

curl -i -X GET http://rcswitch.apiary.io/switches

Implement the REST Server with Express

In the previous step we designed the REST API. Now it’s time to start with some JavaScript hacking. The framework Express works on top of node.js and is a very easy possibility to create a small web application or in this case a REST-Server which delivers and accepts JSON-data.

That’s the basic code to setup a http server with Express (server.js):

var express = require('express'),
    api = require('./routes/api');
var app = express();
 
app.configure(function(){
  app.use(express.bodyParser());
});
 
// JSON API
app.get('/switches', api.switches);
app.get('/switches/:id', api.switch);
app.post('/switches', api.addSwitch);
app.put('/switches/:id', api.editSwitch);
app.delete('/switches/:id', api.deleteSwitch);
 
// Start server
app.listen(8000);
console.log("Server running at http://127.0.0.1:8000/");

In a separate file (api.js) we call the previously installed rcswitch-library (this is only a snippet – the full source code is on Github):

var util = require('util')
var exec = require('child_process').exec;
 
// GET
exports.switches = function (req, res) {
  console.log('Getting switches.');
  var switches = [];
  res.json(data);
};
 
// PUT
exports.editSwitch = function (req, res) {
  var id = req.params.id;
  if (id >= 0 && id <= data.length) {
    console.log('Switch Status of switch with id: ' + id + " to " + req.body.status);
    var script = data[id].script;
    var command = data[id].command;
    switchStatus(script,command,req.body.status);
    data[id].status = req.body.status;
    res.send(200);
  } else {
    res.json(404);
  }
};
 
function switchStatus(script, command, status){
    var execString = script + " " + command + " " + status;
    console.log("Executing: " + execString);
    exec(execString, puts);
}

To install the whole Server from my Github Repository run the following commands:

git clone https://github.com/denschu/rcswitch-rest
cd rcswitch-rest
npm install
node server.js

Configuration

In the file api.js you need to configure your devices which you want to operate through the REST Server. This is a minimal example configuration:

var data = [
    {
      "id": "0", "url": "/switches/0", "name": "Lamp 1", "script": "sudo /home/pi/rcswitch-pi/sendRev", "command": "B 1", "status": "0"
    }  
  ];

Test it also with curl

The call to the local server should respond with the same structure like the mock server above.

curl -i -X GET http://raspberrypi:8080/switches

Now, you can also switch the first device on through HTTP:

curl -i -X PUT -H 'Content-Type: application/json' -d '{"status": "1"}' http://raspberrypi:8000/switches/0

The mock server is used by the AngularJS-Application per default, so you can play around with it without having a Raspberry Pi etc.

Create the GUI with AngularJS and Twitter Bootstrap

Ok, now the Server is finished and we can start to design the GUI. I used the CSS-Framework Twitter Bootstrap, because it’s very easy to create a responsive user interface with a minimal effort of time and knowledge about GUI-Design 😉

Let’s create a button:

<div class="container">
	<table class="table table-hover">
		<tbody>
			<tr>
				<td>
					<h2>Lamp 1</h2>
					<div class="btn-group" data-toggle="buttons-radio">
					    <button type="button" class="btn btn-success">On</button>
					    <button type="button" class="btn btn-danger" >Off</button>
					 </div>
				</td>
			</tr>
		</tbody>
	 </table>	
</div>

Bootstrapping AngularJS

Angular Seed is basically a application template for a typical AngularJS web app. It helps you to bootstrap the development environment very quickly. It contains also some tests and a web-server to start hacking without the need to setup a complete infrastructure. To get a basic overview I can recommend the tutorial directly from AngularJS which is also based on the Angular Seed project template. Home.Pi was completely developed with the template. That is the main application definition:

angular.module('homePiApp', ['homePiApp.filters', 'homePiApp.services', 'homePiApp.directives']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/', {templateUrl: 'partials/switches.html', controller: SwitchListCtrl});
    $routeProvider.otherwise({redirectTo: '/'});
  }]);

In a separate service (app/js/services.js) we call the existing REST API on apiary.io:

var app = angular.module('homePiApp.services', ['ngResource']);
 
var url = "http://rcswitch.apiary.io/switches";
 
app.service('Switch', function($http) {
  this.query = function() {
  	console.log("Returning Switches");
	  return $http.get(url).then(function (response) {
	    console.log(response);
	    return response.data;
	});
  };
});

To make the static HTML Template from above more dynamic, just add some AngularJS magic:

<div class="container">
	<table class="table table-hover">
		<tbody>
			<tr ng-repeat="switch in switches">
				<td>
					<h2>{{switch.name}}</h2>
					<div class="btn-group" data-toggle="buttons-radio">
					    <button type="button" class="btn btn-success" ng-click="turnSwitchOn(switch.id)">On</button>
					    <button type="button" class="btn btn-danger" ng-click="turnSwitchOff(switch.id)">Off</button>
					 </div>
				</td>
			</tr>
		</tbody>
	 </table>	
</div>

To get the whole application up and running just clone the Github-Repo and start the web server for the AngularJS-Client:

git clone https://github.com/denschu/home.pi
cd home.pi
./scripts/web-server.js

The application runs here: http://localhost:8080/app/index.html

When you want to test against your local REST server, then just replace the “url” with the adress of your web server in the services.js-file.

var url = "http://raspberrypi:8080/switches"

Start the servers in the backround

To run the servers in the backround, then start them with nohup and delegate the output to a logfile. There are other possibilities available, for example Forever. Give it a try!

nohup node server.js > /tmp/rcswitch-rest.log &
nohup ./scripts/web-server.js > /tmp/homepi.log &

What’s next?

From my point of view I must say that the frameworks and technologies in the context of JavaScript improved a lot over the last years. There are a lot of other areas and tools to play around with, e.g.

  • Grunt for build management
  • RequireJS for dependency management
  • Bower for package management on the client
  • Yeoman

Maybe I will automate the build and deployment stuff with TravisCI and get the software running on a cloud platform like Heroku. There are also a lot of functional features in my brain. But let’s see. What do you think about it? Are that maybe technologies that you would use in your enterprise projects? I would appreciate any kind of feedback. Pull requests on Github are always welcome.

The Source Code

PS: My friend Daniel laughed about the selected version number “1.0”. Yes, it’s “1.0.”! It’s already in production! 😀

  • Facebook
  • Delicious
  • Digg
  • StumbleUpon
  • Reddit
  • Blogger
  • LinkedIn
Dennis Schulte

15 Responses to Home Automation with AngularJS and node.js on a Raspberry Pi

  1. For easier handling during development I installed a Bonjour service on the Raspberry Pi. It’s now possible to directly access the Pi with the Finder (Mac required ).

    No. Just install Samba and you’re ready to go.
    SMB is the de-facto protocol for network shares,
    and is supported natively on Linux, Darwin (i.e. Mac) and Windows.

  2. Hi,

    Interessting Job. I created too an home automation with Raspberry Pi + Arduino (communication is done with X10 and ZigBee).
    Here is a demo I just release :
    https://www.youtube.com/watch?v=y7T3nvGo9TI

    I will move from JqueryMobile to Angular to test it….Do you know any good AngularJs UI (like JqueryUI) ?
    Thx.

  3. Great tutorial! I am in the process of developing a simple home automation system, and am using this tutorial as the go-to-guide! It is also introducing me to some new coding principles (e.g. AngularJS).

  4. Dennis Schulte says:

    Please use thise version for this tutotial: https://github.com/denschu/home.pi/tree/v2.0

    The other one ist based on MQTT and will be moved to a new project, when I have time for it…

  5. Luis says:

    Hi Dennis,
    I’m a programmer for high level languages…. and want to get into the home and building automation field. I love your tutorial with NODE.js…. Would you please send some nice links so I can follow.
    Thank you very much!

  6. Quang Pham says:

    Hi, Thank you for the amazing tutorial. It’s very useful for me :)

    I want to use an external antenna to boost the signal. Would you mind telling where should I begin with? Which antenna is compatible? How could I attach the antenna?

    Cheers

  7. daniel says:

    Out of interest do the buttons toggle on screen to show their state?
    and arethere any obvious gpio limitations.

    thanks

  8. Daniel says:

    I’ve followed the instructions and bought an adapter from the link recommended RSL3660R-UK MODEL R&TTE

    I have a XY-FST 433MHZ transmitter which i’m not getting any joy switching dial code 11 via command line.

    I see others using same Maplin remote socket with arduino, is it possible to alter rcswitch config file or am I missing something?

    thanks

  9. Incredible excercise! I am at present improving a basic home automation framework, and am utilizing this tutorial as the go-to-guide! It is like wise acquainting me with some new coding standards.

    http://cewqatar.com

  10. Daniel says:

    Clear as mud and broken links, looks superb, but the comment use v2 less than helpful- looks great, but several people tried and ESP required
    further to this
    https://github.com/ninjablocks/433Utils codesend worked for my sockets

  11. Aimen says:

    Hi,
    Thx for sharing your great stuff.
    I have managed to install the v2.2 version.
    But i have some question
    How can i make the server run at boot of thé RaspberryPi, to start it i need to go on homepi v2.2 folder and execute sudo grunt serve.
    How do you set the configuration of your switch the 1111 thing ?
    I have try to send with a curl command but it doesn’t work ?
    And last question does the v2.2 need to install rcswitch ?
    Regards
    Aimen

  12. Aimen says:

    hi,
    i finally managed to make it work i had to edit some files like services.js to specify the ip of the raspberry.
    What’s the difference between the v1 and the v2 ?
    Thx

  13. YemSalat says:

    I know thats kinda irrelevant, but why tables for the layout??

    Anyways, thanks for the post, interesting stuff!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>