powerpods/goTool/README.md
simon 490e0ee61f Add UART SET_LOG_LEVEL for runtime master ESP-IDF logging.
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>
2026-06-06 18:03:34 +02:00

149 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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` | 1619 | 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` 05); 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
```