Expose the command via goTool CLI/REST and dashboard controls so log verbosity can be tuned without reflashing. Co-authored-by: Cursor <cursoragent@cursor.com>
149 lines
6.3 KiB
Markdown
149 lines
6.3 KiB
Markdown
# goTool
|
||
|
||
Host-side UART client for the Powerpod **master** ESP.
|
||
|
||
Full system documentation (roles, ESP-NOW, framing, protobuf): [`../main/README.md`](../main/README.md).
|
||
|
||
## Usage
|
||
|
||
```bash
|
||
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 |
|
||
| `deadzone` | `0x06` | Get/set accelerometer deadzone LSB (`-set`, `-value`, `-client`, `-all`) |
|
||
| `tap-notify` | `0x1b` | Get/set which tap kinds (single/double/triple) notify via ESP-NOW (`-set`, `-client`, `-all`, `-single`, `-double`, `-triple`) |
|
||
| `cache-status` | `0x1d` | Subscribed accel + tap cache (`CACHE_STATUS`); one UART round-trip for 16 ms polling |
|
||
| `unicast-test` | `0x07` | Sends ESP-NOW unicast test to one slave (`-client`, `-seq`) |
|
||
| `echo-ping` | `0x1e` | ESP-NOW echo round-trip to one slave (`-client`); prints `rtt_ms` (host UART chain) and `esp_rtt_us` (master ESP-NOW, raw µs) |
|
||
| `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 |
|
||
| `ota-progress` | 21 | Query per-slave ESP-NOW OTA progress on the master (`-client N`, default all) |
|
||
| `led-ring` | 8 | LED ring: `-mode clear\|color\|progress\|digit\|blink\|find-me`, `-client`, `-all` |
|
||
| `find-me` | 22 | Locate pod (`-client 0` master, `>0` slave via ESP-NOW) |
|
||
| `restart` | 23 | Reboot master or slave (`-client 0` / `>0`) |
|
||
| `log-level` | `0x1f` | Get/set master ESP-IDF log level for tag `"*"` (`-set`, `-level` 0–5); output on UART0 debug, not host UART |
|
||
|
||
`clients` requires slaves to have responded to master discover broadcasts first.
|
||
|
||
For adding commands end-to-end (UART, ESP-NOW, CLI, dashboard), see **[docs/adding-a-feature.md](../docs/adding-a-feature.md)** (Find me example).
|
||
|
||
### 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.
|
||
|
||
```bash
|
||
go run . test -list-configs
|
||
go run . test -list-scenarios
|
||
go run . test -config example-lab -scenario smoke
|
||
go run . test -config example-lab -scenario uart_cmds
|
||
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`](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).
|
||
|
||
```bash
|
||
go run . -port /dev/ttyUSB0 serve
|
||
go run . -port /dev/ttyUSB0 serve -addr :8080 -interval 2s
|
||
go run . -port /dev/ttyUSB0 serve -api-addr :8081 -accel-interval 16ms
|
||
make gotool-serve PORT=/dev/ttyUSB0
|
||
```
|
||
|
||
Open [http://localhost:8080](http://localhost:8080) — shows master firmware info and the ESP-NOW client table from `CLIENT_INFO`.
|
||
|
||
**Tap (dashboard):** two independent controls per slave:
|
||
|
||
| Column | Meaning |
|
||
|--------|---------|
|
||
| Tap-Notify (S/D/T) | Which tap kinds the **slave** sends to the master over ESP-NOW (UART `TAP_NOTIFY`) — does **not** poll UART |
|
||
| Tap (An/Aus) | Host **receive**: poll master tap cache (~16 ms) and show last tap for **≥2 s** |
|
||
|
||
Enable notify first, then turn receive on to see events. Same split as the external WebSocket API (`set_tap_notify` vs `set_tap_stream`).
|
||
|
||
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.
|
||
|
||
### HTTP / WebSocket API
|
||
|
||
`serve` also listens on **`:8081`** for external programs (`-api-addr`, empty to disable). Same UART as the dashboard.
|
||
|
||
| Doc | Content |
|
||
|-----|---------|
|
||
| **[docs/API_WEBSOCKET.md](docs/API_WEBSOCKET.md)** | `ws://…:8081/ws` commands and **`input` push stream** (accel + tap) |
|
||
| **[docs/API_REST.md](docs/API_REST.md)** | REST on `:8080` (dashboard) and `:8081` (battery, LED, service info) |
|
||
|
||
CLI:
|
||
|
||
```bash
|
||
go run . -port /dev/ttyUSB0 tap-notify -client 16 -set -single
|
||
go run . -port /dev/ttyUSB0 cache-status
|
||
```
|
||
|
||
| UI / API | Behaviour |
|
||
|----------|-----------|
|
||
| Firmware OTA card | Same as `ota` CLI; dashboard WebSocket `ota_progress` ([REST doc](docs/API_REST.md)) |
|
||
| `POST /api/ota` | Upload `.bin` to master — slaves updated by firmware over ESP-NOW after `OTA_END` |
|
||
|
||
```bash
|
||
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.
|
||
|
||
```bash
|
||
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`.
|
||
|
||
```bash
|
||
go run . -port /dev/ttyUSB0 echo-ping -client 16
|
||
go run . -port /dev/ttyUSB0 log-level
|
||
go run . -port /dev/ttyUSB0 log-level -set -level 3
|
||
```
|
||
|
||
`log-level` controls `esp_log_*` on the master (UART0 USB console). The host protocol UART (GPIO 2/3) is unchanged.
|
||
|
||
Measures latency to one slave. `rtt_ms` is the full host round-trip (UART + ESP-NOW + UART back). `esp_rtt_us` is the master-side ESP-NOW leg only (`esp_timer_get_time()` delta, raw microseconds from firmware).
|
||
|
||
Example output:
|
||
|
||
```
|
||
echo ping: success=true client_id=16 rtt_ms=49.729 esp_rtt_us=18234
|
||
```
|
||
|
||
`clients` example:
|
||
|
||
```
|
||
clients (2):
|
||
[0] id=42 mac=aabbccddeeff ver=1 available=true used=false last_ping=250 last_success_ping=250
|
||
```
|
||
|
||
## Regenerate protobuf
|
||
|
||
From repo root (needs `protoc`, `protoc-gen-go`, and for C also `pip install protobuf`):
|
||
|
||
```bash
|
||
make gotool-proto # Go: goTool/pb/uart_messages.pb.go
|
||
make proto_generate # C: main/proto/*.pb.h, *.pb.c
|
||
```
|