ledmatrix 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. ledmatrix-0.1.0/LICENSE +21 -0
  2. ledmatrix-0.1.0/MANIFEST.in +2 -0
  3. ledmatrix-0.1.0/PKG-INFO +287 -0
  4. ledmatrix-0.1.0/README.md +245 -0
  5. ledmatrix-0.1.0/pyproject.toml +69 -0
  6. ledmatrix-0.1.0/setup.cfg +4 -0
  7. ledmatrix-0.1.0/src/ledmatrix/__init__.py +33 -0
  8. ledmatrix-0.1.0/src/ledmatrix/async_device.py +64 -0
  9. ledmatrix-0.1.0/src/ledmatrix/canvas.py +208 -0
  10. ledmatrix-0.1.0/src/ledmatrix/cli/__init__.py +1 -0
  11. ledmatrix-0.1.0/src/ledmatrix/cli/main.py +250 -0
  12. ledmatrix-0.1.0/src/ledmatrix/data/50-framework-inputmodule.rules +3 -0
  13. ledmatrix-0.1.0/src/ledmatrix/data/__init__.py +1 -0
  14. ledmatrix-0.1.0/src/ledmatrix/device.py +367 -0
  15. ledmatrix-0.1.0/src/ledmatrix/dither.py +95 -0
  16. ledmatrix-0.1.0/src/ledmatrix/exceptions.py +41 -0
  17. ledmatrix-0.1.0/src/ledmatrix/font/__init__.py +5 -0
  18. ledmatrix-0.1.0/src/ledmatrix/font/bdf.py +112 -0
  19. ledmatrix-0.1.0/src/ledmatrix/font/data/3x5.bdf +946 -0
  20. ledmatrix-0.1.0/src/ledmatrix/font/data/5x7.bdf +1102 -0
  21. ledmatrix-0.1.0/src/ledmatrix/font/data/__init__.py +1 -0
  22. ledmatrix-0.1.0/src/ledmatrix/font/data/tom-thumb.bdf +1024 -0
  23. ledmatrix-0.1.0/src/ledmatrix/font/font.py +111 -0
  24. ledmatrix-0.1.0/src/ledmatrix/geometry.py +49 -0
  25. ledmatrix-0.1.0/src/ledmatrix/hotplug.py +75 -0
  26. ledmatrix-0.1.0/src/ledmatrix/image.py +56 -0
  27. ledmatrix-0.1.0/src/ledmatrix/logging.py +21 -0
  28. ledmatrix-0.1.0/src/ledmatrix/protocol/__init__.py +8 -0
  29. ledmatrix-0.1.0/src/ledmatrix/protocol/framework16.py +66 -0
  30. ledmatrix-0.1.0/src/ledmatrix/protocol/types.py +57 -0
  31. ledmatrix-0.1.0/src/ledmatrix/scheduler.py +67 -0
  32. ledmatrix-0.1.0/src/ledmatrix/shapes.py +36 -0
  33. ledmatrix-0.1.0/src/ledmatrix/transport/__init__.py +9 -0
  34. ledmatrix-0.1.0/src/ledmatrix/transport/base.py +30 -0
  35. ledmatrix-0.1.0/src/ledmatrix/transport/mock.py +47 -0
  36. ledmatrix-0.1.0/src/ledmatrix/transport/serial.py +102 -0
  37. ledmatrix-0.1.0/src/ledmatrix.egg-info/PKG-INFO +287 -0
  38. ledmatrix-0.1.0/src/ledmatrix.egg-info/SOURCES.txt +47 -0
  39. ledmatrix-0.1.0/src/ledmatrix.egg-info/dependency_links.txt +1 -0
  40. ledmatrix-0.1.0/src/ledmatrix.egg-info/entry_points.txt +2 -0
  41. ledmatrix-0.1.0/src/ledmatrix.egg-info/requires.txt +18 -0
  42. ledmatrix-0.1.0/src/ledmatrix.egg-info/top_level.txt +1 -0
  43. ledmatrix-0.1.0/tests/test_canvas.py +116 -0
  44. ledmatrix-0.1.0/tests/test_cli.py +44 -0
  45. ledmatrix-0.1.0/tests/test_device.py +59 -0
  46. ledmatrix-0.1.0/tests/test_dither.py +17 -0
  47. ledmatrix-0.1.0/tests/test_font.py +63 -0
  48. ledmatrix-0.1.0/tests/test_protocol.py +13 -0
  49. ledmatrix-0.1.0/tests/test_scheduler.py +21 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ledmatrix contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ recursive-include src/ledmatrix/font/data *.bdf
2
+ recursive-include src/ledmatrix/data *.rules
@@ -0,0 +1,287 @@
1
+ Metadata-Version: 2.4
2
+ Name: ledmatrix
3
+ Version: 0.1.0
4
+ Summary: A cross-platform Python SDK for the Framework 16 LED Matrix Input Module
5
+ Author: ledmatrix contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jeffthepineapple/ledmatrix
8
+ Project-URL: Documentation, https://github.com/jeffthepineapple/ledmatrix#readme
9
+ Project-URL: Issues, https://github.com/jeffthepineapple/ledmatrix/issues
10
+ Project-URL: Repository, https://github.com/jeffthepineapple/ledmatrix
11
+ Keywords: framework,framework16,led,matrix,serial,hardware
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Classifier: Topic :: System :: Hardware
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: pyserial>=3.5
28
+ Provides-Extra: image
29
+ Requires-Dist: Pillow>=9.0; extra == "image"
30
+ Provides-Extra: array
31
+ Requires-Dist: numpy>=1.21; extra == "array"
32
+ Provides-Extra: dev
33
+ Requires-Dist: build>=1.2; extra == "dev"
34
+ Requires-Dist: pytest>=7.4; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
36
+ Requires-Dist: ruff>=0.6; extra == "dev"
37
+ Requires-Dist: mypy>=1.10; extra == "dev"
38
+ Provides-Extra: all
39
+ Requires-Dist: Pillow>=9.0; extra == "all"
40
+ Requires-Dist: numpy>=1.21; extra == "all"
41
+ Dynamic: license-file
42
+
43
+ # ledmatrix
44
+
45
+ `ledmatrix` is a Python SDK and command-line tool for the Framework 16 LED
46
+ Matrix Input Module. It provides a small drawing API, device discovery, frame
47
+ transport, image/text helpers, frame pacing, and diagnostics that can run with
48
+ or without hardware attached.
49
+
50
+ Current package status: `0.1.0`. The SDK has deterministic tests for protocol
51
+ encoding, canvas operations, fonts, dithering, scheduler behavior, device
52
+ helpers, and CLI behavior. Hardware-in-loop validation is still tracked
53
+ separately because it requires a physical Framework 16 LED Matrix Input Module.
54
+
55
+ ## Features
56
+
57
+ - Canvas drawing for pixels, rectangles, lines, fills, inversion, and packed
58
+ frame output.
59
+ - Device discovery and synchronous or asynchronous device control.
60
+ - CLI commands for listing devices, showing pixels/rectangles/text/images,
61
+ brightness, raw packet inspection, and diagnostics.
62
+ - Optional image and array support through Pillow and NumPy.
63
+ - Font rendering with bundled bitmap fonts.
64
+ - Mock transport for examples, dry runs, and tests without LED hardware.
65
+ - Geometry helpers for the Framework 16 LED Matrix Input Module layout.
66
+
67
+ ## Install
68
+
69
+ Install the base package:
70
+
71
+ ```bash
72
+ pip install ledmatrix
73
+ ```
74
+
75
+ Install optional image and NumPy helpers:
76
+
77
+ ```bash
78
+ pip install "ledmatrix[image]"
79
+ ```
80
+
81
+ Install development tools from a checkout:
82
+
83
+ ```bash
84
+ python -m pip install -e ".[dev,image]"
85
+ ```
86
+
87
+ Linux users may need udev rules before a non-root process can access the input
88
+ module. A packaged rule is included under `src/ledmatrix/data/`.
89
+
90
+ ## Quick Start
91
+
92
+ Create a frame in memory:
93
+
94
+ ```python
95
+ from ledmatrix import Canvas
96
+
97
+ frame = Canvas()
98
+ frame.clear()
99
+ frame.set_pixel(0, 0, 255)
100
+ frame.fill_rect(2, 4, 5, 3, 180)
101
+ frame.draw_line(0, 33, 8, 0, 255)
102
+ ```
103
+
104
+ Send a frame to the first discovered device:
105
+
106
+ ```python
107
+ from ledmatrix import Canvas, open_device
108
+
109
+ canvas = Canvas().clear()
110
+ canvas.fill_rect(1, 8, 7, 4, 200)
111
+
112
+ with open_device() as device:
113
+ device.show_frame(canvas)
114
+ ```
115
+
116
+ Use explicit discovery if you want to choose a device:
117
+
118
+ ```python
119
+ from ledmatrix import list_devices, open_device
120
+
121
+ devices = list_devices()
122
+ if not devices:
123
+ raise SystemExit("No LED Matrix Input Module found")
124
+
125
+ with open_device(devices[0].path) as device:
126
+ print(device.get_device_info())
127
+ ```
128
+
129
+ ## Drawing And Geometry
130
+
131
+ The default geometry is the Framework 16 LED Matrix Input Module: 9 columns by
132
+ 34 rows. Coordinates are zero-based with `(0, 0)` at the top-left of the canvas.
133
+ Pixel values are grayscale integers from `0` to `255`.
134
+
135
+ ```python
136
+ from ledmatrix import Canvas
137
+
138
+ canvas = Canvas()
139
+ canvas.clear()
140
+ canvas.set_pixel(8, 33, 255)
141
+ canvas.fill_rect(x=1, y=8, width=7, height=4, value=160)
142
+ canvas.invert_rect(x=2, y=9, width=2, height=2)
143
+
144
+ payload = canvas.to_bytes()
145
+ ```
146
+
147
+ Additional helpers include `draw_circle`, `draw_triangle`, `ImagePipeline`,
148
+ `normalize_dither`, and `dither`.
149
+
150
+ Per-pixel intensity is controlled by the pixel value in the frame:
151
+
152
+ ```python
153
+ canvas = Canvas().clear()
154
+ canvas.set_pixel(4, 17, 64) # dim pixel
155
+ canvas.set_pixel(5, 17, 255) # full-intensity pixel
156
+ ```
157
+
158
+ Device brightness is separate and applies globally to the module:
159
+
160
+ ```python
161
+ from ledmatrix import open_device
162
+
163
+ with open_device() as device:
164
+ device.set_brightness(50)
165
+ device.show_frame(canvas)
166
+ ```
167
+
168
+ The CLI `pixel` command currently turns a coordinate on; use the Python API when
169
+ you need a specific per-pixel grayscale value.
170
+
171
+ ## Text And Images
172
+
173
+ Text rendering uses bundled bitmap fonts:
174
+
175
+ ```python
176
+ from ledmatrix import Canvas
177
+ from ledmatrix.font import Font
178
+
179
+ canvas = Canvas().clear()
180
+ font = Font.load("3x5")
181
+ font.draw_text(canvas, 0, 0, "Hi")
182
+ ```
183
+
184
+ Image helpers are available when Pillow is installed:
185
+
186
+ ```python
187
+ from PIL import Image
188
+ from ledmatrix import ImagePipeline
189
+
190
+ image = Image.open("icon.png")
191
+ canvas = ImagePipeline(dither="bayer4x4").process(image)
192
+ ```
193
+
194
+ ## Device API
195
+
196
+ The synchronous API is centered on `Device`:
197
+
198
+ ```python
199
+ from ledmatrix import Canvas, Device
200
+
201
+ with Device("/dev/ttyACM0") as device:
202
+ device.set_brightness(50)
203
+ device.show_frame(Canvas().clear().set_pixel(4, 17, 255))
204
+ ```
205
+
206
+ The package also exports `AsyncDevice` for asyncio applications,
207
+ `FrameScheduler` for frame pacing, and exceptions such as
208
+ `DeviceNotFound`, `DeviceDisconnected`, and `ProtocolError`.
209
+
210
+ ## CLI
211
+
212
+ The package installs a `ledmatrix` command:
213
+
214
+ ```bash
215
+ ledmatrix list
216
+ ledmatrix info
217
+ ledmatrix brightness 50
218
+ ledmatrix pixel 4 17
219
+ ledmatrix rect 1 8 7 4
220
+ ledmatrix clear
221
+ ledmatrix text "Hi"
222
+ ledmatrix image icon.png
223
+ ```
224
+
225
+ Diagnostics and hardware-free inspection:
226
+
227
+ ```bash
228
+ ledmatrix pixel 4 17 --dry-run
229
+ ledmatrix rect 1 8 7 4 --dry-run
230
+ ledmatrix raw 0x32 00 --dry-run
231
+ ledmatrix orientation-test
232
+ ledmatrix system
233
+ ```
234
+
235
+ Use `ledmatrix --help` and `ledmatrix <command> --help` for command-specific
236
+ arguments such as device paths, orientation, brightness, and dry-run options.
237
+
238
+ ## Current Validation Status
239
+
240
+ Validated in the repository:
241
+
242
+ - Canvas bounds handling, drawing primitives, and packed frame conversion.
243
+ - Protocol message encoding for SDK commands.
244
+ - Device helper behavior with mock transports.
245
+ - Font loading/rendering and image dithering helpers.
246
+ - CLI command behavior in deterministic tests.
247
+
248
+ Known validation follow-up:
249
+
250
+ - Static analysis cleanup remains for the current checkout. The test suite
251
+ passes, but the virtualenv `mypy src` run reports existing serial-transport
252
+ typing issues.
253
+
254
+ Still requiring real hardware validation:
255
+
256
+ - End-to-end frame display on a physical Framework 16 LED Matrix Input Module.
257
+ - Brightness/power behavior against firmware.
258
+ - Orientation confirmation on the installed module.
259
+ - Host setup notes for platform-specific serial permissions.
260
+
261
+ See `BUILD_REPORT.md` and `docs/IMPLEMENTATION_NOTES.md` for the current
262
+ validation notes.
263
+
264
+ ## Development
265
+
266
+ From a checkout:
267
+
268
+ ```bash
269
+ python -m pip install -e ".[dev,image]"
270
+ python -m pytest
271
+ ruff check src tests examples
272
+ mypy src
273
+ ```
274
+
275
+ Examples are in `examples/`:
276
+
277
+ ```bash
278
+ python examples/mock_demo.py
279
+ python examples/snake_game.py --dry-run
280
+ python examples/snake_game.py --port /dev/ttyACM0
281
+ python examples/draw_primitives.py /dev/ttyACM0
282
+ python examples/text_marquee.py /dev/ttyACM0
283
+ python examples/hardware_smoketest.py /dev/ttyACM0
284
+ ```
285
+
286
+ More detailed API and PyPI-facing documentation is available in `docs/API.md`
287
+ and `docs/PYPI_GUIDE.md`.
@@ -0,0 +1,245 @@
1
+ # ledmatrix
2
+
3
+ `ledmatrix` is a Python SDK and command-line tool for the Framework 16 LED
4
+ Matrix Input Module. It provides a small drawing API, device discovery, frame
5
+ transport, image/text helpers, frame pacing, and diagnostics that can run with
6
+ or without hardware attached.
7
+
8
+ Current package status: `0.1.0`. The SDK has deterministic tests for protocol
9
+ encoding, canvas operations, fonts, dithering, scheduler behavior, device
10
+ helpers, and CLI behavior. Hardware-in-loop validation is still tracked
11
+ separately because it requires a physical Framework 16 LED Matrix Input Module.
12
+
13
+ ## Features
14
+
15
+ - Canvas drawing for pixels, rectangles, lines, fills, inversion, and packed
16
+ frame output.
17
+ - Device discovery and synchronous or asynchronous device control.
18
+ - CLI commands for listing devices, showing pixels/rectangles/text/images,
19
+ brightness, raw packet inspection, and diagnostics.
20
+ - Optional image and array support through Pillow and NumPy.
21
+ - Font rendering with bundled bitmap fonts.
22
+ - Mock transport for examples, dry runs, and tests without LED hardware.
23
+ - Geometry helpers for the Framework 16 LED Matrix Input Module layout.
24
+
25
+ ## Install
26
+
27
+ Install the base package:
28
+
29
+ ```bash
30
+ pip install ledmatrix
31
+ ```
32
+
33
+ Install optional image and NumPy helpers:
34
+
35
+ ```bash
36
+ pip install "ledmatrix[image]"
37
+ ```
38
+
39
+ Install development tools from a checkout:
40
+
41
+ ```bash
42
+ python -m pip install -e ".[dev,image]"
43
+ ```
44
+
45
+ Linux users may need udev rules before a non-root process can access the input
46
+ module. A packaged rule is included under `src/ledmatrix/data/`.
47
+
48
+ ## Quick Start
49
+
50
+ Create a frame in memory:
51
+
52
+ ```python
53
+ from ledmatrix import Canvas
54
+
55
+ frame = Canvas()
56
+ frame.clear()
57
+ frame.set_pixel(0, 0, 255)
58
+ frame.fill_rect(2, 4, 5, 3, 180)
59
+ frame.draw_line(0, 33, 8, 0, 255)
60
+ ```
61
+
62
+ Send a frame to the first discovered device:
63
+
64
+ ```python
65
+ from ledmatrix import Canvas, open_device
66
+
67
+ canvas = Canvas().clear()
68
+ canvas.fill_rect(1, 8, 7, 4, 200)
69
+
70
+ with open_device() as device:
71
+ device.show_frame(canvas)
72
+ ```
73
+
74
+ Use explicit discovery if you want to choose a device:
75
+
76
+ ```python
77
+ from ledmatrix import list_devices, open_device
78
+
79
+ devices = list_devices()
80
+ if not devices:
81
+ raise SystemExit("No LED Matrix Input Module found")
82
+
83
+ with open_device(devices[0].path) as device:
84
+ print(device.get_device_info())
85
+ ```
86
+
87
+ ## Drawing And Geometry
88
+
89
+ The default geometry is the Framework 16 LED Matrix Input Module: 9 columns by
90
+ 34 rows. Coordinates are zero-based with `(0, 0)` at the top-left of the canvas.
91
+ Pixel values are grayscale integers from `0` to `255`.
92
+
93
+ ```python
94
+ from ledmatrix import Canvas
95
+
96
+ canvas = Canvas()
97
+ canvas.clear()
98
+ canvas.set_pixel(8, 33, 255)
99
+ canvas.fill_rect(x=1, y=8, width=7, height=4, value=160)
100
+ canvas.invert_rect(x=2, y=9, width=2, height=2)
101
+
102
+ payload = canvas.to_bytes()
103
+ ```
104
+
105
+ Additional helpers include `draw_circle`, `draw_triangle`, `ImagePipeline`,
106
+ `normalize_dither`, and `dither`.
107
+
108
+ Per-pixel intensity is controlled by the pixel value in the frame:
109
+
110
+ ```python
111
+ canvas = Canvas().clear()
112
+ canvas.set_pixel(4, 17, 64) # dim pixel
113
+ canvas.set_pixel(5, 17, 255) # full-intensity pixel
114
+ ```
115
+
116
+ Device brightness is separate and applies globally to the module:
117
+
118
+ ```python
119
+ from ledmatrix import open_device
120
+
121
+ with open_device() as device:
122
+ device.set_brightness(50)
123
+ device.show_frame(canvas)
124
+ ```
125
+
126
+ The CLI `pixel` command currently turns a coordinate on; use the Python API when
127
+ you need a specific per-pixel grayscale value.
128
+
129
+ ## Text And Images
130
+
131
+ Text rendering uses bundled bitmap fonts:
132
+
133
+ ```python
134
+ from ledmatrix import Canvas
135
+ from ledmatrix.font import Font
136
+
137
+ canvas = Canvas().clear()
138
+ font = Font.load("3x5")
139
+ font.draw_text(canvas, 0, 0, "Hi")
140
+ ```
141
+
142
+ Image helpers are available when Pillow is installed:
143
+
144
+ ```python
145
+ from PIL import Image
146
+ from ledmatrix import ImagePipeline
147
+
148
+ image = Image.open("icon.png")
149
+ canvas = ImagePipeline(dither="bayer4x4").process(image)
150
+ ```
151
+
152
+ ## Device API
153
+
154
+ The synchronous API is centered on `Device`:
155
+
156
+ ```python
157
+ from ledmatrix import Canvas, Device
158
+
159
+ with Device("/dev/ttyACM0") as device:
160
+ device.set_brightness(50)
161
+ device.show_frame(Canvas().clear().set_pixel(4, 17, 255))
162
+ ```
163
+
164
+ The package also exports `AsyncDevice` for asyncio applications,
165
+ `FrameScheduler` for frame pacing, and exceptions such as
166
+ `DeviceNotFound`, `DeviceDisconnected`, and `ProtocolError`.
167
+
168
+ ## CLI
169
+
170
+ The package installs a `ledmatrix` command:
171
+
172
+ ```bash
173
+ ledmatrix list
174
+ ledmatrix info
175
+ ledmatrix brightness 50
176
+ ledmatrix pixel 4 17
177
+ ledmatrix rect 1 8 7 4
178
+ ledmatrix clear
179
+ ledmatrix text "Hi"
180
+ ledmatrix image icon.png
181
+ ```
182
+
183
+ Diagnostics and hardware-free inspection:
184
+
185
+ ```bash
186
+ ledmatrix pixel 4 17 --dry-run
187
+ ledmatrix rect 1 8 7 4 --dry-run
188
+ ledmatrix raw 0x32 00 --dry-run
189
+ ledmatrix orientation-test
190
+ ledmatrix system
191
+ ```
192
+
193
+ Use `ledmatrix --help` and `ledmatrix <command> --help` for command-specific
194
+ arguments such as device paths, orientation, brightness, and dry-run options.
195
+
196
+ ## Current Validation Status
197
+
198
+ Validated in the repository:
199
+
200
+ - Canvas bounds handling, drawing primitives, and packed frame conversion.
201
+ - Protocol message encoding for SDK commands.
202
+ - Device helper behavior with mock transports.
203
+ - Font loading/rendering and image dithering helpers.
204
+ - CLI command behavior in deterministic tests.
205
+
206
+ Known validation follow-up:
207
+
208
+ - Static analysis cleanup remains for the current checkout. The test suite
209
+ passes, but the virtualenv `mypy src` run reports existing serial-transport
210
+ typing issues.
211
+
212
+ Still requiring real hardware validation:
213
+
214
+ - End-to-end frame display on a physical Framework 16 LED Matrix Input Module.
215
+ - Brightness/power behavior against firmware.
216
+ - Orientation confirmation on the installed module.
217
+ - Host setup notes for platform-specific serial permissions.
218
+
219
+ See `BUILD_REPORT.md` and `docs/IMPLEMENTATION_NOTES.md` for the current
220
+ validation notes.
221
+
222
+ ## Development
223
+
224
+ From a checkout:
225
+
226
+ ```bash
227
+ python -m pip install -e ".[dev,image]"
228
+ python -m pytest
229
+ ruff check src tests examples
230
+ mypy src
231
+ ```
232
+
233
+ Examples are in `examples/`:
234
+
235
+ ```bash
236
+ python examples/mock_demo.py
237
+ python examples/snake_game.py --dry-run
238
+ python examples/snake_game.py --port /dev/ttyACM0
239
+ python examples/draw_primitives.py /dev/ttyACM0
240
+ python examples/text_marquee.py /dev/ttyACM0
241
+ python examples/hardware_smoketest.py /dev/ttyACM0
242
+ ```
243
+
244
+ More detailed API and PyPI-facing documentation is available in `docs/API.md`
245
+ and `docs/PYPI_GUIDE.md`.
@@ -0,0 +1,69 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ledmatrix"
7
+ version = "0.1.0"
8
+ description = "A cross-platform Python SDK for the Framework 16 LED Matrix Input Module"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [{name = "ledmatrix contributors"}]
13
+ keywords = ["framework", "framework16", "led", "matrix", "serial", "hardware"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3 :: Only",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Software Development :: Libraries",
26
+ "Topic :: System :: Hardware",
27
+ ]
28
+ dependencies = ["pyserial>=3.5"]
29
+
30
+ [project.optional-dependencies]
31
+ image = ["Pillow>=9.0"]
32
+ array = ["numpy>=1.21"]
33
+ dev = ["build>=1.2", "pytest>=7.4", "pytest-cov>=4.1", "ruff>=0.6", "mypy>=1.10"]
34
+ all = ["Pillow>=9.0", "numpy>=1.21"]
35
+
36
+ [project.scripts]
37
+ ledmatrix = "ledmatrix.cli.main:main"
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/jeffthepineapple/ledmatrix"
41
+ Documentation = "https://github.com/jeffthepineapple/ledmatrix#readme"
42
+ Issues = "https://github.com/jeffthepineapple/ledmatrix/issues"
43
+ Repository = "https://github.com/jeffthepineapple/ledmatrix"
44
+
45
+ [tool.setuptools]
46
+ package-dir = {"" = "src"}
47
+ include-package-data = true
48
+
49
+ [tool.setuptools.packages.find]
50
+ where = ["src"]
51
+
52
+ [tool.setuptools.package-data]
53
+ ledmatrix = ["font/data/*.bdf", "data/*.rules"]
54
+
55
+ [tool.pytest.ini_options]
56
+ addopts = "-q"
57
+ testpaths = ["tests"]
58
+
59
+ [tool.ruff]
60
+ line-length = 100
61
+ target-version = "py39"
62
+
63
+ [tool.ruff.lint]
64
+ select = ["E", "F", "I", "B", "UP"]
65
+
66
+ [tool.mypy]
67
+ python_version = "3.9"
68
+ strict = true
69
+ warn_unused_ignores = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,33 @@
1
+ """Framework 16 LED Matrix SDK."""
2
+ from .async_device import AsyncDevice
3
+ from .canvas import Canvas
4
+ from .device import Device, DeviceDetails, DeviceInfo, list_devices, open_device
5
+ from .dither import dither
6
+ from .exceptions import (
7
+ DeviceDisconnected,
8
+ DeviceError,
9
+ DeviceNotFound,
10
+ DeviceStalled,
11
+ ImageDependencyError,
12
+ LedMatrixError,
13
+ ProtocolError,
14
+ TransportError,
15
+ TransportUnavailable,
16
+ UnsupportedCapability,
17
+ )
18
+ from .geometry import FW16_LED_MATRIX, MatrixGeometry, PackingOrder
19
+ from .font import Font, draw_text_scrolling
20
+ from .hotplug import DeviceWatcher
21
+ from .image import ImagePipeline
22
+ from .protocol import Command, DeviceCapabilities, FirmwareVersion, Pattern
23
+ from .scheduler import FrameScheduler
24
+
25
+ __version__ = "0.1.0"
26
+
27
+ __all__ = [
28
+ "AsyncDevice", "Canvas", "Command", "Device", "DeviceCapabilities", "DeviceDetails", "DeviceDisconnected",
29
+ "DeviceError", "DeviceInfo", "DeviceNotFound", "DeviceStalled", "DeviceWatcher", "FW16_LED_MATRIX",
30
+ "FirmwareVersion", "Font", "FrameScheduler", "ImageDependencyError", "ImagePipeline", "LedMatrixError",
31
+ "MatrixGeometry", "PackingOrder", "Pattern", "ProtocolError", "TransportError", "TransportUnavailable",
32
+ "UnsupportedCapability", "__version__", "dither", "draw_text_scrolling", "list_devices", "open_device",
33
+ ]