I've been wanting to build a Weasley Clock for a long time. It's really the perfect IoT project. Some cell phone location data, a Raspberry Pi or Arduino, a bit of clockwork, and you've got something that seems like magic.
Like any good programmer, I got started by googling to see if I could find anyone who's already solved the problem. As it turns out, I could! And, after reading through all of them, I decided that, without woodworking tools or a 3D printer, I was not equipped to build a nice clock. At least not yet.
But that's ok. I'm a web developer. I made a website instead, and put it in a picture frame behind a mirror to make it look pretty.
Taking inspiration from the best Weasley Clock guide I found so far, I decided to use Owntracks to tap into our iPhones' Significant-Change Location Service to get our whereabouts without taking down our batteries or compromising our security. Every time we move outside a certain radius (say, 250m), our iPhones fire up Owntracks which in turn shoots off location over MQTT or HTTP.
But where is it shooting that location to?
At first, I wanted to host a full-stack site on my Raspberry Pi at home. But almost immediately, I ran into the classic issue of hosting at home: DDNS. At that point, I could either dive back into that DDNS world which I hadn't touched since my Minecraft server years ago, or...
Well. I'm a web developer. I used the cloud instead. I've been having a fun time hosting static sites on Netlify for a while now. This seemed like as good an opportunity as ever to dive into the rest of the JAMstack and figure out what all the serverless hype was all about.
After poking around, it seemed like FaunaDB was a good serverless persistence layer. With an okay free plan, too. And how could I get data to FaunaDB? Well, my best friend Netlify had just the service for that. The two even had a nice example I could follow.
With all that back-end stuff out of the way, let's get to the fun stuff. Time to build a clock. For the front-end, I chose Svelte. Because Svelte is just nice.
It didn't take more than a day to build a quick and slick clock that did all the things: pulling data from FaunaDB with Netlify Functions on an interval, displaying a pretty clock with SVG, playing a chime when a hand moved, animating everything with some satisfying springs... bam.
Really the most difficult part was dynamically setting the interval so that I wouldn't exceed any of my free-tier limits. This is where it would've been nice to have a traditional server that notified the front-end over a websocket whenever there was new data, but that's just not something serverless is set up for. Oh well.
Oh wait! There's one more bit of back-end that I have to talk about. After receiving a location from Owntracks/FaunaDB, the front-end can optionally request an ETA for someone. And that feature was built using the Google Maps Directions API, and again, Netlify Functions. I can even switch between driving and transit; something I'm totally planning on implementing maybe. Cool!
So I really was sad that I couldn't build a nice physical clock like those links up above. I didn't want to just have some computer screen hanging on a wall, showing a clock on some website. I wanted it to be a physical object, not a digital object. So I did the best I could and finally built that magic mirror I've been wanting to build.
Taking cues from a MagPi article I had saved as well as this nice forum thread I put together my BOM:
- An IKEA Frame
- An 8x10" Two-Way Mirrored Acryllic
- A low-profile 9.7" LCD
- A Raspberry Pi 3B+ I had lying around
- A 2.5A Micro-USB Switched Power Supply
- A short micro-usb cable to power the display
- A short HDMI cable to connect it to the Pi
- USB Speakers which required some busting out of their case and minor re-soldering
- And a little bit of mounting tape
Put them all together, set up the Pi's OS, start the Pi in kiosk mode, and bam.
Magic Mirror JAMStack Weasley Clock.
Sound effects obtained from https://www.zapsplat.com