Command-line tool

pipx install openbricks installs one console script, openbricks, which mirrors the pybricksdev workflow: flash firmware over USB, then run / upload / stop programs and pull logs over BLE. With the [sim] extra installed, openbricks sim forwards to the MuJoCo-backed simulator.

A typical session:

$ openbricks flash --name RobotA     # port, chip and newest firmware auto-detected
$ openbricks list                    # hubs in BLE range
$ openbricks run -n RobotA main.py   # push + stream output
$ openbricks upload -n RobotA main.py  # stage; start it with the hub button
$ openbricks stop -n RobotA          # Ctrl-C a running program
$ openbricks log -n RobotA           # dump the most recent run log
$ openbricks docs hardware           # open this manual offline in your browser

Firmware versions and provenance

openbricks flash first reports the firmware already on the chip — version plus an (official) / (customized) suffix — before it looks up the newest release. Flashing the same version again, or an older one, asks for confirmation first; pass --yes to skip the prompt in scripts.

Every firmware image published by CI is signed (Ed25519), and the CLI ships the matching public key. An image whose .bin.sig verifies is labeled (official); anything else — a self-built image, a missing or wrong signature — is (customized). Customized firmware flashes normally: the suffix is provenance, not a gate. After each flash the verdict is stored on the hub, which is how the next openbricks flash labels the current firmware.

The suffix follows the version everywhere it reaches you: the firmware 1.79.0 (official) banner at the top of every openbricks run, the started: header line in every run log (openbricks log), and the flash preflight above. On the hub, openbricks.firmware_label() returns the same string.

Reference

The reference below is generated from the CLI’s own argument parser, so it always matches the installed version.

Host-side CLI for flashing and running code on openbricks hubs, plus a MuJoCo-backed simulator (openbricks sim ).

usage: openbricks [-h] [--version] COMMAND ...

Positional Arguments

COMMAND

Possible choices: flash, run, upload, stop, list, log, servo-id, paste-probe, docs, doc, sim

Named Arguments

--version

Print the openbricks package version and exit.

Sub-commands

flash

Flash a firmware image onto a hub (via esptool) and write the hub’s BLE advertising name into NVS (via mpremote). –name is mandatory so every hub gets a unique identifier — two hubs with the same name can’t be individually addressed over BLE.

openbricks flash [-h] --name NAME [--port PORT] [--firmware FIRMWARE]
                 [--chip CHIP] [--baud BAUD] [--skip-erase] [--yes]
Named Arguments
--name

Hub identifier for BLE (required, <=20 chars recommended).

--port

Serial port (/dev/ttyUSB0, /dev/cu.usbserial-XXXX, COM5 …). Omit to auto-detect — works when exactly ONE ESP device is connected (Espressif native USB or a CP210x/CH340/FTDI bridge).

--firmware

Path to firmware.bin produced by scripts/build_firmware.sh or downloaded from the Releases page. Omit to download the newest release automatically for the detected chip (cached under ~/.cache/openbricks/firmware).

--chip

esptool –chip value (esp32, esp32s3, auto). Default: auto.

Default: 'auto'

--baud

esptool flash baud rate. Default: 460800.

Default: '460800'

--skip-erase

Skip erase_flash (faster dev loop; leaves stale NVS keys).

Default: False

--yes

Skip the confirmation prompt when the target firmware is the same version as (or older than) the current one.

Default: False

run

Connect to the named hub over BLE, push SCRIPT to its REPL (via paste mode), and stream stdout/stderr back to this terminal until the script finishes. Ctrl-C interrupts the remote program.

openbricks run [-h] -n NAME [-c CODE] [--scan-timeout SCAN_TIMEOUT] [--debug]
               [SCRIPT]
Positional Arguments
SCRIPT

Path to the local Python script to run on the hub. Mutually exclusive with -c.

Named Arguments
-n, --name

Hub name baked in at flash time (openbricks flash --name).

-c, --code

Inline Python code to run on the hub (analogous to python -c CODE). Useful for quick diagnostics — e.g. openbricks run -n ls -c 'import openbricks; print(openbricks.__version__)'. Mutually exclusive with the SCRIPT positional.

--scan-timeout

How long to scan for the named hub before giving up. Default: 5.0 s.

Default: 5.0

--debug

Print every BLE notify packet (timestamp + hex + ascii) to stderr as it arrives. Use to diagnose ‘timed out reading from hub’ errors — tells you whether the hub is sending anything at all.

Default: False

upload

Upload SCRIPT to the hub’s filesystem (default path /program.py). The uploaded code does NOT run automatically — the hub’s frozen main.py watches the hub button and exec’s the staged script on each short press. Second short-press stops a running program. (Pybricks calls this same operation download from the hub’s perspective; we name by direction-of-data-travel — bytes flow up to the hub.)

openbricks upload [-h] -n NAME [--path PATH] [--scan-timeout SCAN_TIMEOUT]
                  SCRIPT
Positional Arguments
SCRIPT

Path to the local Python script to stage.

Named Arguments
-n, --name

Hub name baked in at flash time.

--path

Destination path on the hub’s filesystem. Default: /program.py (which the frozen launcher reads).

Default: '/program.py'

--scan-timeout

BLE scan timeout. Default: 5.0 s.

Default: 5.0

stop

Connect to the named hub over BLE and send a single Ctrl-C, which MicroPython surfaces as KeyboardInterrupt. Use when a long-running openbricks run has already ended and you just want the hub to idle again.

openbricks stop [-h] -n NAME [--scan-timeout SCAN_TIMEOUT]
Named Arguments
-n, --name

Hub name.

--scan-timeout

BLE scan timeout. Default: 5.0 s.

Default: 5.0

list

Run a BLE scan and print every device found, sorted by RSSI (strongest first). Unnamed devices are shown with a placeholder so you can still spot a hub whose name wasn’t flashed.

openbricks list [-h] [--timeout TIMEOUT] [--all]
Named Arguments
--timeout

Scan duration in seconds. Default: 5.0.

Default: 5.0

--all

Show every BLE device, not just those with names. Useful when debugging a hub that came up without a flashed name.

Default: False

log

Every program executed via the launcher (button press OR openbricks run) gets its stdout / stderr tee’d to a flash file under /openbricks_logs/. Ten rotating slots are kept. With no flags this prints the most recent run; --list shows the index; --run N selects a specific slot. Useful for post-mortem on an untethered run where no live console was attached.

openbricks log [-h] -n NAME [--list] [--run RUN] [--scan-timeout SCAN_TIMEOUT]
Named Arguments
-n, --name

Hub name baked in at flash time.

--list

List the available run indices + their on-flash size, instead of dumping a run’s contents.

Default: False

--run

Specific run index to dump. Defaults to the most recent.

--scan-timeout

BLE scan timeout. Default: 5.0 s.

Default: 5.0

servo-id

Scans the bus (IDs 0..253), rewrites the servo’s EEPROM ID register, and verifies the result. With several servos attached, –old-id is required so the tool never guesses which one to re-ID. Wire the servo to a USB half-duplex adapter (e.g. the URT-2 board) — this talks directly to the adapter’s serial port, no hub involved.

openbricks servo-id [-h] -p PORT [--scan] [--old-id OLD_ID]
                    [--baudrate BAUDRATE] [--timeout TIMEOUT]
                    [new_id]
Positional Arguments
new_id

Bus ID to assign (0..253). Omit with –scan.

Named Arguments
-p, --port

Serial port of the USB adapter, e.g. /dev/cu.usbmodem123 (ls /dev/cu.usb*).

--scan

Just list the IDs that answer on the bus; change nothing.

Default: False

--old-id

Current ID of the servo to re-ID. Required when more than one servo is attached; otherwise auto-detected.

--baudrate

Bus baudrate. Default: 1000000 (Feetech factory).

Default: 1000000

--timeout

Per-ping serial read timeout in seconds. Default: 0.02 (a full 254-ID scan takes ~5 s).

Default: 0.02

paste-probe

Pastes padded no-op programs of increasing size through the real raw-paste path and reports the largest that completes, plus how each failure presents (truncated vs hung). Use before changing the firmware’s MICROPY_REPL_STDIN_BUFFER_MAX: two windows may be in flight at once, so that setting is only safe at or below the measured limit.

openbricks paste-probe [-h] -n NAME [--scan-timeout SCAN_TIMEOUT] [--max MAX]
                       [--timeout TIMEOUT]
Named Arguments
-n, --name

Hub BLE name.

--scan-timeout

BLE scan timeout in seconds. Default: 5.

Default: 5.0

--max

Largest size to try, bytes. Default: 8192.

Default: 8192

--timeout

Per-size timeout in seconds. Default: 15.

Default: 15.0

docs (doc)

Opens the full manual in your browser — the same Sphinx build as docs.openbricks.dev, API reference included, bundled and served from disk so no internet is needed. Pass a topic to jump straight to that page.

openbricks docs [-h] [topic]
Positional Arguments
topic

Page to open (e.g. install, hardware, robotics). Guides and API pages both work. Omit for the index.

sim

Forwards all remaining arguments to the MuJoCo-backed simulator’s CLI. Use openbricks sim --help to see the sim’s own subcommand list.

openbricks sim