This commit is contained in:
Dave Jones
2015-09-24 16:34:21 +01:00
parent 7811ed67c9
commit 980e4e7144
2 changed files with 46 additions and 30 deletions

View File

@@ -62,6 +62,9 @@ class GPIOThread(Thread):
def stop(self): def stop(self):
self.stopping.set() self.stopping.set()
self.join() self.join()
def join(self):
super(GPIOThread, self).join()
_GPIO_THREADS.discard(self) _GPIO_THREADS.discard(self)

View File

@@ -1,5 +1,6 @@
from time import sleep from time import sleep
from threading import Lock from threading import Lock
from itertools import repeat
from RPi import GPIO from RPi import GPIO
@@ -42,19 +43,19 @@ class DigitalOutputDevice(OutputDevice):
def on(self): def on(self):
""" """
Turn the device on. Turns the device on.
""" """
self._stop_blink() self._stop_blink()
super(DigitalOutputDevice, self).on() super(DigitalOutputDevice, self).on()
def off(self): def off(self):
""" """
Turn the device off. Turns the device off.
""" """
self._stop_blink() self._stop_blink()
super(DigitalOutputDevice, self).off() super(DigitalOutputDevice, self).off()
def blink(self, on_time=1, off_time=1): def blink(self, on_time=1, off_time=1, n=None, background=True):
""" """
Make the device turn on and off repeatedly in the background. Make the device turn on and off repeatedly in the background.
@@ -63,12 +64,24 @@ class DigitalOutputDevice(OutputDevice):
off_time: 1 off_time: 1
Number of seconds off Number of seconds off
n: None
Number of times to blink; None means forever
background: True
If True, start a background thread to continue blinking and return
immediately. If False, only return when the blink is finished
(warning: the default value of n will result in this method never
returning).
""" """
self._stop_blink() self._stop_blink()
self._blink_thread = GPIOThread( self._blink_thread = GPIOThread(
target=self._blink_led, args=(on_time, off_time) target=self._blink_led, args=(on_time, off_time, n)
) )
self._blink_thread.start() self._blink_thread.start()
if not background:
self._blink_thread.join()
self._blink_thread = None
def toggle(self): def toggle(self):
""" """
@@ -81,33 +94,14 @@ class DigitalOutputDevice(OutputDevice):
else: else:
self.on() self.on()
def flash(self, on_time=1, off_time=1, n=1):
"""
Turn the device on and off a given number of times.
on_time: 1
Number of seconds on
off_time: 1
Number of seconds off
n: 1
Number of iterations
"""
for i in range(n):
self.on()
sleep(on_time)
self.off()
if i+1 < n: # don't sleep on final iteration
sleep(off_time)
def _stop_blink(self): def _stop_blink(self):
if self._blink_thread: if self._blink_thread:
self._blink_thread.stop() self._blink_thread.stop()
self._blink_thread = None self._blink_thread = None
def _blink_led(self, on_time, off_time): def _blink_led(self, on_time, off_time, n):
while True: iterable = repeat(0) if n is None else repeat(0, n)
for i in iterable:
super(DigitalOutputDevice, self).on() super(DigitalOutputDevice, self).on()
if self._blink_thread.stopping.wait(on_time): if self._blink_thread.stopping.wait(on_time):
break break
@@ -132,7 +126,7 @@ class LED(DigitalOutputDevice):
""" """
super(LED, self).off() super(LED, self).off()
def blink(self, on_time=1, off_time=1): def blink(self, on_time=1, off_time=1, n=None, background=True):
""" """
Make the LED turn on and off repeatedly in the background. Make the LED turn on and off repeatedly in the background.
@@ -141,8 +135,17 @@ class LED(DigitalOutputDevice):
off_time: 1 off_time: 1
Number of seconds off Number of seconds off
n: None
Number of times to blink; None means forever
background: True
If True, start a background thread to continue blinking and return
immediately. If False, only return when the blink is finished
(warning: the default value of n will result in this method never
returning).
""" """
super(LED, self).blink(on_time, off_time) super(LED, self).blink(on_time, off_time, n, background)
def toggle(self): def toggle(self):
""" """
@@ -151,6 +154,7 @@ class LED(DigitalOutputDevice):
""" """
super(LED, self).toggle() super(LED, self).toggle()
class Buzzer(DigitalOutputDevice): class Buzzer(DigitalOutputDevice):
""" """
A Buzzer component. A Buzzer component.
@@ -167,7 +171,7 @@ class Buzzer(DigitalOutputDevice):
""" """
super(Buzzer, self).off() super(Buzzer, self).off()
def blink(self, on_time=1, off_time=1): def blink(self, on_time=1, off_time=1, n=None, background=True):
""" """
Make the Buzzer turn on and off repeatedly in the background. Make the Buzzer turn on and off repeatedly in the background.
@@ -176,8 +180,17 @@ class Buzzer(DigitalOutputDevice):
off_time: 1 off_time: 1
Number of seconds off Number of seconds off
n: None
Number of times to blink; None means forever
background: True
If True, start a background thread to continue blinking and return
immediately. If False, only return when the blink is finished
(warning: the default value of n will result in this method never
returning).
""" """
super(Buzzer, self).blink() super(Buzzer, self).blink(on_time, off_time, n, background)
def toggle(self): def toggle(self):
""" """