Beliebte Suchanfragen
//

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

24.3.2013 | 8 minutes of reading time

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 .

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:

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.

1ssh-keygen
2cat ~/.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:

1sudo apt-get install git-core
2sudo apt-get update
3sudo apt-get upgrade
4git clone git://git.drogon.net/wiringPi
5cd wiringPi
6./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:

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

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:

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

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

1#Turn Rev switch 1 with Group B on
2sudo ./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:

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

Compile it:

1sudo ./configure
2sudo make
3sudo make install

Test it:

1sudo 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:

1curl -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):

1var express = require('express'),
2    api = require('./routes/api');
3var app = express();
4 
5app.configure(function(){
6  app.use(express.bodyParser());
7});
8 
9// JSON API
10app.get('/switches', api.switches);
11app.get('/switches/:id', api.switch);
12app.post('/switches', api.addSwitch);
13app.put('/switches/:id', api.editSwitch);
14app.delete('/switches/:id', api.deleteSwitch);
15 
16// Start server
17app.listen(8000);
18console.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 ):

1var util = require('util')
2var exec = require('child_process').exec;
3 
4// GET
5exports.switches = function (req, res) {
6  console.log('Getting switches.');
7  var switches = [];
8  res.json(data);
9};
10 
11// PUT
12exports.editSwitch = function (req, res) {
13  var id = req.params.id;
14  if (id >= 0 && id <= data.length) {
15    console.log('Switch Status of switch with id: ' + id + " to " + req.body.status);
16    var script = data[id].script;
17    var command = data[id].command;
18    switchStatus(script,command,req.body.status);
19    data[id].status = req.body.status;
20    res.send(200);
21  } else {
22    res.json(404);
23  }
24};
25 
26function switchStatus(script, command, status){
27    var execString = script + " " + command + " " + status;
28    console.log("Executing: " + execString);
29    exec(execString, puts);
30}

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

1git clone https://github.com/denschu/rcswitch-rest
2cd rcswitch-rest
3npm install
4node 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:

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

Test it also with curl

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

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

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

1curl -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:

1<div class="container">
2    <table class="table table-hover">
3        <tbody>
4            <tr>
5                <td>
6                    <h2>Lamp 1</h2>
7                    <div class="btn-group" data-toggle="buttons-radio">
8                        <button type="button" class="btn btn-success">On</button>
9                        <button type="button" class="btn btn-danger" >Off</button>
10                     </div>
11                </td>
12            </tr>
13        </tbody>
14     </table>	
15</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:

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

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

1var app = angular.module('homePiApp.services', ['ngResource']);
2 
3var url = "http://rcswitch.apiary.io/switches";
4 
5app.service('Switch', function($http) {
6  this.query = function() {
7      console.log("Returning Switches");
8      return $http.get(url).then(function (response) {
9        console.log(response);
10        return response.data;
11    });
12  };
13});

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

1<div class="container">
2    <table class="table table-hover">
3        <tbody>
4            <tr ng-repeat="switch in switches">
5                <td>
6                    <h2>{{switch.name}}</h2>
7                    <div class="btn-group" data-toggle="buttons-radio">
8                        <button type="button" class="btn btn-success" ng-click="turnSwitchOn(switch.id)">On</button>
9                        <button type="button" class="btn btn-danger" ng-click="turnSwitchOff(switch.id)">Off</button>
10                     </div>
11                </td>
12            </tr>
13        </tbody>
14     </table>	
15</div>

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

1git clone https://github.com/denschu/home.pi
2cd home.pi
3./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.

1var 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!

1nohup node server.js > /tmp/rcswitch-rest.log &
2nohup ./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! 😀

share post

//

Gemeinsam bessere Projekte umsetzen.

Wir helfen deinem Unternehmen.

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.