Open the Pod Bay Doors, HAL
How I automated my apartment's lights and locks using an Arduino, a Raspberry Pi, and Flask.
May 22, 2014

Home automation and remote management is one of the fastest growing and most fragmented sectors of the tech industry. Today’s homes can be outfitted with internet-connected everything - lights, outlets, thermostats. That being said, it’s still a very young market; its products are often hacky, its interfaces ugly and poorly designed, and the communication protocols divided.

I’ve bought my fair share of this buggy first generation of devices - I’ve got a Nest thermostat which I’m very impressed with, some Belkin WeMo light switches which I’m decidedly unimpressed with, and a half-dozen open source wireless light bulbs sold by a New Zealand company called LimitlessLED.

These manufactured solutions are cool, but they’re expensive and they don’t play particularly well - if at all - together; there is no unified way of managing them. As a solution to this, my roommates and I decided to build a system to tie together what we could of our existing tech as well as add our own custom hardware for controlling our apartment door and building access. We used an Arduino to handle the hardware control, and a Raspberry Pi running a Flask web server to host our website and interface with the Arduino.

The code for this project can be found on Github..\

Doors & Access

The Hardware

The lock on my apartment building’s front door - as is the case in almost all Boston apartment buildings- is triggered by a button on a panel next to each apartment’s door. This panel also allegedly provides the ability to listen and talk to whomever is waiting below, but our ‘listen’ and ‘talk’ buttons - like those in almost all Boston apartments - have never worked.

With this in mind, we went about building designing our access solutions. There were actually two separate issues to tackle. Building access was relatively easy, but apartment access would require moving parts to turn the door’s deadbolt.

Building access required us to electronically trigger the OPEN button on the control panel while maintaining the ability to actually manually press the button to buzz the door open. With a little bit of EECE 2410 and a transistor, we were able to ‘buzz’ our building’s door open with a simple logic HIGH on our Arduino.

With building access out of the way, we went about designing our deadbolt lock ‘unlocker’. I’d always wanted to be able to lock and unlock the apartment remotely, and while solutions like the Lockitron and August are succinct and very cool, I’m less than willing to shell out 200 bucks on a unreviewed, untest piece of new hardware.

photo of motor bright
photo of door panel wiring

Building our own was easy (and cheap) enough; we picked up a little servo motor and went about attaching it to our door with a band clamp, and some zip-ties, then hooked it up to our Arduino. We made use of the broken “talk” and “listen” buttons on our door panel by mapping them to the lock and unlock motor functions. This we could control our locks via either the door panel or our website.

photo of hal design

The Software

This portion of the project is controlled directly by the Arduino (which in turn is commanded by our web server). The code is simple and really just listens for input and triggers the appropriate action when input is detected.

if (openButtonState == HIGH) {
      Serial.print("\nopen button: ");

As for website input, the web server handles client-side actions and converts them to serial transmissions to the Arduino. When the user sends the unlock command on the website, Flask uses pySerial to send a value to the Arduino’s serial buffer. The Arduino polls this buffer and when it sees a value it recognizes, it performs the corresponding hardware action.

if (Serial.available() > 0) {
	incomingByte =;
	if (incomingByte == DOOR_TRIGGER) {
	if (incomingByte == LOCK_TRIGGER) {
	if (incomingByte == UNLOCK_TRIGGER) {


We have a couple different prefab remote-control light solutions in our apartment. Limitless LED bulbs in the living room, and Belkin WeMo light switches in both my and my roommate’s bedrooms.

The Limitless LED bulbs are RF-controlled bulbs which are linked to the internet via a WiFi-RF bridge. The API is stupid-simple and with a very minimal amount of Python code we were able to port the Limitless App’s functionality to our own site.

The WeMo light switch were a whole other beast. To start with, Belkin’s official WeMo app only works about 30% of the time, so you’re never actually sure if this terrible terrible product is actually connected to your network, secondly there is no API. The closest thing I’ve found to a prebuilt way to interact with WeMo products is iancmcc’s ouimeaux project. When the WeMo’s are working as they should, ouimeaux works fine as a controller; it’s written in Python too which made it very easy to add to our existing Flask project.


When I eventually received my Spark Core a whole new set of possible projects opened up. As a proof-of-concept, I ended up building a remote-control outlet and adding it to this web-app. I’ve written a whole post on it here.

The Web Layer

The backend of our website is Flask. It’s lite-weight, it’s fast, it’s simple to set up, and it’s Python - what more could a mobile website ask for?

The backend of the project handles all of our device control. The Arduino that controls our lock and building buzzer is commanded via serial data produced by pySerial. The lights, outlets, and WeMo devices are all controlled via various API requests and make use of a number of Python libraries. More information on these can be found on github.

We implemented OAuth authentication via Flask OAuth to limit site access to a list of authorized users which we keep in a JSON file.

photo of preview 1
photo of preview 2

For a good portion of our development, our website consisted of a blank page with some unstyled buttons on a white canvas. One weekend, on a long bus ride to Montréal I found the time to build out a better looking front-end. I wrote templates and views for the two different control modes using Backbone and JST - probably overkill for something so simple - and spit out a half-decent single-page interface.


There are a number of improvements and upgrades I’d like to make to the site. First and foremost, I’d like for our pageload speed to be a bit faster. Our JS could do with some optimization and minification.

In addition to our webapp, we’re also working on a Pebble App and Android App. One big piece of functionality I’d like to add is proximity/presence awareness. I’d like to get a service running that is capable of unlocking the door when an authorized user first connects to the apartment’s WiFi; at the same time it’d be nice to be able to lock the door in the event that no authorized users are in the apartment. These would likely require some sort of asynchronous task manager like Celery so it might take a while to implement.

From a hardware standpoint, it has occurred to me that the functionality currently shared between the Arduino and the Raspberry Pi could probably have been minimized to just the Pi and its GPIO pins. Though it would require a separate power supply to drive the motor, it would make the project much simpler.

photo of cable mgmt edit


I laser-cut an enclosure for the ugly motor/pipe-band rigging. Originally I was going to 3D print it at my university’s shop, but laser-cutting 1/8” wood was much cheaper and I think the finish looks nice.

photo of enclosure angle