In an effort to try and avoid having a smartphone next to my bed (and, of course, for the fun of making things), I decided to build my own smart alarm clock out of a Raspberry Pi.
One of the amazing things about the Raspberry Pi Compute Module is that there is a limitless number of cool and wacky things you can plug them in to. You can get the official I/O board, the all-in-one PC, a handheld tablet, even a 5-inch smartphone-like board. Jeff Geerling has a comprehensive database showing off even more things that are possible with the Compute Module 4.
For this project, I decided to go with Seeed Studio’s reTerminal.
I really love using Seeed Studio for personal hardware projects. They have a lot of great stuff, a US-based warehouse for speedy shipping, great documentation, custom software libraries, and even a YouTube channel.
The reTerminal in particular seemed like a good fit for this project. Notably featuring:
But best and most important of all: a built-in buzzer! Rated at 85db. My original plan was to have music or an alarm chime play out of a connected USB speaker or something, but having a buzzer built-in is really ideal.
For the software, I didn’t want to use a desktop-oriented UI library like Gtk, since all of the controls would be optimized for the mouse, and not for touch. There have been more efforts lately to make Gtk more touch-friendly, particularly in Gtk+4 with the incorporation of a library called libhandy, which tries to make Gtk widgets work better on Linux-based smartphones like the Librem 5. Qt is an option too, but I since I wasn’t making a desktop app, I would probably spend way too much time customizing the theme/appearance of everything to get it to look exactly how I wanted.
I had this exact same problem with my home-built thermostat project too. For Chipotherm, I actually ended up writing my own UI library, but it still has a lot of shortcomings, and I planned to do much more advanced things with the alarm clock.
It turns out, there’s already a great project for dealing with bare bones, totally custom UI. Clutter is used by the GNOME shell for drawing and animating the core parts of the desktop environment. It ended up being a real pleasure to use, with excellent Vala API bindings and easy ways to embed OpenGL views or Gtk elements (which is handy since I was considering embedding some kind of Home Assistant web UI).
From there, it was pretty easy to get a basic alarm UI set up, and activate the buzzer! The buzzer is exposed to the OS just like an LED, so I have complete control over the beeping pattern. Here’s a video of the alarm going off showing what the buzzer sounds like.
Unfortunately there’s no way to control the pitch of the beep since it’s only binary (and the beeper connected to an expansion board, so I can’t do PWM), but an annoying sound is kind of what I wanted for an alarm anyway.
Here’s what the UI looks like for setting the alarm.
The last step was to add home automation controls. My home is already set up with the fantastic Home Assistant, which is thoroughly hacker-friendly. Most of the lights in my room are connected to Shellies, so setting up the code to talk to the Home Assistant API was a total breeze. Just some basic POST requests to change the state of lights, and listening on a websocket for any changes in light state.
I even added a button for my coffee machine downstairs, so I can have it warmed up before I even get out of bed. I ended up programming the rest of the buttons on the reTerminal to control all of the lights in my room, and even added little labels to each switch so I know which does what.
I’ve been using this as my primary alarm clock for over a year now, and it hasn’t had any problems waking me up. You can see from the video above how responsive the automation controls are too!
In the future, I’d like to write a program that exposes more statistics and data regarding my sleep performance. I actually already have a scale beneath my bed that detects significant weight changes, and thus reports bed occupancy status to my server. Home Assistant knows exactly how long I’ve been in bed for, and can even detect displacements in weight which could indicate sleep disturbances. It would be cool to show some kind of graph or data visualization of this in the UI.
As always, the source code for this program is GPLv3 and available on my SourceHut.