I really got interested in epaper recently and wanted to do a project with an epaper display. Using an extra Raspberry Pi Zero W I had lying around, I was able write a little Python to display upcoming meetings from my Google Calendar.
The Screen
If you search for epaper displays for a Raspberry Pi, one of the top results will be for Waveshare. They offer a bunch of different sizes with black & white and color options. I went with the 2.13inch, 2 color display since it matched the size of the Raspberry Pi Zero W perfectly. The physical installation was one step, slide the GPIO header pins on the Pi into the display.
For the Raspberry Pi, I used the 32-bit Raspberry Pi OS Bullseye image. I followed the setup instructions on the Waveshare wiki and successfully ran the demo. The screen sprang to life, displayed some text and images and shut off.
Accessing the calendar
The next step was accessing my calendar. Most epaper calendar projects required either an ical feed or the Google Calendar API. My work calendar doesn’t allow either, so I had to look elsewhere.
I found gcalendar, a command line tool that can read your Google Calendar. To authenticate it launches a browser and starts the standard Google authentication workflow for a third party app. Once authorized, I tested the app in the command line and it returned a list of events.
pi@PiZero:~ $ gcalendar --calendar WorkCal --no-of-days 1
2022-03-11:09:30 - 2022-03-11:10:00 Just a test meeting
2022-03-11:10:30 - 2022-03-11:11:00 Another test meeting later in the day
2022-03-11:14:00 - 2022-03-11:14:30 Test afternoon meeting this has a pretty long title for an event
Not super exciting, but it worked.
Avoiding Python
After some searching, I figured out a couple of options to display text on the display.
- Use epaper.js, a command line application that can render a URL onto an epaper display
- Use Waveshare’s Python demo as a starting point and add on some custom code
I decided I didn’t want to learn Python at the moment and went with the epaper.js route. I followed the installation instructions in the epaper.js repo. Then I created a super simple html website using txti.es.
I ran the following command ejs refresh rpi-2in13-v2 "http://txti.es/qr8k1"
et voilĂ :
From these instructions I learned how to use a bash script to generate HTML from the gcalendar output.
|
|
I then served up the generated index.html locally with http-server. Then I ran the epaper.js command to display the page on my epaper display.
ejs refresh rpi-2in13-v2 "http://localhost:8080"
While it technically worked, it wasn’t exactly useful, and it seemed like way too many steps for mediocre results.
Embracing Python
I really avoided the Python route because I know next to nothing about programming, but it became clear it was probably the easier route to get my epaper calendar display working. After a little trial and error with the Waveshare Python demo, I was able to strip out all of the steps other than the step that displayed some text. I repositioned the text and was able to output a decent first step.
|
|
A lot more googling led me to Python’s subprocess so I could run the gcalendar command and capture in the output. I then replaced my test text with the gcalendar output.
Clearly, the output formatting was suboptimal. I wanted to drop the date, use a 12 hour clock, and put the event title on a second line. A plain text output wasn’t going to work, so I’d need to switch to gcalendar’s json output.
[{"calendar_color": "#143648", "summary": "Test event 1", "start_date": "2022-03-13", "start_time": "09:00", "end_date": "2022-03-13", "end_time": "10:00", "location": ""}, {"calendar_color": "#143648", "summary": "Test event 2", "start_date": "2022-03-13", "start_time": "12:00", "end_date": "2022-03-13", "end_time": "13:00", "location": ""}, {"calendar_color": "#143648", "summary": "Test event 3 with a long title to test out splitting this on two lines", "start_date": "2022-03-13", "start_time": "15:00", "end_date": "2022-03-13", "end_time": "16:00", "location": ""}]
Many google searches later I figured out how to load the json as Python list of dictionaries and pick out individual values (e.g. only the start time, end time, and title of the first event).
|
|
09:00 - 10:00
Test event 1
Thanks to a Stack Overflow thread, I was also able to convert from 24 time to 12 hour time with AM/PM.
|
|
09:00 AM - 10:00 AM
Test event 1
Finally, I wrapped the text for long event titles (again thanks to Stack Overflow).
|
|
03:00 PM - 04:00 PM
Test event 3 with a long
title to test out
FULL LONG TITLE:
Test event 3 with a long title to test out splitting this on two lines
Putting this together with the Waveshare demo, I was successfully able to display the next two events on my Google Calendar on the epaper display.
|
|
Automate with crontab
The last thing I needed to do was run my python script at regular intervals. I added the python script to the pi user’s crontab and set it to run every 15 minutes. I also had to add a PATH definition to the crontab so gcalendar ran properly (thanks Stack Overflow yet again).
Improvements
It’s working, but my upcoming meeting display isn’t perfect. In the future I’d like to make some quality of life changes, but that will have to wait for a future post.
To Do
- Fix error when there is less than two future meetings
- Add a message when there are no meetings
- Figure out how to deal with overlapping meetings
- Flip the screen so the power port is on the top
- Hide the current meeting when it’s almost over