From 84a88f45f0a1704255ae1e658204a4d9d42d63b2 Mon Sep 17 00:00:00 2001 From: Samuel Abels Date: Sat, 17 Oct 2026 09:57:17 +0000 Subject: [PATCH 1/4] Restore raw machine communication in the Console (Show verbose) Since the GRBL protocol stack moved into the raydriver Rust session, raw lines no longer reached the Python logging pipeline, so the console's 'Show verbose' switch had nothing to display (besides high-level state changes). raydriver 0.4.0 now reports each complete line via raw_rx/raw_tx session events; the driver logs them with the same categories the old Python driver used: STATUS_POLL for status reports, MACHINE_RESPONSE for ok/error acknowledgements, MACHINE_EVENT for other incoming lines, and RAW_IO for outgoing commands. Bumps the raydriver requirement to ==0.4.0. Closes #573 --- pixi.toml | 2 +- rayforge/machine/driver/grbl/grbl_serial.py | 19 ++++++++ .../driver/grbl/test_grbl_serial_driver.py | 43 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/pixi.toml b/pixi.toml index c06d8149f..c14a778f0 100644 --- a/pixi.toml +++ b/pixi.toml @@ -39,7 +39,7 @@ patchelf = "==0.19.2" [feature.app.pypi-dependencies] raygeo = "==1.66.0" -raydriver = "==0.3.0" +raydriver = "==0.4.0" rayforge = { editable = true, path = "." } ruida-pa = "==0.22.0" aiohttp = "==3.14.5" diff --git a/rayforge/machine/driver/grbl/grbl_serial.py b/rayforge/machine/driver/grbl/grbl_serial.py index 1b97fc8ee..4a5ec454d 100644 --- a/rayforge/machine/driver/grbl/grbl_serial.py +++ b/rayforge/machine/driver/grbl/grbl_serial.py @@ -306,9 +306,28 @@ def _on_session_event(self, name: str, payload: Any) -> None: key, value = payload self.config[key] = value self.config_changed.send(self) + elif name == "raw_rx": + self._log_raw_line(payload, received=True) + elif name == "raw_tx": + self._log_raw_line(payload, received=False) else: # pragma: no cover - unknown events are ignored logger.debug(f"Ignoring session event: {name}") + def _log_raw_line(self, line: str, received: bool) -> None: + """Log a raw line from the session's communication so the + console (with 'Show verbose' enabled) shows the full + conversation with the device.""" + if received: + if line.startswith("<") and line.endswith(">"): + category = "STATUS_POLL" + elif line == "ok" or line.startswith("error:"): + category = "MACHINE_RESPONSE" + else: + category = "MACHINE_EVENT" + else: + category = "RAW_IO" + logger.info(line, extra=self._log_extra(category)) + async def cleanup(self): logger.debug("Cleanup initiated.") if self._session is not None: diff --git a/tests/machine/driver/grbl/test_grbl_serial_driver.py b/tests/machine/driver/grbl/test_grbl_serial_driver.py index 8fbfd9868..b5251d30e 100644 --- a/tests/machine/driver/grbl/test_grbl_serial_driver.py +++ b/tests/machine/driver/grbl/test_grbl_serial_driver.py @@ -1,6 +1,7 @@ """Tests for the Rust-backed GrblSerialDriver.""" import asyncio +import logging import time import pytest @@ -421,6 +422,48 @@ async def job(): assert b"M5\n" in sent +@pytest.mark.asyncio +class TestRawLogging: + async def test_settings_reply_is_logged(self, connected_driver, caplog): + drv, _mock, _emulator, _recorder = connected_driver + with caplog.at_level( + logging.INFO, + logger="rayforge.machine.driver.grbl.grbl_serial", + ): + await drv._require_session().execute_interactive_command("$$") + messages = [record.getMessage() for record in caplog.records] + assert any(message.startswith("$") for message in messages) + assert "ok" in messages + + async def test_outgoing_command_is_logged(self, connected_driver, caplog): + drv, _mock, _emulator, _recorder = connected_driver + with caplog.at_level( + logging.INFO, + logger="rayforge.machine.driver.grbl.grbl_serial", + ): + await drv._require_session().execute_interactive_command("$$") + assert any( + record.getMessage() == "$$" + and record.__dict__.get("log_category") == "RAW_IO" + for record in caplog.records + ) + + async def test_status_reports_are_logged(self, connected_driver, caplog): + _drv, _mock, _emulator, _recorder = connected_driver + with caplog.at_level( + logging.INFO, + logger="rayforge.machine.driver.grbl.grbl_serial", + ): + + def has_status_report(): + return any( + record.__dict__.get("log_category") == "STATUS_POLL" + for record in caplog.records + ) + + await wait_until(has_status_report) + + def _slow_job(n_lines: int) -> str: """Long alternating moves that keep the planner busy.""" return "\n".join(f"G1 X{50 if i % 2 else 0} F600" for i in range(n_lines)) From b4aef4434d82be104e846bcd3c7fb859bcb28a5c Mon Sep 17 00:00:00 2001 From: Samuel Abels Date: Sat, 17 Oct 2026 13:23:19 +0200 Subject: [PATCH 2/4] refactor: consume typed raydriver session events raydriver 0.5.0 delivers a typed SessionEvent to the driver's event callback instead of (name, payload) string tuples, so _on_session_event now matches on the event variants; each former branch became a small named handler. The callback is annotated as a union of the stub's variant classes with assert_never in the fall-through, so an event added on the Rust side fails the type check here until it is handled. Also regenerates pixi.lock (raydriver 0.3.0 -> 0.4.0) and syncs requirements.txt and debian/requirements-bundle.txt with the pixi.toml pin; both were left at 0.3.0. Requires the raydriver typed-events change (barebaric/raydriver#5); the pin and lockfile move to 0.5.0 once it is released. --- debian/requirements-bundle.txt | 2 +- pixi.lock | 46 ++++---- rayforge/machine/driver/grbl/grbl_serial.py | 118 ++++++++++++-------- requirements.txt | 2 +- 4 files changed, 98 insertions(+), 70 deletions(-) diff --git a/debian/requirements-bundle.txt b/debian/requirements-bundle.txt index 4a37351fd..ea76bd326 100644 --- a/debian/requirements-bundle.txt +++ b/debian/requirements-bundle.txt @@ -1,6 +1,6 @@ asyncudp==0.11.0 pyvips==3.2.0 -raydriver==0.3.0 +raydriver==0.4.0 raygeo==1.66.0 ruida-pa==0.22.0 trimesh==5.1.1 diff --git a/pixi.lock b/pixi.lock index 467bf6e67..5910e51b8 100644 --- a/pixi.lock +++ b/pixi.lock @@ -243,6 +243,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/13/d4/1152d1c7ab42d8b908be64fd200ddc870dc9d4925e951198702084aa1a7d/linkify_it_py-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/17/fe/77f4a24264e728fd95542e53f026a91249b51d1611087b8c82d3a033ea97/asyncudp-0.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/42/a945f65cc61c739ec80f4112c4b78ed1791f25d33f45f19389c9c9e247e2/pypdf-6.20.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/29/aa/2b759dae05e1f1c992b90dc8e82b851753dbd0bcdc927ead377d2c6ec207/raydriver-0.4.0.tar.gz - pypi: https://files.pythonhosted.org/packages/38/bb/d215ee7c73b61497b28a5503f9f53523f294fcc936762b7caf90e0c1c2b5/pyparsing-3.3.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/99/2e119d541d596daea39643eb9312b47c7847383951300f889166938035b1/rpyc-6.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/51/8041c2e70649e5b7f2a0aedbbbd0609ac099cfaa0cbde2014279c9c05756/cairosvg-2.9.1-py3-none-any.whl @@ -263,7 +264,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/8d/15/1633010b26e88e872c93b67c0b6c5e174fb74cb6fb5c1472b4d51d4a8f22/platformdirs-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/f6/fb68b8c08f864ecee8f7f7ee2f1203ed5cba2335215de69e4f621eb47db5/trimesh-5.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/11/0e6f11117525ff0eec40ebac3d313376f102df93ca44ad9e893ee85e4f89/pycparser-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/cd/11159bcba680ac5f16e48443206d278768f464cc42fe4bfeb169c33db7b6/raydriver-0.3.0.tar.gz - pypi: https://files.pythonhosted.org/packages/93/d8/ba13451aa6b745c49536e87b6bf8f629b950e84bd0e8308f7dc6883b67e2/cairocffi-1.7.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9a/8e/cde07147b6fc56b9ae0fe01d9c0bebd730b2be2c3052d3a5a117e13f561e/multidict-7.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl @@ -471,6 +471,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/80/3a286bd33f82e55c03ab984c934b88f2696932b80b04faf8fea6c0e9e730/raydriver-0.4.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl @@ -514,7 +515,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/be/02/bce7a1d70e9d0f6ea8623c16386138c251b5855af6cd3a11433d3fba4e66/semver-3.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c5/0a/1423bb61b5f06376fe6ccf79c8781e2bb5e36c78c1814c78913b7425950f/bokeh-3.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/c3/0bebaaec98aa7cb43e04a8a6079b4aecb83338f6b4b3a32eb837c4c484ea/raydriver-0.3.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/d1/89/5d4c86da1130d9059681e5b6cd7645df5c10279a6a079c5c37dcb2cc6f3f/narwhals-2.27.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl @@ -919,6 +919,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/17/fe/77f4a24264e728fd95542e53f026a91249b51d1611087b8c82d3a033ea97/asyncudp-0.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/42/a945f65cc61c739ec80f4112c4b78ed1791f25d33f45f19389c9c9e247e2/pypdf-6.20.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/29/aa/2b759dae05e1f1c992b90dc8e82b851753dbd0bcdc927ead377d2c6ec207/raydriver-0.4.0.tar.gz - pypi: https://files.pythonhosted.org/packages/2c/3c/4a01195d93420cad1175bedad13a515dc8a56f95a6e39789b92e582682f5/ruff-0.17.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/38/bb/d215ee7c73b61497b28a5503f9f53523f294fcc936762b7caf90e0c1c2b5/pyparsing-3.3.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/99/2e119d541d596daea39643eb9312b47c7847383951300f889166938035b1/rpyc-6.0.2-py3-none-any.whl @@ -947,7 +948,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/8d/15/1633010b26e88e872c93b67c0b6c5e174fb74cb6fb5c1472b4d51d4a8f22/platformdirs-4.13.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/f6/fb68b8c08f864ecee8f7f7ee2f1203ed5cba2335215de69e4f621eb47db5/trimesh-5.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/90/11/0e6f11117525ff0eec40ebac3d313376f102df93ca44ad9e893ee85e4f89/pycparser-3.11-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/93/cd/11159bcba680ac5f16e48443206d278768f464cc42fe4bfeb169c33db7b6/raydriver-0.3.0.tar.gz - pypi: https://files.pythonhosted.org/packages/93/d8/ba13451aa6b745c49536e87b6bf8f629b950e84bd0e8308f7dc6883b67e2/cairocffi-1.7.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/9a/8e/cde07147b6fc56b9ae0fe01d9c0bebd730b2be2c3052d3a5a117e13f561e/multidict-7.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl @@ -1173,6 +1173,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/80/3a286bd33f82e55c03ab984c934b88f2696932b80b04faf8fea6c0e9e730/raydriver-0.4.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl @@ -1228,7 +1229,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/be/02/bce7a1d70e9d0f6ea8623c16386138c251b5855af6cd3a11433d3fba4e66/semver-3.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c5/0a/1423bb61b5f06376fe6ccf79c8781e2bb5e36c78c1814c78913b7425950f/bokeh-3.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c8/c3/0bebaaec98aa7cb43e04a8a6079b4aecb83338f6b4b3a32eb837c4c484ea/raydriver-0.3.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/d1/89/5d4c86da1130d9059681e5b6cd7645df5c10279a6a079c5c37dcb2cc6f3f/narwhals-2.27.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/8b/f837f52905395ba4510fe61f753c24833fb0a9c76e21267bb9f828b664a9/filelock-4.1.1-py3-none-any.whl @@ -9493,7 +9493,7 @@ packages: - pypi: ./ name: rayforge requires_dist: - - raydriver==0.3.0 + - raydriver==0.4.0 - raygeo==1.66.0 - aiohttp==3.14.5 - asyncudp==0.11.0 @@ -9591,6 +9591,15 @@ packages: sha256: c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0 requires_dist: - hidapi ; extra == 'cp2110' +- pypi: https://files.pythonhosted.org/packages/0a/80/3a286bd33f82e55c03ab984c934b88f2696932b80b04faf8fea6c0e9e730/raydriver-0.4.0-cp311-abi3-macosx_11_0_arm64.whl + name: raydriver + version: 0.4.0 + sha256: 79e9e1932c0d7048f7ab47653e6426efe32f24e4e3086846ea6929d65693de2e + requires_dist: + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-timeout ; extra == 'test' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl name: cffi version: 2.1.1 @@ -9696,6 +9705,15 @@ packages: - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/29/aa/2b759dae05e1f1c992b90dc8e82b851753dbd0bcdc927ead377d2c6ec207/raydriver-0.4.0.tar.gz + name: raydriver + version: 0.4.0 + sha256: 450011e7110ffa46fdbbed993830d9a1366457009352a9f4eb674ca03ca0e07f + requires_dist: + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-timeout ; extra == 'test' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/2c/3c/4a01195d93420cad1175bedad13a515dc8a56f95a6e39789b92e582682f5/ruff-0.17.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: ruff version: 0.17.0 @@ -9998,15 +10016,6 @@ packages: version: '3.11' sha256: 51d5a8ba2be0bbe440b99d2112604c95bbbc3c2748a64260186c541e1729cd80 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/93/cd/11159bcba680ac5f16e48443206d278768f464cc42fe4bfeb169c33db7b6/raydriver-0.3.0.tar.gz - name: raydriver - version: 0.3.0 - sha256: e7ad8d69e135fb84fb1e01275ac815c59afd192dcc94ca9b65c5f5ab568f2f57 - requires_dist: - - pytest ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-timeout ; extra == 'test' - requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/93/d8/ba13451aa6b745c49536e87b6bf8f629b950e84bd0e8308f7dc6883b67e2/cairocffi-1.7.1-py3-none-any.whl name: cairocffi version: 1.7.1 @@ -10286,15 +10295,6 @@ packages: requires_dist: - ifaddr>=0.1.7 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/c8/c3/0bebaaec98aa7cb43e04a8a6079b4aecb83338f6b4b3a32eb837c4c484ea/raydriver-0.3.0-cp311-abi3-macosx_11_0_arm64.whl - name: raydriver - version: 0.3.0 - sha256: 52f183fd7f6b90bb81d8d84a253da51e4d0a146b6ca9fd4ff6e6b90f4cb7d2cf - requires_dist: - - pytest ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-timeout ; extra == 'test' - requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl name: tornado version: 6.5.10 diff --git a/rayforge/machine/driver/grbl/grbl_serial.py b/rayforge/machine/driver/grbl/grbl_serial.py index 4a5ec454d..fd475cb0c 100644 --- a/rayforge/machine/driver/grbl/grbl_serial.py +++ b/rayforge/machine/driver/grbl/grbl_serial.py @@ -5,11 +5,12 @@ from typing import ( TYPE_CHECKING, Any, + assert_never, cast, ) import serial -from raydriver.grbl import GrblSession +from raydriver.grbl import GrblSession, SessionEvent from raydriver.grbl.parser import ( error_code_to_device_error, extract_device_name_from_output, @@ -54,6 +55,7 @@ ) if TYPE_CHECKING: + from raydriver.grbl.types import DeviceState as SessionDeviceState from raygeo.ops import Ops from ....core.doc import Doc @@ -63,6 +65,18 @@ logger = logging.getLogger(__name__) +AnySessionEvent = ( + SessionEvent.StateChanged + | SessionEvent.ConnectionStatusChanged + | SessionEvent.CommandStatusChanged + | SessionEvent.JobFinished + | SessionEvent.ProbeStatusChanged + | SessionEvent.WcsUpdated + | SessionEvent.ConfigChanged + | SessionEvent.RawRx + | SessionEvent.RawTx +) + class GrblSerialDriver(Driver): """ @@ -265,53 +279,67 @@ def _setup_implementation(self, **kwargs: Any) -> None: event_callback=self._on_session_event, ) - def _on_session_event(self, name: str, payload: Any) -> None: + def _on_session_event(self, event: AnySessionEvent) -> None: """Re-emit Rust session events as Rayforge blinker signals.""" - if name == "state_changed": - state = from_session_state(payload) - old_status = self.state.status - self.state = state - if state.status != old_status: - logger.info( - f"Device state changed: {state.status.name}", - extra=self._log_extra("STATE_CHANGE"), - ) - self.state_changed.send(self, state=state) - elif name == "connection_status_changed": - status_str, message = payload + match event: + case SessionEvent.StateChanged(): + self._on_state_changed(event.state) + case SessionEvent.ConnectionStatusChanged(): + self._on_connection_status_changed(event.status, event.message) + case SessionEvent.CommandStatusChanged(): + self._on_command_status_changed(event.status, event.message) + case SessionEvent.JobFinished(): + self.job_finished.send(self) + case SessionEvent.ProbeStatusChanged(): + self.probe_status_changed.send(self, message=event.message) + case SessionEvent.WcsUpdated(): + self.wcs_updated.send(self, offsets=event.offsets) + case SessionEvent.ConfigChanged(): + self._on_config_changed(event.key, event.value) + case SessionEvent.RawRx(): + self._log_raw_line(event.line, received=True) + case SessionEvent.RawTx(): + self._log_raw_line(event.line, received=False) + case _: + assert_never(event) + + def _on_state_changed(self, session_state: "SessionDeviceState") -> None: + state = from_session_state(session_state) + old_status = self.state.status + self.state = state + if state.status != old_status: logger.info( - f"Connection status: {status_str}" - + (f" - {message}" if message else ""), - extra=self._log_extra("MACHINE_EVENT"), + f"Device state changed: {state.status.name}", + extra=self._log_extra("STATE_CHANGE"), ) - self.connection_status_changed.send( - self, - status=TransportStatus[status_str], - message=message, - ) - elif name == "command_status_changed": - status_str, message = payload - self.command_status_changed.send( - self, - status=TransportStatus[status_str], - message=message, - ) - elif name == "job_finished": - self.job_finished.send(self) - elif name == "probe_status_changed": - self.probe_status_changed.send(self, message=payload) - elif name == "wcs_updated": - self.wcs_updated.send(self, offsets=payload) - elif name == "config_changed": - key, value = payload - self.config[key] = value - self.config_changed.send(self) - elif name == "raw_rx": - self._log_raw_line(payload, received=True) - elif name == "raw_tx": - self._log_raw_line(payload, received=False) - else: # pragma: no cover - unknown events are ignored - logger.debug(f"Ignoring session event: {name}") + self.state_changed.send(self, state=state) + + def _on_connection_status_changed( + self, status_str: str, message: str | None + ) -> None: + logger.info( + f"Connection status: {status_str}" + + (f" - {message}" if message else ""), + extra=self._log_extra("MACHINE_EVENT"), + ) + self.connection_status_changed.send( + self, + status=TransportStatus[status_str], + message=message, + ) + + def _on_command_status_changed( + self, status_str: str, message: str | None + ) -> None: + self.command_status_changed.send( + self, + status=TransportStatus[status_str], + message=message, + ) + + def _on_config_changed(self, key: str, value: int) -> None: + self.config[key] = value + self.config_changed.send(self) def _log_raw_line(self, line: str, received: bool) -> None: """Log a raw line from the session's communication so the diff --git a/requirements.txt b/requirements.txt index 779acbc2a..835da6b52 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -raydriver==0.3.0 +raydriver==0.4.0 raygeo==1.66.0 aiohttp==3.14.5 asyncudp==0.11.0 From 103c9c63dcf19daf56b9163289d9ed129eda31ff Mon Sep 17 00:00:00 2001 From: Samuel Abels Date: Sat, 17 Oct 2026 13:56:24 +0200 Subject: [PATCH 3/4] Bump raydriver to 0.5.0 Raydriver 0.5.0 delivers the typed SessionEvent consumed by the driver's event callback. Relocks pixi.lock and syncs the requirement files with the pin. --- debian/requirements-bundle.txt | 2 +- pixi.lock | 34 +++++++++++++++++----------------- pixi.toml | 2 +- requirements.txt | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/debian/requirements-bundle.txt b/debian/requirements-bundle.txt index ea76bd326..c5a49dbba 100644 --- a/debian/requirements-bundle.txt +++ b/debian/requirements-bundle.txt @@ -1,6 +1,6 @@ asyncudp==0.11.0 pyvips==3.2.0 -raydriver==0.4.0 +raydriver==0.5.0 raygeo==1.66.0 ruida-pa==0.22.0 trimesh==5.1.1 diff --git a/pixi.lock b/pixi.lock index 5910e51b8..5c9a6f483 100644 --- a/pixi.lock +++ b/pixi.lock @@ -239,11 +239,11 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/97/a6f94b0ab3e1dc61a4d7652fcbd231a3a3753e1e0616e4e2a0207ec240c9/raydriver-0.5.0.tar.gz - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/d4/1152d1c7ab42d8b908be64fd200ddc870dc9d4925e951198702084aa1a7d/linkify_it_py-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/17/fe/77f4a24264e728fd95542e53f026a91249b51d1611087b8c82d3a033ea97/asyncudp-0.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/42/a945f65cc61c739ec80f4112c4b78ed1791f25d33f45f19389c9c9e247e2/pypdf-6.20.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/29/aa/2b759dae05e1f1c992b90dc8e82b851753dbd0bcdc927ead377d2c6ec207/raydriver-0.4.0.tar.gz - pypi: https://files.pythonhosted.org/packages/38/bb/d215ee7c73b61497b28a5503f9f53523f294fcc936762b7caf90e0c1c2b5/pyparsing-3.3.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/99/2e119d541d596daea39643eb9312b47c7847383951300f889166938035b1/rpyc-6.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/41/51/8041c2e70649e5b7f2a0aedbbbd0609ac099cfaa0cbde2014279c9c05756/cairosvg-2.9.1-py3-none-any.whl @@ -471,7 +471,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/80/3a286bd33f82e55c03ab984c934b88f2696932b80b04faf8fea6c0e9e730/raydriver-0.4.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl @@ -515,6 +514,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/be/02/bce7a1d70e9d0f6ea8623c16386138c251b5855af6cd3a11433d3fba4e66/semver-3.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c5/0a/1423bb61b5f06376fe6ccf79c8781e2bb5e36c78c1814c78913b7425950f/bokeh-3.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a1/b285a8eb89406bb93c113afb4a21ac20ebe6de69c08c4a07edf241cfb6f8/raydriver-0.5.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/d1/89/5d4c86da1130d9059681e5b6cd7645df5c10279a6a079c5c37dcb2cc6f3f/narwhals-2.27.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl @@ -914,12 +914,12 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0a/97/a6f94b0ab3e1dc61a4d7652fcbd231a3a3753e1e0616e4e2a0207ec240c9/raydriver-0.5.0.tar.gz - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/d4/1152d1c7ab42d8b908be64fd200ddc870dc9d4925e951198702084aa1a7d/linkify_it_py-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/17/fe/77f4a24264e728fd95542e53f026a91249b51d1611087b8c82d3a033ea97/asyncudp-0.11.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/42/a945f65cc61c739ec80f4112c4b78ed1791f25d33f45f19389c9c9e247e2/pypdf-6.20.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/29/aa/2b759dae05e1f1c992b90dc8e82b851753dbd0bcdc927ead377d2c6ec207/raydriver-0.4.0.tar.gz - pypi: https://files.pythonhosted.org/packages/2c/3c/4a01195d93420cad1175bedad13a515dc8a56f95a6e39789b92e582682f5/ruff-0.17.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/38/bb/d215ee7c73b61497b28a5503f9f53523f294fcc936762b7caf90e0c1c2b5/pyparsing-3.3.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/99/2e119d541d596daea39643eb9312b47c7847383951300f889166938035b1/rpyc-6.0.2-py3-none-any.whl @@ -1173,7 +1173,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/80/3a286bd33f82e55c03ab984c934b88f2696932b80b04faf8fea6c0e9e730/raydriver-0.4.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl @@ -1229,6 +1228,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/be/02/bce7a1d70e9d0f6ea8623c16386138c251b5855af6cd3a11433d3fba4e66/semver-3.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c5/0a/1423bb61b5f06376fe6ccf79c8781e2bb5e36c78c1814c78913b7425950f/bokeh-3.10.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/a1/b285a8eb89406bb93c113afb4a21ac20ebe6de69c08c4a07edf241cfb6f8/raydriver-0.5.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/d1/89/5d4c86da1130d9059681e5b6cd7645df5c10279a6a079c5c37dcb2cc6f3f/narwhals-2.27.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/8b/f837f52905395ba4510fe61f753c24833fb0a9c76e21267bb9f828b664a9/filelock-4.1.1-py3-none-any.whl @@ -9493,7 +9493,7 @@ packages: - pypi: ./ name: rayforge requires_dist: - - raydriver==0.4.0 + - raydriver==0.5.0 - raygeo==1.66.0 - aiohttp==3.14.5 - asyncudp==0.11.0 @@ -9591,10 +9591,10 @@ packages: sha256: c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0 requires_dist: - hidapi ; extra == 'cp2110' -- pypi: https://files.pythonhosted.org/packages/0a/80/3a286bd33f82e55c03ab984c934b88f2696932b80b04faf8fea6c0e9e730/raydriver-0.4.0-cp311-abi3-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/0a/97/a6f94b0ab3e1dc61a4d7652fcbd231a3a3753e1e0616e4e2a0207ec240c9/raydriver-0.5.0.tar.gz name: raydriver - version: 0.4.0 - sha256: 79e9e1932c0d7048f7ab47653e6426efe32f24e4e3086846ea6929d65693de2e + version: 0.5.0 + sha256: 1176aff89fe97230a2565e987cbcaf63dddd0ee4e997f5ecd8103e0752aa9b4c requires_dist: - pytest ; extra == 'test' - pytest-asyncio ; extra == 'test' @@ -9705,15 +9705,6 @@ packages: - brotlicffi>=1.2 ; platform_python_implementation != 'CPython' and extra == 'speedups' - backports-zstd ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and sys_platform != 'android' and sys_platform != 'ios' and extra == 'speedups' requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/29/aa/2b759dae05e1f1c992b90dc8e82b851753dbd0bcdc927ead377d2c6ec207/raydriver-0.4.0.tar.gz - name: raydriver - version: 0.4.0 - sha256: 450011e7110ffa46fdbbed993830d9a1366457009352a9f4eb674ca03ca0e07f - requires_dist: - - pytest ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-timeout ; extra == 'test' - requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/2c/3c/4a01195d93420cad1175bedad13a515dc8a56f95a6e39789b92e582682f5/ruff-0.17.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl name: ruff version: 0.17.0 @@ -10295,6 +10286,15 @@ packages: requires_dist: - ifaddr>=0.1.7 requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/cb/a1/b285a8eb89406bb93c113afb4a21ac20ebe6de69c08c4a07edf241cfb6f8/raydriver-0.5.0-cp311-abi3-macosx_11_0_arm64.whl + name: raydriver + version: 0.5.0 + sha256: 601697e2c3fed3faaa43a211daf7ec41f2acf1bb6bc2f05a312199ebbf6c309f + requires_dist: + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-timeout ; extra == 'test' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl name: tornado version: 6.5.10 diff --git a/pixi.toml b/pixi.toml index c14a778f0..328cb370c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -39,7 +39,7 @@ patchelf = "==0.19.2" [feature.app.pypi-dependencies] raygeo = "==1.66.0" -raydriver = "==0.4.0" +raydriver = "==0.5.0" rayforge = { editable = true, path = "." } ruida-pa = "==0.22.0" aiohttp = "==3.14.5" diff --git a/requirements.txt b/requirements.txt index 835da6b52..439db4f81 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -raydriver==0.4.0 +raydriver==0.5.0 raygeo==1.66.0 aiohttp==3.14.5 asyncudp==0.11.0 From cb3bea7ce3dcfefeedd2e6b0537b368069c06c66 Mon Sep 17 00:00:00 2001 From: Samuel Abels Date: Sat, 17 Oct 2026 15:01:37 +0200 Subject: [PATCH 4/4] Type the session event callback, drop the duplicated event union Raydriver 0.5.1 types event_callback as Callable[[SessionEvent], Any] in its stubs, so _on_session_event takes the SessionEvent directly and the hand-written union of all variant classes is no longer needed; unknown events fall through to the debug log. Bumps raydriver to 0.5.1, relcoks pixi.lock and syncs the requirement files with the pin. --- debian/requirements-bundle.txt | 2 +- pixi.lock | 46 ++++++++++----------- pixi.toml | 2 +- rayforge/machine/driver/grbl/grbl_serial.py | 17 +------- requirements.txt | 2 +- 5 files changed, 28 insertions(+), 41 deletions(-) diff --git a/debian/requirements-bundle.txt b/debian/requirements-bundle.txt index c5a49dbba..6068ed7a6 100644 --- a/debian/requirements-bundle.txt +++ b/debian/requirements-bundle.txt @@ -1,6 +1,6 @@ asyncudp==0.11.0 pyvips==3.2.0 -raydriver==0.5.0 +raydriver==0.5.1 raygeo==1.66.0 ruida-pa==0.22.0 trimesh==5.1.1 diff --git a/pixi.lock b/pixi.lock index 5c9a6f483..b89d44d46 100644 --- a/pixi.lock +++ b/pixi.lock @@ -239,7 +239,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/97/a6f94b0ab3e1dc61a4d7652fcbd231a3a3753e1e0616e4e2a0207ec240c9/raydriver-0.5.0.tar.gz - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/d4/1152d1c7ab42d8b908be64fd200ddc870dc9d4925e951198702084aa1a7d/linkify_it_py-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/17/fe/77f4a24264e728fd95542e53f026a91249b51d1611087b8c82d3a033ea97/asyncudp-0.11.0-py3-none-any.whl @@ -291,6 +290,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/df/f3/90993aab504fa2e1f28fcc09aa16b6ea4f00e75a037d9136e737855833e2/pyvips-3.2.0.tar.gz - pypi: https://files.pythonhosted.org/packages/e4/62/c3c23511ebe3d76dc679db0bb045dfd20ed3452bec12dcbbe8d655498a7d/vtracer-0.6.15.tar.gz - pypi: https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fa/06/6ab120a209276d8dced861ee11434ae2732ae70f8604df9b26c8ee3120d9/raydriver-0.5.1.tar.gz - pypi: https://files.pythonhosted.org/packages/fa/48/f36d233ce749d1bb880cb5e6f8bb171dc2effabc7435c31da604d831b3ec/gitpython-3.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/be/35261223d9416a0751cdff1c7b4a6f881387218a12d439fe22fefebc8c04/textual-8.2.8-py3-none-any.whl @@ -503,6 +503,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a5/1a/ad561f99f90884089e6403b76c220610809429ba868a81a2e7ce115d32e0/propcache-0.5.4-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a5/f4/efe06066f1f15711cc51720faae0e4b838625ce62e8f0833f9f1476aeecf/raydriver-0.5.1-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a8/67/7094dfc74bd9b7263a71a1a5706965750600d7cf740795ce123860986206/zeroconf-0.151.5-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a8/71/9219fe65ef32bddc0b5d14e1d98dfefe9d2c9c1b1d1e93efca1f29fcbd4d/xyzservices-2026.9.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ad/9b/9fb3585dabcd73a1b2a6267f63f62649347c9e6d072c9fde365b105abb2c/build-1.6.1-py3-none-any.whl @@ -514,7 +515,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/be/02/bce7a1d70e9d0f6ea8623c16386138c251b5855af6cd3a11433d3fba4e66/semver-3.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c5/0a/1423bb61b5f06376fe6ccf79c8781e2bb5e36c78c1814c78913b7425950f/bokeh-3.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/a1/b285a8eb89406bb93c113afb4a21ac20ebe6de69c08c4a07edf241cfb6f8/raydriver-0.5.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/d1/89/5d4c86da1130d9059681e5b6cd7645df5c10279a6a079c5c37dcb2cc6f3f/narwhals-2.27.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl @@ -914,7 +914,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz - pypi: https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0a/97/a6f94b0ab3e1dc61a4d7652fcbd231a3a3753e1e0616e4e2a0207ec240c9/raydriver-0.5.0.tar.gz - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/d4/1152d1c7ab42d8b908be64fd200ddc870dc9d4925e951198702084aa1a7d/linkify_it_py-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/17/fe/77f4a24264e728fd95542e53f026a91249b51d1611087b8c82d3a033ea97/asyncudp-0.11.0-py3-none-any.whl @@ -982,6 +981,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/df/f3/90993aab504fa2e1f28fcc09aa16b6ea4f00e75a037d9136e737855833e2/pyvips-3.2.0.tar.gz - pypi: https://files.pythonhosted.org/packages/e4/62/c3c23511ebe3d76dc679db0bb045dfd20ed3452bec12dcbbe8d655498a7d/vtracer-0.6.15.tar.gz - pypi: https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fa/06/6ab120a209276d8dced861ee11434ae2732ae70f8604df9b26c8ee3120d9/raydriver-0.5.1.tar.gz - pypi: https://files.pythonhosted.org/packages/fa/48/f36d233ce749d1bb880cb5e6f8bb171dc2effabc7435c31da604d831b3ec/gitpython-3.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fa/70/fffc9613501877c0a10a1ef73a165e6ded3e53f6e7502227fef56d973933/identify-2.6.20-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl @@ -1215,6 +1215,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a5/1a/ad561f99f90884089e6403b76c220610809429ba868a81a2e7ce115d32e0/propcache-0.5.4-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a5/f4/efe06066f1f15711cc51720faae0e4b838625ce62e8f0833f9f1476aeecf/raydriver-0.5.1-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a7/20/643f3c8f75594f937b2bf74801241c56a2e2b8e139d24dff8b66b28cdd7f/ruff-0.17.0-py3-none-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a8/67/7094dfc74bd9b7263a71a1a5706965750600d7cf740795ce123860986206/zeroconf-0.151.5-cp315-cp315-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/a8/71/9219fe65ef32bddc0b5d14e1d98dfefe9d2c9c1b1d1e93efca1f29fcbd4d/xyzservices-2026.9.1-py3-none-any.whl @@ -1228,7 +1229,6 @@ environments: - pypi: https://files.pythonhosted.org/packages/be/02/bce7a1d70e9d0f6ea8623c16386138c251b5855af6cd3a11433d3fba4e66/semver-3.1.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c5/0a/1423bb61b5f06376fe6ccf79c8781e2bb5e36c78c1814c78913b7425950f/bokeh-3.10.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/cb/a1/b285a8eb89406bb93c113afb4a21ac20ebe6de69c08c4a07edf241cfb6f8/raydriver-0.5.0-cp311-abi3-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl - pypi: https://files.pythonhosted.org/packages/d1/89/5d4c86da1130d9059681e5b6cd7645df5c10279a6a079c5c37dcb2cc6f3f/narwhals-2.27.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d7/8b/f837f52905395ba4510fe61f753c24833fb0a9c76e21267bb9f828b664a9/filelock-4.1.1-py3-none-any.whl @@ -9493,7 +9493,7 @@ packages: - pypi: ./ name: rayforge requires_dist: - - raydriver==0.5.0 + - raydriver==0.5.1 - raygeo==1.66.0 - aiohttp==3.14.5 - asyncudp==0.11.0 @@ -9591,15 +9591,6 @@ packages: sha256: c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0 requires_dist: - hidapi ; extra == 'cp2110' -- pypi: https://files.pythonhosted.org/packages/0a/97/a6f94b0ab3e1dc61a4d7652fcbd231a3a3753e1e0616e4e2a0207ec240c9/raydriver-0.5.0.tar.gz - name: raydriver - version: 0.5.0 - sha256: 1176aff89fe97230a2565e987cbcaf63dddd0ee4e997f5ecd8103e0752aa9b4c - requires_dist: - - pytest ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-timeout ; extra == 'test' - requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl name: cffi version: 2.1.1 @@ -10123,6 +10114,15 @@ packages: - pytest-regressions ; extra == 'testing' - pytest-timeout ; extra == 'testing' requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/a5/f4/efe06066f1f15711cc51720faae0e4b838625ce62e8f0833f9f1476aeecf/raydriver-0.5.1-cp311-abi3-macosx_11_0_arm64.whl + name: raydriver + version: 0.5.1 + sha256: bd446b322a15a646a9264bb22aed1fb6212d247cb861ae5df85b8ec5fa61448d + requires_dist: + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-timeout ; extra == 'test' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/a7/20/643f3c8f75594f937b2bf74801241c56a2e2b8e139d24dff8b66b28cdd7f/ruff-0.17.0-py3-none-macosx_11_0_arm64.whl name: ruff version: 0.17.0 @@ -10286,15 +10286,6 @@ packages: requires_dist: - ifaddr>=0.1.7 requires_python: '>=3.10' -- pypi: https://files.pythonhosted.org/packages/cb/a1/b285a8eb89406bb93c113afb4a21ac20ebe6de69c08c4a07edf241cfb6f8/raydriver-0.5.0-cp311-abi3-macosx_11_0_arm64.whl - name: raydriver - version: 0.5.0 - sha256: 601697e2c3fed3faaa43a211daf7ec41f2acf1bb6bc2f05a312199ebbf6c309f - requires_dist: - - pytest ; extra == 'test' - - pytest-asyncio ; extra == 'test' - - pytest-timeout ; extra == 'test' - requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/cd/5b/ff5fc58fa2427c30dea74c90053f4fc5eda1e7f3833ed3ecc7147fe2b311/tornado-6.5.10-cp39-abi3-macosx_10_9_universal2.whl name: tornado version: 6.5.10 @@ -10512,6 +10503,15 @@ packages: version: 1.28.2 sha256: 7113846b35dbf0a033f088e4f4fb543dabeb4b0b12c112966a1ca1ee2d5eacae requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/fa/06/6ab120a209276d8dced861ee11434ae2732ae70f8604df9b26c8ee3120d9/raydriver-0.5.1.tar.gz + name: raydriver + version: 0.5.1 + sha256: 1ed667bfa4c8486d4e68af7e2baf48f9ffd1a8e7a66a0a3357358b8c1db5c8c7 + requires_dist: + - pytest ; extra == 'test' + - pytest-asyncio ; extra == 'test' + - pytest-timeout ; extra == 'test' + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/fa/48/f36d233ce749d1bb880cb5e6f8bb171dc2effabc7435c31da604d831b3ec/gitpython-3.2.0-py3-none-any.whl name: gitpython version: 3.2.0 diff --git a/pixi.toml b/pixi.toml index 328cb370c..0de23d9eb 100644 --- a/pixi.toml +++ b/pixi.toml @@ -39,7 +39,7 @@ patchelf = "==0.19.2" [feature.app.pypi-dependencies] raygeo = "==1.66.0" -raydriver = "==0.5.0" +raydriver = "==0.5.1" rayforge = { editable = true, path = "." } ruida-pa = "==0.22.0" aiohttp = "==3.14.5" diff --git a/rayforge/machine/driver/grbl/grbl_serial.py b/rayforge/machine/driver/grbl/grbl_serial.py index fd475cb0c..87a021dc3 100644 --- a/rayforge/machine/driver/grbl/grbl_serial.py +++ b/rayforge/machine/driver/grbl/grbl_serial.py @@ -5,7 +5,6 @@ from typing import ( TYPE_CHECKING, Any, - assert_never, cast, ) @@ -65,18 +64,6 @@ logger = logging.getLogger(__name__) -AnySessionEvent = ( - SessionEvent.StateChanged - | SessionEvent.ConnectionStatusChanged - | SessionEvent.CommandStatusChanged - | SessionEvent.JobFinished - | SessionEvent.ProbeStatusChanged - | SessionEvent.WcsUpdated - | SessionEvent.ConfigChanged - | SessionEvent.RawRx - | SessionEvent.RawTx -) - class GrblSerialDriver(Driver): """ @@ -279,7 +266,7 @@ def _setup_implementation(self, **kwargs: Any) -> None: event_callback=self._on_session_event, ) - def _on_session_event(self, event: AnySessionEvent) -> None: + def _on_session_event(self, event: SessionEvent) -> None: """Re-emit Rust session events as Rayforge blinker signals.""" match event: case SessionEvent.StateChanged(): @@ -301,7 +288,7 @@ def _on_session_event(self, event: AnySessionEvent) -> None: case SessionEvent.RawTx(): self._log_raw_line(event.line, received=False) case _: - assert_never(event) + logger.debug(f"Ignoring session event: {event!r}") def _on_state_changed(self, session_state: "SessionDeviceState") -> None: state = from_session_state(session_state) diff --git a/requirements.txt b/requirements.txt index 439db4f81..08744b842 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -raydriver==0.5.0 +raydriver==0.5.1 raygeo==1.66.0 aiohttp==3.14.5 asyncudp==0.11.0