Riddlegate: automating apartment intercoms

If you’ve ever lived in an apartment building or gated complex, you’ve probably seen one of these things:

Apartment Intercom

A person dials some code to reach you, you make sure it’s someone you’re expecting, and you press some digits on your phone to grant access.

However handy this is, there are situations where it’s not very helpful. I found, for example, that delivery drivers would often arrive while I was in a meeting or otherwise away from my phone. I really wanted to be able to just give them a code that allowed them access.

Enter Twilio. It enables exactly this. You rent a phone number through them (very cheap — on the order of $1/month), which can be configured to call HTTP endpoints when it receives a call, SMS, etc.

I built a small application around this to automate my apartment’s intercom. The intercom is configured to call my Twilio number, which will interact with the application. I called it “Riddlegate” after that plotline in The Neverending Story with the sphinxes. It’s pretty simple and self-explanatory. Here’s a screenshot of the admin UI:


Now when I have a guest, I can give them instructions that don’t involve me being near my phone:

  1. Dial <number>
  2. Wait for tone
  3. Dial <passcode>

And Riddlegate will buzz them in!

A (hopefully-not-too-terse) setup guide is included in the Github README.


Given that this controls access to your building/complex, security is an important concern. There are a few things Riddlegate does to improve security:

  1. Twilio signs all requests it sends with your API key. Riddlegate validates these signatures and denies access when it detects an invalid signature. This prevents a would-be attacker from brute-forcing your access code if they were to discover your endpoint URL.
  2. Admin area is password-protected. This is obviously only as secure as the password you choose. Also obviously better if you serve over HTTPS.

Security cameras: automatically recording and uploading footage when a door is opened

My last post detailed how to integrate a cheap IP cam with SmartThings. I briefly mentioned a SmartApp that took a picture when the door opened. This was pretty straightforward. I wanted to take it a step further and trigger recording when my door was opened (but no one is home). Beyond the obvious, I had the following requirements:

  1. SmartThings needs to be able toggle recording. The SmartApp should notify my household when it begins recording.
  2. Tampering with the camera shouldn’t destroy already captured footage.
  3. Footage should start uploading somewhere offsite as soon as possible.
  4. Control over uploaded footage.

I already covered (1) in my last post. My integration with the IP camera enables a scheduled recording feature, and configures this feature to always record. Switching off recording clears the schedule.

Uploading footage to S3

The camera I’m using already has builtin support to upload footage to an FTP server, which leaves everything but uploading to offsite storage.

Since it’s easy and cheap, I decided to upload footage to Amazon S3. I then needed a tool that:

  1. Watched for newly created files to appear in the directory my internal FTP server is pointed at. When a new file is detected:
  2. Immediately begin a streaming upload to S3. Since the file size isn’t known ahead of time, I made use of the multipart upload API, which allows for the breaking down of uploads into smaller (5MB) chunks.
  3. When the file is done being written to, complete the upload (i.e., tell Amazon the file is done being uploaded). This makes the file available on S3.

This seemed like a good fit for inotify, which allows for the monitoring of filesystem events. It’s possible to set up notifications that are triggered when, for example, a new file within a directory is opened, closed, or modified.

I didn’t find a tool that did exactly what I wanted, so I made a ruby library that did. I called it “s3reamer“. My sincerest apologies for being an awful portmanteau-ist. I run this on my home server:

This will automatically begin uploading to S3 when recording on the device is triggered. Here’s a snippet from the log file:

Uploading starts within a few seconds of recording being switched on. Most of that delay is waiting for the camera to begin uploading.

SmartApp to trigger recording when door opens

This part was pretty straightforward. Code below. This also sends a push notification when recording is switched on so my household knows and can react accordingly.

Integrating Foscam FI9821P with SmartThings

Motivated mostly by curiosity, I was recently in the market for a cheap IP camera. After a little bit of research, I settled on a Foscam FI9821P (I got mine for ~$45 as an Amazon Warehouse Deal). The app provided by Foscam is pretty nice, but I wanted to integrate it with my home automation setup as well. In particular, I wanted to accomplish the following:

  1. Secure access. Any communication with the camera should require some secure authentication mechanism.
  2. SmartThings integration. I wanted a device in SmartThings I could play around with.
  3. REST endpoint. Although I could probably get most of what I want done with SmartThings alone, I didn’t want to be bound to it.

SmartThings has a device type for cameras, so as long as there’s some way to access the camera within SmartThings, (2) is easy. In a previous post, I outlined a setup that uses HMAC to secure communication with smart home devices. I leveraged it in this project as well.

I should mention that I stumbled across some existing attempts at this, but nothing that would’ve given (1) and (3).

I put together this route for my home automation gateway, which accomplishes (1) and (3). With it, I can capture a snapshot and control some rudimentary functionalities of the camera. I can, for example, request a snapshot of what the camera is currently seeing simply by accessing this URL (with the appropriate security headers in place):


You can see that there’s baked in support for multiple cameras (since the endpoint is scoped by a camera name). While I don’t anticipate buying more cameras, I figured adding support would make this project more generally useful.

To integrate with SmartThings, I created a virtual device (code embedded below). It allows me to request an image, shift the camera to one of three preset positions, and to start/stop recording. Here’s a demo of the interface:SmartThings Interface

This project was a lot of fun, and quite a bit easier than I was anticipating. My favorite thing this has enabled is a SmartThings SmartApp that signals the camera to take a picture when my front door opens. To avoid being too creepy, this only happens when no one is home. If I can muster the motivation, I’ll probably write a separate post about that.

Cheap alternative to Phillips Hue LED Strip

I have some RGB LED strips in my bedroom to light an area other lighting in the room doesn’t reach. The strips I bought were inexpensive, but they only interact with the included infrared remote. I wanted to be able to control these lights with SmartThings. There are a couple of ways you can do this:

Easy and spendy

Phillips has a bunch of products that integrate nicely with SmartThings. The obvious contender here is this guy. However, for this to work, you’d also need a Phillips Hue Bridge. In total, this is going to run you somewhere between $150 and $250, depending on how many feet of LED strip you want.

Partially because this seemed unreasonably expensive, but especially considering I’d already glued LED strips to my walls, this solution wasn’t appealing.

Cheap and complicated

Browsing around, I found a cheap ($30) LED controller advertising “WiFi” control:

It was exactly what I was hoping for. It has a tiny TCP server that allows network control. The official mobile app is actually quite good, but it doesn’t integrate with the rest of my SmartThings stuff. I toyed around a little bit and managed to reverse engineer the protocol. I put it in a rubygem, available here.

This allowed me to programmatically control the LEDs, but obviously still no integration with SmartThings. Fortunately, that wasn’t very hard either.


The overall design looks something like this:


I’ll elaborate on each of these components in the following sections.

REST server

The TCP API works nicely, but I wanted to wrap it in something that’d be easier to interface with. I wrote a really small REST gateway using sinatra. This serves two functions:

  1. Easy access. Obviously, integrating directly with a TCP server kind of sucks in comparison to making a REST call.
  2. Security. I added a before block in the sinatra to verify HMAC codes computed using a shared secret. This prevents unauthorized parties from using this server. Wouldn’t want randos turning my lights off and on!

This little server listens for requests on port 8000.


I use nginx as the externally facing endpoint because I have a bunch internal webservers, and nginx makes it easier to manage all of them. It also adds the ability to address the webserver using a subdomain instead of a custom port. The config looks like this:

Notice the server is listening on port 81. My router opens port 80, and forwards it to port 81 on my home server. I do this because internal services I don’t want to expose to the outside world run on port 80, but I’d prefer to use port 80 from the outside world. The request chain looks something like:

Integrating with SmartThings

SmartThings has what they call “Virtual Devices“, which is a way to define a custom device in terms of its capabilities. A Virtual Device can, for example, declare that it’s a switch (giving it an on/off toggle), a switch level (giving it a dimmer slider), or a “color control” (giving it a hue/saturation control). One can also insert code that’s called whenever one of the controls changes value. Perfect!

I created the following Virtual Device based on the Phillips Hue device template that interacts with the REST server mentioned previously.

All one needs to do at this point is create a new device within SmartThings that makes use of this Virtual Device.


This ended up working out way better than I expected. From what I can tell, it behaves exactly like a first-class citizen within SmartThings. I’m super happy with how easy (and fun!) it was.


  1. [Oct-21, 2015] — I noticed there was a bug in the SmartThings Virtual Device signature generation method. It wasn’t properly padding signatures beginning with 0. I fixed this by using the built in byte[].encodeHex().

Words With Friends Dictionary

I’ve been doing a bit of work with a move generator for Zynga’s popular variant on Scrabble, Words With Friends (WWF). To be any good at that, you need a list of words what WWF considers valid. Fortunately, they mention on their website that they use a slightly modified version of ENABLE, which is freely available.

Unfortunately, I noticed that sometimes WWF would complain about words I generated not being valid. After ensuring that the generated words were indeed in the ENABLE dictionary, it became obvious that Zynga’s dictionary removes some words from ENABLE. From experience, these generally included words that some people might consider offensive. For example, the word ABO, which is a pejorative for an Aboriginal Australian, is not recognized by WWF. In addition to this, ENABLE includes words that are longer than 15 letters. Since WWF’s board is 15×15, it’s impossible to form a word longer than 15 letters. Strangely enough, WWF still recognizes these words, despite them not being valid plays.

In an attempt to get a dictionary that’s as close to possible as the one WWF is actually using, I used an open source library I’ve been developing to ping them with all of the words shorter than 16 letters in the ENABLE dictionary. They removed about 50 words from the standard ENABLE dictionary.

A quick poll of a few “cheat” websites indicated that they were using the vanilla ENABLE dictionary, which includes the removed words.

You can find the updated dictionary here: wwf-dictionary.

Minification and disk caching

It’s probably pretty obvious that resource minification is a good thing. The bandwidth savings this affords you are probably negligible, but the fact that your site has fewer objects to load means faster page load times, and fewer requests sent to your server.

Ideally, you’ll have one file for all of your javascript source, and one more for all of your stylesheets. There are some pretty nifty WordPress plugins that do all of the work for you. This is great. Whenever you update your javascript or stylesheets, these plugins will generate a fresh minified file for you automatically. How lovely.

One has to be careful, though. Gathering up all of your source, minifying it, and throwing it all into a single file is a slightly costly operation. It’s a good thing, then, that all of the plugins I mentioned earlier provide some sort of caching mechanism. Some are a little less thoughtful of performance, however. Consider, for example, Better WordPress Minify. Here’s what the link to my minified javascript file looked like:


This is clearly getting passed to PHP every time someone requests the page. Why is that bad? Because PHP is a resource hog. Serving a static file is almost always cheaper! This is especially true when PHP is just going to read a cached file from the disk anyway. As far as I can tell, that’s exactly what this plugin does. I can’t seem to find any way to change the caching mechanism without editing the source. Here’s how it serves cached files:

In contrast, here’s what the minified javascript link looks like under W3 Total Cache’s minify:


This looks much nicer! This is, in fact, a static file. We could even serve it from a more lightweight web server, or push it to a CDN. W3TC supports doing both of these things. Here’s the magic: if the file exists, it’ll be served normally. If it hasn’t been generated, the request will eventually hit this rewrite rule:

rewrite ^/wp-content/w3tc/min/(.+\.(css|js))$ /wp-content/w3tc/min/index.php?file=$1 last;

This forwards the request to W3TC’s minify handler, which generates and caches the minified resource. From that point forward, it’ll be served as a static file. Nice!

Incidentally, W3TC’s page cache does exactly the same thing. When configured properly, this plugin makes it pretty easy to withstand pretty heavy traffic spikes.

You might not notice the difference in performance when your server is under a light load, but trust me. If you let PHP handle the caching, you’ll get a visit from the 502 Bad Gateway fairy in no time.

Of course, this all assumes you’re on a single host and have no interest in stuff like memcached.

LaTeX to Postscript Image

Earlier this week, I was preparing a presentation that was to include some simple equations I already had LaTeX for. The slideshow in question had far too many fiddly figures to justify bothering with beamer. Rather than fussing with powerpoint addins, I figured it’d be easiest to just include some images of the equations.

Rasterized images of text look horrendous in powerpoint presentations, so I figured I’d try to include postscript images instead. I found a nice post on the TeX section of stackexchange that detailed how to turn an equation into a PNG, and I adapted it for my own use.

Here’s a hacky bash script I wrote to make use of this technique. Note that if you want to do anything outside of math mode, you’ll have to remove the \[ \] surrounding \lformula. There were a few times I wanted to use \eqnarray and had to do this.