RaspberryPi home automation gateway – Hardware and Demo

UPDATE: An updated version of this gateway install guide is published here. The rest of this post is kept here for legacy purposes, some links to source files might be obsolete or not work any longer, please see the linked guide above for the latest code and walkthrough.

In this last part of the RaspberyPi home automation gateway series I will show an example of hardware implementation that talks to the RaspberryPi secured realtime home automation gateway, and share the firmware source code.

GarageMote is a garage door controller shield that can be used to remotely control a garage door from anywhere on the web or from your smartphone.

GarageMote was created for several reasons. Mainly because as I’m adding more Moteino based home automation devices around my property, one of the nice things I wanted to be able to do is control the garage door remotely. It’s become so routine to close the garage door when I leave from home that sometimes when I’m already 5 or 10 minutes away I wonder if I actually closed it. And so I want to be able to check the door status and close it if it was left open by mistake, without having to drive back home. Or maybe it’s useful to be able to let someone in without giving them the garage code every time.

The hardware is simplistic, the shield has a small relay, a diode, 2 resistors. The 8 pin header has connections for 2 hall effect sensors and the door opener. I used a female header to connect an 8 wire cable to the two sensors. One sensor is for the open position one is for the closed position. That way you can tell whether the door is open, closed, or stuck somewhere in between. The other two wires are a contact closure driven by the small relay to trigger a door action, and are connected directly to the garage opener. This is equivalent to operating the garage from the regular door opener, and thus GarageMote does not interfere with the normal garage door operation.

A sender Moteino can then be plugged into GarageMote to read the sensors, report status changes, and listen for door action commands from the gateway. The receiver Moteino is connected to the RaspberryPi, where node-serialport will communicate with GarageMote and other home automation devices on the property.

The receiving end is another Moteino that acts as the gateway between the home automation wireless network and the RaspberryPi, which is responsible for bridging the home automation to the web, so it could be accessed remotely from anywhere on the web. Here is a sample setup shown with a RaspberryPi Rev1 model B, along with the Moteino acting as gateway to the Moteino wireless node network, and ATXRaspi for shutdown/reboot control:

One challenge was to secure the RaspberryPi against eavesdropping and unauthorized access. This is achieved using SSL encryption and authentication. As a webserver I’m using NGINX.  The backend home automation is driven by node.js and socket.io, which is proxied through the webserver. All the details of how this is achieved have already been posted in the previous post.

Here’s a simple web interface running from RaspberryPi that has a status button which shows the current garage door position and can be used to query the status at any time. Then the door action button which will say either “Open it!”  or “Close it!” depending  on the current status. The “Clear log” button will just clear the log which displays the Moteino output broadcasted from the websocket. You can see that the garage door was recently open and then closed, letting me know someone just pulled into the garage:

GarageMote can be mounted on the side of the opener using velcro tape. An old phone charger can be used to power the Moteino. The two hall sensors are attached in such a way to detect the small magnets that are mounted on the belt or chain of the opener. In my case the magnets are velcro taped to the belt, and move along with it. Using velcro allows for easy adjustments when testing the magnet positions. When the door is closed the magnet on the closed side is detected. As the belt pulls the door open, the magnet moves away and the other magnet comes on the open side. This way I can always tell whether the door is open or closed, or somewhere in between:

Gateway.js

Here’s the gateway.js node app that runs on the RaspberryPi. This code will ensure that the requests are coming from localhost, and hence reject any outside connections. Create the file with nano then dump the content and save it:

sudo nano ~/moteino/gateway.js
var io = require('socket.io').listen(8080);
var serialport = require("serialport");
// change "/dev/ttyAMA0" to whatever your Pi's GPIO serial port is
var serial = new serialport.SerialPort("/dev/ttyAMA0", { baudrate : 115200, parser: serialport.parsers.readline("\n") });

//authorize handshake - make sure the request is coming from nginx, not from the outside world
//if you comment out this section, you will be able to hit this socket directly at the port it's running at, from anywhere!
//this was tested on Socket.IO v1.2.1 and will not work on older versions
io.use(function(socket, next) {
 var handshakeData = socket.request;
 console.log("AUTHORIZING CONNECTION FROM " + handshakeData.connection.remoteAddress + ":" + handshakeData.connection.remotePort);
 if (handshakeData.connection.remoteAddress == "localhost" || handshakeData.connection.remoteAddress == "127.0.0.1")
 next();
 next(new Error('REJECTED IDENTITY, not coming from localhost'));
});

io.sockets.on('connection', function (socket) {
  var address = socket.handshake.address;
  console.log("New connection from " + address.address + ":" + address.port);

  // respond to STATUS updates
  socket.on('GRGSTS', function (data) {
    socket.emit('MOTEINOLOG', 'getting status...');
    serial.write('GRGSTS');
  });

  // open garage
  socket.on('GRGOPN', function (data) {
    socket.emit('MOTEINOLOG', 'requesting open...');
    serial.write('GRGOPN');
  });

  // close garage
  socket.on('GRGCLS', function (data) {
    socket.emit('MOTEINOLOG', 'requesting close...');
    serial.write('GRGCLS');
  });
});

serial.on("data", function (data) {
  var status = '';
  if (data.indexOf(' OPEN ') != -1)  status = 'Open';
  if (data.indexOf(' CLOSED ') != -1) status = 'Closed';
  if (data.indexOf(' OPENING ') != -1) status = 'Opening';
  if (data.indexOf(' CLOSING ') != -1) status = 'Closing';
  if (data.indexOf(' UNKNOWN ') != -1) status = 'Unknown';
  if (status.length >0)
    io.sockets.emit('MOTEINO', status);  
  io.sockets.emit('MOTEINOLOG', data);
});

You can then start this app using:

cd ~/moteino
node gateway.js &

Now to make the gateway.js app start automatically when RaspberryPi boots, we need a startup script which will start node.js with the user ‘pi’ and look for a gateway.js file in the /home/pi/moteino directory. The output stream from gateway.js will be stored in the file nodejs.log. Create the file nodejs.sh:

sudo nano /etc/init.d/nodejs-moteino.sh

Then add the following content and save it:

#!/bin/bash
### BEGIN INIT INFO
# Provides: nodejs-moteino.sh
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Example initscript
# Description: This file should be used to construct scripts to be
# placed in /etc/init.d.
### END INIT INFO
NODE=/opt/node/bin/node
SERVER_JS_FILE=/home/pi/moteino/gateway.js
USER=pi
OUT=/home/pi/nodejs.log
case "$1" in
start)
	echo "starting node: $NODE $SERVER_JS_FILE"
	sudo -u $USER $NODE $SERVER_JS_FILE > $OUT 2>$OUT &
	;;
stop)
	killall $NODE
	;;
*)
	echo "usage: $0 (start|stop)"
esac
exit 0

Note: If you want to use a privileged port (TCP/IP port numbers below 1024) you will need to start the script as root. Make the script executable with chmod, then register the script as a service with update-rc.d. Then the gateway.js app will automatically start up when the Raspberry Pi boots:

cd /etc/init.d
sudo chmod 755 nodejs-moteino.sh
sudo update-rc.d nodejs-moteino.sh defaults

Once that is done, you can get the HTML interface to the garage door, and copy it to your /var/www/default directory you created in the last post (copy these files: index.php, icon.ico).

If gateway.js has already been started, you should be able to open a browser and point it at your IP address (if you setup port forwarding on your router to point to your Pi) or just the Pi’s LAN address. You will be greeted with the SSL warning page, and then the auth_basic prompt where you need to enter the credentials that you placed in the .htpasswd file (see previous post).
The youtube video at the top of this post shows how all this works.

Source code, schematic and config files

If you’re not using Moteino based hardware you can always adapt whatever you have to this setup. Even the sketches could be adapted for other similar hardware since Moteino is just an Arduino UNO compatible board that includes a wireless RFM12B/RFM69 transceiver.

As long as you setup port forwarding to your Pi address (port 80 and 443), you should be able to access this home automation interface from your smartphone when you’re on the road.

This is the whole point, to be able to do that securely using a realtime websocket, and have the peace of mind that no one else can access it but yourself.

So that wraps up this long series. Whew! It was pretty intensive and it would have been impossible to manage all this content in a single post, that’s why I split it up in separate sections that each address a subtopic. Again, I hope I didn’t miss anything significant.

Enjoy!

18 thoughts on “RaspberryPi home automation gateway – Hardware and Demo

    • I haven’t tried every newer version but tried several. I settled with .10.12 because that worked and is very stable. But .10.20 might also, try it!

  1. Pingback: RaspberryPi Home Automation Gateway @RaspberryPi #piday #raspberrypi « adafruit industries blog

  2. Nice work Felix. Love to see simple/elegant solutions like this.

    When you get ready to look at DB to persist state across reboots, if you need, check out https://github.com/louischatriot/nedb it is pretty sweet for embedded type lightweight needs. I used to read/write my own flat files, but this is much better.

  3. Pingback: Raspberry Pi Garage Door Automation

  4. I love what your doing! I am attempting to do some similar work but I ran into an issue along the way and didn’t like the solution. I noticed that you say for your system to work outside of the LAN you would need to set up port forwarding. For me this is not the elegant solution I wanted…I want a more plug and play solution. I have spent a lot of time looking into how to use socket connections that originate within the LAN to establish a connection to a server. This allows for communication without the need of port forwarding on the users side…. In the end I just wanted to say great work…And +1 for using sockets and making a nice UI…

    JT

    • Thanks! BTW – a 3rd party server is also not really a plug and play, and adds another layer of things I’d rather not deal with. Port forwarding is just simple networking.

  5. Nice job Felix. Do you have part numbers for the Hall Sensors and Magnets you used? I could not find them listed anywhere.

    Thanks,

    Vince

  6. Nice work Felix! I enjoy your blog very much.
    I wondered why you hooked up the radio modules through a Moteino instead of interfacing them directly with the RPi? Could you say something about time delays of your system?

    • First because that’s the main idea behind Moteino and I would not want to rewrite the radio libraries for RPi, second because it’s much easier to let the Moteino do the hard work and read the data serially on the Pi. There are almost no delays, except when I load the interface from my smart phone, there’s some delay because of the mobile network.

  7. In the last week I decided I wanted to sort out how to wirelessly access my garage door, and after comparing what you’ve done here against (what feels like) all the other options (which I won’t mention because I don’t want to drive traffic, but I’ll just say the commercial solutions, the many that run arduino to relays + iPhone/Android apps, and the awful one that runs off of a bluetooth headset) I really appreciate the work that has gone into actually making this solution robust and secure.

    However, I’m not planning any other home automation projects for the foreseeable future, and I don’t own an raspberry pi, so I’ll be buying one for this project. I was planning on wirelessly connecting the pi to my home network with a usb wifi dongle.

    So finally, here are my questions. Can I connect the pi directly to GarageMote and have it operate without too much alteration of your code (i.e., what do I do about the sender node/base node moteino code, is it just passing the GarageMote sensor reads, status changes, action commands to/from the pi)? And if so, is there a reason to NOT connect the pi to GarageMote without moteinos? Thanks Felix!

    • Thanks for the feedback, the solution makes use of Moteino since I did not want a Pi to be tied to one sensor/node. I have not tried, but you could technically drive the small relay with 2 or perhaps 3 pins of the Pi but you have to turn them ALL on instantly or as close to that as possible to avoid any issues with the Pi. OR you could just use a transistor to supply the reuquired power for the relay which is probably a better idea. You also need to hook up the 2 hall sensors to your Pi and read the HI/LOW to determine the status. Then you replace that whole serial communication with the master Moteino with GPIO reads and the write for the relay. That’s about it I guess… If you’d like to update about the progress please share in the forum, thanks

  8. Great Job on the entire project!!! I have been looking for a cheap but secure and robust solution for home networking and stumbled accros your site while looking up Zigbee option… I have one question maybe you or someone knows….

    If i wanted to have the RPi basically pole or have sockets(preferred) to a server lets say from goDaddy running a front end can this be done? any tutorials out there?

    Basically my whole family wants to have this as an option(three homes) and i would like to set it up for them being the Techy in the family. I was thinking of having a central site hosted by godaddy providing a front end that the RPi can connect to and hold a connection for when a user logs into the site.

    I haven’t been able to find this anywhere for the RPi… Any Ideas?????

    • Aaron – if you’re looking for a complete solution, like “21 steps to RPi multi home automation with webhost frontend” you probably won’t find it, but I could be wrong. Your host could be running the front end similar to how I set it up, then your PI/backends could host the individual secured sockets etc. The possibilities are endless. But you’ll be doing a fair amount of coding, always fun 😉

Comments are closed.