Device topology and physical connection
The studio never touches hardware. Everything physical happens on the bench, through the agent process. This page introduces what the agent reaches β serial ports and the shell β how a bench is put together, and the naming conventions that keep a rack of benches intelligible.
The device under test
There are three layers, and only the innermost one is physical:
| Layer | Where it runs | What it does |
|---|---|---|
| Studio | Your server | Sends commands, shows results. No hardware access. |
| Agent | The bench that owns the device | Opens ports, runs scripts, reports results. |
| Device | The bench | The DUT, the serial peer, the networked target. |
The agent is the only process that opens a port or spawns a process on the bench. A device in DK Studio is therefore addressed the way the agent reaches it: a serial port path on the bench, or a host reachable over the network from the bench.
USB and serial
A USB-serial adapter plugged into the bench appears as a serial port. The agent finds it with the
get_serial_ports command, whose result carries a JSON array in output.stdout:
[
{
"path": "/dev/tty.usbmodem14201",
"manufacturer": "FTDI",
"serialNumber": "FT9ABCDE",
"vendorId": "0403",
"productId": "6001"
}
]Each entry describes one adapter, and the fields are the adapter's identity: the path you open it by, its manufacturer, its serial number, and the USB vendor and product ids.
The agent loads serialport lazily. On a host without the native bindings β or without the USB
permissions to see them β get_serial_ports succeeds but returns an empty array, and
open_serial fails. If the list is empty, install the agent's dependencies on that bench and
check that the user running the agent may read the port.
The serial commands are:
| Command | Args | Behaviour |
|---|---|---|
get_serial_ports | none | Lists the serial ports the agent can see. |
open_serial | path (required), baudRate (default 115200) | Opens the port. |
serial_write | path and data (both required) | Writes bytes; refused if the port is not open or not writable. |
close_serial | path (required) | Closes the port. |
{ "agentId": "6d1fβ¦", "command": "open_serial",
"args": { "path": "/dev/tty.usbmodem14201", "baudRate": 115200 } }open_serial over the command API passes only path and baudRate to the port. Framing options
β dataBits, stopBits and parity β are accepted by the agent's own local endpoint,
POST /api/serial on port 3001, and not by the socket path. Over the socket, 8 data bits, 1 stop
bit and no parity are the only settings you get.
Bytes arriving on an open port are handled on the agent and printed to its own console and local
serial panel. The studio records the serial metadata β path, manufacturer, serial number, vendor
id and product id β and receives it in device_event messages when a port connects or disconnects.
Networked targets
A target that speaks over IP β an ECU, a gateway, a DUT behind a router β is reached with the
shell command. The script runs under /bin/bash on the bench:
| Argument | Default | Meaning |
|---|---|---|
script | required | The script text. |
cwd | /tmp | The working directory. The script is written to <cwd>/.agent_script_<timestamp>.sh, mode 0755, and run. |
The timeout is not an argument: it travels beside args, as the request's own timeout, and
defaults to 300000 milliseconds.
{ "agentId": "6d1fβ¦", "command": "shell",
"args": { "script": "ping -c 3 192.168.1.42 && curl -s http://192.168.1.42/health",
"cwd": "/tmp" },
"timeout": 15000 }The result carries output.stdout, output.stderr, output.exitCode and output.durationMs.
A timeout exits with -2 and sets stderr to Command timed out after <ms>ms; a script that
cannot be spawned exits with -1.
Because the script runs on the bench, the bench needs the routes, credentials and DNS that the target requires. The studio is not on that network and does not need to be.
Test benches
A bench is a machine, an agent process, and the things plugged into it. A minimal bench needs:
| Component | Requirement |
|---|---|
| Host | Linux or macOS with Node.js 24+, pnpm 11, and bash at /bin/bash. |
| Agent | One process, installed with ./install.sh so it runs as a service and survives a reboot. |
| Licence | One licence per bench, issued from Admin β Licences. |
| Credentials | The licence code, entered once in the agent's registration form; the credentials the studio issues in return are stored in data/agent.json. |
| Hardware | Serial adapters and DUTs, reachable as ports on the bench. |
Issue one licence per bench. A licence is claimed once; presenting the same code again is refused, so a bench that is reinstalled keeps its identity only if it re-registers with the credentials it already holds β and a shared licence across a fleet makes revocation meaningless.
It holds the agent's API key and agent secret in plain text. It is also the file that makes a reinstalled bench come back with the same identity, so exclude it from image snapshots that get copied between machines, and restrict its permissions.
Naming conventions
Nothing in the product enforces a naming scheme, so pick one and apply it consistently β the agent list is only as readable as the names you give it.
| Element | Convention | Example |
|---|---|---|
| Agent name | <site>-<room>-<bench>-<role> | sh-b12-bench03-dut |
| Serial port path | The stable device path, not /dev/ttyUSB0 | /dev/serial/by-id/usb-FTDI_FT9ABCDE-if00-port0 |
| Device reference | The port path or target host as seen from the bench | 192.168.1.42 |
| Licence | One per bench, named by the bench, not by the person holding it | β |
Two rules that pay off:
- Use the
/dev/serial/by-id/path, not/dev/ttyUSB0. ThettyUSB*numbering changes when adapters are replugged or reordered; theby-idpath is derived from the adapter's serial number and does not. - Make the agent name the physical location. When a bench goes offline, the name is what tells you where to go.
Related pages
- Remote shell and serial β the command formats in depth.
- Command reference β every command and its arguments.
- Network requirements β how the bench reaches the studio.
- Agent registration and entitlements β issuing a licence per bench.