---
title: "pbl lab"
canonical_url: https://developer.repebble.com/pebbleos/docs/pbl/lab/
last_updated: 2026-11-02
sdk_version: 4.33.1
---
# pbl lab

Source: https://developer.repebble.com/pebbleos/docs/pbl/lab/

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.

## Lab files

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@pvtserial: /dev/tty.wchusbserial5B7A1355001getafix:board: getafix@dvt2serial: /dev/tty.wchusbserial5B7A1354971supply: ppk2asterix:board: asterixserial: /dev/tty.usbmodem0010500000001probe: 1366:1051:001050000000# Power supplies (see docs/pbl/power.md for the types); one powers one# watch at a time.supplies:ppk2:type: ppk2port: 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](https://developer.repebble.com/pebbleos/docs/pbl/run.md), [pbl erase](https://developer.repebble.com/pebbleos/docs/pbl/erase.md), [pbl debug](https://developer.repebble.com/pebbleos/docs/pbl/debug.md) and [pbl debugserver](https://developer.repebble.com/pebbleos/docs/pbl/debugserver.md) (`--tty`, `--probe`), [pbl console](https://developer.repebble.com/pebbleos/docs/pbl/console.md) (`--tty`, `--baudrate`), [pbl image\_resources](https://developer.repebble.com/pebbleos/docs/pbl/image_resources.md) and [pbl image\_recovery](https://developer.repebble.com/pebbleos/docs/pbl/image_recovery.md) (`--tty`), and [pbl itest](https://developer.repebble.com/pebbleos/docs/pbl/itest.md), 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. [pbl power](https://developer.repebble.com/pebbleos/docs/pbl/power.md) powers it with its supply. With a lab in place, a watch is a `pbl run` away:

```
pbl run --resources
pbl console
```

## Locks

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](https://developer.repebble.com/pebbleos/docs/pbl/itest.md) 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 `flock`s 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.

## Options

```
pbl lab [-h] [-b DIR] [--dry-run] [--lab FILE] [--watch NAME] [--json]
```

`--json`

Print it as JSON

Generated from PebbleOS [75673c495](https://github.com/coredevices/pebbleos/commit/75673c4953f885989a721d882f39939bc6c8e56b). This page is maintained in the pebbleos repository: [docs/pbl/lab.md](https://github.com/coredevices/pebbleos/blob/75673c4953f885989a721d882f39939bc6c8e56b/docs/pbl/lab.md).
