“Firewalls are a hardware solution to a software problem.”—Someone at ShmooCon
The situation: I share an office with my brother. This office is in a suite of other offices that we share with another company. Sometimes I work from home; sometimes I go in. I haven't been in the office for the past few weeks because of a motorcycle accident (from which I hope to be fully recovered by the time you read this—fingers crossed). That got me thinking, I have no idea if anyone has been in my office during the time I've been out. It would be great if I had some sort of basic security system that could tell me if people entered my office and, if possible, show me a picture of who they were.
The first thing I did when I moved in was upgrade the lock to my office. This actually was more about laziness than security. I got a keypad lock so I still could get in even if I forgot my keys (or needed someone else to get something if I wasn't there). When I went shopping, there were a lot of locks from which to choose. The one that really caught my eye was the Schlage Wireless Keypad lock. This was a keypad lock, but it also included Z-Wave support. Schlage had an add-on version and a starter kit. The starter kit included a wireless hub and a lamp controller. It didn't seem like a terrible deal until I realized the included hub required a monthly service fee to use it, which turned me off.
I figured there had to be a way to control it from Linux. If I could do that, I could meet my first goal—alert me when someone enters. I've used X10 for a long time, and it always was pretty easy to script from Linux. I assumed Z-Wave would be the same, but it turns out, Z-Wave communication is a lot more complicated (I guess I shouldn't be surprised, as it is much more advanced than X10).
Under Linux, there are two paths to follow to Z-Wave access. The first is the LinuxMCE (www.linuxmce.com). This project is a combination of media management, home automation, phone and security system, all built on top of Kubuntu. In order to access Z-Wave from it, you need a Z-Wave hardware dongle. Several supported dongles are listed on the Web site. I was especially interested in this path, because of rhouse from Fernand Galiana (github.com/derailed/rhouse). rhouse lets you script LinuxMCE from Ruby. It seemed like a solution right up my alley.
The second path for Z-Wave is the Vera from Mi Casa Verde (www.micasaverde.com). I first learned about this product in the May 2009 issue of LJ (www.linuxjournal.com/article/10302). As I already mentioned, I've used (struggled with) X10, and the Vera seemed like a solution that would be more reliable and more accessible to my other family members.
Choosing a path always is hard. The LinuxMCE path was tempting because it used the least amount of hardware and the most amount of software (which favors my skills). But, I ended up choosing the Vera, because of deployment issues. I don't run Kubuntu, so I either would have to set up another box in my office or run a virtual machine on my workstation (and handle passing through the USB Z-Wave dongle). The Vera box uses little energy and, thus, does not generate much heat—something that is always a consideration here in south Texas. I decided to start with the Vera and figured I always could fall back on the LinuxMCE.
I turned on and set up the Vera. A handy guide on the Wiki (wiki.micasaverde.com/index.php/Schlage_Lock) walked me through the process of pairing the lock. The first step was upgrading my firmware. My Vera was running 1.0.434, but 1.0.602 was required for the lock, and the current version was 1.0.939. I went to the latest version, figuring I might get other improvements as a bonus.
If you have ever worked with X10, the pairing process for Z-Wave is a breath of fresh air. Instead of messing with small toggles, you simply pull the dongle out and press a button to put it in pairing mode. Then, you activate the Z-Wave device. Next, you put the dongle back into the Vera and start configuring your new device. This would all be true if you were talking to a normal Z-Wave device, like a lamp. It turns out, they take lock management a lot more seriously. As a result, the pairing process is much more involved. And, it's a little more complicated, because the Schlage does not emit a very strong signal (a result of it trying to conserve battery power and being encased inside the lock mechanism). That didn't prove to be too much of a problem, because I had a network and power port not very far from the door.
I did the secure pairing dance, which mostly meant starting the pairing process and then running to the door to punch in a programming code. After two attempts, I got a green light from the lock. I was able to see the lock on the Vera device screen. Things always should go this smoothly. I started adding and removing code. I clicked on lock and unlock. Nothing seemed to happen. It turns out that although the lock and Vera were talking, they still were exchanging encryption information—meaning that all my messing around was being queued up until it was done. After about ten minutes, the lock and Vera were fully in sync.
Here is where I realized the LinuxMCE path is not as clear as I thought. I did some research, and I was not able to find anyone who reported pairing with a lock under LinuxMCE successfully. I would have been really frustrated to have gotten Kubuntu, LinuxMCE and rhouse installed only to find out the lock was unsupported.
Once the job queue was cleared, I was able to add myself as a user to Vera. My profile on the Vera has an e-mail and cell-phone number so I can get SMS alerts. Vera supports the concept of “scenes”. A scene allows you to tie together an event, a notification and one or more changes to Z-Wave devices. I created a scene called Door Opened, which was tied to the event that is generated when the lock reports being opened. I also told the scene to notify me via both e-mail and SMS.
Once this was set up, I was notified when the door opened. This was completely independent of entering a pin on the keypad, which meant that when I left the door unlocked, going in and out of the room generated alerts. The SMS can take some time, so by the time I realized how many alerts I had generated, I was getting a lot of them.
Knowing someone is in my office is a great improvement. In the event of an actual compromise, it would be better to have some information about who the intruder was. That brings me to the second part of the solution, the Webcam. I had one lying around and figured this would be a good use for it.
The Vera appears to be a rebadged ASSU WL-500gP. It is running OpenWRT with custom modifications to it. This turned out to be a good thing, because it means software compiled for OpenWRT works on the Vera. Mi Casa Verde does not officially support changes at this level, but it gives you full root access, so at least it doesn't get in the way.
The first step to doing this sort of thing is hooking up the Webcam to my normal workstation. I've learned from experience that if you cannot get it to work easily on a full Linux install, you have no shot at getting it to work on an embedded device. The Webcam plugged in, and I installed luvcview, a simple viewer program that lets you see what the Webcam sees. I ran luvcview and immediately was looking at a small picture of myself. This was awesome on two fronts. I'm pretty sure this cam didn't work under Linux the last time I tried it, and now I can move on to the hard stuff.
Getting shell access on the Vera is really easy. Go to Advanced→Net & wifi→Advanced configuration. It will ask you to set a root password. From that point on, you will be able to ssh in as root. The filesystem is a little confusing at first. Using df, the root filesystem appears to be completely full. The way the system is created, that is not actually true. In most cases, you can ignore that and simply untar things on to the root filesystem with no problems.
OpenWRT normally uses ipkg to manage packages, and that is broken on the Vera. The workaround is very straightforward though. You simply follow the same process for all packages. It turns out that the ipk package is just a set of nested tarballs. Here is the process for installing the gphoto2 package:
cd /tmp wget http://downloads.x-wrt.org/xwrt/kamikaze/snapshots/ ↪brcm-2.4/packages/gphoto2_2.4.7-1_brcm-2.4.ipk tar -xzvf gphoto2_2.4.7-1_brcm-2.4.ipk cd / tar -xzvf /tmp/data.tar.gz
I was really excited, because there are two options for doing the image capture: gphoto2 and motion. gphoto2 is a command-line tool for controlling a normal digital camera. motion is a tool for controlling a Webcam and detecting motion.
What I really, really wanted was motion, which would provide an actual video of the person entering, but I ran into a classic version problem. The Vera/ASUS uses a Broadcom chipset for the onboard wireless. This is apparently flaky under the 2.6 kernel, so it is using a 2.4 kernel. The Webcam drivers for 2.4 are really limited. It turns out the uvc driver that allowed the Webcam to work on my workstation is available only in 2.6. I couldn't find a Webcam around the house that was supported with the drivers at my disposal.
So, that sent me on the hunt to get gphoto2 to work. It requires an actual digital camera. I had three different cameras from which to choose: a Canon SD1100, a Canon SD780 and a Canon EOS 400. You probably are noticing a theme here—they are all Canons. I love the little Powershot cameras. The last one is a DSLR that actually belongs to my wife (she's more serious about photography).
Here is where I learned that Canon has used its own protocol in the past, but apparently it's coming around. As a result, you need a recent version of gphoto2 in order to access the above cameras. In this case, I was incredibly lucky. It turns out the latest, greatest version was available and compiled already for me (downloads.x-wrt.org/xwrt/kamikaze/snapshots/brcm-2.4/packages).
In order to make this work, you need three different packages: gphoto2, libgphoto2 and libgphoto2-drivers. The instructions above work for installing gphoto2. The libs take some extra steps:
cd /tmp wget http://downloads.x-wrt.org/xwrt/kamikaze/snapshots/ ↪brcm-2.4/packages/libgphoto2-drivers_2.4.7-1_brcm-2.4.ipk tar -xzvf libghoto2-drivers_2.4.7-1_brcm-2.4.ipk tar -xzvf data.tar.gz wget http://downloads.x-wrt.org/xwrt/kamikaze/snapshots/ ↪brcm-2.4/packages/libgphoto2-_2.4.7-1_brcm-2.4.ipk tar -xzvf libghoto2_2.4.7-1_brcm-2.4.ipk tar -xzvf data.tar.gz
This gives you the /tmp/usr/lib directory. Then:
cd /tmp/usr/lib/libgphoto2/2.4.7/ rm -f any_drivers_for_cameras_you_dont_have
In my case, I left canon.so, directory.so and ptp2.so. The last two are needed to talk to my camera. If you don't clear out the drivers directory, you will run out of space when you try to copy this on to the Flash portion of the Vera:
cd /usr/lib cp -R /tmp/usr/lib/* .
Now you can hook up your camera. Typing gphoto2 -a should list all your camera's abilities. The most important ability is capture. The Powershots reported being able to capture images, but I was unsuccessful in actually getting them to do so. They require a special command to open the lens that did not work. I hooked up the EOS and got an IO error. After some research, I found I needed to format the memory card. Once that was done, I could trigger the camera from the command line. Thanks to an idea from wearetherock (snipplr.com/view/19935/post-twitpic-with-curl), I found out that posting a tweet with the picture was super easy. This solved two problems at once. The first is that the Flash memory in the Vera can not keep very many pictures around, and second, the system is more secure if I can store the picture off-site, safe from intruders.
The script is dead simple:
#!/bin/sh cd /tmp gphoto2 --capture-image-and-download --filename=now.jpg ↪--force-overwrite curl -F "username=USERNAME" -F "password=PASSWORD" ↪-F "message=Intruder Cam" -F media=@//tmp/now.jpg http://twitpic.com/api/uploadAndPost
(Replace USERNAME/PASSWORD with valid credentials.)
Now that I had the picture capture happening, I just needed to connect it to the open door event. I found some people were monitoring a logfile (which in recent firmware has changed to /tmp/log/cmh/LuaUPnP.log). That would be fine if I wanted a record of what happened. Instead, I want the camera to trigger on an event.
It turns out Mi Casa Verde has a solution for this. The latest firmware adds in Luup. This is a Lua-based interface to the system. It allows you to do some pretty advanced scripting. In my case, I only need to do some simple scripting.
I put my shell script in /root/upload.sh. The scene I already had created had a button for Luup scene. I don't actually know any Lua, but in this case, Lua expertise wasn't really required. I simply entered:
os.execute("/root/upload.sh >/dev/null 2>&1")
This told Vera to run my little shell script whenever that scene was triggered. So when the door was opened, the camera would take a picture and upload it to Twitter.
Now when I open the door, it takes a picture. If I spend some more time on this, I could add more logic so that the notification and picture happen only at certain times of day or night. This would be useful to cut down on the notifications I was getting every time I left the office to do something else like eat lunch.
I actually was really surprised at how far I was able to get. Barring some hardware issues (stupid dongle), I was able to wire up a system that monitored my door and notified me (and the entire world via Twitter). Long term though, I ran into some problems with my solution.
In the end, I was not able to convince my wife to sacrifice her camera permanently to improve the quality of my security system. I will have to find a cheaper digital camera.
I also ran into a number of problems getting my event to trigger properly. I thought it was the result of poor programming on my part, but I discovered I had a defective dongle (forum.micasaverde.com/index.php?topic=1855.0). I'm not sure whether that was the root cause of my problem, but as a software developer, I feel it is my responsibility to blame the hardware first. I still was waiting on a replacement when I wrote this article (more because I just submitted the request five minutes ago), but I will assume that the new dongle has showed up and everything works like a charm by the time you read this. If you get this far, and it does not work, contact me, and I'll tell you what I had to do to fix it.
There is one last thing to discuss—security. When I started this project, the goal was to increase the physical security of my office. Assuming everything I did always works, I now will receive a notification when someone enters my office (through the door). Assuming that I find a replacement camera, I also will have a picture that I can quickly check to see whether the person should be there. On the surface, it seems like things are more secure than before.
As I mentioned previously, I have a door with a keypad lock. To get in, you have to get a PIN or break down the door. Thanks to my new security system, there now is a third option. If you compromise the Vera, you can add your own PIN to the door. Then, you can enter the office with a minimum of fuss. There are a number of guides on making the Vera more secure, so maybe it is not actually a big deal. I guess this is the reason security is so difficult. I thought I was making things better by improving the monitoring of the room, but my implementation may have weakened my security on other fronts. For me, the trade-off is an acceptable one, but I'm mentioning it so you can make your own decision. I suppose that's why I'm so terrible at security—I am too happy to make the trade-off.