Raspberry Pi as a Google Calender 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 Calender 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.

67 comments

  1. Cia91 says:

    Hi, i’m really a noob, but i want to try this :D

    ..but where i have to paste you code? i have to create a .py file? where i have to put this file?

    • devon says:

      Hi! You do have to create a file, and the code is the green block of the blog post. I suggest downloading and installing a program called geany for the raspberry pi

  2. jamesmstone says:

    Hey
    This is awesome
    What OS do you run on your pi

  3. Mateus says:

    Thanks for the tip! Very helpfull

  4. Cliff Miller says:

    Re: Error at line 14 – no ‘xe’
    I had the same problem.

    You have to install a python module ‘pyfeed’ which gives you the xe and some other items used in the program. I found it at

    http://home.blarg.net/~steveha/pyfeed.html

  5. Cia91 says:

    I think there is a little bug.

    If i set the wake event on calendar with the option ‘repeat every day’ it doesn’t work…

    It’s a common problem?

    • devon says:

      hmm! I haven’t used this feature in google cal as I don’t really have a regimented wake up schedule. Please comment again if you come up with a solution!

    • lampenschakelen says:

      Hi Devon or Cia91
      Did you find out how to fix problem with repeat every day.

      It’s almost perfect working with my lights turn of on.
      thanks,

      • devon says:

        No I haven’t really had the need to use that feature as I wake up at a different time almost daily. If you figure it out please feel free to post here!

        • Eddie Bijnen says:

          See my reply that i posted a few months ago. It tells you how you can add it in. It also tells you about another bug.

          • lampenschakelen says:

            Eddie Bijnen Idon’t now how to change it to youre way.

            I add After line 28 fallowing:
            query.singleevents = ‘true’
            query.orderBy = ‘startTime’
            query.sortorder = ‘ascending’

            but i get back a error

      • Cia91 says:

        Try the solution posted from Bruce

  6. Jesse Dyer says:

    I just got a Pi, and happened across a Zen Alarm clock (130 bucks new, 4 bucks for me). I plan on wiring the striker into a GPIO channel, and use a 2 line LED display instead of the clock face. The only piece I needed, you’ve written.

    Thank you!

  7. Stephen Shaw says:

    I cannot thank you enough for making this little gem.
    Not only have I got something that integrates perfectly with my workflow to wake me up in an easy and effective manner, I have learnt more about my pi and python from following this code.
    My deepest thanks!
    Warmest regards,
    Stephen

  8. Josh says:

    Hey there, I wanted to try this out but i kept running into problems ( iv never had to use python before).

    Iv installed python, pyfeed and even the xe just incase but I am getting an error for line 16 import error no module named apscheduler.scheduler.

    please help?

    • devon says:

      Thanks for giving this a go!
      You will need to install AP scheduler https://pypi.python.org/pypi/APScheduler/

      • Josh says:

        Now its saying 2-13 import not found, cant read /var/mail/feed.date.rfc3339, /var/mail/datetime, /var/mail/apscheduler.scheduler. 17-19 import not found, 20 syntax error ( unexpected.

        really not liking python so far haha.

        Thank you very much for your help so far though!

        • devon says:

          hi! can you post your code to pastebin?

          • Josh says:

            pi@raspberrypi ~ $ cd /share
            pi@raspberrypi /share $ sudo ./pi-alarm.py
            ./pi-alarm.py: 2: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 3: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 4: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 5: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 6: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 7: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 8: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 9: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 10: ./pi-alarm.py: import: not found
            ./pi-alarm.py: 11: ./pi-alarm.py: import: not found
            : not foundpy: 12: ./pi-alarm.py:
            ./pi-alarm.py: 13: ./pi-alarm.py: import: not found
            from: can’t read /var/mail/feed.date.rfc3339
            from: can’t read /var/mail/datetime
            from: can’t read /var/mail/apscheduler.scheduler
            ./pi-alarm.py: 17: ./pi-alarm.py: import: not found
            : not foundpy: 18: ./pi-alarm.py:
            ./pi-alarm.py: 20: ./pi-alarm.py: Syntax error: “(” unexpected
            pi@raspberrypi /share $

            Is there a setup I failed to run?

          • Josh says:

            Is there something i failed to install?

  9. Pyr says:

    How do I run the program?

  10. Darkiwn says:

    Hello, your idea is amazing and just tha I need. But I have an error: ImportError: cannot import name tf_from_timestamp.

    Really, I don’t know what happen.

    Maybe the problem could be my OS, Raspbmc.

    Thank you very much!

  11. Paulus says:

    Works very well!! Thanks for publishing!

    Is there anyone who knows how to alter the code for the SingeEvent=TRUE parameter. I tried interting it in several ways, but my understanding of this way of programming is not enough to get it working. Normally Google is my best friend, but after searching for several hours, i found no solution. TYVM!

    • devon says:

      Hmm, this isn’t really relevant to my application, but if you figure out what’s going on, please report back!

  12. BruceR says:

    This code uses v2 of the Google Calendar API, I have done some work with v3 and used SingleEvents=True . v3 is a bit different, especially with authentication, but not that hard to use once you work out which code to steal from google’s dev site. Details on my blog.

  13. Works perfect! Thank you for some awesome code. I mirrored on my site giving credit and some detailed steps for the extra parts I had to install.

  14. Frank Seguin says:

    Hi . Thank you for your post. I am getting the following error:

    Output:

    File “Alarm.py”, line 41
    os.system(command)
    ^
    IndentationError: unexpected indent

    Code:

    command =”mpg321″ + ” ” + “/home/pi/Alarm/” + “‘”+songfile+”‘”+ ” -g 100″

    Thank you

    • devon says:

      Hi! It would appear that you copy-pasted incorrectly. Try doing it again.

      • Paulus says:

        is it possible that mpg321 is not installed on your system? I remember the error and I think installing mpg321 resolved it.

        • Paulus says:

          check also that the /home/pi/Alarm/-folder is present and that upper/lowercase matches the command. It also has to have mp3s in it which can be played.

  15. Cameron says:

    Hi,
    So I have put the Google Data Library on my Pi and have unzipped it. I have also put on the xe module. When I go into python I copy the code from the website and fill in my email and password. I have also put a mp3 into the designated folder, But as soon as I try to run the program I get syntax errors over and over. Is there something that I am doing wrong or not installing

    • devon says:

      please comment the errors you are having!

      • Cameron says:

        There’s an error in your program:Invalid syntax. Every error I would get I would delete and run the program again. I got this at ln:12 ln:18 ln:27 and more.

        Thanks,
        Cameron

  16. Eddie says:

    Working on getting the script to accept recurring events but i just got to say.

    GOOGLE YOU’RE *$@#$^ Reference material sucks. Twice it has just been flat out WRONG

  17. Shaun says:

    Hey, thanks for an awesome post!
    I’ve got it working, and everything seems to work, but I get the error:

    No handlers could be found for logger “apscheduler.scheduler”

    Any ideas???

    • devon says:

      Hey, thanks for the comment try adding “import logging logging.basicConfig()” to your code and tell me how it goes!

  18. I’ve managed to make it response to recurring events. on line 28 add ‘singleevents=true’ in the query body: query = gdata.calendar.service.CalendarEventQuery(‘default’, ‘private’, ‘full’, text_query, ‘singleevents=true’) and it works well.

  19. Blake says:

    hello,

    I am trying to download the XE library and have a few problems. It takes me to https://myaccount.avvanta.com/ where it asks me for a registration number and password and I don’t see any way of getting that. How did you get the XE libraries?

    Thanks,

    Blake

  20. Kaliniso says:

    Hello guys,

    Is it possible to have the code file wake.py because I have a error but I don’t find it. thanks in advance

  21. W. says:

    Just want to say, nice work!
    Looking forward to some more similar stuff!

  22. Eric says:

    Very nice, thanks for posting this! Was testing this out and noticed a few things have changed since you’ve written it (like the way apscheduler works– doesn’t seem to have .scheduler available now) so I updated it and cleaned it up a bit. Using mpg123 instead of mpg321 and no real need to use xe or the feed/atom stuff. Running this locally on a Mac, you can install gdata and apscheduler with pip; I only had to install mpg123 locally from here: http://www.mpg123.de/download.shtml

    Here’s the python code:
    http://pastebin.com/CSyp6fMi

  23. Eric says:

    To update my previous comment, I’ve re-written it to use Google’s v3 API / OAuth and to play mp3s based on event names:

    https://github.com/ehamiter/get-on-the-bus

    Thanks for the inspiration!

Leave a Reply