ruida-pa 0.20.4__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 (51) hide show
  1. ruida_pa-0.20.4/LICENSE +21 -0
  2. ruida_pa-0.20.4/MANIFEST.in +2 -0
  3. ruida_pa-0.20.4/PKG-INFO +673 -0
  4. ruida_pa-0.20.4/README.md +641 -0
  5. ruida_pa-0.20.4/protocols/__init__.py +0 -0
  6. ruida_pa-0.20.4/protocols/ruida/__init__.py +0 -0
  7. ruida_pa-0.20.4/protocols/ruida/rpa_plotter.py +730 -0
  8. ruida_pa-0.20.4/protocols/ruida/ruida_analyzer.py +440 -0
  9. ruida_pa-0.20.4/protocols/ruida/ruida_parser.py +821 -0
  10. ruida_pa-0.20.4/protocols/ruida/ruida_protocol.py +620 -0
  11. ruida_pa-0.20.4/pyproject.toml +52 -0
  12. ruida_pa-0.20.4/rpa.py +445 -0
  13. ruida_pa-0.20.4/rpalib/__init__.py +0 -0
  14. ruida_pa-0.20.4/rpalib/app_adapter.py +75 -0
  15. ruida_pa-0.20.4/rpalib/bokeh_app.py +381 -0
  16. ruida_pa-0.20.4/rpalib/bokeh_plotter.py +421 -0
  17. ruida_pa-0.20.4/rpalib/bokeh_view.py +1445 -0
  18. ruida_pa-0.20.4/rpalib/gluescript_signature.py +90 -0
  19. ruida_pa-0.20.4/rpalib/rd_binary_reader.py +63 -0
  20. ruida_pa-0.20.4/rpalib/rpa_emitter.py +120 -0
  21. ruida_pa-0.20.4/rpalib/rpa_line.py +58 -0
  22. ruida_pa-0.20.4/rpalib/rpa_swizzler.py +115 -0
  23. ruida_pa-0.20.4/rpalib/rpyc_client.py +1115 -0
  24. ruida_pa-0.20.4/rpalib/rpyc_service.py +970 -0
  25. ruida_pa-0.20.4/rpalib/ruida_transcoder.py +424 -0
  26. ruida_pa-0.20.4/rpalib/version.py +74 -0
  27. ruida_pa-0.20.4/rpascript/__init__.py +20 -0
  28. ruida_pa-0.20.4/rpascript/__main__.py +6 -0
  29. ruida_pa-0.20.4/rpascript/encoding.py +455 -0
  30. ruida_pa-0.20.4/rpascript/generator.py +239 -0
  31. ruida_pa-0.20.4/rpascript/interpreter.py +982 -0
  32. ruida_pa-0.20.4/rpascript/tui.py +146 -0
  33. ruida_pa-0.20.4/rpascript/tui_adapter.py +5325 -0
  34. ruida_pa-0.20.4/ruida_pa.egg-info/PKG-INFO +673 -0
  35. ruida_pa-0.20.4/ruida_pa.egg-info/SOURCES.txt +49 -0
  36. ruida_pa-0.20.4/ruida_pa.egg-info/dependency_links.txt +1 -0
  37. ruida_pa-0.20.4/ruida_pa.egg-info/entry_points.txt +3 -0
  38. ruida_pa-0.20.4/ruida_pa.egg-info/requires.txt +4 -0
  39. ruida_pa-0.20.4/ruida_pa.egg-info/top_level.txt +5 -0
  40. ruida_pa-0.20.4/ruidadriver/__init__.py +14 -0
  41. ruida_pa-0.20.4/ruidadriver/rd_gluescript.py +2013 -0
  42. ruida_pa-0.20.4/ruidadriver/rd_session.py +88 -0
  43. ruida_pa-0.20.4/ruidadriver/rd_status.py +591 -0
  44. ruida_pa-0.20.4/ruidadriver/rd_transport.py +471 -0
  45. ruida_pa-0.20.4/ruidadriver/ruida_driver.py +1085 -0
  46. ruida_pa-0.20.4/ruidadriver/transport/__init__.py +9 -0
  47. ruida_pa-0.20.4/ruidadriver/transport/base.py +38 -0
  48. ruida_pa-0.20.4/ruidadriver/transport/udp_transport.py +78 -0
  49. ruida_pa-0.20.4/ruidadriver/transport/usb_transport.py +75 -0
  50. ruida_pa-0.20.4/ruidadriver/transport_events.py +14 -0
  51. ruida_pa-0.20.4/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Steve Isaacs
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
+ prune docs
2
+ prune tests
@@ -0,0 +1,673 @@
1
+ Metadata-Version: 2.4
2
+ Name: ruida-pa
3
+ Version: 0.20.4
4
+ Summary: RPA Protocol Analyzer - Parse and decode Ruida protocol packets
5
+ Author: Ruida Protocol Analyzer Contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/StevenIsaacs/ruida-pa
8
+ Project-URL: Repository, https://github.com/StevenIsaacs/ruida-pa
9
+ Project-URL: Issues, https://github.com/StevenIsaacs/ruida-pa/issues
10
+ Keywords: ruida,laser,cnc,protocol,analyzer,decoder,udp,tui
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Software Development :: Debuggers
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: bokeh>=3.9
28
+ Requires-Dist: pyserial>=3.5
29
+ Requires-Dist: textual>=0.32
30
+ Requires-Dist: rpyc>=6.0
31
+ Dynamic: license-file
32
+
33
+ # RPA — Ruida Protocol Analyzer
34
+
35
+ A comprehensive Python-based protocol analyzer for analyzing Ruida CNC controller communications. This tool parses network packet captures from tshark/Wireshark to decode and interpret the binary Ruida protocol used in laser cutters, engravers, and CNC machines.
36
+
37
+ NOTE: This is a project which is rapidly evolving. New features and changes are added almost daily. If you clone or fork this project you may want to update regularly. Once all planned features have been added a more controlled release process will be used.
38
+
39
+ ## Features
40
+
41
+ - **File-based Analysis**: Process existing tshark capture files
42
+ - **State Machine Parser**: Robust parsing using a finite state machine architecture
43
+ - **Hierarchical Commands**: Handles nested command structures (command/subcommand)
44
+ - **Type-aware Parameters**: Decodes coordinates, power levels, speeds, and other data types
45
+ - **Flexible Output**: Console output, file output, verbose modes, and raw packet display
46
+ - **Error Handling**: Configurable error handling with resync capabilities
47
+ - **Move and Cut Plotting**: When enabled moves and cut lines are plotted using Bokeh
48
+ - **Automation-friendly**: `rpa.py` accepts a tshark log file and produces structured, text-based output suitable for scripting, pipelines, and CI/CD systems.
49
+ - **Script Generation and Plot Export**: `--generate-rd` and `--save-plot` flags for binary `.rd` output and headless HTML plot export
50
+
51
+ This tool is designed to be used to discover and diagnose problems related to UDP communications with a Ruida controller. Much of the Ruida protocol is unknown and new commands or parameters may be discovered during analysis. The nature of such discovery often requires new experiments or parsing algorithms when new information is learned. Because of this the best experience using this tool is within VSCode or its forks like VSCodium and Antigravity. These IDEs allow stepping through the code to observe the analyzer's behavior along with side by side display of moves and cuts. And, when needed, this tool can be hacked to refine analysis. If you create a hack which can be useful to others please consider contributing it to this project.
52
+
53
+ ## Documentation
54
+
55
+ In-depth guides for working with the scripting and interface layers are available in `docs/guides/`:
56
+
57
+ | Guide | Description |
58
+ |-------|-------------|
59
+ | [docs/guides/gluescript-guide.md](docs/guides/gluescript-guide.md) | High-level job scripting layer (GlueScript) between application code and low-level rpascript, covering job/layer declarations, `.cglu` persistence, and the command registry for re-staging jobs. |
60
+ | [docs/guides/integration-guide.md](docs/guides/integration-guide.md) | For developers building external applications that control Ruida controllers programmatically via the RdDriver API, including remote control over RPyC. |
61
+ | [docs/guides/rpascript-guide.md](docs/guides/rpascript-guide.md) | Reference for the low-level rpascript (`.rds`) line-oriented script format consumed by `RdDriver.run()`. |
62
+ | [docs/guides/tui-guide.md](docs/guides/tui-guide.md) | User guide for the interactive terminal UI of `rpa-script`: session management, script execution, capture import, real-time monitoring, and slash commands. |
63
+
64
+ ## VSCode Extension (GlueScript & Ruida Script)
65
+
66
+ The repository ships a zero-build VSCode **workspace extension** for authoring
67
+ the two script formats, located at
68
+ `.vscode/extensions/local.gluescript-rpascript/`:
69
+
70
+ - **GlueScript (`.cglu`)** — the high-level job scripting transcript used by the `/gluescript` TUI command, documented in the [GlueScript guide](docs/guides/gluescript-guide.md).
71
+ - **Ruida Script (`.rds`)** — the low-level line-oriented script format consumed by `RdDriver.run()`, documented in the [Ruida Script guide](docs/guides/rpascript-guide.md).
72
+
73
+ The extension provides syntax highlighting, language configuration, and code
74
+ snippets for both formats. It works in VSCode and its forks such as VSCodium
75
+ and Antigravity.
76
+
77
+ ### Installing
78
+
79
+ Open this repository as the workspace root in VSCode. The editor detects the
80
+ `.vscode/extensions/` folder and prompts you to install the extension into
81
+ the workspace. After the one-time install, the extension auto-loads whenever
82
+ this workspace is opened. No build step is required.
83
+
84
+ ### Features
85
+
86
+ - **Syntax highlighting** for `.cglu` and `.rds` files
87
+ - **Language configuration** — comment markers, bracket pairs, and
88
+ auto-closing pairs tuned to each format
89
+ - **Snippets** for common GlueScript methods and Ruida Script commands
90
+
91
+ ### Snippets
92
+
93
+ Type a snippet prefix in a `.cglu` or `.rds` file and select it from the
94
+ IntelliSense completion list (or press `Ctrl+Space`), then tab through the
95
+ placeholders to fill in values.
96
+
97
+ GlueScript method snippets (22) cover the persisted layer actions and
98
+ job/layer declarations: `declare_job`, `declare_layer`, `end_job`, `comment`,
99
+ `inline`, `delay`, `wait`, `power`, `power_range`, `air_assist_on`,
100
+ `air_assist_off`, `cut_speed`, `move_speed`, `frequency`, `pwm`,
101
+ `select_laser`, `move_xy_to`, `move_x_to`, `move_y_to`, `cut_xy_to`,
102
+ `cut_x_to`, `cut_y_to`.
103
+
104
+ Ruida Script snippets (7) cover common script blocks: `session`,
105
+ `job-header`, `layer-block`, `move`, `delay`, `wait`, `end-job`.
106
+
107
+ ### File Associations
108
+
109
+ | Extension | Language ID | Grammar |
110
+ |-----------|--------------|---------------------|
111
+ | `.cglu` | `gluescript` | `source.gluescript` |
112
+ | `.rds` | `rpascript` | `source.rpascript` |
113
+
114
+ `.rd` files are deliberately **not** associated — `.rd` is the binary RDWorks
115
+ format, not Ruida Script text.
116
+
117
+ ### Samples
118
+
119
+ Example `.cglu` and `.rds` files demonstrating both formats live in the extension's `samples/` directory.
120
+
121
+ ## Background
122
+
123
+ The Ruida protocol is a proprietary binary communication protocol used by Ruida CNC controllers, commonly found in:
124
+ - CO2 laser cutters and engravers
125
+ - Fiber laser systems
126
+ - CNC routers with Ruida controllers
127
+ - Industrial cutting and marking systems
128
+
129
+ This analyzer was developed to understand and document the protocol for research, debugging, and integration purposes.
130
+
131
+ This tool is laser-focused on the Ruida protocol only.
132
+
133
+ ## Requirements
134
+
135
+ - Python 3.10+
136
+ - Wireshark/tshark installed and accessible in PATH
137
+ - Network access to capture Ruida controller communications
138
+
139
+ ## Installation
140
+
141
+ ### Option 1: Install from PyPI (recommended)
142
+
143
+ ```bash
144
+ pip install ruida-pa
145
+ ```
146
+
147
+ All dependencies (bokeh, pyserial, textual, rpyc) are installed automatically, so the TUI (`rpa-script --tui`) and plotting work out of the box.
148
+
149
+ ### Option 2: Install from source (recommended for development)
150
+
151
+ ```bash
152
+ git clone https://github.com/StevenIsaacs/ruida-pa.git
153
+ cd ruida-pa
154
+
155
+ # Create and activate a virtual environment
156
+ python -m venv .venv
157
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
158
+
159
+ # Install the package in editable mode
160
+ pip install -e .
161
+ ```
162
+
163
+ ### Option 3: Direct install from source
164
+
165
+ ```bash
166
+ pip install git+https://github.com/StevenIsaacs/ruida-pa.git
167
+ ```
168
+
169
+ After installation, the `rpa` command is available globally (when the venv is active):
170
+ ```bash
171
+ rpa --help
172
+ ```
173
+ The `rpa-script` command (script interpreter/playback) is also installed:
174
+
175
+ ```bash
176
+ rpa-script --help
177
+ ```
178
+
179
+ ### Requirements
180
+
181
+ - Python 3.10+
182
+ - Wireshark/tshark installed and accessible in PATH
183
+ - Network access to capture Ruida controller communications
184
+
185
+ ### Building a Standalone Binary
186
+
187
+ A standalone binary (no Python required) can be built with PyInstaller:
188
+
189
+ ```bash
190
+ # Linux
191
+ ./build.sh
192
+
193
+ # Windows (PowerShell)
194
+ .\build.ps1
195
+
196
+ # The binary is placed in dist/
197
+ ./dist/rpa --help
198
+ ```
199
+
200
+ Requirements: PyInstaller (`pip install pyinstaller`) and a working build environment (gcc/clang on Linux, Visual Studio on Windows).
201
+
202
+ ## Usage
203
+
204
+ **Note:** When running from source code, make sure to activate your Python virtual environment first:
205
+ ```bash
206
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
207
+ ```
208
+
209
+ ### Capture Traffic with tshark
210
+
211
+ First, capture Ruida protocol traffic using tshark. Replace `<ruida_ip>` with your controller's IP address:
212
+
213
+ ```bash
214
+ tshark -Y "(ip.addr == <ruida_ip> && udp.payload)" -T fields \
215
+ -e frame.time_delta -e udp.port -e udp.length -e data.data > capture.log
216
+ ```
217
+
218
+ ### Analyze Captured Data
219
+
220
+ #### Basic Analysis
221
+ ```bash
222
+ python rpa.py capture.log
223
+ ```
224
+
225
+ `.rd` — RDWorks binary files can be decoded directly.
226
+
227
+ #### Advanced Options
228
+ ```bash
229
+ # Verbose output with raw packet data
230
+ python rpa.py --verbose --raw capture.log
231
+
232
+ # Save decoded output to file
233
+ python rpa.py -o decoded.txt capture.log
234
+
235
+ # Quiet mode, stop on first error
236
+ python rpa.py --quiet --stop-on-error -o results.txt capture.log
237
+
238
+ # Generate .rds script and .rd binary output
239
+ python rpa.py --generate-rd capture.log
240
+
241
+ # Generate .rd binary from an existing .rds script
242
+ python rpa.py script.rds
243
+
244
+ # Save interactive plot as standalone HTML
245
+ python rpa.py --save-plot capture.log
246
+
247
+ # Decode a binary .rd file directly
248
+ python rpa.py capture.rd
249
+ ```
250
+
251
+ ## Command Line Options
252
+
253
+ | Option | Description |
254
+ |--------|-------------|
255
+ | `--bokeh-port <port>` | Set the Bokeh server port for `--plot-moves` (default: 5006). |
256
+ | `--generate-rd` | Generate a binary `.rd` file from the decoded commands. Auto-enables `--generate-script` for `.log`/`.txt` input. For `.rd` input, appends `-reencoded` suffix to avoid overwriting. |
257
+ | `--generate-script` | Generate a `.rds` Ruida Script file from the decoded commands. Combined with `-o <file>` to control the output path. |
258
+ | `--magic <magic_number>` | Specify the swizzle magic number rather than attempt to discover it in the capture. |
259
+ | `--out <file>`, `-o <file>` | Write decoded data to specified file. |
260
+ | `--plot-moves` | Plot head moves and cuts. This also displays power and speed settings. |
261
+ | `--quiet`, `-q` | Suppress stdout output. |
262
+ | `--raw` | Include raw packet dumps with decoded output. |
263
+ | `--save-plot` | Save the interactive plot as a standalone HTML file instead of opening a Bokeh server. Produces `{stem}[-{ext}]-view.html`. |
264
+ | `--stop-on-error` | Stop processing on first decode error. |
265
+ | `--unswizzled` | Output the unswizzled and unprocessed data. |
266
+ | `--verbose` | Generate detailed output with additional information. |
267
+
268
+ ### Interactive TUI (Terminal User Interface)
269
+
270
+ For detailed documentation of the TUI, including session management,
271
+ script execution, capture import, visualization, and all slash commands:
272
+
273
+ **[docs/guides/tui-guide.md](docs/guides/tui-guide.md)**
274
+
275
+ Quick start:
276
+
277
+ ```bash
278
+ rpa-script
279
+ ```
280
+
281
+ The TUI provides interactive access to Ruida controllers via terminal,
282
+ combining connection management, script execution, real-time monitoring,
283
+ and capture import from other laser applications.
284
+
285
+ NOTE: The TUI is intended to be used only for discovery and diagnostic purposes and is NOT for a production environment. Jobs requiring thousands of layer actions should not be run using the TUI because of the overhead involved.
286
+
287
+ ### Crash Handling
288
+
289
+ If an unhandled exception occurs, a persistent error screen displays the
290
+ traceback with Rich formatting. Press any key to exit the TUI.
291
+
292
+ ## Script Generation & Round-Trip Testing
293
+
294
+ `rpa-script` is a script interpreter that plays back Ruida Script (`.rds`) files and
295
+ generates tshark-format binary output. Combined with `rpa --generate-script`, this
296
+ enables round-trip testing: capture → decode → script → tshark → re-decode.
297
+
298
+ ### Generating Scripts from Captures
299
+
300
+ Use `--generate-script` to produce both a `.txt` decode file and a `.rds` script file:
301
+
302
+ ```bash
303
+ python rpa.py --generate-script -o output.txt capture.log
304
+ ```
305
+
306
+ This produces `output.txt` (human-readable decode) and `output.rds` (script file).
307
+ If `-o` is omitted, the script file is named after the input file (e.g. `capture.rds`).
308
+
309
+ The generated `.rds` includes:
310
+ - A `# Source:` header tracking the original capture filename
311
+ - `# Packet N` comments at each packet boundary
312
+ - Reply values captured from controller responses (e.g. `CardID:RDC6442S`)
313
+
314
+ ### Playing Back Scripts
315
+
316
+ Convert a `.rds` script to tshark-format binary output:
317
+
318
+ ```bash
319
+ # Output to stdout (pipe directly to rpa for decoding)
320
+ rpa-script script.rds | python rpa.py -
321
+
322
+ # Output to file
323
+ rpa-script script.rds -o output.tshark
324
+ ```
325
+
326
+ ### Full Round-Trip Workflow
327
+
328
+ Use the `.rds` file as input to `rpa-script` to regenerate tshark packets,
329
+ then re-decode them to verify round-trip fidelity:
330
+
331
+ ```bash
332
+ # Step 1: Decode and generate script
333
+ python rpa.py --generate-script capture.log
334
+
335
+ # Step 2: Play back the script to regenerate packets
336
+ rpa-script capture.rds -o capture-rt.tshark
337
+
338
+ # Step 3: Re-decode the generated packets
339
+ python rpa.py -o capture-rt.txt capture-rt.tshark
340
+
341
+ # Step 4: Compare the original and round-trip decode files
342
+ diff <(grep '^[0-9]' capture.txt) <(grep '^[0-9]' capture-rt.txt)
343
+ ```
344
+
345
+ ### Generating Binary `.rd` Files
346
+
347
+ Use `--generate-rd` to produce a binary `.rd` file alongside the decode output:
348
+
349
+ ```bash
350
+ python rpa.py --generate-rd -o output capture.log
351
+ ```
352
+
353
+ This produces `output.txt` (decode), `output.rds` (script), and `output.rd` (binary). If `-o` is omitted, the `.rd` file is named after the input file.
354
+
355
+ For `.rds` input, `.rd` output is generated directly without decode:
356
+
357
+ ```bash
358
+ python rpa.py script.rds # Produces script.rd
359
+ ```
360
+
361
+ For `.rd` input, `--generate-rd` re-encodes with a `-reencoded` suffix to avoid overwriting:
362
+
363
+ ```bash
364
+ python rpa.py --generate-rd capture.rd # Produces capture-reencoded.rd
365
+ ```
366
+
367
+ The `--magic` flag controls the swizzle byte (default `0x88`).
368
+
369
+ ### `.rds` Script Format
370
+
371
+ Ruida Script (`.rds`) files are line-oriented text files. Each line contains
372
+ a command mnemonic followed by optional parameters and an optional expected reply:
373
+
374
+ ```rds
375
+ # Source: capture.log
376
+
377
+ # Packet 1
378
+ GET_SETTING MEM_CARD_ID = CardID:RDC6442S
379
+
380
+ # Packet 2
381
+ new_packet
382
+ REF_POINT_2
383
+ SET_ABSOLUTE
384
+ MOVE_FAR_XY X=10000mm Y=20000mm
385
+ ```
386
+
387
+ - Lines starting with `#` are comments
388
+ - `new_packet` marks a boundary between packets
389
+ - `= value` after a command captures the controller's reply
390
+ - Packet numbering comments (`# Packet N`) provide human-readable guidance
391
+
392
+ ## Output Format
393
+
394
+ The analyzer produces human-readable output showing:
395
+ - Timestamp and packet information
396
+ - Decoded command names
397
+ - Parameter values with appropriate units
398
+ - Error messages for malformed packets
399
+
400
+ Where (see example):
401
+ - pkt_n = Current packet number
402
+ - cmd_n = Current command number for all commands in the captured session
403
+ - msg_n = Message number in the current command
404
+ - dir = --> or <-- or ---(below)
405
+ - take = Buffer take index
406
+ - remaining = Number of bytes remaining in the buffer
407
+ - checksum = The calculated file checksum
408
+ - msg_class = Message classes can be either:
409
+ - PRT = Protocol related
410
+ - INT = Internal engine related
411
+ - msg_type = The message type.
412
+ - For protocol messages:
413
+ - RDR = Packet reader
414
+ - PRS = Data parser
415
+ - SHK = Message handshake
416
+ - ERR = Errors with parsing or incoming data
417
+ - FTL = Fatal errors (will trigger an exit)
418
+ - vrb = Verbose message (when --verbose is used)
419
+ - raw = Raw tshark and unswizzled packets or other raw data.
420
+ - --- = Packet direction not determined
421
+ - --> = Packets from the host
422
+ - <-- = Packets from the controller
423
+ - For internal messages:
424
+ - PRT = An error caused by a protocol specification
425
+ - INF = Information only
426
+ - WRN = A warning about a correctable error
427
+ - CRT = A critical error -- will continue to run
428
+ - FTL = A fatal error which triggers an exit
429
+
430
+ Typical messages have the format:
431
+ ```
432
+ <pkt_n>:<cmd_n>:<msg_n>:<msg_type>:<message>
433
+ ```
434
+ Decoded output has the format:
435
+ ```
436
+ <pkt_n>:<cmd_n>:<msg_n>:PRT:PRS:<dir>:T=<take> R=<remaining> SUM=<checksum>
437
+ ```
438
+
439
+ There may be times when the amount of time between packets is important when
440
+ diagnosing a problem. The time between packets in the log file is indicated as:
441
+ ```
442
+ 0003:000001:023:PRT:RDR:<--:Interval:0.000071S
443
+ ```
444
+
445
+ ## File Checksum
446
+
447
+ The end of a file sent to the controller ends with a SET_FILE_SUM command
448
+ which includes the checksum calculated by the host. It is assumed the
449
+ controller then compares the host's checksum with its internally calculated
450
+ checksum. If the sums do not match the controller may display a message
451
+ indicating the failure.
452
+
453
+ RPA also calculates a checksum and compares its result with the SET_FILE_SUM
454
+ checksum. If they do not match an ERR message is emitted. e.g.:
455
+ ```
456
+ 0228:030441:004:PRT:ERR:-->:Checksum mismatch:
457
+ decoded=9763961
458
+ accumulated=9756933
459
+ difference =7028
460
+ ```
461
+
462
+ It is currently believed the checksum is a simple sum of all the bytes
463
+ in commands related to engraving and cutting.
464
+
465
+ Excluded commands include:
466
+ - Any commands related to getting or setting controller memory locations
467
+ - Controller keyboard commands (e.g. jogging button presses)
468
+
469
+ NOTE: It is currently unclear as to which bytes are to be included in the
470
+ checksum calculation. Using LightBurn captures there is currently a consistent
471
+ discrepancy of 220 (shown as a difference). This implies there are only one or
472
+ two bytes missing from the calculation -- at least for LightBurn captures.
473
+
474
+ ## Example Output
475
+
476
+ ### Normal Verbose Output
477
+ ```
478
+ 0001:000001:003:PRT:RDR:---:Interval:-0.000101S
479
+ 0001:000001:004:PRT:raw:-->:
480
+ Sep 25, 2025 22:33:40.474975135 PDT 40200,50200 14 0261d4890df7
481
+
482
+ 0001:000001:005:PRT:raw:-->:
483
+ da00057e
484
+ 0001:000001:006:PRT:RDR:-->:SHK:001:Expecting ACK
485
+ 0001:000001:007:vrb:Exiting state: sync
486
+ 0001:000001:008:vrb:Entering state: expect_sub_command
487
+ 0001:000001:009:vrb:Exiting state: expect_sub_command
488
+ 0001:000001:010:vrb:Entering state: decode_parameters
489
+ 0001:000001:011:vrb:Priming: ('Addr:{:04X}', 'mt', 'mt')
490
+ 0001:000001:012:vrb:Decoding parameter 1.
491
+ 0001:000001:013:vrb:Decoded parameter 1=Addr:057E:Card ID.
492
+ 0001:000001:014:vrb:Exiting state: decode_parameters
493
+ 0001:000001:015:vrb:Entering state: mt_command
494
+ 0001:000001:016:PRT:PRS:-->:T=0004 R=0000 SUM=00000000:
495
+ GET_SETTING Addr:057E:Card ID
496
+
497
+ 0001:000001:017:vrb:-->:da00057e
498
+ 0001:000001:018:vrb:<--:
499
+ 0002:000001:019:PRT:RDR:-->:Interval:0.000101S
500
+ 0002:000001:020:PRT:raw:<--:
501
+ Sep 25, 2025 22:33:40.475076666 PDT 50200,40200 9 c6
502
+
503
+ 0002:000001:021:PRT:raw:<--:
504
+ cc
505
+ 0002:000001:022:PRT:RDR:<--:SHK:000:ACK
506
+ ```
507
+
508
+ ### Unknown Data Output
509
+ All unknowns are marked with "TBD". These can be either newly discovered commands
510
+ or addresses or unknown data formats for previously discovered commands or
511
+ addresses. This indicates data which requires further investigation.
512
+
513
+ Unknown parameter values are output in binary, hex, and decimal.
514
+ ```
515
+ 0010:000393:001:INT:---:Next command...
516
+ 0010:000393:002:vrb:Checksum: disabled
517
+ 0010:000393:003:vrb:Checksum: ENABLED
518
+ 0010:000393:004:vrb:Exiting state: expect_command
519
+ 0010:000393:005:vrb:Entering state: expect_sub_command
520
+ 0010:000393:006:vrb:Exiting state: expect_sub_command
521
+ 0010:000393:007:vrb:Entering state: decode_parameters
522
+ 0010:000393:008:vrb:Priming: ('\nTBD:{0:035b}b: 0x{0:08x}: {0}', 'tbd', 'tbd')
523
+ 0010:000393:009:vrb:Decoding parameter 1.
524
+ 0010:000393:010:vrb:Forwarding 0xEA to state sync
525
+ 0010:000393:011:vrb:Exiting state: decode_parameters
526
+ 0010:000393:012:vrb:Entering state: sync
527
+ 0010:000393:013:PRT:PRS:-->:T=0270 R=0741 SUM=00176437:
528
+ FEED_INFO:
529
+ TBD:00000000000000000000000000000000000b: 0x00000000: 0
530
+
531
+ 0010:000393:014:vrb:-->:e70a0000000000ea
532
+ 0010:000393:015:vrb:<--:
533
+ ```
534
+
535
+ ### Checksum Message
536
+ The file checksum message triggers the following message sequence. The
537
+ checksum message itself is NOT included in the checksum.
538
+ ```
539
+ 0228:030440:006:vrb:Checksum: disabled
540
+ 0228:030440:007:vrb:Backed out: [229, 5]
541
+ 0228:030440:008:vrb:Exiting state: expect_sub_command
542
+ 0228:030440:009:vrb:Entering state: decode_parameters
543
+ 0228:030440:010:vrb:Priming: ('Sum:0x{0:010X} ({0})', 'checksum', 'uint_35')
544
+ 0228:030440:011:vrb:Decoding parameter 1.
545
+ 0228:030440:012:vrb:Decoded parameter 1=Sum:0x000094FC79 (9763961).
546
+ 0228:030440:013:vrb:Parameters decoded.
547
+ 0228:030440:014:vrb:Exiting state: decode_parameters
548
+ 0228:030440:015:vrb:Entering state: expect_command
549
+ 0228:030440:016:PRT:PRS:-->:T=0925 R=0001 SUM=09756933:
550
+ SET_FILE_SUM Sum:0x000094FC79 (9763961)
551
+
552
+ 0228:030440:017:vrb:-->:e5050004537879
553
+ 0228:030440:018:vrb:<--:
554
+ 0228:030441:001:INT:---:Next command...
555
+ 0228:030441:002:vrb:Checksum: disabled
556
+ 0228:030441:003:vrb:Checksum: ENABLED
557
+ 0228:030441:004:PRT:ERR:-->:Checksum mismatch:
558
+ decoded=9763961
559
+ accumulated=9756933
560
+ difference =7028
561
+
562
+ ```
563
+
564
+ ### Move Plotting
565
+ When move plotting is enabled an interactive Bokeh visualization is opened
566
+ in a browser window showing all individual head moves. Hovering over a line
567
+ will display a tooltip showing the move command ID, end point coordinates,
568
+ length, power, and speed. The visualization supports filtering by move type
569
+ (moves/cuts), power range, and speed range. Right-click on any vector for
570
+ context menu options including opening a new tab filtered from that command.
571
+
572
+ ![Example:](example-moves.png)
573
+
574
+ ## Protocol Structure
575
+
576
+ The Ruida protocol uses a hierarchical binary command structure:
577
+
578
+ - **Single Commands**: Direct command byte followed by parameters
579
+ - **Hierarchical Commands**: Command byte + subcommand byte + parameters
580
+ - **Parameters**: Type-specific encoding (coordinates, power, speed, etc.)
581
+
582
+ ### Supported Parameter Types
583
+
584
+ - **Coordinates**: Absolute and relative positioning in micrometers
585
+ - **Power Values**: Laser power percentages
586
+ - **Speed Values**: Movement speeds in micrometers/second
587
+ - **Time Values**: Delays and timing in microseconds
588
+ - **Control Values**: Various machine control parameters
589
+
590
+ ## Architecture
591
+
592
+ The analyzer uses a finite state machine with the following states:
593
+ - `IDLE`: Ready for new packet
594
+ - `COMMAND_BYTE`: Processing main command
595
+ - `SUBCOMMAND_BYTE`: Processing hierarchical subcommands
596
+ - `PARAMETER_PARSING`: Extracting typed parameters
597
+ - `ERROR`: Handling parse failures
598
+
599
+ ## Known Issues
600
+
601
+ - **File checksum discrepancy with LightBurn captures**: The analyzer's file checksum does not always match the value in `SET_FILE_SUM`. Using LightBurn captures there is a consistent discrepancy of 220, implying only one or two bytes are missing from the calculation — at least for LightBurn captures. Exactly which bytes participate in the checksum remains unclear. See the [File Checksum](#file-checksum) section for details and an example mismatch. (`auto_checksum=True` in the driver may likewise not match LightBurn output.)
602
+
603
+ - **Incomplete protocol coverage**: Much of the Ruida protocol is unknown. Unknown commands, addresses, and parameter formats are marked `TBD` in the output and require further investigation (see [Unknown Data Output](#unknown-data-output)). Examples of open questions: the meaning of the 35-bit `FEED_INFO` value, and the effect of min/max power settings on plotting.
604
+
605
+ - **Move Speed Distribution histogram does not display speed:** Intra-layer travel speed commands are not well understood. Currently, the Ruida controller default is used but that too is currently unknown. Because of this the histogram is a gray block.
606
+
607
+ - **TUI unresponsiveness when listing large scripts**: In the interactive TUI, `/list script` (and the related `/list` subcommands) writes each line to the log widget in a synchronous loop, which can freeze the interface for a noticeable period when a script has thousands of lines. A related handshake-thread blocking issue that caused random status disconnects has been fixed; the event-loop saturation from per-line writes remains. This is why the TUI is intended for discovery and diagnostic use only and not for production workloads (see the [Interactive TUI](#interactive-tui-terminal-user-interface) section).
608
+
609
+ ## Future Plans
610
+
611
+ - **Controlled release process**: This project evolves rapidly with near-daily changes. Once all planned features have been added, a more controlled release process will be used (see the note at the top of this README).
612
+
613
+ - **Multi-job GlueScript support**: A GlueScript currently contains a single job; support for more than one job per script is planned.
614
+
615
+ - **Direct to machine code:** Currently GlueScript generates rpascript which is then used to generate raw Ruida machine code. Using rpascript as an intermediate format aids problem diagnosis and discovery but at a cost in additional overhead. In a future release GlueScript will generate machine code directly.
616
+
617
+ - **Configurable driver commands**: Driver commands are currently hard-coded as `RdDriver` class private variables; a configuration file for these is planned.
618
+
619
+ - **Additional protocol support**: The driver architecture is designed to support other protocols, such as GCODE, in the future. Adding a protocol means creating a parallel `protocols/<name>/` directory with its own analyzer.
620
+
621
+ - **U-axis plotting support**: Move plotting currently covers the X/Y axes; U-axis moves are a planned addition.
622
+
623
+ ## Contributing
624
+
625
+ Contributions are welcome! This is an ongoing analysis project. Areas where help is needed:
626
+
627
+ - **Protocol Documentation**: Adding new command interpretations
628
+ - **Parameter Types**: Implementing additional data type decoders
629
+ - **Testing**: Validating against different Ruida controller models
630
+ - **Features**: Additional analysis and export capabilities
631
+
632
+ ### Adding New Protocol Specificatons
633
+
634
+ Protocol specifications are defined in the protocol tables. For example:
635
+ ```python
636
+ # In CT (Command Table)
637
+ 0x88: ('MOVE_FAR_XY', XFARDIM, YFARDIM),
638
+ ```
639
+
640
+ Parameter decoders are defined as tuples:
641
+ ```python
642
+ XFARDIM = ('X={}mm', 'dim', 'int_35')
643
+ # ^format ^decoder ^raw_type
644
+ ```
645
+
646
+ ## License
647
+
648
+ This project is released under the MIT License. See [LICENSE](LICENSE) for details.
649
+
650
+ ## Disclaimer
651
+
652
+ This tool is for educational and research purposes. The Ruida protocol is proprietary, and this analyzer is based on analysis of network traffic. Use responsibly and respect intellectual property rights.
653
+
654
+ ## Acknowledgments
655
+
656
+ - Developed for understanding Ruida CNC/laser cutter communications
657
+ - Inspired by the need for open tools in the CNC/laser space
658
+ - Built with insights from the embedded systems and maker communities
659
+
660
+ ### Sources
661
+
662
+ - MeerK40T: https://github.com/meerk40t/meerk40t/tree/main/meerk40t/ruida
663
+ - Ruida protocol: https://edutechwiki.unige.ch/en/Ruida
664
+
665
+ ## Support
666
+
667
+ - **Issues**: Please report bugs and feature requests via GitHub issues
668
+ - **Discussions**: Use Discord or GitHub discussions for questions and protocol insights
669
+ - **Documentation**: Help improve protocol documentation through pull requests
670
+
671
+ ---
672
+
673
+ **Note**: This analyzer is a work in progress. Protocol coverage is incomplete, and new command interpretations are added as they're discovered and validated.