YouTube Video: https://www.youtube.com/watch?v=G7_qA9KGnHY
My wife had a nightmare that she woke up from a nap and couldn’t breathe, and she couldn’t call me for help since I was in the other room and she didn’t have enough air left to call for me. Naturally, I wanted to come up with a completely over-engineered solution to this problem, so I built this remote, which I call Wife Alert. She pushes this button and I get emailed, texted, my phone starts playing Patrick’s siren noise, and my entire computer is taken over by a flashing red screen that screams at me.
It's very effective.
It's very effective.
THE REMOTE
The remote is 3D printed, just big enough to fit a Raspberry Pi Zero (the version with headers because I didn’t feel like soldering). It’s wiring is pretty simple; it’s got a big red button that the Pi’s script is listening to, and it’s got two LEDs that show whether or not the alarm is currently going off. I should point out that a Raspberry Pi is not a requirement here and is probably overkill. An Arduino would have been a better fit here, especially because the startup time on the Pi is really long and it’s difficult to get the script on it to reliably run automatically when it starts up, I just didn’t have any lying around.
THE BACK END
So this is what is happening in the background when that button is pushed. There are the four physical components that interact with it, there’s the cloud part of it in AWS, and then there’s some additional message-delivery things as well. When the button the remote gets pushed, the Raspberry Pi in the remote sends a message to SNS, which is a notification-delivery service provided by AWS, that can send a single notification to a bunch of different places, which is what we want here.
It sends the message to my email, both my personal one and my work email, and directly to my phone as a text message. It also sends it to an SQS queue, another AWS service for message handling, as well as to a Lambda function, which is basically a way to run code in the cloud. This queue has a delay, which we’ll get to in a second. The Lambda function does a few things. Most importantly, it sets the value of this SSM parameter. This is the only actual data stored in this system in between events, and it’s basically just a small parameter with a name and a value we can change, that other systems can check. The alarm and the desktop script check the value of this every few seconds, and when the value isn’t “OK” they go off. The Lambda function changes this value from OK to ALARM. After that, the next time the alarm or desktop checks the value they’ll see that it’s no longer OK and they’ll do their thing. The Lambda also calls the Firebase API, which is Google’s mobile notification platform, which sends a notification to a custom Android app I wrote that goes into alarm mode when it gets that notification.
So, now we’re in alarm mode. All of the devices, now including the remote, are still checking the parameter every few seconds, waiting for it to go back to OK so they can stop alarming. This is where the queue comes in. It just forwards along whatever messages are passed in, but I added a 60-second delay. So one minute after an event comes in, the queue invokes a second Lambda function. All this function does is change the parameter value back to OK. A few seconds later, all of the devices that are checking the parameter value will notice and calm back down. The phone isn’t checking the parameter and it just has a timeout, mostly because I am definitely not an Android developer and didn’t want to invest the time in figuring that out.
It sends the message to my email, both my personal one and my work email, and directly to my phone as a text message. It also sends it to an SQS queue, another AWS service for message handling, as well as to a Lambda function, which is basically a way to run code in the cloud. This queue has a delay, which we’ll get to in a second. The Lambda function does a few things. Most importantly, it sets the value of this SSM parameter. This is the only actual data stored in this system in between events, and it’s basically just a small parameter with a name and a value we can change, that other systems can check. The alarm and the desktop script check the value of this every few seconds, and when the value isn’t “OK” they go off. The Lambda function changes this value from OK to ALARM. After that, the next time the alarm or desktop checks the value they’ll see that it’s no longer OK and they’ll do their thing. The Lambda also calls the Firebase API, which is Google’s mobile notification platform, which sends a notification to a custom Android app I wrote that goes into alarm mode when it gets that notification.
So, now we’re in alarm mode. All of the devices, now including the remote, are still checking the parameter every few seconds, waiting for it to go back to OK so they can stop alarming. This is where the queue comes in. It just forwards along whatever messages are passed in, but I added a 60-second delay. So one minute after an event comes in, the queue invokes a second Lambda function. All this function does is change the parameter value back to OK. A few seconds later, all of the devices that are checking the parameter value will notice and calm back down. The phone isn’t checking the parameter and it just has a timeout, mostly because I am definitely not an Android developer and didn’t want to invest the time in figuring that out.
THE ALARM
The red light was an Amazon purchase, but the base needed to be 3D printed like the remote was. This also uses a Raspberry Pi Zero, although this one didn’t headers to save space, since there was already a lot of stuff that needed to fit into the case which I wanted to be as compact as possible. The Pi sits on the bottom, the big horizontal thing at the top is a relay which allows the Pi to turn on the big light, which requires 12 volts, by sending the 3.3 volts that the Pi can output to the relay, which basically acts like an electronically activated switch. The little pronged piece is a voltage regulator, and a 12 volt power supply sticks out the back to power everything. It was super important to me that there was only one cable sticking out the back of the alarm, but Raspberry Pis are normally powered by micro USB cables, which are built for 5 volts, and the light required 12. To get around this, I cut a micro USB cable in half and exposed the power wires, which I could then attach to the 12 volt power supply with a little voltage regulator, which takes 12 volts and turns it into 5 (and some heat).
I initially had lofty plans for this case, with little holes for screws and a hole to mount the voltage regulator, but that all went out the window as soon as I tried fitting all this into the case with wires getting in the way. The Pi is stuck to the bottom with some tape, everything else is just suspended by the wires. But, once you get the light on all that messiness goes away and it looks pretty good, with just the power port sticking out the back. I also made sure to backstop that port when I was designing the case, so I can push about as hard as I want when I plug it in and I won’t accidentally shove the cable into the case and break anything. I wanted to attach the light without anything sticking out the bottom of the case, and I didn’t want to screw directly into the plastic or try to print threads or capture something threaded, so I left two holes open in the back, just wide enough to capture a nut so I could screw the light onto the base nice and tightly and from the front you don’t see anything.
I initially had lofty plans for this case, with little holes for screws and a hole to mount the voltage regulator, but that all went out the window as soon as I tried fitting all this into the case with wires getting in the way. The Pi is stuck to the bottom with some tape, everything else is just suspended by the wires. But, once you get the light on all that messiness goes away and it looks pretty good, with just the power port sticking out the back. I also made sure to backstop that port when I was designing the case, so I can push about as hard as I want when I plug it in and I won’t accidentally shove the cable into the case and break anything. I wanted to attach the light without anything sticking out the bottom of the case, and I didn’t want to screw directly into the plastic or try to print threads or capture something threaded, so I left two holes open in the back, just wide enough to capture a nut so I could screw the light onto the base nice and tightly and from the front you don’t see anything.