HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Raspberry Pi LED for new emails

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
newraspberryforemailsled

Problem

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 "---> ---> Checking feed"
messages = int(feedparser.parse("https://" + USERNAME + ":" + PASSWORD + "@mail.google.com/gmail/feed/atom")["feed"]["fullcount"])

if messages >= 1:
# turn on big LED
print "Turning on Big LED"

Solution

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.

Code Snippets

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)
thread_stop = Event()
b = threading.Thread.run(target=blink, args=(thread_stop, 1, 0))

Context

StackExchange Code Review Q#47147, answer score: 3

Revisions (0)

No revisions yet.