IoT Calendar: Creating a Calendar Service for IoT Devices

This is the first in a series of articles about using microcontroller devices with e-paper displays for displaying dynamic calendars.

Standards can be a wonderful thing. At their best, they let computer hardware and software inter-operate between multiple vendors. Take calendar standards, for example. With the iCalendar standard, you can send a meeting invite from your GMail account to an Office365 user, who may be at the gym at the moment but sees the invite from his smart phone. From his smart phone, he accepts the invitation and sends back the confirmation to the GMail user. You can also subscribe to calendars, which will update automatically when a change occurs. For example, if you subscribe to a baseball team’s calendar, and your team makes it to the playoffs, new playoff games (and hopefully World Series games) will magically appear in your calendar.

So, when I set out to create an IoT application that displays events from a subscribed calendar for the current day, I discovered a problem. Parsing an iCalendar feed to find the current day’s events is very resource intensive for an IoT device.  The device would need to do the following:

  • Read the iCalendar feed, which can be several or hundreds of KBytes in size
  • Parse the iCalendar feed, looking for just those events that are occurring today
  • For repeating events, expand the repeating event rule to all possible dates to see if any of them are occurring today
  • If there are exceptions to a repeating event (meeting cancelled or rescheduled to another day, for example), do not include those meetings
  • Include the timezone in the date check to prevent events from displaying on the wrong day

That is quite a bit of work involved, even for larger devices. I did not find any options out there for an IoT device to read calendar events, so I decided to create my own service. I call it the IoT Calendar service. The service is available at http://iotcalendar.org . An account is required to receive an API key but a free tier is available for checking calendars once per day. The service is straightforward: at it’s simplest form, An IoT device submits a URL containing the iCalendar feed URL to the service, the service parses the data and returns with a list of events for the current day in JSON format. The service takes care of all of the above, including expanding repeating events and checking the timezones. Several libraries exist for parsing JSON data on Arduino and similar devices (my target platform), so this looked like the logical choice. This service could also be used by other languages that support JSON, including Python. The service was written in PHP utilizing the ZapCal Library, a library I wrote for PHP developers that is available at icalendar.org .

Here is an example of a URL sent from the microcontroller device to the IoT calendar service:

https://iotcalendar.org/iotevents?tzid=America/New_York&apikey={apikey}&url=http://americanhistorycalendar.com/peoplecalendar?format=ical

At a minimum, the timezone field, API key and url field are sent to the service. The timezone field is a valid timezone as defined by the PHP language, a list of which can be found at this page.

The service will send back a list of events in JSON format scheduled for that day. Here is an example:

{
    "name": "People in History",
    "events": [
        {
            "summary": "John Hancock",
            "ldstart": "20190123",
            "duration": 1440,
            "rday": 0,
            "allday": 1
        },
        {
            "summary": "Joseph Hewes",
            "ldstart": "20190123",
            "duration": 1440,
            "rday": 0,
            "allday": 1
        }
    ]
}

The rday field is the day of the event relative to today. Other days to check can be added to the URL for other days, like tomorrow, for example, which would have an rday of 1. Add the field “&rdays=0,1” to display events for today and tomorrow. For days where there are no events then no events will be returned. For testing purposes, adding “&pretty” to the URL will format the JSON data in a nice readable output like the example above.

Another service was also created to help IoT devices calculate the local time by returning the time offset of the given timezone. This is helpful for devices retrieving the current time from an NTP server and need to convert the UTC time given from an NTP server to local time.

The syntax for using  the iottzoffset service is:

https://iotcalendar.org/iottzoffset?apikey={apikey}&tzid={tzid}

where {tzid} is a timezone as defined as a valid timezone in PHP. For example,

https://iotcalendar.org/iottzoffset?apikey={apikey}&tzid=America/New_York

returns the current timezone offset for the New York timezone, as in the following:

{
    "offset": -300
}

“offset” is in minutes from the UTC timezone.  This value will vary during the year depending when Daylight Savings TIme (DST) is in effect.

More details of the service can be found at iCalendar.org . You can sign up for a free account at IoTCalendar.org . A free account allows checking for events an average of once per day.

1 comment

Leave a Reply

Your email address will not be published. Required fields are marked *