mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
Fix #68
Actually, this isn't so much a fix as a re-working of RGBLED. This
renames the `rgb` property to `color` because that's what the property
really represents (combined with `picamera.Color` this lets you do stuff
like `rgb_led.color = Color('red')`), and simplifies the internals of
the class. It also adds the common `close` method and context manager
capabilities.
Finally, it corrects an error I hadn't noticed earlier where
PWMOutputDevice isn't properly cleaning up PWM threads on close.
This commit is contained in:
@@ -164,9 +164,10 @@ class PWMOutputDevice(DigitalOutputDevice):
|
|||||||
Generic Output device configured for PWM (Pulse-Width Modulation).
|
Generic Output device configured for PWM (Pulse-Width Modulation).
|
||||||
"""
|
"""
|
||||||
def __init__(self, pin=None, frequency=100):
|
def __init__(self, pin=None, frequency=100):
|
||||||
|
self._pwm = None
|
||||||
super(PWMOutputDevice, self).__init__(pin)
|
super(PWMOutputDevice, self).__init__(pin)
|
||||||
try:
|
try:
|
||||||
self._pwm = GPIO.PWM(self._pin, frequency)
|
self._pwm = GPIO.PWM(self.pin, frequency)
|
||||||
self._pwm.start(0.0)
|
self._pwm.start(0.0)
|
||||||
self._frequency = frequency
|
self._frequency = frequency
|
||||||
self._value = 0.0
|
self._value = 0.0
|
||||||
@@ -174,6 +175,17 @@ class PWMOutputDevice(DigitalOutputDevice):
|
|||||||
self.close()
|
self.close()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self._pwm:
|
||||||
|
# Ensure we wipe out the PWM object so that re-runs don't attempt
|
||||||
|
# to re-stop the PWM thread (otherwise, the fact that close is
|
||||||
|
# called from __del__ can easily result in us stopping the PWM
|
||||||
|
# on *another* instance on the same pin)
|
||||||
|
p = self._pwm
|
||||||
|
self._pwm = None
|
||||||
|
p.stop()
|
||||||
|
super(PWMOutputDevice, self).close()
|
||||||
|
|
||||||
def _read(self):
|
def _read(self):
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
@@ -212,80 +224,62 @@ class PWMOutputDevice(DigitalOutputDevice):
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
def _led_property(index, doc=None):
|
||||||
|
return property(
|
||||||
|
lambda self: getattr(self._leds[index], 'value'),
|
||||||
|
lambda self, value: setattr(self._leds[index], 'value', value),
|
||||||
|
doc
|
||||||
|
)
|
||||||
|
|
||||||
class RGBLED(object):
|
class RGBLED(object):
|
||||||
"""
|
"""
|
||||||
Single LED with individually controllable Red, Green and Blue components.
|
Single LED with individually controllable red, green and blue components.
|
||||||
|
|
||||||
|
red: `None`
|
||||||
|
The GPIO pin that controls the red component of the RGB LED.
|
||||||
|
|
||||||
|
green: `None`
|
||||||
|
The GPIO pin that controls the green component of the RGB LED.
|
||||||
|
|
||||||
|
blue: `None`
|
||||||
|
The GPIO pin that controls the blue component of the RGB LED.
|
||||||
"""
|
"""
|
||||||
def __init__(self, red=None, green=None, blue=None):
|
def __init__(self, red=None, green=None, blue=None):
|
||||||
if not all([red, green, blue]):
|
self._leds = tuple(PWMOutputDevice(pin) for pin in (red, green, blue))
|
||||||
raise GPIODeviceError('Red, Green and Blue pins must be provided')
|
|
||||||
|
|
||||||
self._red = PWMOutputDevice(red)
|
red = _led_property(0)
|
||||||
self._green = PWMOutputDevice(green)
|
green = _led_property(1)
|
||||||
self._blue = PWMOutputDevice(blue)
|
blue = _led_property(2)
|
||||||
self._leds = (self._red, self._green, self._blue)
|
|
||||||
|
@property
|
||||||
|
def color(self):
|
||||||
|
return (self.red, self.green, self.blue)
|
||||||
|
|
||||||
|
@color.setter
|
||||||
|
def color(self, value):
|
||||||
|
self.red, self.green, self.blue = value
|
||||||
|
|
||||||
def on(self):
|
def on(self):
|
||||||
"""
|
"""
|
||||||
Turn the device on
|
Turn the device on
|
||||||
"""
|
"""
|
||||||
for led in self._leds:
|
self.color = (1, 1, 1)
|
||||||
led.on()
|
|
||||||
|
|
||||||
def off(self):
|
def off(self):
|
||||||
"""
|
"""
|
||||||
Turn the device off
|
Turn the device off
|
||||||
"""
|
"""
|
||||||
|
self.color = (0, 0, 0)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
for led in self._leds:
|
for led in self._leds:
|
||||||
led.off()
|
led.close()
|
||||||
|
|
||||||
@property
|
def __enter__(self):
|
||||||
def red(self):
|
return self
|
||||||
return self._red.value
|
|
||||||
|
|
||||||
@red.setter
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
||||||
def red(self, value):
|
self.close()
|
||||||
self._red.value = self._validate(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def green(self):
|
|
||||||
return self._green.value
|
|
||||||
|
|
||||||
@green.setter
|
|
||||||
def green(self, value):
|
|
||||||
self._green.value = self._validate(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def blue(self):
|
|
||||||
return self._blue.value
|
|
||||||
|
|
||||||
@blue.setter
|
|
||||||
def blue(self, value):
|
|
||||||
self._blue.value = self._validate(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def rgb(self):
|
|
||||||
r = self.red
|
|
||||||
g = self.green
|
|
||||||
b = self.blue
|
|
||||||
return (r, g, b)
|
|
||||||
|
|
||||||
@rgb.setter
|
|
||||||
def rgb(self, values):
|
|
||||||
r, g, b = values
|
|
||||||
self.red = r
|
|
||||||
self.green = g
|
|
||||||
self.blue = b
|
|
||||||
|
|
||||||
def _validate(self, value):
|
|
||||||
_min = self._min_value
|
|
||||||
_max = self._max_value
|
|
||||||
if _min >= value >= _max:
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
raise GPIODeviceError(
|
|
||||||
"Colour value must be between %s and %s" % (_min, _max)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Motor(object):
|
class Motor(object):
|
||||||
|
|||||||
Reference in New Issue
Block a user