Describe master-to-slave distribution after UART OTA, partial final block, reboot, and goTool /api/ota behaviour. Co-authored-by: Cursor <cursoragent@cursor.com>
goTool
Host-side UART client for the Powerpod master ESP.
Full system documentation (roles, ESP-NOW, framing, protobuf): ../main/README.md.
Usage
cd goTool
go mod tidy
go run . -port /dev/ttyUSB0 version
go run . -port /dev/ttyUSB0 clients
| Flag | Default | Description |
|---|---|---|
-port |
(required) | Serial port on master UART (GPIO2/3 adapter) |
-baud |
921600 |
Must match firmware UART_BAUD_RATE |
Commands
| Command | UART payload | Description |
|---|---|---|
version |
0x03 |
Prints version and git_hash from firmware |
clients |
0x04 |
Lists slaves registered on the master via ESP-NOW |
unicast-test |
0x07 |
Sends ESP-NOW unicast test to one slave (-client, -seq) |
test |
— | Run an automated scenario (JSON configs under testdata/) |
serve |
— | Web dashboard at http://localhost:8080 (WebSocket live updates) |
ota |
16–19 | UART firmware upload to master; firmware then pushes to slaves via ESP-NOW |
clients requires slaves to have responded to master discover broadcasts first.
Automated tests
Bench configs (testdata/configs/) list network, MACs, and serial ports (uart.master for commands, *_console for esptool reset). Scenarios run UART commands plus optional reset steps.
go run . test -list-configs
go run . test -config example-lab -scenario smoke
go run . test -config my-lab -scenario smoke -port /dev/ttyUSB1 -v
With a complete bench config, -port is optional for test (uses uart.master from JSON).
See testdata/README.md for the JSON schema.
Web dashboard
Polls the master over UART and pushes state to the browser via WebSocket (Alpine.js + Bootstrap 5).
go run . -port /dev/ttyUSB0 serve
go run . -port /dev/ttyUSB0 serve -addr :8080 -interval 2s
make gotool-serve PORT=/dev/ttyUSB0
Open http://localhost:8080 — shows master firmware info and the ESP-NOW client table from CLIENT_INFO.
If the UART device is unplugged or the port disappears, serve keeps running and retries on each poll interval; the UI shows UART off until the port is available again.
The dashboard can configure nodes using the same UART commands as the CLI:
| UI action | CLI equivalent |
|---|---|
| Nur Master | deadzone -set -value N -client 0 |
| Einzelner Slave | deadzone -set -value N -client ID |
| Alle Slaves | per-slave ESP-NOW (Master bleibt unverändert; CLI -all setzt auch den Master) |
| Unicast test | unicast-test -client ID |
HTTP API (used by the web UI): GET/POST /api/deadzone, POST /api/unicast-test, POST /api/ota (multipart field firmware, max 2 MiB).
| UI / API | Behaviour |
|---|---|
| Firmware OTA card | Same as ota CLI; progress via WebSocket ota_progress events |
POST /api/ota |
Upload .bin to master only — slaves are updated by firmware over ESP-NOW after OTA_END |
go run . -port /dev/ttyUSB0 ota build/powerpod.bin
Waits for ready after start (~30 s erase), sends 200-byte OTA_PAYLOAD frames, reads block_ack every 4 KiB, then OTA_END. The master then distributes to all available slaves (no extra host traffic); success is reported only when that finishes. Allow several minutes for large images. Reboot master and slaves to boot the new firmware.
go run . -port /dev/ttyUSB0 unicast-test -client 16 -seq 42
On success the slave serial log should show UNICAST TEST OK from master … seq=42.
Example output:
clients (2):
[0] id=42 mac=aabbccddeeff ver=1 available=true used=false last_ping=250 last_success_ping=250
Regenerate protobuf
protoc --go_out=./pb --go_opt=paths=source_relative \
--go_opt=Muart_messages.proto=powerpod/gotool/pb \
-I ../main/proto ../main/proto/uart_messages.proto