Alright, here's the scoop. I currently live in a dorm hall and whenever I or my roommate enter the room we unlock the door and relock it at the same time. Originally, the purpose of this was to save time. Need to leave? Instead of having to lock the door with a key, all you have to do is shut the door. Wow! I just a whole 5 seconds of my time. How could I sound more like a programmer?? A whole 5 seconds.
Unforutanly, all of those 5 seconds saved are thwarted by forgetting our keys inside our room and locking ourselves out. What happens next is a 5-minute walk down to the university's safety and security building to get a spare key. In total between getting a spare key and returning it, an extra 20 minutes can be added to my day at random.
So What's My Solution?
I could just not lock my door. It's a safe college, nothing is ever going to get stolen. In fact, I could even just lock the door when I leave, 5 seconds is way less than 20 minutes. But nope! I over-engineered the crap out of it...
Raspberry Pi Auto-Door 1000
Yup! You heard it right, I spent countless man-hours building a device to automatically unlock my door for me.
It's a rather simple mechanical design. At the beginning of this project, no matter whether the door is locked or unlocked, it can still be opened from inside the room. This is my starting point.
I have a motor attached to the inside of the door with non-permanent adhesive. I then have a string going from the motor to the doorknob. Funny enough, the string is attached to the doorknob with duct tape.
Finally, the motor is connected to a control board. Currently, this is a raspberry pi 2 but I have plans of slimming it down to an Esp8266.
The result is when the control board gets a trigger to open the door, it then tells the motor to spin. The motor coils the string like a winch. In turn, from the inside, the doorknob spins allowing someone to enter the room.
I have door motor thingy, now all I need is a secure way of triggering it. Originally, I had plans to add facial recognition with an Xbox Kinect mounted outside the door for 3d biometrics. However, I went with something simpler, a button. It's so easy, both my roommate and I have a button on our phones, we push it and the door opens! In fact, I can open the door from anywhere with the internet.
So, how did I do it? Well, this is where it gets a little complex.
What didn't work and why: The raspberry pi sits behind a NAT firewalled network and dynamically assigns IP addresses. What this means is I have zero chances of having the Pi listen for commands via a self-hosted web server or rest API. This would have been the most simplistic, standard solution for doing things. so then, I did a lot of googling - Yes, "googling" is a skill- and while I did find a few workarounds such as UPNP -basically dynamic port forwarding- and dynamic DNS -an auto-updating URL to match the randomly changing IP address-, these felt like duct-taping a broken coffee mug back together, it just won't work well in the end.
What did work: After much more googling, I came across Adafruit IO. Adafruit made a wonderful service and programing libraries, called IO. Foundationally, the purpose of IO is to get information from point A to point B over the internet. Hence the name IO, Input-Output. This is perfect for me because Adafruit already had a way of triggering a DIY IoT device behind a NAT firewall. Essentially, their IO library queries Adafruit's servers every half second to see if the state of a variable has changed.
Funny enough, Adafruit IO connects as a third-party service to IFTTT. IFTTT is another amazing service. It's one that allows you to setup recipes of sorts for one type of event to trigger some other thing on the internet. One of IFTTT's triggers is a button widget through its mobile app.
While normally I would be inclined to include my source code, I can lessen attack vectors and the chances of my raspberry door getting hacked by excluding it. However, below is a flow chart/pseudo code for the whole setup.
A cool thought I had: The trigger for IFTTT doesn't have to be the button widget on my phone. IFTTT has hundreds of other triggers. What other ways might I want to open my door?
Maintenance and Fine Tuning
Hardware: Firstly, the winch kept failing. The rope kept slipping or missing the track to be wound up. In the end, this made it so the door didn't open. To fix this problem, I drilled a small hole in the winch round part, this kept the rope from slipping. To solve the second problem, I attached a square piece of cardboard as a guide.
Software: To begin with, the python script I wrote kept getting killed. In fact, I still don't know what was killing it but without it, my door won't open remotely. My solution was to have a cronjob checking every minute if my python script is running, if it wasn't running I started a new instance of it. That paired with starting the script in my rc.local file -at boot- was enough to stabilize functionality for everyday use.
While making use of cronjobs and rc.local, I added two more features. First, the raspberry pi restarts every night at 2 AM -Everyone including computers needs rest-. The other thing I did was to put my source code into a git repository and at boot, the pi pulls the latest version of it from a remote repository. Instead of having to manually ssh into the pi -Yes, the IP changed from time to time, this was true pain- to make an update to my code, now all I have to do is upload it to the cloud. Yay!
Hey if you are reading this, you made it to the end. Thank you!