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