E-Paper Calendar Ep.3 — Fetching Calendar Data and Displaying It
This article is migrated from Medium and translated by Gemini pro 2.5.
Actually, I finished testing this part a long time ago, but I got busy and forgot to document it. I’m adding these notes here for my own future reference.
Fetching Google Calendar Data
First up was fetching data from Google Calendar. I originally expected this to be a huge hassle, but by following the steps in Google’s official API documentation, I got it working right away.
Google provides support for many languages. I chose Python because the Waveshare e-paper demo for Raspberry Pi also uses Python, and as I’ll explain, this turned out to be very convenient.
Google’s documentation already clearly explains the credential and environment setup. I’ll just pull out and highlight the key code snippet for fetching calendar events.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Call the Calendar API
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
print('Getting the upcoming 10 events')
events_result = service.events().list(calendarId='primary', timeMin=now,
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])
if not events:
print('No upcoming events found.')
return
# Prints the start and name of the next 10 events
for event in events:
start = event['start'].get('dateTime', event['start'].get('date'))
print(start, event['summary'])
Displaying Data on the E-Paper
Next up was displaying the data on the e-paper screen. The Waveshare demo code is quite complete. It uses the Python Pillow library (PIL) to convert text into an image, making it incredibly easy to draw any picture and text you want onto the display.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#initialize e-paper process
epd = epd7in3g.EPD()
epd.init()
epd.Clear()
#setting some font size for drawing words
font24 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 24)
font18 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 18)
font40 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 40)
#make a new image
Himage = Image.new('RGB', (epd.width, epd.height), epd.WHITE) # 255: clear the frame
draw = ImageDraw.Draw(Himage)
#draw some words on the image
draw.text((5, 0), 'hello world', font = font18, fill = epd.RED)
draw.text((5, 20), '7.3inch e-Paper', font = font24, fill = epd.YELLOW)
draw.text((5, 45), u'微雪电子', font = font40, fill = epd.BLACK)
draw.text((5, 85), u'微雪电子', font = font40, fill = epd.YELLOW)
draw.text((5, 125), u'微雪电子', font = font40, fill = epd.RED)
#send the image to e-paper display
epd.display(epd.getbuffer(Himage))
The code above is the most important part of the demo. The next step is simply to combine the two: change the part that’s being drawn to use the data fetched from Google Calendar.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#initialize e-paper process
epd = epd7in3g.EPD()
epd.init()
epd.Clear()
#setting some font size for drawing words
font24 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 24)
font18 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 18)
font40 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 40)
# Call the Calendar API
service = build('calendar', 'v3', credentials=creds)
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
events_result = service.events().list(calendarId='primary', timeMin=now,
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])
if not events:
print('No upcoming events found.')
return
# Prints the start and name of the next 10 events
for event in events:
start = event['start'].get('dateTime', event['start'].get('date'))
print(start, event['summary'])
# Drawing on the image
logging.info("1.Drawing on the image...")
Himage = Image.new('RGB', (epd.width, epd.height), epd.WHITE) # 255: clear the frame
draw = ImageDraw.Draw(Himage)
line = 0
for event in events:
data = event['start'].get('dateTime', event['start'].get('date'))+' '+event['summary']
draw.text((5, line), data, font = font24, fill = epd.BLACK)
line+=18 #next line
#push the image to e-paper display
epd.display(epd.getbuffer(Himage))
And just like that, the main functionality of the project is complete. It was much smoother than I expected.
Lingering Issues
I’ve noted a few small problems so far:
Events synced from iCloud to Google Calendar are not being fetched by the Google API.
Due to the screen resolution, Manarin fonts become blurry if the font size is too small.
The next step is the overall system design, including the update frequency and the screen layout… (This will probably be the most difficult and time-consuming part).

