Raspberry Pi LED for new emails I'm learning how to use Python with the Raspberry Pi. I successfully followed the tutorial for how to have a Python script run on the Pi to check for new email and turn on an LED if any new messages are in an inbox. I wanted to give myself a challenge by adding a feature to blink a secondary LED to indicate the number of waiting messages. I played around for a while and got a script working, but would like to know if I implemented this correctly.

Am I using threading correctly? Is there an easier way to check a feed every n seconds, and if new messages are present, then continually run blink() until the next feed check?

#!/user/bin/env python

from threading import Thread, Event
from time import sleep
import feedparser
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
BLUE_LED = 17
BIG_LED = 23
GPIO.setup(BLUE_LED, GPIO.OUT)
GPIO.setup(BIG_LED, GPIO.OUT)

USERNAME = "user@gmail.com"
PASSWORD = "gzvioCNiAvFvKoqY"

class Repeat(Thread):
    def __init__(self,delay,function,*args,**kwargs):
        Thread.__init__(self)
        self.abort = Event()
        self.delay = delay
        self.args = args
        self.kwargs = kwargs
        self.function = function
    def stop(self):
        self.abort.set()
    def run(self):
        while not self.abort.isSet():
            self.function(*self.args,**self.kwargs)
            self.abort.wait(self.delay)

def blink(count):
    for x in range(0, count):
        print "blink", x + 1
        GPIO.output(BLUE_LED, True)
        sleep(.25)
        GPIO.output(BLUE_LED, False)
        sleep(.25)
    sleep(1) #pause between blinks

try:
    while True:

        print "Starting b"
        b = Repeat(1,blink,0)
        b.start()
        big_led = 0

        print "---&gt; ---&gt; Checking feed"
        messages = int(feedparser.parse("https://" + USERNAME + ":" + PASSWORD + "@mail.google.com/gmail/feed/atom")["feed"]["fullcount"])

        if messages &gt;= 1:
            # turn on big LED
            print "Turning on Big LED"
            GPIO.output(BIG_LED, True)
            big_led = 1
            print "There are", messages, "unread email messages"
            b = Repeat(1,blink,messages)
            b.start()
        else:
            print "There are no new messages"
            if big_led == 1:
                print "Turning off Big LED"
                GPIO.output(BIG_LED, False)

        sleep(60) # check the feed every minute for new mail
        print "Stopping b"
        b.stop()
        b.join()
except (KeyboardInterrupt, SystemExit):
    b.stop()
    b.join()
    GPIO.cleanup()
    print 'Program Stopped Manually!'
    raise
That looks about right. Your thread doesn't do very much, though, so you might want to consider something like so (untested):

def blink(abort, delay, count):
    while not abort.isSet():
        for x in range(0, count):
            print "blink", x + 1
            GPIO.output(BLUE_LED, True)
            sleep(.25)
            GPIO.output(BLUE_LED, False)
            sleep(.25)
        sleep(1) #pause between blinks
        abort.wait(delay)


Then later

thread_stop = Event()
b = threading.Thread.run(target=blink, args=(thread_stop, 1, 0))


which prevents need for the whole class. It's not a suggestion as much as a note that you did more than you needed to.

Note that your blink should really be using abort.wait and should cooperate with the other abort.wait to have sensible timings.