It's so cute

The other day I saw a video by someone who bought a cheap little clock, and it was interesting, because that little clock had been taunting me for months by showing up constantly in my AliExpress recommendations. I held off on buying it because what am I going to do with yet another clock, but the video said that it has an ESP8266 inside, and that, with a little soldering and programming, you could run ESPhome on it!

Obviously, I didn’t need any more convincing, so I ordered one, though I remembered I’d been seeing this clock listed for $6, and balked at the $16 the video mentioned, so I ordered another version that I found for $12, hoping it would be the same.

Fairly serendipitously for this purchase, the last bedside clock I made was showing its age a bit. Mainly, the dimmest setting on its screen was bright enough to be annoying when I’m in bed, and the screen has been burned-in quite a bit. A new monochrome OLED screen is an easy fix, but I’d prefer a color one (especially if it can be dimmed more), so hopefully I’d be able to replace the Do Not Be Alarmed clock with this new one.

The new clock arrived promptly, and I got to work.

Work

Dashing.

The first thing I did was what any good engineer would do, I eschewed the company of my friends and shut myself in a room where I could work on my clock in peace. The second thing I did was to open the clock up, as the video mentioned, in no uncertain terms, that I would need to solder some headers if I were to ever program this clock.

Imagine my surprise and dismay when, upon opening up the device, I saw no headers or any accessible points to connect anything to program it with. I wasn’t too sad about it, as I’ve programmed ESP8266 modules often by just touching the pins to the microcontroller board, and the clock has an ESP-12F package soldered on it, so the pins are large enough to connect things to, so I got ready for the agony of trying to hold five wires firmly to the board while I press the Enter key on the keyboard with my nose. At this point I was obviously cursing myself for trying to save $4 and not getting the “good” version, but it was what it was.

While examining the (very simple) board, though, I flipped it over and saw what looked like a USB-TTL chip. That chip turned out to be a USB-TTL chip indeed, which took me by surprise, because it meant I didn’t even have to open the thing up! Sure enough, connecting the USB-C port to the computer showed the clock as a USB device, and flashing ESPhome worked perfectly.

Next step: The configuration.

The configuration

I used the configuration from the video as a starting point, as it already contained the pinout for the screen, the screen type and dimensions, and various other niceties. The original configuration used Home Assistant, which I don’t use, so I took those things out.

The visuals

The first draft version.

I’m terrible at any sort of visual design, so I can’t really say that I designed things with any intent, I mostly stumbled onto a design that didn’t seem terrible, and used that. I went through a few iterations, with the time first being centered and the date below it, then with the time being shown diagonally (as in the photo on the right), and finally copying the face of my Xiaomi watch and arriving at the final design.

Usually I’ll open Inkscape and try to mock up something to see how the colors, layout, separators, and other visual elements fit together, but here I didn’t really do any of that, and just iterated on the display directly. It took a bit of positioning elements around, but I think the end result is pretty good.

One serendipitous thing that I did was add a synthwavy-ground-grid type of thing, which gave the face a really nice touch. I initially added it as somewhat of a test, but I liked it so much I ended up keeping it in the final version.

The time

The final look.

The time and date were very easy to add. ESPhome supports NTP natively, so getting the correct time over the network was just a matter of adding the appropriate NTP servers in a small stanza.

This way, the time keeps updating with DST as well, following the timezone properly. This is actually a lot of work to do manually, as I found out when I made the Do Not Be Alarmed clock, and the fact that ESPhome does it for me is fantastic and saves a ton of work.

It basically just worked. The last thing to add was to show various sensor values that are relevant to a bedside clock.

The sensors

My house is instrumented to use Zigbee (with Zigbee2MQTT), and some WiFi sensors that publish to MQTT on specific topics. ESPhome supports MQTT natively, and it can subscribe to topics, listen for updates, and update the screen whenever a topic gets published to.

Usually, when I wake up, I want to know what time it is, what date, what the temperature outside is, in case I need to go out, and maybe what the humidity inside the flat is. I use Zigbee Sonoff or Aqara temperature/humidity sensors, so I wanted the values read from those. I also have a makeshift CO2 sensor in the bedroom (I made that using an ESP8266 with ESPhome and an SCD41 CO2 sensor), and I wanted to see the CO2 value so I know whether I should open a door a bit wider when it gets too high.

These were the values I mainly wanted to display, so I added subscriptions in the MQTT integration to these sensors’ topics, and instructed ESPhome to parse the values they sent. Then, I positioned the elements that I wanted to show the values around the screen.

At this point, there was a small issue: When the clock is restarted (which is, admittedly, rarely), the sensor values show 0, or NA, until the sensor wakes up and sends a reading, which might happen every ten minutes or so. I wanted the clock to show the last value quickly, so I enabled “retain message” in the Zigbee2MQTT options for the sensors I was interested in. “Retain” is an MQTT flag that tells the server to remember the latest message in that specific topic, and send it to you when you subscribe, no matter how long ago it was actually sent. This fixed the issue, and now the clock shows the last values on bootup, which is perfect.

The dimming

And now we get to the most important part of the whole project: The dimming!

This clock is, indeed, much better at dimming. You can dim it very very low before turning the backlight off altogether, but it does get hard to read at very low brightnesses. I ended up using a brightness of about 6%, and a max brightness of 60%, and it’s perfect.

The way min/max works is that the clock starts dimming from 60% to 6% for about an hour before the time when I usually go to bed. Then, it stays dim throughout the entire night, and starts brightening again around the time I wake up, and takes an hour to go back to 60% brightness.

This way, the clock is dim throughout the night when I’m asleep, but bright in the day, when I might need to look at it in well-lit conditions.

This works really well and is a massive improvement on my last clock, and the nice, colorful screen doesn’t hurt, either.

With that, the clock was complete!

Epilogue

This was a very simple build, and it only took an hour or two, but it was lots of fun and I absolutely love the final result. I also really like the fact that I get a lot of use out of something like this. I look at my bedside clock a lot, and having a better clock is a massive quality of life upgrade. I’ve been looking for a better clock for ages, but never found one that ticked all the boxes, until this one came along.

I heavily recommend buying one, you can use my config to program it with, and customize it to your liking:

https://github.com/skorokithakis/esphome-configs

There’s also a version with an ESP32, which is much more powerful, but I don’t know if the pinouts have been figured out yet, so I don’t know how easy it would be to program. However, if you do get one of these clocks, I’ll be looking forward to anything you make with it, if you want to share!

As always, if you have any questions or feedback, please let me know! You can find me on X or BlueSky, or email me directly.