Skip to content

Commit 62bf653

Browse files
authored
Merge pull request #266 from geonnave/config-cli-wiring
config: unify the dotbot CLI config into one file (dotbot -c config.toml)
2 parents c2147ec + 11fb85e commit 62bf653

36 files changed

Lines changed: 2850 additions & 151 deletions

‎AGENTS.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pip install pydotbot # or `pip install -e .`
2727
dotbot --help # unified dispatcher: fw / device / swarm / run
2828
dotbot fw --help # firmware artifacts: build / fetch / list / make
2929
dotbot device --help # one cabled device: flash an app/role, read info
30-
dotbot swarm --help # the fleet over the air (optional: pip install pydotbot[swarm])
30+
dotbot swarm --help # the fleet over the air (swarmit; in the base install)
3131
dotbot run --help # host-side processes (controller, gateway, simulator, ...)
3232
dotbot run controller --help # start the controller
3333
dotbot run lh2-calibration --help # LH2 calibration (optional: pip install pydotbot[calibrate])
@@ -52,8 +52,9 @@ CI: `.github/workflows/continuous-integration.yml` — `tox` on Linux/macOS/Wind
5252
- **`PyDotBot-utils`** — `pyproject.toml:49`; used by `utils/hooks/sdist.py:build_frontend`
5353
- **`DotBot-libs`** — checked out in CI to build `utils/control_loop` C library
5454
- **`DotBot-firmware`** — referenced only in README (flashing instructions); no code dep
55-
- **`swarmit`** — optional sibling package (`pyproject.toml`'s
56-
`[testbed]` extra); imported lazily inside `dotbot/cli/testbed.py`.
55+
- **`swarmit`** — sibling package, a core dependency (`pyproject.toml`);
56+
imported lazily inside `dotbot/cli/swarm.py`, which bridges the unified
57+
config's `conn`/`swarm_id` into swarmit's flags at the mount boundary.
5758
- **`dotbot-provision`** — vendored into `dotbot/provision/` (Phase 2,
5859
2026-05). Standalone PyPI package scheduled for deprecation.
5960
- **`dotbot-lh2-calibration` (Python)** — vendored into

‎README.md‎

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ talk to it, and it drives the swarm through a gateway.
4242
See the whole thing run with nothing but Python:
4343

4444
```bash
45-
pip install --pre pydotbot
45+
pip install --pre pydotbot # using 'pre' while we are at release candidate
4646
dotbot run simulator -w # opens the web UI at http://localhost:8000/PyDotBot/, driving a simulated swarm
4747
```
4848

@@ -61,11 +61,13 @@ import requests, time
6161
BASE = "http://localhost:8000"
6262
bot = requests.get(f"{BASE}/controller/dotbots").json()[0]["address"]
6363

64-
# roll forward for ~1 s - the motors stop after 200 ms, so keep sending
65-
for _ in range(10):
64+
# roll in a circle for ~5 s - left_y and right_y are the two wheel speeds
65+
for _ in range(50):
6666
requests.put(f"{BASE}/controller/dotbots/{bot}/0/move_raw",
67-
json={"left_x": 0, "left_y": 60, "right_x": 0, "right_y": 60})
67+
json={"left_x": 0, "left_y": 60, "right_x": 0, "right_y": 30})
6868
time.sleep(0.1)
69+
requests.put(f"{BASE}/controller/dotbots/{bot}/0/move_raw",
70+
json={"left_x": 0, "left_y": 0, "right_x": 0, "right_y": 0})
6971
```
7072

7173
The full surface - every endpoint, the live WebSocket stream, and CSV data
@@ -92,7 +94,7 @@ Minimal hardware setup:
9294
## Install
9395

9496
```bash
95-
pip install --pre 'pydotbot[swarm]' # --pre while 0.29 is in pre-release
97+
pip install --pre pydotbot # --pre while 0.29 is in pre-release
9698
git clone --recurse-submodules --branch develop https://github.com/DotBots/DotBot-firmware.git
9799
```
98100

@@ -120,10 +122,13 @@ Every command and flag is documented in the [CLI reference][cli-doc].
120122
Build and flash firmware for a single dotbot:
121123

122124
```bash
123-
# build the bare dotbot app into ./artifacts/ (needs SEGGER Embedded Studio)
125+
# build the bare dotbot apps into ./artifacts/ (needs SEGGER Embedded Studio)
126+
# two steps because the DotBot has two cores
124127
dotbot fw artifacts --app dotbot
128+
dotbot fw artifacts --app nrf5340_net --target nrf5340dk-net
125129
# cable-flash it to the bot whose J-Link serial starts with 77
126-
dotbot device flash dotbot -s 77
130+
dotbot device flash dotbot -s 77 # app core
131+
dotbot device flash nrf5340_net -b nrf5340dk-net -s 77 # network core
127132
```
128133

129134
Now, build and flash the gateway to connect to a robot.
@@ -132,7 +137,7 @@ computer; it bridges the robot's radio to USB serial.
132137

133138
```bash
134139
# build the gateway firmware for your DK board into ./artifacts/ (needs SEGGER Embedded Studio)
135-
dotbot fw artifacts --app dotbot_gateway -t nrf52840dk
140+
dotbot fw artifacts --app dotbot_gateway --target nrf52840dk
136141
# cable-flash it to the DK whose J-Link serial starts with 10
137142
dotbot device flash dotbot_gateway -b nrf52840dk -s 10
138143
```
@@ -151,60 +156,58 @@ and driving it from the web UI ([controller guide][controller-doc]).
151156

152157
### setup the swarm
153158

154-
To operate as a swarm, we need to fetch some firmware, and setup a configuration file:
159+
To operate as a swarm, set your swarm connection config:
155160

156161
```bash
157-
# pull the pre-compiled firmwares from a release
158-
dotbot fw fetch -f 0.8.0rc1 # or build yourself with: dotbot fw artifacts --sandbox
159-
# configure where to connect and which swarm
160-
cat > swarm-config.toml <<'EOF'
161-
conn = "mqtts://argus.paris.inria.fr:8883"
162-
swarm_id = "1234"
163-
EOF
162+
dotbot config init --conn mqtts://argus.paris.inria.fr:8883 --swarm-id 1234
164163
```
165164

166-
> `argus.paris.inria.fr` is our Inria Paris broker and `1234` our swarm - replace
167-
> `conn` and `swarm_id` with your own broker and swarm id (your testbed admin
168-
> provides these).
165+
> `argus.paris.inria.fr` is our Inria Paris broker and `1234` our swarm - pass
166+
> your own `--conn` and `--swarm-id` (your testbed admin provides these). This
167+
> writes `./dotbot.toml`; commands run from this directory pick it up, so you
168+
> don't repeat the flags. Full schema: the [configuration reference][config-doc].
169169
170170
The swarm mode also requires a special "sandbox" firmware in each dotbot.
171-
We also need a more powerful gateway firmware.
172-
Let's flash both:
171+
We also need a more powerful gateway firmware. Let's flash both - the network
172+
id comes from your config:
173173

174174
```bash
175-
dotbot device flash-mari-gateway -n 1234 -s 10 -f 0.8.0rc1 # flash the gateway, setting its swarm id to 0x1234
176-
dotbot device flash-swarmit-sandbox -n 1234 -s 77 -f 0.8.0rc1 # flash the sandbox firmware - do this on each dotbot
175+
dotbot fw fetch -f 0.8.0rc1 # pull the pre-compiled firmwares from a release
176+
dotbot device flash-mari-gateway -s 10 -f 0.8.0rc1 # flash the gateway
177+
dotbot device flash-swarmit-sandbox -s 77 -f 0.8.0rc1 # the sandbox firmware - do this on each dotbot
177178
```
178179

179180
(`device flash-mari-gateway` / `flash-swarmit-sandbox` auto-fetch
180181
the release into `./artifacts/` if it isn't already there.)
181182

182-
Now, run the gateway:
183+
Now, run the gateway (the broker comes from your config):
183184

184185
```bash
185-
dotbot run gateway -m mqtts://argus.paris.inria.fr:8883 -p /dev/cu.usbmodem0010500324491
186+
dotbot run gateway -p /dev/cu.usbmodem0010500324491
186187
```
187188

188189
### use the swarm
189190

190-
191191
You can flash as many dotbots as you want, all at once! First, how about making them spinnnn 🔄 🔄
192192

193193
```bash
194-
dotbot swarm -c swarm-config.toml flash ./artifacts/spin-sandbox-dotbot-v3.bin -ys # flash the whole fleet with a simple spinning app
194+
dotbot swarm flash ./artifacts/spin-sandbox-dotbot-v3.bin -ys # flash the whole fleet with a simple spinning app
195195
```
196196

197+
(`dotbot swarm` reads the same `dotbot.toml` as the rest - pass `--conn` /
198+
`--swarm-id` to override it for one run.)
199+
197200
Then, flash another experiment:
198201

199202
```bash
200-
dotbot swarm -c swarm-config.toml stop # ensure all robots are in bootloader
201-
dotbot swarm -c swarm-config.toml flash ./artifacts/dotbot-sandbox-dotbot-v3.bin -ys # this firmware allows bots to be remote-controlled
203+
dotbot swarm stop # ensure all robots are in bootloader
204+
dotbot swarm flash ./artifacts/dotbot-sandbox-dotbot-v3.bin -ys # this firmware allows bots to be remote-controlled
202205
```
203206

204207
Observe and control your swarm from a web interface:
205208

206209
```bash
207-
dotbot run controller --conn mqtts://argus.paris.inria.fr:8883 --swarm-id 1234 -w # will open a webpage at http://localhost:8000/PyDotBot/
210+
dotbot run controller -w # will open a webpage at http://localhost:8000/PyDotBot/
208211
```
209212

210213
Full walkthrough of fleet operations - status, OTA flash, start/stop, monitor -
@@ -222,8 +225,8 @@ dotbot device flash lh2_calibration -s 77
222225
dotbot run lh2-calibration collect -p /dev/tty.usbmodem0007745943981 -d 200 # square of side 20 cm
223226

224227
# 2. push the resulting calibration to the fleet over the air
225-
dotbot swarm -c swarm-config.toml stop # ensure all robots are in bootloader
226-
dotbot swarm -c swarm-config.toml calibrate-lh2 ~/.dotbot/calibration-2026-05-26T14-00-36Z.toml
228+
dotbot swarm stop # ensure all robots are in bootloader
229+
dotbot swarm calibrate-lh2 ~/.dotbot/calibration-2026-05-26T14-00-36Z.toml
227230
```
228231

229232
Your bots now report their `(x, y)` location. The full setup - arena sizing,
@@ -236,12 +239,10 @@ Full command reference and guides - running the controller + web UI, the four
236239
CLI namespaces (`fw` / `device` / `swarm` / `run`), hardware, and LH2
237240
calibration - are in the [documentation][doc-link].
238241

239-
Some commands need optional runtime deps:
242+
Swarm orchestration is in the base install. Only LH2 calibration needs an extra:
240243

241244
```bash
242-
pip install --pre 'pydotbot[swarm]' # swarmit (fleet orchestration)
243245
pip install --pre 'pydotbot[calibrate]' # opencv-python + textual (LH2 calibration)
244-
pip install --pre 'pydotbot[all]' # everything
245246
```
246247

247248
Hitting a snag (e.g. the web UI not loading in Firefox)? See
@@ -274,6 +275,7 @@ See `LICENSE` in each component repository.
274275
[fw-doc]: https://pydotbot.readthedocs.io/en/latest/cli/fw.html
275276
[device-doc]: https://pydotbot.readthedocs.io/en/latest/cli/device.html
276277
[swarm-doc]: https://pydotbot.readthedocs.io/en/latest/cli/swarm.html
278+
[config-doc]: https://pydotbot.readthedocs.io/en/latest/reference/configuration.html
277279
[controller-doc]: https://pydotbot.readthedocs.io/en/latest/guides/controller.html
278280
[lh2-doc]: https://pydotbot.readthedocs.io/en/latest/guides/lh2-calibration.html
279281
[troubleshooting-doc]: https://pydotbot.readthedocs.io/en/latest/reference/troubleshooting.html

‎doc/cli/device.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ dotbot device flash nrf5340_net -b nrf5340dk-net -s 10
7171
| `-b, --board` | Target board → chip family + core (default `dotbot-v3`) |
7272
| `-s, --sn-starting-digits` | J-Link serial **prefix**, e.g. `77` (v3) or `10` (DK) |
7373
| `--sandbox` | Resolve the sandbox-app flavor (`.bin`) |
74-
| `-c, --config` | `Debug` \| `Release` (default `Release`) |
74+
| `--build-config` | `Debug` \| `Release` (default `Release`) |
7575

7676
## Flash a role
7777

‎doc/cli/fw.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ Studio (SES). Point the CLI at the checkout (otherwise it looks for
1515

1616
```bash
1717
export DOTBOT_FIRMWARE_REPO=/path/to/DotBot-firmware
18+
# or persist it once in ~/.dotbot/config.toml:
19+
# [fw]
20+
# firmware_repo = "/path/to/DotBot-firmware"
1821
```
1922

2023
## Which command do I want?
@@ -43,7 +46,7 @@ Both share the same build options:
4346
|---|---|
4447
| `-a, --app <app>` | Build one app (default: every app for the target) |
4548
| `-t, --target <target>` | Board/target (default: `dotbot-v3`) |
46-
| `-c, --config Debug\|Release` | Build config (default: `Release`) |
49+
| `--build-config Debug\|Release` | Build configuration (default: `Release`) |
4750
| `--sandbox` | TrustZone NS flavor → `sandbox-<board>`, emits `.bin` |
4851
| `--rebuild` | Force a full rebuild (default: incremental) |
4952
| `-v, --verbose` | Full SES output |

‎doc/cli/swarm.md‎

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ see [`fw`](fw.md). The host bridge and dashboard come from [`run`](run.md).
1414
1. provision (once) device flash-mari-gateway + device flash-swarmit-sandbox
1515
2. host bridge run gateway (UART <-> MQTT)
1616
3. build the payload fw artifacts --sandbox (or fw fetch)
17-
4. operate swarm -c config flash | start | stop | status | monitor
17+
4. operate swarm flash | start | stop | status | monitor
1818
```
1919

2020
## 1. Provision once
@@ -70,24 +70,24 @@ The connection is given as global options *before* the subcommand, or in a
7070
See `dotbot swarm --help` for the full list.
7171

7272
```bash
73-
cat > tb-config.toml <<'EOF'
74-
conn = "mqtts://argus.paris.inria.fr:8883"
75-
swarm_id = "1234"
76-
EOF
73+
dotbot config init --conn mqtts://argus.paris.inria.fr:8883 --swarm-id 1234
7774
```
7875

79-
If the broker needs auth, set `DOTBOT_MQTT_USER` / `DOTBOT_MQTT_PASS`.
76+
This writes `./dotbot.toml`; `dotbot swarm` discovers it from the current
77+
directory like the other `dotbot` commands (pass `--conn` / `--swarm-id` / `-c`
78+
to override). If the broker needs auth, set `DOTBOT_MQTT_USER` /
79+
`DOTBOT_MQTT_PASS`.
8080

8181
## 5. Operate the fleet
8282

8383
```bash
84-
dotbot swarm -c tb-config.toml status # who's out there + their state
85-
dotbot swarm -c tb-config.toml status -w # keep watching
86-
dotbot swarm -c tb-config.toml flash ./artifacts/spin-sandbox-dotbot-v3.bin -ys
87-
dotbot swarm -c tb-config.toml stop # back to bootloader (before re-flashing)
88-
dotbot swarm -c tb-config.toml start # (re)start the loaded app
89-
dotbot swarm -c tb-config.toml monitor # tail SWARMIT_EVENT_LOG from bots
90-
dotbot swarm -c tb-config.toml message "hello" # custom text to the bots
84+
dotbot swarm status # who's out there + their state
85+
dotbot swarm status -w # keep watching
86+
dotbot swarm flash ./artifacts/spin-sandbox-dotbot-v3.bin -ys
87+
dotbot swarm stop # back to bootloader (before re-flashing)
88+
dotbot swarm start # (re)start the loaded app
89+
dotbot swarm monitor # tail SWARMIT_EVENT_LOG from bots
90+
dotbot swarm message "hello" # custom text to the bots
9191
```
9292

9393
To replace a running experiment: `stop`, then `flash ... -ys`.
@@ -107,8 +107,8 @@ Send a calibration (captured from one cabled bot - see
107107
[LH2 calibration](../guides/lh2-calibration.md)) to the whole fleet:
108108

109109
```bash
110-
dotbot swarm -c tb-config.toml stop
111-
dotbot swarm -c tb-config.toml calibrate-lh2 ~/.dotbot/calibration-<UTC>.toml
110+
dotbot swarm stop
111+
dotbot swarm calibrate-lh2 ~/.dotbot/calibration-<UTC>.toml
112112
```
113113

114114
It accepts a `calibration-*.toml` or the legacy raw payload; the format is
@@ -118,7 +118,7 @@ picked by file extension.
118118

119119
| Command | What it serves | Default port |
120120
|---|---|---|
121-
| `dotbot run controller --conn ... --swarm-id ... -w` | drive/visualize Web UI + REST/WS | `8000` |
121+
| `dotbot run controller -w` | drive/visualize Web UI + REST/WS | `8000` |
122122
| `dotbot swarm serve` | SwarmIT FastAPI orchestration backend | `8001` |
123123

124124
`dotbot swarm` auto-discovers a running `serve` daemon; pass `--no-server` to

‎doc/conf.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@
130130
# YouTube (demo video + its thumbnail) bot-blocks the linkcheck crawler.
131131
r"https://www\.youtube\.com/",
132132
r"https://img\.youtube\.com/",
133+
# Badge services (shields.io, badge.fury.io) are decorative and
134+
# intermittently time out or rate-limit the linkcheck bot.
135+
r"https://img\.shields\.io/",
136+
r"https://badge\.fury\.io/",
133137
]
134138

135139
# -- Options for autosummary/autodoc output -----------------------------------

‎doc/guides/controller.md‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,22 @@ the UI with no robot or gateway.
4242

4343
## Use a config file
4444

45-
Keep your connection settings in a TOML file instead of repeating flags:
45+
Save your connection once instead of repeating flags:
4646

4747
```bash
48-
# use settings from the config file
49-
dotbot run controller --config-path swarm-config.toml
48+
# save where to connect (writes ./dotbot.toml)
49+
dotbot config init --conn mqtts://broker:8883 --swarm-id 1234
5050

51-
# use the config file but override the connection (run a simulator instead)
52-
dotbot run controller --config-path swarm-config.toml --conn simulator
51+
# the controller picks it up automatically when run from here
52+
dotbot run controller
53+
54+
# override the saved connection for one run (a simulator instead)
55+
dotbot run controller --conn simulator
5356
```
5457

55-
CLI flags override config-file values when both are given.
58+
CLI flags override config-file values when both are given. See the
59+
[configuration reference](../reference/configuration.md) for how the file is
60+
discovered and the full schema.
5661

5762
## The web UI
5863

‎doc/guides/lh2-calibration.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ Send the captured calibration over the air. Stop any running app first, then
8888
push the `.toml` (see [swarm](../cli/swarm.md) for the connection config):
8989

9090
```bash
91-
dotbot swarm -c tb-config.toml stop
92-
dotbot swarm -c tb-config.toml calibrate-lh2 ~/.dotbot/calibration-<UTC>.toml
91+
dotbot swarm stop
92+
dotbot swarm calibrate-lh2 ~/.dotbot/calibration-<UTC>.toml
9393
```
9494

9595
`calibrate-lh2` accepts either a `calibration-*.toml` or the legacy raw

0 commit comments

Comments
 (0)