Brookesia USB CLI
brookesia-usb controls the ESP-Brookesia USB service over a single serial
transport: the CDC-ACM channel of USB Serial/JTAG, or a UART for boards that
only expose a USB-to-UART bridge. The protocol version is 1.
Install
python -m pip install brookesia-usb
The install pulls in pyserial. Check the installed version:
brookesia-usb --version
Port selection
The CLI discovers the port automatically and verifies the device with the
protocol hello command. It prefers USB Serial/JTAG and falls back to a
USB-to-UART bridge when no Serial/JTAG port is present:
- USB Serial/JTAG candidates (Espressif VID:PID
0x303A:0x1001or a matching port description) are probed first. - USB-to-UART candidates (common bridge VID:PID pairs,
/dev/ttyUSB*, or non-Serial/JTAG/dev/ttyACM*) are probed next.
brookesia-usb devices
brookesia-usb status
brookesia-usb --port /dev/ttyACM0 status
brookesia-usb --port /dev/ttyUSB0 --baudrate 921600 status
--port: Serial/JTAG (/dev/ttyACM*) or USB-to-UART (/dev/ttyUSB*) path. Omitted means automatic discovery.--baudrate: ignored for USB Serial/JTAG, which has no physical baud rate. For a UART transport it must match the device console baud rate (for exampleCONFIG_ESP_CONSOLE_UART_BAUDRATE). Default115200.--timeout: per-read and write timeout in seconds. Default10.
When several matching devices are present, pass --port explicitly using a path
reported by devices. A single Serial/JTAG CDC configuration normally exposes
only /dev/ttyACM0; the absence of /dev/ttyACM1 is expected.
Opening a USB-to-UART port resets the device, so the CLI retries hello until
the service is ready. Close idf.py monitor, minicom, or any other program that
reads the same port before running a command.
Control sessions
Commands that need a control session send hello and validate protocol version
1, the transport reported by the device (serial_jtag or uart), and the
exclusive session state, then send goodbye on exit. Device logs are
suppressed for the duration of the session so they cannot corrupt JSON responses
or file frames.
Commands
List devices
List all serial devices and identify the Serial/JTAG candidate:
brookesia-usb devices
This command does not open a control session and returns non-zero when no serial device is found.
Get service status
Query the USB service, transport connection, session state, and active transfer:
brookesia-usb status
brookesia-usb --port /dev/ttyACM0 status
Call a service function
Call any registered Brookesia service function whose arguments can be
represented by the service JSON schema. Use Manager to discover the
available services and functions:
brookesia-usb call Manager GetServiceNames '{}'
brookesia-usb call Manager GetServiceSchema '{"Name":"Storage"}'
brookesia-usb call SystemCore GetSystemInfo '{}'
brookesia-usb call SystemCore GetStorageLayout '{}'
brookesia-usb call Storage FSStat '{"Path":"/littlefs"}'
brookesia-usb call Storage FSList '{"Path":"/littlefs"}'
The JSON argument must be an object and parameter names and types must match the function schema. ServiceManager applies required-parameter, default-value, unknown-parameter, and type validation on the device. This includes service functions that modify storage, such as remove and rename; the USB Serial/JTAG connection is treated as a trusted control boundary.
Functions that require a RawBuffer argument cannot be called through this
JSON interface because a host pointer is not valid in device memory. Use
put or install for file and package data instead.
Calling the Usb service itself is rejected to prevent recursive calls into
the active USB control session.
Upload a file
Upload a local file to a relative path under the configured device upload root
(/littlefs/usb by default):
brookesia-usb put ./logs/session.bin logs/session.bin
The CLI calculates the file size and SHA-256 digest, sends CRC-protected 16 KiB-or-smaller frames, waits for an ACK after every data frame, and reports progress on stderr.
Absolute paths, .. path components, symbolic-link escapes, and destinations
outside the upload root are rejected. Existing files are not overwritten by
default. To explicitly replace an existing file:
brookesia-usb put ./config/device.json config/device.json --overwrite
The device accepts files up to the configured maximum, initially 8 MiB. A transfer is first written to a temporary file and is renamed or handed to the system bridge only after size and SHA-256 verification succeeds.
Install a BPK package
Send a complete BPK package to the device for validation and installation:
brookesia-usb install ./build/my_app.bpk
The package is staged in the USB temporary directory. The system_core bridge performs the existing manifest, ZIP path-safety, staging, replacement, and rollback checks. The host cannot select an application directory directly.
The CLI never retries an installation after a disconnect or an ambiguous failure. Re-run the command only after checking the device status.
Abort a transfer
Abort the active transfer by request ID:
brookesia-usb abort 42
abort is an emergency command and does not start a new control session. It
removes the temporary file and returns an aborted response when request 42
is active. An unknown request ID returns a device error and a non-zero exit
status.
Errors and exit status
The CLI prints errors to stderr and returns 0 only after the requested device
operation succeeds. It returns 1 for transport, protocol, validation, or
device errors. Common device error codes include:
invalid_command: malformed JSON or unsupported operation;busy: another control session or transfer is active;bad_frame: invalid CRC, frame type, or sequence;size_mismatch/hash_mismatch: declared metadata does not match data;path_denied: unsafe path or overwrite not explicitly enabled;storage_full: temporary storage cannot be created or written;install_failed: system_core rejected or failed to install the package;timeout: no host activity within the configured timeout;aborted: the host or device cancelled the transfer.
If the board is not found, first check the Serial/JTAG Type-C cable and inspect the available devices:
ls /dev/ttyACM*
brookesia-usb devices
Close idf.py monitor, minicom, or another program that is reading
/dev/ttyACM0 before running a control command; Serial-JTAG has one shared
CDC channel and cannot safely multiplex competing readers.
The absence of /dev/ttyACM1 is expected for the Serial-JTAG single-CDC
configuration.
Development
Install from a source checkout together with the test extras, then run the lint and unit tests:
python -m pip install -e "tools/brookesia_usb[test]"
python -m flake8 --config=.flake8 tools/brookesia_usb/src tools/brookesia_usb/tests
python -m pytest tools/brookesia_usb/tests
Release
The package is published manually with twine.
-
Bump
versionintools/brookesia_usb/pyproject.toml. -
Build and validate the distribution:
python -m pip install --upgrade build twine python -m build tools/brookesia_usb python -m twine check tools/brookesia_usb/dist/*
-
Upload with a PyPI API token (or an interactive prompt):
python -m twine upload tools/brookesia_usb/dist/*
-
Tag the release, for example
usb-cli-v0.2.0.
Release files for brookesia-usb 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| brookesia_usb-0.1.1.tar.gz | 20.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| brookesia_usb-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.7 kB
Release files / brookesia_usb-0.1.1.tar.gz
| Download URL | brookesia_usb-0.1.1.tar.gz |
|---|---|
| Size | 20.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fa8fe244388c5e8830207f8d195a8c61c0560faa5cba2a435bcff06393451e11
|
|
BLAKE2b-256 checksum How to use checksums |
49c7efc78bfa64ef9cf68004274fbe365a57a18380aaf62d1faceac761098478
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.12
|
Release files / brookesia_usb-0.1.1-py3-none-any.whl
| Download URL | brookesia_usb-0.1.1-py3-none-any.whl |
|---|---|
| Size | 15.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
96af63e95d9a22d4d0e0a0b1cbcbea188ac005921f59f8e1126ba606e23dfbb3
|
|
BLAKE2b-256 checksum How to use checksums |
e683bd9179eff36b3534589f232538783c49e1ae519f5db311dfdc25c6c697f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.12
|