Skip to content

Error check colors #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Mar 11, 2024
76 changes: 40 additions & 36 deletions adafruit_rgbled.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: MIT

# pylint: disable=raise-missing-from
"""
`adafruit_rgbled`
================================================================================
Expand Down Expand Up @@ -85,34 +86,32 @@ 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.
"""

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])) == "<class 'Pin'>":
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("<class '") and pin_type.endswith("Pin'>"):
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
Expand Down Expand Up @@ -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