How to make a Physical Gmail Notifier

Or: how to turn this..

Google Notifier

into this..

Physical Notifier

I was given a lovely glowing cube by the generous people at Linden Labs as a freebie at a job fair yesterday, and I decided that it was far too attractive to simply sit there on a shelf, pulsating forlornly until its batteries went flat. How about making it useful, while maintaining its visual appeal?

It All Starts With A Cube

The following guide is deliberately fairly high-level, because the exact details will vary depending on your operating system and particular hardware setup. I did this with my Mac, but hopefully there'll be enough information here for you make it work on your system, perhaps with a little Googling.

If you don't happen to have a glowing cube lying around, you can modify this to work with almost any output device you could think of, from a simple LED, or a buzzer, to something far more clever like moving a servo (Gmail Notifier Robot, anyone?)

The basic system has three components:

  • the software that runs on your computer,
  • the electronics hardware that sits between the computer and the output device,
  • and the software that runs on that hardware.

Every so often, the computer checks for new emails in your Gmail account, and then tells the electronics board whether any have arrived. If they have, the board turns on the output device (the cube). Simple.

Hardware

The hardware itself is the popular Arduino board, the tinkerer's dream device. I'm actually using a Boarduino, but any variant should work (subject to a small but important detail, see below). This might be particularly interesting with a Bluetooth Arduino..

The Arduino talks with your computer over a serial connection, which runs over the normal USB cable you use to communicate with your Arduino.

Here's the first important note: the latest Arduino Diecimila has an "auto-reset" feature which allows you to upload programs to the board without manually pressing the Reset button every time. This works by resetting the board whenever it receives any data over the serial port. Because we are going to be sending serial data to the board regularly, this is not what we want. Fortunately, this feature can be disabled on my Boarduino by simply removing a capacitor (C6), but it may be trickier on the official Arduino. Any suggestions for how to get round this in software would be gladly received (leave a comment!). One way is to simply keep the serial port open all the time (perhaps using the Serial Proxy, link at the bottom of this page). This solution isn't much use for me, as I'll be unplugging the USB connection regularly and don't want to have to disable anything first. However this may be fine if your computer is a desktop and you can leave the Arduino plugged in all the time. If you go this route, you'll have to use a different script running on the computer, and make sure it runs continually rather than repeatedly. I'll leave this to you!

I connected up the cube using a PC fan extension cable from Maplin - simply because the connector on the end fits perfectly on the pins of my Boarduino. Use your own method to connect your output device.

Fan Cable

I chopped off the "plug" end of the cable and soldered it onto the battery connectors on the cube, drilling a hole in the battery cover to allow the wires to pass through:

Battery compartment Cable exit

Connected up to the Boarduino for testing:

Connected up

Software

This project requires two bits of software: one running on the Arduino to receive serial data and toggle the output accordingly, and one running on the computer to check for new emails and send data out over the serial port. To re-iterate, these code listings should only be used as a guide. They work for me, but I don't guarantee they'll work for you, and I accept no responsibility for breaking things. If you don't understand what this code is doing, you probably shouldn't be running it.

The Arduino software is fairly trivial. It just loops round, watching for bytes coming in over the serial port, and sets a variable called "mail" to be true if the data is an 'M', and false if it's an 'N' (of course these characters are arbitrary). It then updates the value of the output pin to be equal to this mail variable. You can hack this and expand it or modify it however you like - perhaps you could make an LED blink when you have new email instead of just turn on?

int outPin = 12; // Output connected to digital pin 12
int mail = LOW; // Is there new mail?
int val; // Value read from the serial port

void setup()
{
    pinMode(outPin, OUTPUT); // sets the digital pin as output
    Serial.begin(9600);
    Serial.flush();
}

void loop()
{
    // Read from serial port
    if (Serial.available())
    {
        val = Serial.read();
        Serial.println(val);
        if (val == 'M') mail = HIGH;
        else if (val == 'N') mail = LOW;
    }

    // Set the status of the output pin
    digitalWrite(outPin, mail);
}

Upload this to your Arduino, and then connect your output device to pin 12.

The software for the computer takes the form of a Python script, and is slightly trickier. First, it tries to open the serial port for communication with your Arduino. If it can't do this (say, if your USB cable is unplugged), it quits immediately. If the serial port opens successfully, the script has to talk to Google's servers to determine if you have any new email waiting for you. It does this by authenticating with your Gmail username and password, and then requesting the Atom feed for your inbox (this part of the script is based on code from here). It then parses out the line containing the number of unread messages (the XML tag is called ). If the unread message count is zero, it sends an 'N' over the serial connection. If it's greater than zero, it sends an 'M'.

This requires the pySerial library and the Universal Feed Parser module from .

import serial, sys, feedparser

#Settings - Change these to match your account details
USERNAME="username@gmail.com"
PASSWORD="yourpassword"
PROTO="https://"
SERVER="mail.google.com"
PATH="/gmail/feed/atom"

SERIALPORT = "/dev/tty.usbserial-FTDK0P3M" # Change this to your serial port!

# Set up serial port
try:
    ser = serial.Serial(SERIALPORT, 9600)
except serial.SerialException:
    sys.exit()

newmails = int(feedparser.parse(
    PROTO + USERNAME + ":" + PASSWORD + "@" + SERVER + PATH
)["feed"]["fullcount"])

# Output data to serial port
if newmails > 0: ser.write('M')
else: ser.write('N')

# Close serial port
ser.close()

Now, this script needs to be run regularly (say, once a minute) so that when you get a new email, your notifier will light up promptly. On Mac OS X, the launchd service handles, among other things, launching programs at set intervals (on other Unix systems liked Linux, you may need to use cron. On Windows, I have no idea - but I'd imagine it's possible somehow).

Put this code in a .plist file (mine's called org.j4mie.check-gmail.plist - I have no idea if you have to follow the weird naming format, but it works for me) and save it in ~/Library/LaunchAgents (create this folder if it doesn't exist). Don't forget to change the second ProgramArguments string to the location of your Python script.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.j4mie.check-gmail</string>
<key>OnDemand</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python</string>
<string>/Users/yourusername/path/to/check-gmail.py</string>
</array>
<key>StartInterval</key>
<integer>60</integer>
</dict>
</plist>

UPDATE: As Jonas Stenberg pointed out in the comments, you may need to alter the /usr/bin/python string in this plist file to point to the location of the Python interpreter on your machine, for example /usr/local/bin/python2.5.

To load this plist file into launchd, type launchctl load ~/Library/LaunchAgents/org.j4mie.check-gmail.plist at the terminal (or reboot your computer).

And, with any luck, that should be it! Once a minute, your Python script will execute, checking for any new emails in your inbox. If any have arrived, your cube (or other output device) should spring into life!

Physical Notifier

Comments

blog comments powered by Disqus