REST API#

dotbot run controller exposes a FastAPI REST server for reading DotBot state and sending commands. The React web UI and the MQTT bridge use the same controller; REST is the simplest way to script the swarm from your own code.

Where it lives#

Start a controller (see dotbot run):

dotbot run controller --conn /dev/ttyACM0          # serial gateway
dotbot run controller --conn mqtts://broker:8883 --swarm-id 1234   # over MQTT

The server listens on port 8000 by default (--controller-http-port to change it). Interactive OpenAPI docs - schemas, payloads, and a “try it out” button - are served by the running app at:

http://localhost:8000/api
OpenAPI UI

That page is the authoritative, version-matched reference. The table below is a quick map; treat /api as the source of truth.

Endpoints#

All paths are under http://localhost:8000. {address} is the 8-byte hex DotBot id; {application} is 0 (DotBot) or 1 (SailBot).

Method

Path

Purpose

GET

/controller/dotbots

List connected DotBots

GET

/controller/dotbots/{address}

One DotBot’s state

GET

/controller/map_size

Controller map size

GET

/controller/background_map

Background map image (base64)

PUT

/controller/dotbots/{address}/{application}/move_raw

Drive the motors

PUT

/controller/dotbots/{address}/{application}/rgb_led

Set the RGB LED

PUT

/controller/dotbots/{address}/{application}/waypoints

Set navigation waypoints

DELETE

/controller/dotbots/{address}/positions

Clear position history

Two WebSocket endpoints push live updates: /controller/ws/status (state stream) and /controller/ws/dotbots (send move_raw / rgb_led / waypoints as JSON).

Quick examples#

Install requests: pip install requests.

List DotBots - address identifies a bot; status is 0 active, 1 inactive, 2 lost.

import requests
print(requests.get("http://localhost:8000/controller/dotbots").json())

Set the RGB LED (red/green/blue, 0–255):

import requests
addr = "9903ef26257feb31"   # from the list above
requests.put(
    f"http://localhost:8000/controller/dotbots/{addr}/0/rgb_led",
    json={"red": 255, "green": 0, "blue": 0},
)

Drive the motors - only left_y / right_y are used; values in [-100, 100], and absolute values below ~50 won’t overcome friction.

import requests
addr = "9903ef26257feb31"
requests.put(
    f"http://localhost:8000/controller/dotbots/{addr}/0/move_raw",
    json={"left_x": 0, "left_y": 60, "right_x": 0, "right_y": 60},
)

Motors stop after 200 ms

The firmware halts the motors if no move_raw arrives within 200 ms. To keep a DotBot moving, send commands in a loop with a delay under 200 ms.