I was visiting Vancouver on October 14th, 2018, when the temperature in Denver dropped into the teens and the city had its first snowfall of the season. I arrived back home that evening and the next morning I went to work. Around 5pm, my neighbor texted me a photo of my backyard, saying “you have spouting water in your backyard.” Unbeknownst to me, the backflow preventer in my yard had frozen in the cold snap and when my sprinklers turned on that morning, it had cracked. Water had sprayed against the brick of the house for close to 8 hours and a lot of it ended up spilling into my finished basement.
Fast forward a few months and the basement is still not yet put back to its original state. My upcoming Twilio orientation would require that I build something with their services and I very much wanted to avoid a flood from happening again, so I decided to do something about it. I picked up the Raspberry Pi Zero W (tiny computer beloved by hobbyists) I had lying around and I got to work. The goal: create a device that would notify me if the temperature is below the set threshold.
First, I gathered the parts. I needed to set up the Pi as a standalone computer and since the Pi only has one practical USB interface, I plugged a mouse into an old Apple wired keyboard with USB hub and ordered a Micro USB to USB adapter. I also ordered a Mini HDMI to HDMI adapter so I could hook the Pi to a monitor. Next, I created a bootable Micro SD card of the Raspbian with Desktop OS using Etcher on my MacBook. After some research, I found a suitable temperature sensor (DS18B20) that I knew could be connected to a Raspberry Pi and purchased Dupont jumper wires to avoid soldering the sensor to the Pi.
Once all the pieces had arrived, I fired up the Pi and connected it to WiFi so that I could remote in via SSH/RDC. From there, I installed a Node.js version specifically for the Pi’s ARMv6L processor architecture (Note: Node v11.15.0 was the latest I could find). I tracked down a tutorial on how to use the temperature sensor, but I realized that the Pi model I had wasn’t easy to interface with. Not having worked with hardware before, I didn’t know what headers were or why I needed them. I did my research and learned that there are several options:
- Buy the headers and solder them to the Zero W myself
- Buy a hammer headers kit to use with the Zero W
- Buy a Zero WH with pre-soldered headers
A soldering kit costs around $20 and then I’d have to learn how to solder. The hammer headers kit is only $6.50, but it would take a few more days to arrive. The Zero WH is $13.99 and I could pick it up at Micro Center. I opted for instant gratification and got in the car.
Thankfully, I didn’t have to set up the OS again since the Zero WH also had a Micro SD card slot. I was able to pick back up in the video tutorial where I left off. The tutorial shows how to use the Dupont male-to-male jumper wires to connect the temperature sensor to the Pi’s headers without soldering (I should really learn how to do that one day). Note: Make sure the Pi is not plugged in. Red (power) goes on the bottom left pin, black (ground) goes on the pin third from the top left, and green (data) goes on the GPIO #4 pin fourth from the bottom left. Your wire colors may vary, just try to be consistent.
Now that the device is connected, there are some minor tweaks to the startup scripts needed to register the new input device. Let the Pi boot up to the desktop and then place this code at the bottom of the /boot/config.txt
file:
The tutorial was coded with Python, but I didn’t know Python so I chose to write my interface with Node:
Once the tutorial showed me how to connect to the sensor from the code, I took it from there and wrote the rest of the program. A controller hand offs data to each of the utilities, polling for sensor data every so often. When the temperature received is at or below the threshold, the app makes a request to a Twilio Functions endpoint (a serverless function/lambda with Twilio context), which reports the data to the predetermined phone number via text message. You’ll have to obtain a phone number from Twilio and use that as the from
value:
After an extended trial-and-error period, it worked! But that wasn’t enough; I still had to present this to the new Twilions at orientation.
Without a monitor and keyboard, I wasn’t able to connect to the Pi and start the program. I considered doing this remotely from my laptop, but I was unable to SSH or RDC on Twilio’s guest network. A colleague suggested I use ngrok to create a publicly-accessible SSH tunnel (with a randomized port), which was exactly what I was looking for. I edited the wpa_supplicant
file to prioritize the Twilio guest WiFi (not required), added ngrok as a service to be run via systemd, and created a config for ngrok to be run against:
Every time the Pi was turned on, it created a tunnel to the ngrok services. I could log onto the ngrok dashboard to see which port was needed to connect to the Pi via the ngrok domain name regardless of which network it was on. Brilliant.
To create a detachable/re-attachable session, use the `screen` command (I had to `apt-get` it onto the Pi). This allowed me to ssh in, start the script, and exit my ssh session without stopping the script. If I didn’t use this, the script would quit when I logged out.
Here is the final result:
At the orientation “graduation” in San Francisco in early June 2019, I brought my Pi (powered by a Mophie battery bank) and sensor, my laptop, and a glass of ice water to the stage. I fired up the Cold Snap program and dipped the sensor in the water; we all watched the polling report back the temperature changes. As soon as the temp hit the threshold, an SMS report was sent to my phone. Success! I had earned my red track jacket.
This was a really fun project to piece together and I learned quite a bit about both IoT and Twilio’s service offerings. In retrospect, setup would have been slightly easier with a Bluetooth mouse and keyboard instead of the USB variety and ngrok was a lifesaver. You can find my source code on GitHub.
Parts
- Raspberry Pi Zero WH
- Raspberry Pi AC power supply
- DS18B20 temperature sensor kit
- 120pcs Multicolored Dupont Wire 40pin
- Mini HDMI to HDMI adapter
- Micro USB to USB adapter
- USB keyboard w/ hub
- USB mouse
- HDMI-capable monitor
- HDMI cable
- Micro SD card (and SD adapter)