GopherCal: Experiments with eInk
I have to admit, last year, I got fascinated by eink. It's through a few hackernews posts and I loved the following projects: https://www.invisible-computers.com/, and https://gregraiz.com/posts/i-made-an-eink-newspaper/ and I wanted something similar but with a Todoist integration.
Also, it had been a while since I wrote some code, and I was looking for some side projects to tinker with. And a DIY eInk calendar + TODO organiser seemed like a great idea, so I got this 10" Inkplate back in July 2023. And the saga began.
The idea
The idea was simple: Calendar and TODO list a single glance away.
My working style is super chaotic, I tend to have a ton of things on plate and sometimes end up focusing on the wrong thing. A sorted TODO list with clear priorities would hopefully keep me focused and working on the right things.
Implementation
The inkplate comes with an ESP32 and you could do a lot of things with it. There are projects that actually generate the whole image in the ESP board itself. However, this is one of my first microcontroller projects, and I am not too fluent in C++ and I wanted to be done with this as quickly as possible.
So the next thing I looked into was to generate the image on a webserver and the inkplate just downloads the image at regular intervals and just displays it. This was simpler, and I had a fair idea of what this involves.
Attempt #1: Render webpages directly
The most obvious solution is to use either phantomJS or chrome-headless, navigate to Todoist and Google Calendar and to render the HTML as images. Or use a chrome webdriver to control the browser running on my computer.
This had a couple of problems:
- Login / cookie problem: For this to work, I need to log-in to my work email which is not very trivial and needs a couple of layers of 2FA. And in general the security posture and reliability here looked low.
- RISC-V problem: The current always-on computer I had was a VisionFive 2 RISC-V board which didn't have a lot of performance, and running a full blown Chrome on it seemed like a bad idea.
Attempt #2: Render custom images in Go
While the login problem was an issue, I could still use the Todoist and Google APIs to get the JSON needed and then render my own HTML view the way I wanted it. I started working on it and managed to get both the Todoist (easy) and Calendar events (tricky) JSONs.
As I started to write some HTML, I thought why not generate the whole image in Go. I came across this excellent blog post by Mat Ryer on generating images with the gg library. Huh, it presented a straightforward way to render all the rectangles and text I wanted!
So off I went and after writing a bunch of REALLY UGLY code, I got it working! I literally learnt how to use gg
as I built this, so I can already a bunch of clean ups I could do.
Now the inkplate just calls the Go server every 5mins and downloads the rendered image. The rendering and transmission takes about 4s on average and I feel like most of it is still getting the data from Todoist and Google Calendar APIs.
Find the Code here
You can find the code here: https://github.com/gouthamve/gophercal, with detailed instructions on how to create the Todoist and Google credentials and running the server.
Side projects need to be sequential
I hadn't done any side-projects in a while and GopherCal made me realise how long they take the patience you need to "finish" one. I don't have a lot of free time and having many side-projects at once means I won't make meaningful progress on any of them.
After nearly a year of tinkering around with it, and finally printing a stand for it, I think I can call GopherCal "done". Now on to the next side-project which is low-effort monitoring for Prusa 3D Printers 😄
It is super helpful
Having the calendar one glance away has been a godsend. It is easy to understand how much I get done today, and also if I can take a walk or step out for lunch.
The other interesting thing is that I can tell very easily if I'm overloaded. If my todo list is super long, I start cutting down on things and ping my manager that I need some help.
Bonus: Yak shaving for a stand
Initially I had GopherCal sitting next to my computer but it wasn't too stable and sometimes go into the way of my monitor. So I mounted it to the top of the monitor with some 3M velcro patches.
But I wasn't really happy about this either and wanted to print it a proper a stand so it sit next to my monitor at a decent height. And this I used to justify buying a 3d printer. But I was missing a place to put the printer, so I teamed up with Ben to build a workbench! After all that, I finally printed a stand for the GopherCal that I am thrilled with!