Use the Serial Console
Talk to USB-serial peripherals from the OctoMY Hub
Serial Console
The Serial Console is the OctoMY Hub UI that wraps libserial (our forked
QSerialPort) for talking to USB-serial peripherals — CDC-ACM boards,
FTDI / CP210x / CH34x / PL2303 cables, etc.
Modes
Two modes per connection:
- Simple — type a single line, press Send. The chosen line ending is appended.
- Drip-feed — paste or load a multi-line payload, then stream it to the receiver one line at a time. Pacing is configurable per connection (see below).
Note — "Drip-feed" was previously called "G-code" mode. Existing connections that were saved as
gcodemigrate silently on first load; nothing on disk needs to change.
Drip-feed configuration
When Mode = Drip-feed, the Connection settings activity exposes a Drip-feed config block:
| Knob | Default | Notes |
|---|---|---|
| Pacing | Ack |
Ack = wait for receiver reply; Delay = fixed-ms gap; Free = no gate. |
| Ack regex | ^ok\b |
Matched against each received line; a match advances. |
| Error regex | ^(error|alarm)\b |
If matched, the run aborts (or logs, see "Abort on error"). |
| Ack timeout | 5000 ms | Maximum wait between send and receiver ack. |
| Delay | 50 ms | Used only when Pacing = Delay. |
| Comment prefix | ; |
Lines whose first non-whitespace char is the prefix are dropped. Empty = no comment stripping. |
| Line ending | LF (\n) |
Appended to every paced line. |
| Trim trailing whitespace | off | When on, each line is right-trimmed before send. |
| Abort on error | on | When off, error-regex matches are logged but the run continues. |
The defaults reproduce the previous GRBL/G-code behaviour exactly, so existing flows keep working without any adjustment.
What you can ask the AI
The Hub's chat assistant (OPAL) can answer questions about your serial setup and (with confirmation) edit the saved-connections list. None of these tasks open a live port or send bytes yet — that surface arrives in the next batch of releases.
Read-only questions
These run without prompting for permission.
| Ask | Behind the scenes | What you get back |
|---|---|---|
| "List my serial connections." | serial.list-connections |
A JSON array of saved connections (id, name, port, baud, mode), plus a count. |
| "What serial ports are on this machine?" | serial.list-ports |
A JSON array of physically detected ports, with manufacturer / VID / PID / serial number when known. |
| "Tell me about the 'Lab Uno' connection." | serial.get-connection |
Every persisted field of the named connection — port settings, mode, full drip-feed config, plus an is-open flag. |
| "Is anything currently streaming?" | serial.get-status |
Open-session count and a per-session JSON snapshot — port, baud, drip-feed state ({idle, running, paused, finished, cancelled, errored}) and progress for every live session. |
Connection management
These prompt you to confirm under the serial.config permission
scope (once per session by default) before they touch the
saved-connections list.
| Ask | Behind the scenes | What it does |
|---|---|---|
| "Create a serial connection called 'Lab Uno' for /dev/ttyACM0 at 115200." | serial.create-connection |
Creates a new connection with the given parameters. Returns its fresh id. Validates baud / data-bits / parity / stop-bits / flow-control / mode / display before saving — invalid inputs fail with a "State: no changes" message. |
| "Set the 'Lab Uno' baud to 9600 and switch it to drip-feed." | serial.update-connection |
Updates one or more fields on the matching id. Returns the JSON list of fields that actually changed; passing values that already match is a "No fields changed" success. Empty strings reset a field to its default. Refuses while a console session is open against that connection. |
| "Delete the 'Old test rig' connection." | serial.delete-connection |
Removes the connection. Idempotent — asking again after it is gone reports "already deleted" as success. Refuses if a session is open; pass force=true (e.g. "delete it even if it's open") to close the session first and then remove. |
You can also tell the assistant "go to serial" to navigate to the connection list. The Utilities menu's Serial button opens the same list view; from there you can create, edit, delete, or open a tabbed console for any saved connection.
Heads up — the assistant uses the connection id (a UUID) to mutate or remove a connection. If you ask it to update or delete something by name, the assistant first runs
serial.get-connectionto look up the id; if there are two connections with the same name it will report the ambiguity rather than guess.
Sessions outlive their tab. Connecting to a port opens a session that lives on the node, not on the tab. Closing the console tab does not close the session — the port stays open and any RX is recorded in the rolling log. Click Disconnect on the tab, or ask the assistant "close the serial session for X" (
serial.close), to actually release the port. If the device is unplugged, the session closes automatically with reason "detached" and the tab shows a "Device detached" notice.
Session lifecycle
These prompt you to confirm under the serial.io permission scope.
serial.open and serial.close confirm once per session by default;
the send tasks below confirm every call because they put bytes on
a real wire. Approving every call is not the default for read-only
or session-lifecycle scopes — it is reserved for the send tasks.
| Ask | Behind the scenes | What it does |
|---|---|---|
| "Open the 'Lab Uno' connection." | serial.open |
Creates a live session against the saved port at the saved baud. Idempotent — opening an already-open session is a success no-op. Failures are surfaced with a "no port set" / "port busy" / "USB permission denied" hint and a concrete next step. |
| "Close the serial session for 'Lab Uno'." | serial.close |
Releases the port. Idempotent — closing a session that was never open is also a success no-op. |
| "What's the latest output on 'Lab Uno'?" | serial.read-log |
Snapshots the rolling RX buffer (default 4 KiB tail, hard cap 1 MiB). The since-ms-ago parameter narrows to a recent window (0 = no window). Read-only — no permission scope. |
Sending bytes
These all carry the serial.io scope and re-prompt you every
call — that is by design and the recommended default.
| Ask | Behind the scenes | What it does |
|---|---|---|
| "Send '?' to the Uno." | serial.send-line |
Sends one line of text; the line ending defaults to the connection's drip-feed line ending (or \n if unset) and can be overridden per-call. Refused while a drip-feed run is active. |
| "Send the bytes 30 0d 0a to the Uno." | serial.send-bytes |
Sends raw bytes (hex-encoded). Whitespace in the hex string is tolerated; an odd number of digits or a non-hex character is a parameter error. |
| "Send '$I' to the Uno and tell me what it replies." | serial.send-and-wait |
Sends a line and waits for an RX regex match (or timeout). The default expect-regex is ^.+, which returns on the first non-empty line; pass (?s) patterns to match across multi-line responses. Returns the matched text plus subsequent RX lines. |
Drip-feed via the assistant
You can also drive a drip-feed run end-to-end through the assistant.
All mutators carry serial.io with every-call confirmation;
status is read-only.
| Ask | Behind the scenes | What it does |
|---|---|---|
| "Drip-feed this G-code to 'Lab Uno' …" | serial.dripfeed-start |
Starts a non-blocking run with the inline payload (≤ 1 MiB; larger payloads need the file-source variant in a future release). Pacing defaults to the connection's drip-feed config; pass pacing="manual" for step-through, "free" for no-gate. |
| "How's the drip-feed going on Lab Uno?" | serial.dripfeed-status |
Snapshots state (running / paused / finished / cancelled / errored), sent, total, pacing. Read-only — no permission scope. |
| "Pause / resume / cancel the drip-feed." | serial.dripfeed-{pause, resume, cancel} |
Lifecycle controls. All idempotent — pausing an already-paused run is a success no-op. |
| "Send the next 5 lines." | serial.dripfeed-advance |
Manual-pacing only — releases up to N lines from the gate. Errors with a "use pause / resume for ack pacing" hint when the active run isn't manual-paced. |
| "Drip-feed /data/…/job.gcode to 'Lab Uno'." | serial.dripfeed-file |
Same as dripfeed-start but reads the payload from a local file. On Android the path must resolve under the app's writable storage; out-of-sandbox paths are rejected with a "copy the file into <appDir>/files/ first" suggestion. File cap is 64 MiB. |
| For protocol-level details, build OctoMY™ from | ||
| source and consult the developer documentation that ships with the build. |