The Google Calendar Event Display code uses the Google Calendar API's Event list endpoint to return events from a specific calendar.
The results from a GET request to this endpoint will look something like the following:
{ "kind": "calendar#events", "etag": "\"p32c9b6vtqmbes0g\"", "summary": "Meetings", "updated": "2021-01-12T15:06:56.911Z", "timeZone": "America/New_York", "accessRole": "owner", "defaultReminders": [], "nextPageToken": "CigKGjMyajF0bm0xcmwzbDBnbWhmNTNyaW9xb3B2GAEggIDA3tm_zrYXGg0IABIAGJiVm_3Vlu4CIgcIBBC35scP", "items": [ { "kind": "calendar#event", "etag": "\"3219736474490000\"", "id": "32j1tnm1rl3l0gmhf53rioqopv", "status": "confirmed", "htmlLink": "https://www.google.com/calendar/event?eid=MzJqMXRubTFybDNsMGdtaGY1M3Jpb3FvcHYgYWpmb242cGhsN24xZG1wanNkbGV2dHFhMDRAZw", "created": "2021-01-05T17:35:02.000Z", "updated": "2021-01-05T17:37:17.245Z", "summary": "Adafruit Show and Tell", "creator": { "email": "" }, "organizer": { "email": "@group.calendar.google.com", "displayName": "Meetings", "self": true }, "start": { "dateTime": "2021-01-06T19:30:00-05:00" }, "end": { "dateTime": "2021-01-06T20:00:00-05:00" }, "iCalUID": "@google.com", "sequence": 0, "reminders": { "useDefault": true } } ] }
All events are kept within an items
array which contains detailed information about each event. The code parses this array for the event's summary
and the event's start
dateTime
.
Refreshing Google API Access Token
The Google Calendar API access token expires after a specific time interval. If the access token is expired, the refresh token in secrets.py is used to POST a request to Google's servers for a new access token.
if (int(time.monotonic()) - access_token_obtained>= google_auth.access_token_expiration): print("Access token expired, refreshing...") if not google_auth.refresh_access_token(): raise RuntimeError( "Unable to refresh access token - has the token been revoked?" ) access_token_obtained = int(time.monotonic())
Fetching Calendar Events
Prior to calling Google Calendar, a timestamp must be obtained to display the latest events in ascending order. The code calls the Adafruit IO time service to fetch and set the timestamp we'll use for requesting data from Google Calendar.
# fetch calendar events! print("fetching local time...") now = get_current_time()
We'll display the current date at the top of the MagTag. Passing a pretty_date
argument formats the struct_time timestamp into a human-readable timestamp such as "January 6th, 2021"
# setup header label magtag.set_text( format_datetime(now, pretty_date=True), label_header, auto_refresh=False )
We use call get_calendar_events
with the timestamp to request a list of calendar events in ascending order.
print("fetching calendar events...") events = get_calendar_events(CALENDAR_ID, MAX_EVENTS, now)
Within get_calendar_events
, we perform a HTTP GET to Google Calendar API's event list endpoint
time_max = get_current_time(time_max=True) print("Fetching calendar events from {0} to {1}".format(time_min, time_max)) headers = { "Authorization": "Bearer " + google_auth.access_token, "Accept": "application/json", "Content-Length": "0", } url = ( "https://www.googleapis.com/calendar/v3/calendars/{0}" "/events?maxResults={1}&timeMin={2}&timeMax={3}&orderBy=startTime" "&singleEvents=true".format(calendar_id, max_events, time_min, time_max) ) resp = magtag.network.requests.get(url, headers=headers)
Then, the response is parsed. Each entry in the response's items
array is parsed and appended to an items
list. This list is returned as events
.
resp_json = resp.json() if "error" in resp_json: raise RuntimeError("Error:", resp_json) resp.close() # parse the 'items' array so we can iterate over it easier items = [] resp_items = resp_json["items"] if not resp_items: print("No events scheduled for today!") for event in range(0, len(resp_items)): items.append(resp_items[event]) return items
Back in the while True
loop, the code passes the event
list to display_calendar_events
.
print("displaying events") display_calendar_events(events)
display_calendar_events
iterates through the resp_events
list. In each iteration, it parses an event's start time and description from the list and generates labels to display the data on the device's screen.
def display_calendar_events(resp_events): # Display all calendar events for event_idx in range(len(resp_events)): event = resp_events[event_idx] # wrap event name around second line if necessary event_name = magtag.wrap_nicely(event["summary"], 25) event_name = "\n".join(event_name[0:2]) # only wrap 2 lines, truncate third.. event_start = event["start"]["dateTime"] print("-" * 40) print("Event Description: ", event_name) print("Event Time:", format_datetime(event_start)) print("-" * 40) # Generate labels holding event info magtag.add_text( text_font=font_event, text_position=(7, 40 + (event_idx * 35)), text_color=0x000000, text=format_datetime(event_start), ) magtag.add_text( text_font=font_event, text_position=(88, 40 + (event_idx * 35)), text_color=0x000000, text=event_name, line_spacing=0.65, )
Finally, the display elements are shown on the screen and the MagTag enters low power mode for REFRESH_TIME
minutes.
magtag.graphics.display.refresh() print("Sleeping for %d minutes" % REFRESH_TIME) magtag.exit_and_deep_sleep(REFRESH_TIME * 60)
Text editor powered by tinymce.