Skip to content

Add type hints #8

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 8 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 37 additions & 23 deletions adafruit_is31fl3741/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
from adafruit_register.i2c_struct import ROUnaryStruct, UnaryStruct
from adafruit_register.i2c_bit import RWBit

try:
# Used only for typing
from typing import Optional, Tuple, Union # pylint: disable=unused-import
from PIL.ImageFile import ImageFile
from adafruit_framebuf import FrameBuffer
import busio
except ImportError:
pass

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3741.git"

Expand Down Expand Up @@ -77,7 +86,12 @@ class IS31FL3741:
_shutdown_bit = RWBit(_IS3741_FUNCREG_CONFIG, 0)
_pixel_buffer = None

def __init__(self, i2c, address=_IS3741_ADDR_DEFAULT, allocate=NO_BUFFER):
def __init__(
self,
i2c: busio.I2C,
address: int = _IS3741_ADDR_DEFAULT,
allocate: int = NO_BUFFER,
):
if allocate >= PREFER_BUFFER:
try:
# Pixel buffer intentionally has an extra item at the start
Expand All @@ -95,16 +109,16 @@ def __init__(self, i2c, address=_IS3741_ADDR_DEFAULT, allocate=NO_BUFFER):
self._page = None
self.reset()

def reset(self):
def reset(self) -> None:
"""Reset"""
self.page = 4
self._reset_reg = 0xAE

def unlock(self):
def unlock(self) -> None:
"""Unlock"""
self._lock_reg = 0xC5

def set_led_scaling(self, scale):
def set_led_scaling(self, scale: int) -> None:
"""Set scaling level for all LEDs.

:param scale: Scaling level from 0 (off) to 255 (brightest).
Expand All @@ -119,34 +133,34 @@ def set_led_scaling(self, scale):
i2c.write(scalebuf, end=172) # 2nd page is smaller

@property
def global_current(self):
def global_current(self) -> int:
"""Global current"""
self.page = 4
return self._gcurrent_reg

@global_current.setter
def global_current(self, current):
def global_current(self, current: int) -> None:
self.page = 4
self._gcurrent_reg = current

@property
def enable(self):
def enable(self) -> bool:
"""Enable"""
self.page = 4
return self._shutdown_bit

@enable.setter
def enable(self, enable):
def enable(self, enable: bool) -> None:
self.page = 4
self._shutdown_bit = enable

@property
def page(self):
def page(self) -> Union[int, None]:
"""Page"""
return self._page

@page.setter
def page(self, page_value):
def page(self, page_value: int) -> None:
if page_value == self._page:
return # already set
if page_value > 4:
Expand All @@ -155,7 +169,7 @@ def page(self, page_value):
self.unlock()
self._page_reg = page_value

def __getitem__(self, led):
def __getitem__(self, led: int) -> int:
if not 0 <= led <= 350:
raise ValueError("LED must be 0 ~ 350")
if self._pixel_buffer:
Expand All @@ -173,7 +187,7 @@ def __getitem__(self, led):
)
return self._buf[1]

def __setitem__(self, led, pwm):
def __setitem__(self, led: int, pwm: int) -> None:
if self._pixel_buffer:
# Buffered version doesn't require range checks --
# Python will throw its own IndexError/ValueError as needed.
Expand All @@ -195,7 +209,7 @@ def __setitem__(self, led, pwm):
else:
raise ValueError("LED must be 0 ~ 350")

def show(self):
def show(self) -> None:
"""Issue in-RAM pixel data to device. No effect if pixels are
unbuffered.
"""
Expand Down Expand Up @@ -256,12 +270,12 @@ class IS31FL3741_colorXY(IS31FL3741):
# pylint: disable-msg=too-many-arguments
def __init__(
self,
i2c,
width,
height,
address=_IS3741_ADDR_DEFAULT,
allocate=NO_BUFFER,
order=IS3741_BGR,
i2c: busio.I2C,
width: int,
height: int,
address: int = _IS3741_ADDR_DEFAULT,
allocate: int = NO_BUFFER,
order: int = IS3741_BGR,
):
super().__init__(i2c, address=address, allocate=allocate)
self.order = order
Expand All @@ -275,11 +289,11 @@ def __init__(

# This function must be replaced for each board
@staticmethod
def pixel_addrs(x, y):
def pixel_addrs(x: int, y: int) -> Tuple[int, ...]:
"""Calculate a device-specific LED offset for an X,Y 2D pixel."""
raise NotImplementedError("Supported in subclasses only")

def fill(self, color=None):
def fill(self, color: Optional[int] = None) -> None:
"""Set all pixels to a given RGB color.

:param color: Packed 24-bit color value (0xRRGGBB).
Expand All @@ -294,7 +308,7 @@ def fill(self, color=None):
self[addrs[self.g_offset]] = green
self[addrs[self.b_offset]] = blue

def pixel(self, x, y, color=None):
def pixel(self, x: int, y: int, color: Optional[int] = None) -> Union[int, None]:
"""
Set or retrieve RGB color of pixel at position (X,Y).

Expand All @@ -321,7 +335,7 @@ def pixel(self, x, y, color=None):
)
return None

def image(self, img):
def image(self, img: Union[FrameBuffer, ImageFile]) -> None:
"""Copy an in-memory image to the LED matrix. Image should be in
24-bit format (e.g. "RGB888") and dimensions should match matrix,
this isn't super robust yet or anything.
Expand Down
31 changes: 21 additions & 10 deletions adafruit_is31fl3741/adafruit_ledglasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
from adafruit_is31fl3741 import _IS3741_ADDR_DEFAULT, NO_BUFFER, IS3741_BGR
from . import IS31FL3741_colorXY

try:
# Used only for typing
from typing import Tuple, Any # pylint: disable=unused-import
import busio
except ImportError:
pass


class Right_Ring:
"""The right eye ring of the LED glasses"""
Expand Down Expand Up @@ -60,21 +67,21 @@ class Right_Ring:
b"\x01\x28\x00\x3C\x00\x3D"
)

def __init__(self, is31_controller, order):
def __init__(self, is31_controller: IS31FL3741_colorXY, order: int):
self._is31 = is31_controller
self.r_offset = (order >> 4) & 3
self.g_offset = (order >> 2) & 3
self.b_offset = order & 3

def __setitem__(self, led, color):
def __setitem__(self, led: int, color: int) -> None:
if not 0 <= led <= 23:
raise ValueError("led must be 0~23")
offset = unpack_from(">HHH", self.ledmap_bytes, led * 6)
self._is31[offset[self.r_offset]] = (color >> 16) & 0xFF
self._is31[offset[self.g_offset]] = (color >> 8) & 0xFF
self._is31[offset[self.b_offset]] = color & 0xFF

def __getitem__(self, led):
def __getitem__(self, led: int) -> int:
if not 0 <= led <= 23:
raise ValueError("led must be 0~23")
offset = unpack_from(">HHH", self.ledmap_bytes, led * 6)
Expand All @@ -84,7 +91,7 @@ def __getitem__(self, led):
| self._is31[offset[self.b_offset]]
)

def fill(self, color):
def fill(self, color: int) -> None:
"""Sets all LEDs in a ring to the same color.

:param color: Packed RGB color (0xRRGGBB).
Expand Down Expand Up @@ -129,21 +136,21 @@ class Left_Ring:
b"\x01\x5E\x00\xF0\x00\xF1"
)

def __init__(self, is31_controller, order):
def __init__(self, is31_controller: IS31FL3741_colorXY, order: int):
self._is31 = is31_controller
self.r_offset = (order >> 4) & 3
self.g_offset = (order >> 2) & 3
self.b_offset = order & 3

def __setitem__(self, led, color):
def __setitem__(self, led: int, color: int) -> None:
if not 0 <= led <= 23:
raise ValueError("led must be 0~23")
offset = unpack_from(">HHH", self.ledmap_bytes, led * 6)
self._is31[offset[self.r_offset]] = (color >> 16) & 0xFF
self._is31[offset[self.g_offset]] = (color >> 8) & 0xFF
self._is31[offset[self.b_offset]] = color & 0xFF

def __getitem__(self, led):
def __getitem__(self, led: int) -> int:
if not 0 <= led <= 23:
raise ValueError("led must be 0~23")
offset = unpack_from(">HHH", self.ledmap_bytes, led * 6)
Expand All @@ -153,7 +160,7 @@ def __getitem__(self, led):
| self._is31[offset[self.b_offset]]
)

def fill(self, color):
def fill(self, color: int) -> None:
"""Sets all LEDs in a ring to the same color.

:param color: Packed RGB color (0xRRGGBB).
Expand Down Expand Up @@ -268,7 +275,11 @@ class LED_Glasses(IS31FL3741_colorXY):
)

def __init__(
self, i2c, address=_IS3741_ADDR_DEFAULT, allocate=NO_BUFFER, order=IS3741_BGR
self,
i2c: busio.I2C,
address: int = _IS3741_ADDR_DEFAULT,
allocate: int = NO_BUFFER,
order: int = IS3741_BGR,
):
super().__init__(i2c, 18, 5, address=address, allocate=allocate, order=order)

Expand All @@ -281,5 +292,5 @@ def __init__(
self.grid = self

@staticmethod
def pixel_addrs(x, y):
def pixel_addrs(x: int, y: int) -> Tuple[Any, ...]:
return unpack_from(">HHH", LED_Glasses.ledmap_bytes, ((x * 5) + y) * 6)
15 changes: 13 additions & 2 deletions adafruit_is31fl3741/adafruit_rgbmatrixqt.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,30 @@
from adafruit_is31fl3741 import _IS3741_ADDR_DEFAULT, NO_BUFFER, IS3741_BGR
from . import IS31FL3741_colorXY

try:
# Used only for typing
from typing import Tuple
import busio
except ImportError:
pass


class Adafruit_RGBMatrixQT(IS31FL3741_colorXY):
"""Supports the Adafruit STEMMA QT IS31FL3741 RGB LED matrix."""

rowmap = [8, 5, 4, 3, 2, 1, 0, 7, 6]

def __init__(
self, i2c, address=_IS3741_ADDR_DEFAULT, allocate=NO_BUFFER, order=IS3741_BGR
self,
i2c: busio.I2C,
address: int = _IS3741_ADDR_DEFAULT,
allocate: int = NO_BUFFER,
order: int = IS3741_BGR,
):
super().__init__(i2c, 13, 9, address=address, allocate=allocate, order=order)

@staticmethod
def pixel_addrs(x, y):
def pixel_addrs(x: int, y: int) -> Tuple[int, int, int]:
"""Calulate the RGB offsets into the device array for x,y pixel"""
y = Adafruit_RGBMatrixQT.rowmap[y] # Reorder rows

Expand Down
15 changes: 13 additions & 2 deletions adafruit_is31fl3741/issi_evb.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,28 @@
from adafruit_is31fl3741 import _IS3741_ADDR_DEFAULT, NO_BUFFER, IS3741_BGR
from adafruit_is31fl3741 import IS31FL3741_colorXY

try:
# Used only for typing
from typing import Tuple # pylint: disable=unused-import
import busio
except ImportError:
pass


class ISSI_EVB(IS31FL3741_colorXY):
"""Supports the ISSI IS31FL3741 eval board"""

def __init__(
self, i2c, address=_IS3741_ADDR_DEFAULT, allocate=NO_BUFFER, order=IS3741_BGR
self,
i2c: busio.I2C,
address: int = _IS3741_ADDR_DEFAULT,
allocate: int = NO_BUFFER,
order: int = IS3741_BGR,
):
super().__init__(i2c, 9, 13, address=address, allocate=allocate, order=order)

@staticmethod
def pixel_addrs(x, y):
def pixel_addrs(x: int, y: int) -> Tuple[int, int, int]:
"""Calulate the RGB offsets into the device array for x,y pixel"""
if y > 2:
offset = (x * 10 + 12 - y) * 3
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
Adafruit-Blinka
adafruit-circuitpython-framebuf
adafruit-circuitpython-register
Pillow