diff --git a/adafruit_rgbled.py b/adafruit_rgbled.py index c5c7386..c5893bd 100644 --- a/adafruit_rgbled.py +++ b/adafruit_rgbled.py @@ -2,6 +2,7 @@ # # SPDX-License-Identifier: MIT +# pylint: disable=raise-missing-from """ `adafruit_rgbled` ================================================================================ @@ -85,11 +86,11 @@ class 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[Pin, PWMOut, "PWMChannel"] red_pin: + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] red_pin: The connection to the red LED. - :param Union[Pin, PWMOut, "PWMChannel"] green_pin: + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] green_pin: The connection to the green LED. - :param Union[Pin, PWMOut, "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. Defaults to False. @@ -97,22 +98,20 @@ class RGBLED: def __init__( self, - red_pin: Union[Pin, PWMOut, PWMChannel], - green_pin: Union[Pin, PWMOut, PWMChannel], - blue_pin: Union[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] - 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 enumerate(self._rgb_led_pins): + try: + 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: + 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 @@ -145,31 +144,36 @@ def color(self) -> ColorBasedColorUnion: :returns Union[int, Tuple[int, int, int]]: The current LED color setting. - :raises ValueError: If the input is an int > 0xffffff. + :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 @color.setter def color(self, value: ColorBasedColorUnion): - 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: + if isinstance(value, int): + try: + # Check that integer is <= 0xffffff and create an iterable. + rgb = value.to_bytes(3, "big", signed=False) + except OverflowError: 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]) + 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): + raise ValueError( + "Only a tuple of 3 integers of 0 - 255 for tuple input." + ) 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." + ) + 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 + ) + self._current_color = value