Show the lab: the watches, power supplies and Bluetooth dongles wired to this host, whether their ports are there, which session holds them, and the watch the build runs on.
pbl lab
pbl lab --json
lab: /home/me/.config/pbl/lab.yaml
build: build (obelix@pvt), on watch obelix
watches:
* obelix: obelix@pvt
serial: /dev/tty.wchusbserial5B7A1355001, in use by pid 4242 (pbl console, since 2026-11-02T10:12:03+01:00, in /home/me/pebbleos)
getafix: getafix@dvt2
serial: /dev/tty.wchusbserial5B7A1354971 (missing)
supply: ppk2
supplies:
ppk2: ppk2, auto
--json prints the same for scripts and agents: per port, present
(false when the device node is not there, null when it cannot tell)
and locked_by, the session holding it.
A lab file (YAML) describes the hardware wired to this host, and nothing
else. pbl reads it from --lab, else $PBL_LAB, else
~/.config/pbl/lab.yaml.
tools/libs/pbl-cli/lab.example.yaml describes the format:
# A lab: the hardware wired to this host. pbl reads it from --lab, else
# $PBL_LAB, else ~/.config/pbl/lab.yaml. Commands that reach a watch take
# its ports from the watch running the build; command-line options override
# it. `pbl lab` shows it.
# Watches, by name. `board` may leave out the revision to match any.
# `serial` is the debug serial port (console, sftool, serial debuggers),
# `probe` the debug probe as the probe-rs runner names it, `supply` the one
# wired to its battery terminals.
watches:
obelix:
board: obelix@pvt
serial: /dev/tty.wchusbserial5B7A1355001
getafix:
board: getafix@dvt2
serial: /dev/tty.wchusbserial5B7A1354971
supply: ppk2
asterix:
board: asterix
serial: /dev/tty.usbmodem0010500000001
probe: 1366:1051:001050000000
# Power supplies; one powers one watch at a time.
supplies:
ppk2:
type: ppk2
port: auto # or the PPK2's data port
# Bluetooth dongles: nRF52840s running an H4 HCI UART firmware (see qemu.md),
# by serial port. The integration tests' phone takes the first; the
# emulator, with --bt-hci lab, takes the first and the phone the second.
dongles:
dongle-a:
port: /dev/cu.usbmodem112401
Commands that reach a watch take the ports the command line leaves out
from the lab’s watch for the build: pbl run, pbl erase,
pbl debug and pbl debugserver (--tty, --probe), pbl console
(--tty, --baudrate), pbl image_resources and pbl image_recovery
(--tty), and pbl itest, which takes its whole setup from it. The watch
is the one given with --watch, else the one on the port given with
--tty, else the one running the build’s board; when several do, --watch
has to pick one. With a lab in place, a watch is a pbl run away:
pbl run --resources
pbl console
While a command uses a port, it holds a lock on it, so that sessions running in parallel, people or agents, do not use the same watch at once. Another command that needs the port fails right away, naming who holds it:
error: serial port /dev/tty.wchusbserial5B7A1355001 is in use by pid 4242 (pbl console, since 2026-11-02T10:12:03+01:00, in /home/me/pebbleos)
Serial ports are locked by their device path, whether given with --tty or
taken from the lab, so a pbl console on the debug UART blocks the sftool
runner, which needs the same port, but not an openocd flash over the
probe. Debug probes are locked per lab watch. An pbl itest session on a
watch holds all of its ports, its supply and its dongles for as long as it
runs; the commands it runs itself go through.
The locks are flocks on files in $PBL_LOCK_DIR (default: a pbl-<uid>
directory in the system’s temporary directory). The kernel drops them when
their process exits, so a crashed session leaves none behind.
pbl lab [-h] [-b DIR] [--dry-run] [--lab FILE] [--watch NAME] [--json]
--jsonPrint it as JSON
Generated from PebbleOS bdb74b4cd. This page is maintained in the pebbleos repository: docs/pbl/lab.md.