Raspberry Pi as a Google Calendar Alarm Clock

This post isn’t really thumbnail conducive but I tried!

I have been sleeping in too much. I would like an alarm clock that is easy to set and will play a random song to wake me up.

For a while I was using this program, but as you may be able to tell it requires an awful lot of user input, which isn’t ideal for a sleepy person as they may mess up (as I have, thus this post) but the “fire()” command works really well. To use this program you will need AP scheduler and MPG321 (sudo apt-get install mpg321)

But it wasn’t working. I wanted a way to re-purpose a service I use everyday (that way I wouldn’t have to modify my workflow) as an Alarm Clock. I landed on Google Calendar because I can add events from pretty much every device I interact with on a daily basis, and upon searching found out that developing using the python API wasn’t that hard at all.

To kick things off, you’ll need to download and install the Google Data Library.

I’ll be using this version. Unzip the .tar.gz and from the top top level directory it creates, install the setup.py file. Then run the tests/run_data_tests.py to see if it all works. Mine does fine but it if yours doesn’t, go through this guide written by google to get yourself up and running.

The brunt of this program comes down to a single boolean statement, but first we have to set that up. The API produces an rfc3339 time, and that’s a lot of irrelevant information for this application.

To convert the time I’m using something I found on stackoverflow.

Here’s a video of the system in action, and a basic overview of the setup:

Here’s my program:

#These are the imports google said to include
import gdata.calendar.service
import gdata.service
import atom.service
import gdata.calendar
import gdata.calendar
import atom
import getopt
import sys
import string
import time

import xe #for the time comparator
from feed.date.rfc3339 import tf_from_timestamp #also for the comparator
from datetime import datetime #for the time on the rpi end
from apscheduler.scheduler import Scheduler #this will let us check the calender on a regular interval
import os, random #to play the mp3 later

#this is more stuff google told me to do, but essentially it handles the login credentials
calendar_service = gdata.calendar.service.CalendarService()
calendar_service.email = 'youremail@yourdomain' #your email
calendar_service.password = 'yourgcalpassword' #your password
calendar_service.source = 'Google-Calendar_Python_Sample-1.0'
calendar_service.ProgrammaticLogin()

def FullTextQuery(calendar_service, text_query='wake'):
    print 'Full text query for events on Primary Calendar: \'%s\'' % ( text_query,)
    query = gdata.calendar.service.CalendarEventQuery('default', 'private', 'full', text_query)
    feed = calendar_service.CalendarQuery(query)
    for i, an_event in enumerate(feed.entry):
        for a_when in an_event.when:
            print "---"
            print an_event.title.text ,"Number:",i,"Event Time:",time.strftime('%d-%m-%Y %H:%M',time.localtime(tf_from_timestamp(a_when.start_time))),"Current Time:",time.strftime('%d-%m-%Y %H:%M')

            if time.strftime('%d-%m-%Y %H:%M',time.localtime(tf_from_timestamp(a_when.start_time))) == time.strftime('%d-%m-%Y %H:%M'):
                print "Comparison: Pass"
                print "---"

                songfile = random.choice(os.listdir("/home/pi/alarmclock/test_MP3s/")) #chooses the .mp3 file
                print "File Selected:", songfile
                command ="mpg321" + " " + "/home/pi/alarmclock/test_MP3s/" + "'"+songfile+"'"+ " -g 100" #plays the MP3 in it's entierty. As long as the song is longer than a minute then will only trigger once in the minute that start of the "wake" event

                print command
                os.system(command) #runs the bash command
            else:
                print "Comparison:Fail" #the "wake" event's start time != the system's current time

def callable_func():
    os.system("clear") #this is more for my benefit and is in no way necesarry
    print "------------start-----------"
    FullTextQuery(calendar_service)
    print "-------------end------------"

scheduler = Scheduler(standalone=True)
scheduler.add_interval_job(callable_func,seconds=5)
scheduler.start() #runs the program indefinatly on an interval of 5 seconds

And there you have it! thanks for reading and leave me a comment if you have any questions/suggestions.