From b0044a6c28dcf537a9cf948f41007633acdaa5f2 Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Mon, 20 Mar 2023 13:50:56 +0700 Subject: [PATCH 01/11] Refactored color.setter to give helpful errors if incorrect inputs are given --- adafruit_rgbled.py | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index 18fbbca..55e2e90 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -143,24 +143,29 @@ def color(self) -> Union[int, tuple]: @color.setter def color(self, value: Union[int, tuple]): - self._current_color = value - if isinstance(value, tuple): - for i in range(0, 3): - color = int(max(0, min(65535, value[i] * 257))) - if self._invert_pwm: - color -= 65535 - self._rgb_led_pins[i].duty_cycle = abs(color) - elif isinstance(value, int): - if value > 0xFFFFFF: - raise ValueError("Only bits 0->23 valid for integer input") - r = value >> 16 - g = (value >> 8) & 0xFF - b = value & 0xFF - rgb = [r, g, b] - for color in range(0, 3): - rgb[color] = max(0, min(65535, rgb[color] * 257)) - if self._invert_pwm: - rgb[color] -= 65535 - self._rgb_led_pins[color].duty_cycle = abs(rgb[color]) + old_color = self._current_color + if isinstance(value, int): + try: + rgb = value.to_bytes(3, "big", signed=False) + except OverflowError as exc: + raise ValueError("Only bits 0->23 valid for integer input") from exc + elif isinstance(value, tuple): + try: + rgb = bytes(value) + except (ValueError, TypeError) as exc: + raise ValueError( + "Only a tuple of 3 integers of 0 - 255 for tuple input." + ) from exc else: - raise TypeError("Color must be a tuple or 24-bit integer value.") + raise TypeError( + "Color must be a tuple of 3 integers or 24-bit integer value." + ) + try: + for color, intensity in enumerate(rgb): + self._rgb_led_pins[color].duty_cycle = abs( + intensity * 257 - 65535 * self._invert_pwm + ) + except IndexError as exc: + self.color = old_color + raise ValueError("Tuple must be 3 integers.") from exc + self._current_color = value From 45d0e99746239587b90d0e5bd06c60a420b417fc Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Mon, 20 Mar 2023 13:53:22 +0700 Subject: [PATCH 02/11] Updated docstring for color to reflect new exceptions. --- adafruit_rgbled.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index 55e2e90..c0d9276 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -136,7 +136,8 @@ def color(self) -> Union[int, tuple]: :param Union[int, tuple] value: RGB LED desired value - can be a RGB tuple of values 0 - 255 or a 24-bit integer. e.g. (255, 64, 35) and 0xff4023 are equivalent. - :raises ValueError: If the input is an int > 0xffffff. + :raises ValueError: If the input is an int > 0xffffff or is not a tuple of 3 integers + 0 - 255. :raises TypeError: If the input is not an integer or a tuple. """ return self._current_color @@ -167,5 +168,5 @@ def color(self, value: Union[int, tuple]): ) except IndexError as exc: self.color = old_color - raise ValueError("Tuple must be 3 integers.") from exc + raise ValueError("Tuple must contain 3 integers.") from exc self._current_color = value From 44bc38c16bb7fa109fe859c19f144cc60d4c2085 Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Mon, 20 Mar 2023 19:22:25 +0700 Subject: [PATCH 03/11] Simplified error checking for length of tuple. --- adafruit_rgbled.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index c0d9276..dccb72b 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -144,7 +144,6 @@ def color(self) -> Union[int, tuple]: @color.setter def color(self, value: Union[int, tuple]): - old_color = self._current_color if isinstance(value, int): try: rgb = value.to_bytes(3, "big", signed=False) @@ -153,6 +152,8 @@ def color(self, value: Union[int, tuple]): elif isinstance(value, tuple): try: rgb = bytes(value) + if len(rgb) != 3: + raise ValueError except (ValueError, TypeError) as exc: raise ValueError( "Only a tuple of 3 integers of 0 - 255 for tuple input." @@ -161,12 +162,8 @@ def color(self, value: Union[int, tuple]): raise TypeError( "Color must be a tuple of 3 integers or 24-bit integer value." ) - try: - for color, intensity in enumerate(rgb): - self._rgb_led_pins[color].duty_cycle = abs( - intensity * 257 - 65535 * self._invert_pwm - ) - except IndexError as exc: - self.color = old_color - raise ValueError("Tuple must contain 3 integers.") from exc + for color, intensity in enumerate(rgb): + self._rgb_led_pins[color].duty_cycle = abs( + intensity * 257 - 65535 * self._invert_pwm + ) self._current_color = value From f5a3e0c1d6fcaf852102f46c77177f33ab57b40f Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Mon, 20 Mar 2023 19:26:10 +0700 Subject: [PATCH 04/11] Fixed some docstring indentation errors. --- adafruit_rgbled.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index dccb72b..83d63e5 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -136,8 +136,8 @@ def color(self) -> Union[int, tuple]: :param Union[int, tuple] value: RGB LED desired value - can be a RGB tuple of values 0 - 255 or a 24-bit integer. e.g. (255, 64, 35) and 0xff4023 are equivalent. - :raises ValueError: If the input is an int > 0xffffff or is not a tuple of 3 integers - 0 - 255. + :raises ValueError: If the input is an int > 0xffffff or is a tuple that does not + contain 3 integers of 0 - 255. :raises TypeError: If the input is not an integer or a tuple. """ return self._current_color From 3516ff0fe8eb9f6bf79e252a405ed8980a39aa14 Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Tue, 21 Mar 2023 12:29:49 +0700 Subject: [PATCH 05/11] Made changes to typing. --- adafruit_rgbled.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index 83d63e5..405ea49 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -20,9 +20,6 @@ """ try: from typing import Union - import adafruit_pca9685 as pca9685 - import pwmio - import microcontroller except ImportError: pass @@ -87,20 +84,20 @@ class RGBLED: def __init__( self, - red_pin: Union[microcontroller.Pin, pwmio.PWMOut, pca9685.PWMChannel], - green_pin: Union[microcontroller.Pin, pwmio.PWMOut, pca9685.PWMChannel], - blue_pin: Union[microcontroller.Pin, pwmio.PWMOut, pca9685.PWMChannel], + red_pin: Union["microcontroller.Pin", PWMOut, "PWMChannel"], + green_pin: Union["microcontroller.Pin", PWMOut, "PWMChannel"], + blue_pin: Union["microcontroller.Pin", PWMOut, "PWMChannel"], invert_pwm: bool = False, ) -> None: """ - :param Union[microcontroller.Pin, pwmio.PWMOut, pca9685.PWMChannel] red_pin: + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] red_pin: The connection to the red LED. - :param Union[microcontroller.Pin, pwmio.PWMOut, pca9685.PWMChannel] green_pin: + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] green_pin: The connection to the green LED. - :param Union[microcontroller.Pin, pwmio.PWMOut, pca9685.PWMChannel] blue_pin: + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] blue_pin: The connection to the blue LED. :param bool invert_pwm: False if the RGB LED is common cathode, - True if the RGB LED is common anode. + True if the RGB LED is common anode. Defaults to False. """ self._rgb_led_pins = [red_pin, green_pin, blue_pin] for i in range( # pylint: disable=consider-using-enumerate From 0663429253ca9bdb14e8fe700194b7b0f1b92377 Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Tue, 21 Mar 2023 12:35:26 +0700 Subject: [PATCH 06/11] Added comments to clarify some logic. --- adafruit_rgbled.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index 405ea49..a30f999 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -143,12 +143,13 @@ def color(self) -> Union[int, tuple]: def color(self, value: Union[int, tuple]): if isinstance(value, int): try: + # Check that integer is <= 0xffffff and create an iterable. rgb = value.to_bytes(3, "big", signed=False) except OverflowError as exc: raise ValueError("Only bits 0->23 valid for integer input") from exc elif isinstance(value, tuple): try: - rgb = bytes(value) + rgb = bytes(value) # Check that tuple has 3 integers of 0 - 255. if len(rgb) != 3: raise ValueError except (ValueError, TypeError) as exc: @@ -160,6 +161,7 @@ def color(self, value: Union[int, tuple]): "Color must be a tuple of 3 integers or 24-bit integer value." ) for color, intensity in enumerate(rgb): + # Take advantage of bool truthiness. self._rgb_led_pins[color].duty_cycle = abs( intensity * 257 - 65535 * self._invert_pwm ) From 34bff7acc35a945fd8eaf3184e535a5e6219bce6 Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Tue, 21 Mar 2023 18:44:35 +0700 Subject: [PATCH 07/11] Simplified pin init prior to adding support for Raspi pins. --- adafruit_rgbled.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index a30f999..b40081a 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -100,16 +100,15 @@ def __init__( True if the RGB LED is common anode. Defaults to False. """ self._rgb_led_pins = [red_pin, green_pin, blue_pin] - for i in range( # pylint: disable=consider-using-enumerate - len(self._rgb_led_pins) - ): - if hasattr(self._rgb_led_pins[i], "frequency"): - self._rgb_led_pins[i].duty_cycle = 0 - elif str(type(self._rgb_led_pins[i])) == "": - self._rgb_led_pins[i] = PWMOut(self._rgb_led_pins[i]) - self._rgb_led_pins[i].duty_cycle = 0 - else: - raise TypeError("Must provide a pin, PWMOut, or PWMChannel.") + for pin in self._rgb_led_pins: + try: + if str(type(pin)) == "": + pin = PWMOut(pin) + pin.duty_cycle = 0 + except AttributeError as exc: + raise TypeError( + "Pins must be of type Pin, PWMOut or PWMChannel" + ) from exc self._invert_pwm = invert_pwm self._current_color = (0, 0, 0) self.color = self._current_color @@ -149,7 +148,7 @@ def color(self, value: Union[int, tuple]): raise ValueError("Only bits 0->23 valid for integer input") from exc elif isinstance(value, tuple): try: - rgb = bytes(value) # Check that tuple has 3 integers of 0 - 255. + rgb = bytes(value) # Check that tuple has integers of 0 - 255. if len(rgb) != 3: raise ValueError except (ValueError, TypeError) as exc: From b66abb3adc8b8ec37bcd422ddb08c02a0258704b Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Fri, 24 Mar 2023 07:59:02 +0700 Subject: [PATCH 08/11] Added logic for Raspberry Pi pins --- adafruit_rgbled.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index b40081a..f38da6b 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -100,18 +100,18 @@ def __init__( True if the RGB LED is common anode. Defaults to False. """ self._rgb_led_pins = [red_pin, green_pin, blue_pin] - for pin in self._rgb_led_pins: + for pin, _ in enumerate(self._rgb_led_pins): try: - if str(type(pin)) == "": - pin = PWMOut(pin) - pin.duty_cycle = 0 + pin_type = str(type(self._rgb_led_pins[pin])) + if pin_type.startswith(""): + self._rgb_led_pins[pin] = PWMOut(self._rgb_led_pins[pin]) + self._rgb_led_pins[pin].duty_cycle = 0 except AttributeError as exc: raise TypeError( "Pins must be of type Pin, PWMOut or PWMChannel" ) from exc self._invert_pwm = invert_pwm self._current_color = (0, 0, 0) - self.color = self._current_color def __enter__(self) -> "RGBLED": return self From 7879309bf09253eca40227f65704ea29815b8245 Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Fri, 24 Mar 2023 10:52:24 +0700 Subject: [PATCH 09/11] Removed re-raising errors, it's confusing --- adafruit_rgbled.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index f38da6b..1f85c94 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -2,6 +2,7 @@ # # SPDX-License-Identifier: MIT +# pylint: disable=raise-missing-from """ `adafruit_rgbled` ================================================================================ @@ -106,12 +107,11 @@ def __init__( if pin_type.startswith(""): self._rgb_led_pins[pin] = PWMOut(self._rgb_led_pins[pin]) self._rgb_led_pins[pin].duty_cycle = 0 - except AttributeError as exc: - raise TypeError( - "Pins must be of type Pin, PWMOut or PWMChannel" - ) from exc + except AttributeError: + raise TypeError("Pins must be of type Pin, PWMOut or PWMChannel") self._invert_pwm = invert_pwm self._current_color = (0, 0, 0) + self.color = self._current_color def __enter__(self) -> "RGBLED": return self @@ -144,17 +144,17 @@ def color(self, value: Union[int, tuple]): try: # Check that integer is <= 0xffffff and create an iterable. rgb = value.to_bytes(3, "big", signed=False) - except OverflowError as exc: - raise ValueError("Only bits 0->23 valid for integer input") from exc + except OverflowError: + raise ValueError("Only bits 0->23 valid for integer input") elif isinstance(value, tuple): try: rgb = bytes(value) # Check that tuple has integers of 0 - 255. if len(rgb) != 3: raise ValueError - except (ValueError, TypeError) as exc: + except (ValueError, TypeError): raise ValueError( "Only a tuple of 3 integers of 0 - 255 for tuple input." - ) from exc + ) else: raise TypeError( "Color must be a tuple of 3 integers or 24-bit integer value." From d6f6b2752d7a3075a4008418af549bd64eee2ec1 Mon Sep 17 00:00:00 2001 From: BiffoBear Date: Wed, 12 Apr 2023 07:11:29 +0300 Subject: [PATCH 10/11] Moved doc-string from __init__ to class definition. --- adafruit_rgbled.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index 1f85c94..edee08a 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -81,6 +81,15 @@ class RGBLED: import adafruit_rgbled with adafruit_rgbled.RGBLED(board.D5, board.D6, board.D7, invert_pwm=True) as rgb_led: rgb_led.color = (0, 255, 0) + + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] red_pin: + The connection to the red LED. + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] green_pin: + The connection to the green LED. + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] blue_pin: + The connection to the blue LED. + :param bool invert_pwm: False if the RGB LED is common cathode, + True if the RGB LED is common anode. Defaults to False. """ def __init__( @@ -90,16 +99,6 @@ def __init__( blue_pin: Union["microcontroller.Pin", PWMOut, "PWMChannel"], invert_pwm: bool = False, ) -> None: - """ - :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] red_pin: - The connection to the red LED. - :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] green_pin: - The connection to the green LED. - :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] blue_pin: - The connection to the blue LED. - :param bool invert_pwm: False if the RGB LED is common cathode, - True if the RGB LED is common anode. Defaults to False. - """ self._rgb_led_pins = [red_pin, green_pin, blue_pin] for pin, _ in enumerate(self._rgb_led_pins): try: From 14d8c810849d667150187772962f48f4d625bec2 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sun, 17 Sep 2023 12:58:13 -0500 Subject: [PATCH 11/11] use Pin --- adafruit_rgbled.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index 4851108..c5893bd 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -98,9 +98,9 @@ class RGBLED: def __init__( self, - red_pin: Union["microcontroller.Pin", PWMOut, "PWMChannel"], - green_pin: Union["microcontroller.Pin", PWMOut, "PWMChannel"], - blue_pin: Union["microcontroller.Pin", PWMOut, "PWMChannel"], + red_pin: Union[Pin, PWMOut, "PWMChannel"], + green_pin: Union[Pin, PWMOut, "PWMChannel"], + blue_pin: Union[Pin, PWMOut, "PWMChannel"], invert_pwm: bool = False, ) -> None: self._rgb_led_pins = [red_pin, green_pin, blue_pin]