My Door Is Always Open

There's very little you can't do with Javascript today. My latest diversion was to get told whenever our basement door was left open - a real Internet of Things project!

Using a Raspberry Pi, a magnetic reed switch, a little bit of NodeJS, the Pushover API, and of course the spark of the idea from Mike Frey's presentation at the March NodeMN meeting, I went from a problem to a working solution in just a day.

Project Plan

The problem that I was hoping to solve involved our cats, our basement, and the cats' desire to enter the basement to hide and throw up hairballs in secrecy. I didn't think it was reasonable to consider building something to physically restrain the cats, so the next thought was just to be told when the door was left open.

A couple of options presented themselves... an audible alarm, a flashing light, and even a motorized arm to close the door (to be proactive instead of reactive). None of these solutions were really solving the problem however, what I really wanted was my iPhone to receive the alert.

So the project requirements were spec'ed. Ping a mobile device when the door is left open.

Hardware

The hardware for this project is rather minimal.

Raspberry Pi

I chose to use a Raspberry Pi A+ for the smarts... At only $20 this is the lowest cost member of the RPi family, and yet still has more than enough computing power for a project of this size.

There are a couple of additional expenses when using a Pi, such as a WiFi dongle and a microSD memory card, but combined the total cost of the computing device is still only around $30, which is still less than the cost of the Raspberry Pi 2 itself.

More people need to be aware of the RPi A+ as an option, especially for headless projects that don't require super computational efforts.

Switches

I had no luck finding the door switches locally, though admittedly I didn't try too hard... a disappointing trip to HomeDepot and Ax-Man was about the most effort I gave. I very quickly ordered this switch from Adafruit, two in fact since I have two doors I want to monitor.

Little Bits

Resistors, shrink wrap, and hookup wire were just sourced from my parts bin.

Software

As I said at the start of this post, I began this project from inspiration from Mike Frey and began with his project on github. In the end my code only has some passing resemblence to his since our end goals were a little different.

Pushover API

I found the Pushover service to be the ideal solution for sending notifications to our mobile devices. Using the pushover-notifications npm package made it even simpler to use. Using npm packages in general makes everything simpler.

Timing

Now I didn't want to get notified EVERY TIME the door was opened. We do have legitimate reasons for going into our basement on a regular basis (our laundry room is down there). A little bit of fun Javascript proved simple enough for this.

When the door is opened, I start a timer in code:

sendMessageTimeout = setTimeout(function() {
  pushover.send(msg, function(err, result) {
    if (err) {
      // do something appropriate
    }
  });
}, 5000);

By using that code snippet, five seconds after the door is opened the message will be sent. But what if the door is closed within those 5 seconds?

clearTimeout(sendMessageTimeout);

The clearTimeout() will do what it says on the box, clear the timeout so that no message gets sent!

Multiple Doors

Another deviation I took from Mike's code was that I wanted to create multiple door objects. I might add another door at some other time, so I really wanted this to be an easily configurable option instead of hard coding the door objects.

That was simple enough, but it did expose another cool Javascript trick. My door objects are in an array, and my code had a need to access the last added object to that array. Javascript natively does not have a built-in function for this, so a small addition to the Array prototype was called for:

Array.prototype.last = function() {
  return this[this.length - 1];
};

Now I can simply

door.last().on('open', callback);

Wrap Up

There's more coolness to talk about, but this post is getting a bit long already... I'll make note to write a followup to discuss some other interesting topics such as

  • config npm package
  • onoff npm package
  • more about Pushover
  • wiring diagram

You can find the code for this project in my github account if you're interested in seeing the full thing and how it fits together. Comparing against Mike's code is interesting as well. Maybe you've got some comments and suggestions too!