|
2 | 2 | # |
3 | 3 | # SPDX-License-Identifier: MIT |
4 | 4 |
|
| 5 | +# pylint: disable=raise-missing-from |
5 | 6 | """ |
6 | 7 | `adafruit_rgbled` |
7 | 8 | ================================================================================ |
@@ -85,34 +86,32 @@ class RGBLED: |
85 | 86 | with adafruit_rgbled.RGBLED(board.D5, board.D6, board.D7, invert_pwm=True) as rgb_led: |
86 | 87 | rgb_led.color = (0, 255, 0) |
87 | 88 |
|
88 | | - :param Union[Pin, PWMOut, "PWMChannel"] red_pin: |
| 89 | + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] red_pin: |
89 | 90 | The connection to the red LED. |
90 | | - :param Union[Pin, PWMOut, "PWMChannel"] green_pin: |
| 91 | + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] green_pin: |
91 | 92 | The connection to the green LED. |
92 | | - :param Union[Pin, PWMOut, "PWMChannel"] blue_pin: |
| 93 | + :param Union["microcontroller.Pin", PWMOut, "PWMChannel"] blue_pin: |
93 | 94 | The connection to the blue LED. |
94 | 95 | :param bool invert_pwm: False if the RGB LED is common cathode, |
95 | 96 | True if the RGB LED is common anode. Defaults to False. |
96 | 97 | """ |
97 | 98 |
|
98 | 99 | def __init__( |
99 | 100 | self, |
100 | | - red_pin: Union[Pin, PWMOut, PWMChannel], |
101 | | - green_pin: Union[Pin, PWMOut, PWMChannel], |
102 | | - blue_pin: Union[Pin, PWMOut, PWMChannel], |
| 101 | + red_pin: Union[Pin, PWMOut, "PWMChannel"], |
| 102 | + green_pin: Union[Pin, PWMOut, "PWMChannel"], |
| 103 | + blue_pin: Union[Pin, PWMOut, "PWMChannel"], |
103 | 104 | invert_pwm: bool = False, |
104 | 105 | ) -> None: |
105 | 106 | self._rgb_led_pins = [red_pin, green_pin, blue_pin] |
106 | | - for i in range( # pylint: disable=consider-using-enumerate |
107 | | - len(self._rgb_led_pins) |
108 | | - ): |
109 | | - if hasattr(self._rgb_led_pins[i], "frequency"): |
110 | | - self._rgb_led_pins[i].duty_cycle = 0 |
111 | | - elif str(type(self._rgb_led_pins[i])) == "<class 'Pin'>": |
112 | | - self._rgb_led_pins[i] = PWMOut(self._rgb_led_pins[i]) |
113 | | - self._rgb_led_pins[i].duty_cycle = 0 |
114 | | - else: |
115 | | - raise TypeError("Must provide a pin, PWMOut, or PWMChannel.") |
| 107 | + for pin, _ in enumerate(self._rgb_led_pins): |
| 108 | + try: |
| 109 | + pin_type = str(type(self._rgb_led_pins[pin])) |
| 110 | + if pin_type.startswith("<class '") and pin_type.endswith("Pin'>"): |
| 111 | + self._rgb_led_pins[pin] = PWMOut(self._rgb_led_pins[pin]) |
| 112 | + self._rgb_led_pins[pin].duty_cycle = 0 |
| 113 | + except AttributeError: |
| 114 | + raise TypeError("Pins must be of type Pin, PWMOut or PWMChannel") |
116 | 115 | self._invert_pwm = invert_pwm |
117 | 116 | self._current_color = (0, 0, 0) |
118 | 117 | self.color = self._current_color |
@@ -145,31 +144,36 @@ def color(self) -> ColorBasedColorUnion: |
145 | 144 |
|
146 | 145 | :returns Union[int, Tuple[int, int, int]]: The current LED color setting. |
147 | 146 |
|
148 | | - :raises ValueError: If the input is an int > 0xffffff. |
| 147 | + :raises ValueError: If the input is an int > 0xffffff or is a tuple that does not |
| 148 | + contain 3 integers of 0 - 255. |
149 | 149 | :raises TypeError: If the input is not an integer or a tuple. |
150 | 150 | """ |
151 | 151 | return self._current_color |
152 | 152 |
|
153 | 153 | @color.setter |
154 | 154 | def color(self, value: ColorBasedColorUnion): |
155 | | - self._current_color = value |
156 | | - if isinstance(value, tuple): |
157 | | - for i in range(0, 3): |
158 | | - color = int(max(0, min(65535, value[i] * 257))) |
159 | | - if self._invert_pwm: |
160 | | - color -= 65535 |
161 | | - self._rgb_led_pins[i].duty_cycle = abs(color) |
162 | | - elif isinstance(value, int): |
163 | | - if value > 0xFFFFFF: |
| 155 | + if isinstance(value, int): |
| 156 | + try: |
| 157 | + # Check that integer is <= 0xffffff and create an iterable. |
| 158 | + rgb = value.to_bytes(3, "big", signed=False) |
| 159 | + except OverflowError: |
164 | 160 | raise ValueError("Only bits 0->23 valid for integer input") |
165 | | - r = value >> 16 |
166 | | - g = (value >> 8) & 0xFF |
167 | | - b = value & 0xFF |
168 | | - rgb = [r, g, b] |
169 | | - for color in range(0, 3): |
170 | | - rgb[color] = max(0, min(65535, rgb[color] * 257)) |
171 | | - if self._invert_pwm: |
172 | | - rgb[color] -= 65535 |
173 | | - self._rgb_led_pins[color].duty_cycle = abs(rgb[color]) |
| 161 | + elif isinstance(value, tuple): |
| 162 | + try: |
| 163 | + rgb = bytes(value) # Check that tuple has integers of 0 - 255. |
| 164 | + if len(rgb) != 3: |
| 165 | + raise ValueError |
| 166 | + except (ValueError, TypeError): |
| 167 | + raise ValueError( |
| 168 | + "Only a tuple of 3 integers of 0 - 255 for tuple input." |
| 169 | + ) |
174 | 170 | else: |
175 | | - raise TypeError("Color must be a tuple or 24-bit integer value.") |
| 171 | + raise TypeError( |
| 172 | + "Color must be a tuple of 3 integers or 24-bit integer value." |
| 173 | + ) |
| 174 | + for color, intensity in enumerate(rgb): |
| 175 | + # Take advantage of bool truthiness. |
| 176 | + self._rgb_led_pins[color].duty_cycle = abs( |
| 177 | + intensity * 257 - 65535 * self._invert_pwm |
| 178 | + ) |
| 179 | + self._current_color = value |
0 commit comments