Shut down GPIO threads nicely

The motion sensor queue doesn't shut down properly at script end at the
moment and prevents the interpreter shutting down. This is because it's
a non-daemon thread so `__del__` never gets run and so on.

This is a bit of a major PR - I can split it up if you want. Firstly it
makes a common base class called `GPIODevice` for both `InputDevice` and
`OutputDevice`. This just takes care of the read-only pin stuff. Next it
makes a `GPIOThread` class that ensures its a daemon thread, and which
also ensures proper cleanup on shutdown.

Finally, it fixes `MotionSensor` to use the new `GPIOThread` class
(tested this time! Works nicely) and adds the `blink` method to the
`LED` class (which also works nicely this time).
This commit is contained in:
Dave Jones
2015-09-18 11:19:13 +01:00
parent c810730cf5
commit e2ddad6fea
4 changed files with 118 additions and 37 deletions

43
gpiozero/devices.py Normal file
View File

@@ -0,0 +1,43 @@
from threading import Thread, Event
from RPi import GPIO
class GPIODeviceError(Exception):
pass
class GPIODevice(object):
def __init__(self, pin=None):
if pin is None:
raise GPIODeviceError('No GPIO pin number given')
self._pin = pin
@property
def pin(self):
return self._pin
_GPIO_THREADS = set()
def _gpio_threads_shutdown():
while _GPIO_THREADS:
for t in _GPIO_THREADS.copy():
t.stop()
class GPIOThread(Thread):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
super(GPIOThread, self).__init__(group, target, name, args, kwargs)
self.stopping = Event()
self.daemon = True
def start(self):
self.stopping.clear()
_GPIO_THREADS.add(self)
super(GPIOThread, self).start()
def stop(self):
self.stopping.set()
self.join()
_GPIO_THREADS.discard(self)