Skip to content

Commit 9130da5

Browse files
authored
Improve error checking to Matrix parameters (#131)
1 parent 611a849 commit 9130da5

File tree

2 files changed

+63
-40
lines changed

2 files changed

+63
-40
lines changed

buildhat/devices.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,10 @@ def _setup(device="/dev/serial0"):
7474

7575
def __del__(self):
7676
if hasattr(self, "port") and Device._used[self.port]:
77-
if Device._device_names[self._typeid][0] == "Matrix":
78-
self.clear() # noqa: PLE1101
7977
Device._used[self.port] = False
8078
self._conn.callit = None
8179
self.deselect()
82-
if Device._device_names[self._typeid][0] != "Matrix":
83-
self.off()
80+
self.off()
8481

8582
@staticmethod
8683
def name_for_id(typeid):

buildhat/matrix.py

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,22 @@ def __init__(self, port):
1414
self.mode(2)
1515
self._matrix = [[(0, 0) for x in range(3)] for y in range(3)]
1616

17-
def set_pixels(self, matrix):
17+
def set_pixels(self, matrix, display=True):
1818
"""Write pixel data to LED matrix
1919
2020
:param pixels: 3x3 list of tuples, with colour (0–10) and brightness (0–10) (see example for more detail)
21+
:param display: Whether to update matrix or not
2122
"""
23+
if len(matrix) != 3:
24+
raise MatrixError("Incorrect matrix height")
2225
for x in range(3):
26+
if len(matrix[x]) != 3:
27+
raise MatrixError("Incorrect matrix width")
2328
for y in range(3):
24-
color, brightness = matrix[x][y]
25-
if not (brightness >= 0 and brightness <= 10):
26-
raise MatrixError("Invalid brightness specified")
27-
if not (color >= 0 and color <= 10):
28-
raise MatrixError("Invalid pixel specified")
29+
matrix[x][y] = Matrix.normalize_pixel(matrix[x][y]) # pylint: disable=too-many-function-args
2930
self._matrix = matrix
30-
self._output()
31+
if display:
32+
self._output()
3133

3234
def _output(self):
3335
out = [0xc2]
@@ -38,7 +40,14 @@ def _output(self):
3840
self._write1(out)
3941
self.deselect()
4042

41-
def strtocolor(self, colorstr):
43+
@staticmethod
44+
def strtocolor(colorstr):
45+
"""Return the BuldHAT's integer representation of a color string
46+
47+
:param colorstr: str of a valid color
48+
:return: (0-10) representing the color
49+
:rtype: int
50+
"""
4251
if colorstr == "pink":
4352
return 1
4453
elif colorstr == "lilac":
@@ -63,6 +72,43 @@ def strtocolor(self, colorstr):
6372
return 0
6473
raise MatrixError("Invalid color specified")
6574

75+
@staticmethod
76+
def normalize_pixel(pixel):
77+
"""Validate a pixel tuple (color, brightness) and convert string colors to integers
78+
79+
:param pixel: tuple of colour (0–10) or string (ie:"red") and brightness (0–10)
80+
:return: (color, brightness) integers
81+
:rtype: tuple
82+
"""
83+
if isinstance(pixel, tuple):
84+
c, brightness = pixel # pylint: disable=unpacking-non-sequence
85+
if isinstance(c, str):
86+
c = Matrix.strtocolor(c) # pylint: disable=too-many-function-args
87+
if not (isinstance(brightness, int) and isinstance(c, int)):
88+
raise MatrixError("Invalid pixel specified")
89+
if not (brightness >= 0 and brightness <= 10):
90+
raise MatrixError("Invalid brightness value specified")
91+
if not (c >= 0 and c <= 10):
92+
raise MatrixError("Invalid pixel color specified")
93+
return (c, brightness)
94+
else:
95+
raise MatrixError("Invalid pixel specified")
96+
97+
@staticmethod
98+
def validate_coordinate(coord):
99+
""""Validate an x,y coordinate for the 3x3 Matrix
100+
101+
:param coord: tuple of 0-2 for the X coordinate and 0-2 for the Y coordinate
102+
"""
103+
# pylint: disable=unsubscriptable-object
104+
if isinstance(coord, tuple):
105+
if not (isinstance(coord[0], int) and isinstance(coord[1], int)):
106+
raise MatrixError("Invalid coord specified")
107+
elif coord[0] > 2 or coord[0] < 0 or coord[1] > 2 or coord[1] < 0:
108+
raise MatrixError("Invalid coord specified")
109+
else:
110+
raise MatrixError("Invalid coord specified")
111+
66112
def clear(self, pixel=None):
67113
"""Clear matrix or set all as the same pixel
68114
@@ -71,21 +117,15 @@ def clear(self, pixel=None):
71117
if pixel is None:
72118
self._matrix = [[(0, 0) for x in range(3)] for y in range(3)]
73119
else:
74-
color = ()
75-
if isinstance(pixel, tuple):
76-
c, brightness = pixel
77-
if isinstance(c, str):
78-
c = self.strtocolor(c)
79-
if not (brightness >= 0 and brightness <= 10):
80-
raise MatrixError("Invalid brightness specified")
81-
if not (c >= 0 and c <= 10):
82-
raise MatrixError("Invalid pixel specified")
83-
color = (c, brightness)
84-
else:
85-
raise MatrixError("Invalid pixel specified")
120+
color = Matrix.normalize_pixel(pixel) # pylint: disable=too-many-function-args
86121
self._matrix = [[color for x in range(3)] for y in range(3)]
87122
self._output()
88123

124+
def off(self):
125+
# Never send the "off" command to the port a Matrix is connected to
126+
# Instead, just turn all the pixels off
127+
self.clear()
128+
89129
def level(self, level):
90130
"""Use the matrix as a "level" meter from 0-9
91131
(The level meter is expressed in green which seems to be unchangeable)
@@ -143,22 +183,8 @@ def set_pixel(self, coord, pixel, display=True):
143183
:param pixel: tuple of colour (0–10) or string and brightness (0–10)
144184
:param display: Whether to update matrix or not
145185
"""
146-
if isinstance(pixel, tuple):
147-
c, brightness = pixel
148-
if isinstance(c, str):
149-
c = self.strtocolor(c)
150-
if not (brightness >= 0 and brightness <= 10):
151-
raise MatrixError("Invalid brightness specified")
152-
if not (c >= 0 and c <= 10):
153-
raise MatrixError("Invalid pixel specified")
154-
color = (c, brightness)
155-
else:
156-
raise MatrixError("Invalid pixel specified")
157-
if isinstance(coord, tuple):
158-
if not (isinstance(coord[0], int) and isinstance(coord[1], int)):
159-
raise MatrixError("Invalid coord specified")
160-
else:
161-
raise MatrixError("Invalid coord specified")
186+
color = Matrix.normalize_pixel(pixel) # pylint: disable=too-many-function-args
187+
Matrix.validate_coordinate(coord) # pylint: disable=too-many-function-args
162188
x, y = coord
163189
self._matrix[x][y] = color
164190
if display:

0 commit comments

Comments
 (0)