diff --git a/goTool/README.md b/goTool/README.md index 2a23e7b..44399f0 100644 --- a/goTool/README.md +++ b/goTool/README.md @@ -25,10 +25,8 @@ go run . -port /dev/ttyUSB0 clients | `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`) | -| `accel` | `0x18` | Cached slave accel snapshot from master (`ACCEL_SNAPSHOT`); alias `accel-read` | | `tap-notify` | `0x1b` | Get/set which tap kinds (single/double/triple) notify via ESP-NOW (`-set`, `-client`, `-all`, `-single`, `-double`, `-triple`) | -| `tap` | `0x1c` | Cached tap snapshot from master (`TAP_SNAPSHOT`); events ≤16 ms old | -| `cache-status` | `0x1d` | Combined accel + tap cache (`CACHE_STATUS`); one UART round-trip for 16 ms polling | +| `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`) | | `test` | — | Run an automated scenario (JSON configs under `testdata/`) | | `serve` | — | Web dashboard at `http://localhost:8080` (WebSocket live updates) | @@ -80,257 +78,28 @@ Open [http://localhost:8080](http://localhost:8080) — shows master firmware in Enable notify first, then turn receive on to see events. Same split as the external WebSocket API (`set_tap_notify` vs `set_tap_stream`). -### External API (second HTTP server) - -`serve` starts a separate listener (default **`:8081`**, disable with `-api-addr ""`) for external programs. It shares the same UART connection as the dashboard. - -| Endpoint | Description | -|----------|-------------| -| `GET /` or `GET /api/v1/` | JSON service info (`default_interval_ms`, min/max, `serial_port`, `tap_display_min_ms`) | -| `WebSocket /ws` | Per-connection accel/tap receive + interval; slave ESP-NOW accel/tap control | - -**Accel** — two layers: - -1. **`set_stream`** — this WebSocket connection: whether to receive `accel` JSON and at what poll rate (1 ms … 10 s per client; server UART poll uses the minimum among active subscribers). -2. **`set_accel_stream`** — firmware: whether a slave sends accel to the master over ESP-NOW (16 ms on the pod). - -Accel polling runs only when at least one connection has `receive_accel: true` **and** at least one slave streams (via `set_accel_stream` or dashboard `:8080`). - -**Tap** — also two layers (notify alone does **not** poll UART): - -1. **`set_tap_notify`** — firmware: which tap kinds (single/double/triple) the slave sends to the master over ESP-NOW. -2. **`set_tap_stream`** — this WebSocket connection: poll `CACHE_STATUS` (tap slice) and push `tap` JSON. Events stay visible for **`tap_display_min_ms`** (2000 ms) after first sight. - -Tap polling runs only when at least one connection has `receive_tap: true` (via `set_tap_stream`). - -**Hello** (on connect; accel/tap receive off until `set_stream` / `set_tap_stream`): - -```json -{"type":"hello","serial_port":"/dev/ttyUSB0","interval_ms":16,"tap_display_min_ms":2000,"note":"set_tap_notify configures slave S/D/T only; set_tap_stream enables tap polling/push","commands":["list_clients","set_stream","get_stream","set_accel_stream","get_accel_stream","set_tap_stream","get_tap_stream","set_tap_notify","get_tap_notify","set_led_ring","get_battery"]} -``` - -**List registered slaves** (UART `CLIENT_INFO`; use before per-slave `set_accel_stream` / `set_tap_notify`): - -```json -{"type":"list_clients"} -``` - -Reply: - -```json -{"type":"client_list","success":true,"clients":[{"id":16,"mac":"aa:bb:cc:dd:ee:10","version":1,"available":true,"used":true,"last_ping":1234,"last_success_ping":1200,"accel_stream":false,"tap_notify_single":false,"tap_notify_double":false,"tap_notify_triple":false}]} -``` - -**Receive accel on this connection** (optional `interval_ms`, default from `-accel-interval`): - -```json -{"type":"set_stream","enable":true,"interval_ms":32} -{"type":"get_stream"} -``` - -Reply: - -```json -{"type":"stream_status","receive_accel":true,"interval_ms":32,"success":true} -``` - -**Slave ESP-NOW stream** (per `client_id`): - -```json -{"type":"set_accel_stream","client_id":16,"enable":true} -{"type":"get_accel_stream","client_id":16} -``` - -Reply: - -```json -{"type":"accel_stream_status","client_id":16,"enabled":true,"success":true} -``` - -**LED ring** (same JSON fields as `POST /api/led-ring`): - -```json -{"type":"set_led_ring","mode":"color","client_id":16,"r":255,"g":0,"b":0,"intensity":200} -{"type":"set_led_ring","mode":"digit","all_clients":true,"slaves_only":true,"digit":3,"g":255} -``` - -Reply: `{"type":"led_ring_status","success":true,"slaves_updated":2,...}` - -**Tap notify** (slave ESP-NOW config; per `client_id`, or `all_clients`): - -```json -{"type":"set_tap_notify","client_id":16,"single":true,"double_tap":false,"triple":false} -{"type":"get_tap_notify","client_id":16} -``` - -Reply: - -```json -{"type":"tap_notify_status","client_id":16,"success":true,"single":true,"double_tap":false,"triple":false} -``` - -**Receive tap on this connection** (optional `interval_ms`; default from `-accel-interval`): - -```json -{"type":"set_tap_stream","enable":true,"interval_ms":16} -{"type":"get_tap_stream"} -``` - -Reply: - -```json -{"type":"tap_stream_status","receive_tap":true,"interval_ms":16,"success":true} -``` - -**Tap events** (only to connections with `receive_tap: true`; each event shown ≥2 s): - -```json -{"type":"tap","port":"/dev/ttyUSB0","success":true,"events":[{"client_id":16,"kind":"single","age_ms":3,"shown_at_ms":1717000000123}]} -``` - -**Accel** (only to connections with `receive_accel: true`, and only while slaves stream): - -```json -{"type":"accel","t":1716900123456789012,"success":true,"clients":[{"client_id":16,"valid":true,"x":12,"y":-34,"z":16384,"age_ms":8}]} -``` - -`t` is Unix time in nanoseconds. Each `clients[]` entry is one slave's latest cached sample (raw LSB, ±2g). - -Example (Python): - -```python -import asyncio, json, websockets - -async def main(): - async with websockets.connect("ws://127.0.0.1:8081/ws") as ws: - print(await ws.recv()) # hello - await ws.send(json.dumps({"type": "list_clients"})) - clients = json.loads(await ws.recv())["clients"] - for c in clients: - if not c.get("available"): - continue - await ws.send(json.dumps({"type": "set_accel_stream", "client_id": c["id"], "enable": True})) - print(await ws.recv()) # accel_stream_status - await ws.send(json.dumps({"type": "set_stream", "enable": True, "interval_ms": 16})) - print(await ws.recv()) # stream_status - await ws.send(json.dumps({"type": "set_accel_stream", "client_id": 16, "enable": True})) - print(await ws.recv()) # accel_stream_status - while True: - msg = json.loads(await ws.recv()) - if msg.get("type") != "accel" or not msg.get("success"): - continue - for c in msg.get("clients", []): - if c.get("valid"): - print(c["client_id"], c["x"], c["y"], c["z"]) - -asyncio.run(main()) -``` - -Tap example (notify first, then enable stream on this connection): - -```python -import asyncio, json, websockets - -async def main(): - async with websockets.connect("ws://127.0.0.1:8081/ws") as ws: - print(await ws.recv()) # hello - await ws.send(json.dumps({"type": "set_tap_notify", "client_id": 16, - "single": True, "double_tap": False, "triple": False})) - print(await ws.recv()) # tap_notify_status - await ws.send(json.dumps({"type": "set_tap_stream", "enable": True, "interval_ms": 16})) - print(await ws.recv()) # tap_stream_status - while True: - msg = json.loads(await ws.recv()) - if msg.get("type") == "tap" and msg.get("events"): - for e in msg["events"]: - print(e["client_id"], e["kind"], "age", e.get("age_ms")) - -asyncio.run(main()) -``` - 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: +### HTTP / WebSocket API -| 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` | +`serve` also listens on **`:8081`** for external programs (`-api-addr`, empty to disable). Same UART as the dashboard. -HTTP API (used by the web UI): `GET/PUT /api/live-stream`, `GET/POST /api/deadzone`, `GET/PUT /api/clients/{id}/accel-stream`, `POST /api/accel-stream` (legacy / `all_clients`), `GET/PUT /api/clients/{id}/tap-notify`, `GET/POST /api/tap-notify`, `GET /api/tap-snapshot`, `GET/POST /api/battery`, `POST /api/led-ring`, `POST /api/unicast-test`, `POST /api/find-me`, `POST /api/restart`, `POST /api/ota` (multipart field `firmware`, max 2 MiB). - -**LED ring** (`POST /api/led-ring` and WebSocket `set_led_ring` on `:8081`): - -```json -{"mode":"color","client_id":16,"r":255,"g":0,"b":0,"intensity":128} -{"mode":"digit","client_id":0,"digit":3,"r":0,"g":255,"b":0} -{"mode":"find-me","all_clients":true,"slaves_only":true} -``` - -Modes: `clear`, `color` (full ring), `progress` (0–100), `digit` (0–10 symbols), `blink`, `find-me`. Use `client_id` (0 = master), or `all_clients` (+ optional `slaves_only`) for broadcast. - -**Battery** (`GET/POST /api/battery`, WebSocket `get_battery` on `:8081`): - -```json -{"all_clients":true} -{"client_id":0} -{"client_id":16} -``` - -Response: `samples[]` with `client_id`, `lipo1`/`lipo2` (`valid`, `voltage_mv`, `percent`), `age_ms`. Slaves push to the master every **30 s**; UART reads the cache (fast). Dashboard polls with `all_clients`. - -**Accel stream per slave** (must be enabled before values appear; goTool polls only while at least one slave has stream on): - -```http -GET /api/clients/16/accel-stream -→ {"enabled":false,"client_id":16,"success":true} - -PUT /api/clients/16/accel-stream -Content-Type: application/json -{"enable": true} -→ {"enabled":true,"client_id":16,"success":true} -``` - -Enable all slaves: `POST /api/accel-stream` with `{"write":true,"enable":true,"all_clients":true}`. - -**Tap notify per slave** (slave → master ESP-NOW; does not start host polling): - -```http -GET /api/clients/16/tap-notify -→ {"client_id":16,"success":true,"single":false,"double_tap":false,"triple":false} - -PUT /api/clients/16/tap-notify -Content-Type: application/json -{"single": true, "double_tap": false, "triple": false} -→ {"client_id":16,"success":true,"slaves_updated":1,"single":true,"double_tap":false,"triple":false} -``` - -All slaves: `POST /api/tap-notify` with `{"single":true,"double_tap":false,"triple":false,"all_clients":true}`. - -**Live stream** (dashboard: host-side `CACHE_STATUS` poll ~16 ms; per-slave accel via `accel-stream`): - -```http -PUT /api/live-stream -Content-Type: application/json -{"enable": true} -→ {"enabled":true,"success":true} -``` - -One-shot read: `GET /api/tap-snapshot?client_id=16` → `{"events":[{"client_id":16,"kind":"single","age_ms":4}]}`. +| Doc | Content | +|-----|---------| +| **[docs/API_WEBSOCKET.md](docs/API_WEBSOCKET.md)** | `ws://…:8081/ws` commands, **`accel` / `tap` push stream** format, dashboard `ws://…:8080/ws` | +| **[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 tap -client 16 +go run . -port /dev/ttyUSB0 cache-status ``` | UI / API | Behaviour | |----------|-----------| -| Firmware OTA card | Same as `ota` CLI; WebSocket `ota_progress` with `step` `master` (UART) then `slaves` (ESP-NOW) | -| `POST /api/ota` | Upload `.bin` to master only — slaves are updated by firmware over ESP-NOW after `OTA_END` | +| 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 diff --git a/goTool/api_stream.go b/goTool/api_stream.go index 154cd1d..3d3b6d1 100644 --- a/goTool/api_stream.go +++ b/goTool/api_stream.go @@ -506,8 +506,9 @@ func runAccelStreamer(link *managedSerial, hub *accelStreamHub, dash *wsHub, ctl } if wantAccel { - clients := make([]AccelClientSample, 0, len(cache.GetAccel())) - for _, s := range cache.GetAccel() { + samples := accelSamplesFromCacheStatus(cache) + clients := make([]AccelClientSample, 0, len(samples)) + for _, s := range samples { clients = append(clients, AccelClientSample{ ClientID: s.GetClientId(), Valid: s.GetValid(), @@ -525,8 +526,9 @@ func runAccelStreamer(link *managedSerial, hub *accelStreamHub, dash *wsHub, ctl }) } if wantTap { - fresh := make([]TapClientEvent, 0, len(cache.GetTaps())) - for _, e := range cache.GetTaps() { + events := tapEventsFromCacheStatus(cache) + fresh := make([]TapClientEvent, 0, len(events)) + for _, e := range events { if !e.GetValid() { continue } @@ -537,13 +539,13 @@ func runAccelStreamer(link *managedSerial, hub *accelStreamHub, dash *wsHub, ctl AgeMs: e.GetAgeMs(), }) } - events := hub.ingestTapEvents(fresh) - if len(events) > 0 { + visible := hub.ingestTapEvents(fresh) + if len(visible) > 0 { hub.deliverTap(TapStreamMessage{ Type: "tap", T: now, Success: true, - Events: events, + Events: visible, }) } } diff --git a/goTool/api_tap.go b/goTool/api_tap.go index 35e8091..c8e2a0e 100644 --- a/goTool/api_tap.go +++ b/goTool/api_tap.go @@ -199,14 +199,14 @@ func serveTapSnapshotGet(w http.ResponseWriter, r *http.Request, link *managedSe writeJSON(w, http.StatusBadRequest, tapSnapshotAPIResponse{Error: err.Error()}) return } - resp, err := link.readTapSnapshotPoll(clientID) + cache, err := link.readCacheStatusPoll() if err != nil { writeJSON(w, http.StatusServiceUnavailable, tapSnapshotAPIResponse{Error: err.Error()}) return } - out := tapSnapshotAPIResponse{Events: make([]tapEventView, 0, len(resp.GetEvents()))} - for _, e := range resp.GetEvents() { - if !e.GetValid() { + out := tapSnapshotAPIResponse{Events: make([]tapEventView, 0)} + for _, e := range tapEventsFromCacheStatus(cache) { + if clientID != 0 && e.GetClientId() != clientID { continue } out.Events = append(out.Events, tapEventView{ diff --git a/goTool/cache_status.go b/goTool/cache_status.go new file mode 100644 index 0000000..fc0d6b4 --- /dev/null +++ b/goTool/cache_status.go @@ -0,0 +1,49 @@ +package main + +import "powerpod/gotool/pb" + +// accelSamplesFromCacheStatus maps combined CACHE_STATUS entries to AccelSample +// (for dashboard / WebSocket accel push). +func accelSamplesFromCacheStatus(r *pb.CacheStatusResponse) []*pb.AccelSample { + if r == nil { + return nil + } + out := make([]*pb.AccelSample, 0, len(r.GetClients())) + for _, c := range r.GetClients() { + if c.GetAccel() == nil { + continue + } + a := c.GetAccel() + out = append(out, &pb.AccelSample{ + ClientId: c.GetClientId(), + Valid: a.GetValid(), + X: a.GetX(), + Y: a.GetY(), + Z: a.GetZ(), + AgeMs: a.GetAgeMs(), + }) + } + return out +} + +// tapEventsFromCacheStatus maps combined CACHE_STATUS entries to TapEvent +// (only clients with a consumed pending tap). +func tapEventsFromCacheStatus(r *pb.CacheStatusResponse) []*pb.TapEvent { + if r == nil { + return nil + } + out := make([]*pb.TapEvent, 0, len(r.GetClients())) + for _, c := range r.GetClients() { + if c.GetTap() == nil { + continue + } + t := c.GetTap() + out = append(out, &pb.TapEvent{ + ClientId: c.GetClientId(), + Valid: true, + Kind: t.GetKind(), + AgeMs: t.GetAgeMs(), + }) + } + return out +} diff --git a/goTool/client_api.go b/goTool/client_api.go index 0a3aac8..a57fa05 100644 --- a/goTool/client_api.go +++ b/goTool/client_api.go @@ -40,25 +40,6 @@ func (m *managedSerial) listClientsPoll() ([]*pb.ClientInfo, error) { return decodeClientsPayload(payload) } -func (m *managedSerial) readAccelSnapshotPoll(clientID uint32) (*pb.AccelSnapshotResponse, error) { - msg := &pb.UartMessage{ - Type: pb.MessageType_ACCEL_SNAPSHOT, - Payload: &pb.UartMessage_AccelSnapshotRequest{ - AccelSnapshotRequest: &pb.AccelSnapshotRequest{ClientId: clientID}, - }, - } - body, err := proto.Marshal(msg) - if err != nil { - return nil, fmt.Errorf("encode: %w", err) - } - payload := append([]byte{byte(pb.MessageType_ACCEL_SNAPSHOT)}, body...) - respPayload, err := m.exchangePayloadPoll(payload, "ACCEL_SNAPSHOT") - if err != nil { - return nil, err - } - return decodeAccelSnapshotPayload(respPayload) -} - func decodeBatteryStatusPayload(payload []byte) (*pb.BatteryStatusResponse, error) { if len(payload) < 2 { return nil, fmt.Errorf("short battery response") @@ -222,43 +203,6 @@ func decodeCacheStatusPayload(payload []byte) (*pb.CacheStatusResponse, error) { return r, nil } -func (m *managedSerial) readTapSnapshotPoll(clientID uint32) (*pb.TapSnapshotResponse, error) { - msg := &pb.UartMessage{ - Type: pb.MessageType_TAP_SNAPSHOT, - Payload: &pb.UartMessage_TapSnapshotRequest{ - TapSnapshotRequest: &pb.TapSnapshotRequest{ClientId: clientID}, - }, - } - body, err := proto.Marshal(msg) - if err != nil { - return nil, fmt.Errorf("encode: %w", err) - } - payload := append([]byte{byte(pb.MessageType_TAP_SNAPSHOT)}, body...) - respPayload, err := m.exchangePayloadPoll(payload, "TAP_SNAPSHOT") - if err != nil { - return nil, err - } - return decodeTapSnapshotPayload(respPayload) -} - -func decodeTapSnapshotPayload(payload []byte) (*pb.TapSnapshotResponse, error) { - if len(payload) < 1 { - return nil, fmt.Errorf("empty response payload") - } - var msg pb.UartMessage - if err := proto.Unmarshal(payload[1:], &msg); err != nil { - return nil, fmt.Errorf("decode: %w", err) - } - if msg.GetType() != pb.MessageType_TAP_SNAPSHOT { - return nil, fmt.Errorf("unexpected type %v", msg.GetType()) - } - r := msg.GetTapSnapshotResponse() - if r == nil { - return nil, fmt.Errorf("missing tap_snapshot_response") - } - return r, nil -} - func (m *managedSerial) accelStreamVia( portFn func(func(*serialPort) error) error, req *pb.AccelStreamRequest, @@ -333,43 +277,6 @@ func decodeClientsPayload(payload []byte) ([]*pb.ClientInfo, error) { return info.GetClients(), nil } -func decodeAccelSnapshotPayload(payload []byte) (*pb.AccelSnapshotResponse, error) { - if len(payload) < 1 { - return nil, fmt.Errorf("empty response payload") - } - var msg pb.UartMessage - if err := proto.Unmarshal(payload[1:], &msg); err != nil { - return nil, fmt.Errorf("decode: %w", err) - } - if msg.GetType() != pb.MessageType_ACCEL_SNAPSHOT { - return nil, fmt.Errorf("unexpected type %v", msg.GetType()) - } - r := msg.GetAccelSnapshotResponse() - if r == nil { - return nil, fmt.Errorf("missing accel_snapshot_response") - } - return r, nil -} - -func (s *serialPort) readAccelSnapshot(clientID uint32) (*pb.AccelSnapshotResponse, error) { - msg := &pb.UartMessage{ - Type: pb.MessageType_ACCEL_SNAPSHOT, - Payload: &pb.UartMessage_AccelSnapshotRequest{ - AccelSnapshotRequest: &pb.AccelSnapshotRequest{ClientId: clientID}, - }, - } - body, err := proto.Marshal(msg) - if err != nil { - return nil, fmt.Errorf("encode: %w", err) - } - payload := append([]byte{byte(pb.MessageType_ACCEL_SNAPSHOT)}, body...) - respPayload, err := s.exchangePayload(payload, "ACCEL_SNAPSHOT") - if err != nil { - return nil, err - } - return decodeAccelSnapshotPayload(respPayload) -} - func (s *serialPort) getVersion() (*pb.VersionResponse, error) { payload, err := s.exchange(byte(pb.MessageType_VERSION), "VERSION") if err != nil { @@ -448,25 +355,6 @@ func (s *serialPort) readCacheStatus() (*pb.CacheStatusResponse, error) { return decodeCacheStatusPayload(payload) } -func (s *serialPort) readTapSnapshot(clientID uint32) (*pb.TapSnapshotResponse, error) { - msg := &pb.UartMessage{ - Type: pb.MessageType_TAP_SNAPSHOT, - Payload: &pb.UartMessage_TapSnapshotRequest{ - TapSnapshotRequest: &pb.TapSnapshotRequest{ClientId: clientID}, - }, - } - body, err := proto.Marshal(msg) - if err != nil { - return nil, fmt.Errorf("encode: %w", err) - } - payload := append([]byte{byte(pb.MessageType_TAP_SNAPSHOT)}, body...) - respPayload, err := s.exchangePayload(payload, "TAP_SNAPSHOT") - if err != nil { - return nil, err - } - return decodeTapSnapshotPayload(respPayload) -} - func (s *serialPort) accelDeadzone(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadzoneResponse, error) { msg := &pb.UartMessage{ Type: pb.MessageType_ACCEL_DEADZONE, diff --git a/goTool/cmd_accel.go b/goTool/cmd_accel.go deleted file mode 100644 index 4b60249..0000000 --- a/goTool/cmd_accel.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "fmt" -) - -func runAccel(sp *serialPort) error { - return runAccelSnapshot(sp, 0) -} - -func runAccelSnapshot(sp *serialPort, clientID uint32) error { - r, err := sp.readAccelSnapshot(clientID) - if err != nil { - return err - } - samples := r.GetSamples() - if len(samples) == 0 { - fmt.Println("no accel samples (no slaves or no ESP-NOW stream yet)") - return nil - } - for _, s := range samples { - if !s.GetValid() { - fmt.Printf("client %d: no sample yet\n", s.GetClientId()) - continue - } - fmt.Printf("client %d: x=%d y=%d z=%d (age %d ms, raw LSB ±2g)\n", - s.GetClientId(), s.GetX(), s.GetY(), s.GetZ(), s.GetAgeMs()) - } - return nil -} diff --git a/goTool/cmd_cache_status.go b/goTool/cmd_cache_status.go index b7c3bb4..b817936 100644 --- a/goTool/cmd_cache_status.go +++ b/goTool/cmd_cache_status.go @@ -9,26 +9,24 @@ func runCacheStatus(sp *serialPort) error { if err != nil { return err } - accel := r.GetAccel() - if len(accel) == 0 { - fmt.Println("accel: (none — no slaves with accel stream enabled)") - } else { - for _, s := range accel { - if !s.GetValid() { - fmt.Printf("accel client %d: no sample yet\n", s.GetClientId()) - continue - } - fmt.Printf("accel client %d: x=%d y=%d z=%d (age %d ms)\n", - s.GetClientId(), s.GetX(), s.GetY(), s.GetZ(), s.GetAgeMs()) - } + clients := r.GetClients() + if len(clients) == 0 { + fmt.Println("(no slaves with accel stream or tap notify enabled)") + return nil } - taps := r.GetTaps() - if len(taps) == 0 { - fmt.Println("tap: (none pending)") - } else { - for _, e := range taps { - fmt.Printf("tap client %d: %s (age %d ms)\n", - e.GetClientId(), tapKindLabel(e.GetKind()), e.GetAgeMs()) + for _, c := range clients { + id := c.GetClientId() + if a := c.GetAccel(); a != nil { + if !a.GetValid() { + fmt.Printf("client %d accel: no sample yet\n", id) + } else { + fmt.Printf("client %d accel: x=%d y=%d z=%d (age %d ms)\n", + id, a.GetX(), a.GetY(), a.GetZ(), a.GetAgeMs()) + } + } + if t := c.GetTap(); t != nil { + fmt.Printf("client %d tap: %s (age %d ms)\n", + id, tapKindLabel(t.GetKind()), t.GetAgeMs()) } } return nil diff --git a/goTool/cmd_tap.go b/goTool/cmd_tap.go index c2a6541..bf53bfc 100644 --- a/goTool/cmd_tap.go +++ b/goTool/cmd_tap.go @@ -44,32 +44,6 @@ func runTapNotify(sp *serialPort, args []string) error { return nil } -func runTapSnapshot(sp *serialPort, args []string) error { - fs := flag.NewFlagSet("tap", flag.ExitOnError) - clientID := fs.Uint("client", 0, "client id (0 = all slaves with tap notify)") - if err := fs.Parse(args); err != nil { - return err - } - return runTapSnapshotForClient(sp, uint32(*clientID)) -} - -func runTapSnapshotForClient(sp *serialPort, clientID uint32) error { - r, err := sp.readTapSnapshot(clientID) - if err != nil { - return err - } - events := r.GetEvents() - if len(events) == 0 { - fmt.Println("no tap events (none pending or older than 16 ms)") - return nil - } - for _, e := range events { - fmt.Printf("client %d: %s (age %d ms)\n", - e.GetClientId(), tapKindLabel(e.GetKind()), e.GetAgeMs()) - } - return nil -} - func tapKindLabel(k pb.TapKind) string { switch k { case pb.TapKind_TAP_SINGLE: diff --git a/goTool/dashboard.go b/goTool/dashboard.go index 0045989..e5c0910 100644 --- a/goTool/dashboard.go +++ b/goTool/dashboard.go @@ -643,8 +643,8 @@ func runCacheStatusDashboardPoller(link *managedSerial, hub *wsHub, interval tim if err != nil { continue } - hub.mergeAccel(cache.GetAccel()) - hub.mergeTap(cache.GetTaps()) + hub.mergeAccel(accelSamplesFromCacheStatus(cache)) + hub.mergeTap(tapEventsFromCacheStatus(cache)) } } } diff --git a/goTool/docs/API_REST.md b/goTool/docs/API_REST.md new file mode 100644 index 0000000..9628146 --- /dev/null +++ b/goTool/docs/API_REST.md @@ -0,0 +1,284 @@ +# REST API + +`go run . -port /dev/ttyUSB0 serve` starts two HTTP servers on the same UART link: + +| Base URL | Flag | Used by | +|----------|------|---------| +| `http://localhost:8080` | `-addr` (default `:8080`) | Web dashboard + automation on the UI routes | +| `http://localhost:8081` | `-api-addr` (default `:8081`, `""` disables) | External programs; subset of routes + service info | + +WebSocket streaming (accel/tap push): [`API_WEBSOCKET.md`](API_WEBSOCKET.md). + +All JSON responses use `Content-Type: application/json`. On UART errors many routes return **503** with `"error"` in the body. + +--- + +## External API (`:8081`) + +### Service info + +```http +GET / +GET /api/v1/ +``` + +```json +{ + "name": "powerpod-external-api", + "version": "1", + "serial_port": "/dev/ttyUSB0", + "websocket": "/ws", + "default_interval_ms": 16, + "min_interval_ms": 1, + "max_interval_ms": 10000, + "tap_display_min_ms": 2000, + "description": "..." +} +``` + +### Battery + +```http +GET /api/battery?all_clients=true +GET /api/battery?client_id=16 +POST /api/battery +Content-Type: application/json +``` + +POST body: + +```json +{"all_clients": true} +{"client_id": 0} +{"client_id": 16} +``` + +Response: + +```json +{ + "success": true, + "samples": [ + { + "client_id": 16, + "lipo1": {"valid": true, "voltage_mv": 3850, "percent": 71}, + "lipo2": {"valid": false}, + "age_ms": 1200 + } + ] +} +``` + +Slaves push battery to the master every **30 s**; these routes read the master cache. + +WebSocket equivalent: `get_battery` on `ws://localhost:8081/ws` (reply type `battery_status`). + +### LED ring + +```http +POST /api/led-ring +Content-Type: application/json +``` + +Body: + +```json +{"mode":"color","client_id":16,"r":255,"g":0,"b":0,"intensity":128} +{"mode":"digit","client_id":0,"digit":3,"r":0,"g":255,"b":0} +{"mode":"find-me","all_clients":true,"slaves_only":true} +``` + +| `mode` | Notes | +|--------|--------| +| `clear` | Turn off | +| `color` | Full ring RGB + `intensity` | +| `progress` | `progress` 0–100 | +| `digit` | `digit` 0–10 | +| `blink` | `blink_ms`, `blink_count` | +| `find-me` | Locate pod | + +Use `client_id` (`0` = master) or `all_clients` (+ optional `slaves_only`) for broadcast. + +Response: `success`, `slaves_updated`, optional `error`. + +WebSocket: `set_led_ring` with the same fields plus `"type":"set_led_ring"` → `led_ring_status`. + +--- + +## Dashboard API (`:8080`) + +Used by the web UI; safe for scripts that drive the same features. + +### Live stream (host `CACHE_STATUS` poll ~16 ms) + +```http +GET /api/live-stream +PUT /api/live-stream +Content-Type: application/json +{"enable": true} +``` + +```json +{"enabled": true, "success": true} +``` + +Enables fast UART polling for dashboard accel/tap display. Per-slave accel still requires accel-stream (below). + +### Accel stream (firmware ESP-NOW, per slave) + +```http +GET /api/clients/16/accel-stream +PUT /api/clients/16/accel-stream +Content-Type: application/json +{"enable": true} +``` + +```json +{"enabled": true, "client_id": 16, "success": true} +``` + +All slaves: + +```http +POST /api/accel-stream +Content-Type: application/json +{"write": true, "enable": true, "all_clients": true} +``` + +Polling on the host runs only while at least one slave has streaming enabled (here or via external WebSocket / dashboard). + +### Tap notify (firmware; does not start host tap polling) + +```http +GET /api/clients/16/tap-notify +PUT /api/clients/16/tap-notify +Content-Type: application/json +{"single": true, "double_tap": false, "triple": false} +``` + +```json +{ + "client_id": 16, + "success": true, + "slaves_updated": 1, + "single": true, + "double_tap": false, + "triple": false +} +``` + +All slaves: + +```http +POST /api/tap-notify +Content-Type: application/json +{"single": true, "double_tap": false, "triple": false, "all_clients": true} +``` + +Host tap display / external `set_tap_stream` is separate. + +### Tap snapshot (one-shot, via `CACHE_STATUS`) + +```http +GET /api/tap-snapshot?client_id=16 +``` + +Reads the combined cache (`CACHE_STATUS`); optional `client_id` filters pending tap events. Pending taps are consumed on read. + +```json +{ + "events": [ + {"client_id": 16, "kind": "single", "age_ms": 4} + ] +} +``` + +### Deadzone + +```http +GET /api/deadzone?client_id=0 +POST /api/deadzone +Content-Type: application/json +{"write": true, "deadzone": 128, "client_id": 0} +``` + +With `all_clients` + `slaves_only`: push to ESP-NOW slaves only (master BMA456 unchanged). + +```json +{"deadzone": 128, "client_id": 0, "success": true, "slaves_updated": 2} +``` + +### Unicast test + +```http +POST /api/unicast-test +Content-Type: application/json +{"client_id": 16, "seq": 42} +``` + +### Find me + +```http +POST /api/find-me +Content-Type: application/json +{"client_id": 16} +``` + +`client_id` `0` = master LED ring. + +### Restart + +```http +POST /api/restart +Content-Type: application/json +{"client_id": 16} +``` + +### OTA (master UART upload) + +```http +POST /api/ota +Content-Type: multipart/form-data +``` + +Form field **`firmware`**: binary image, max **2 MiB**. + +```json +{"success": true, "bytes_written": 123456, "target_slot": 1} +``` + +Firmware distributes to slaves over ESP-NOW after `OTA_END`. Progress also appears on dashboard WebSocket as `ota_progress` messages. + +CLI equivalent: `go run . -port /dev/ttyUSB0 ota build/powerpod.bin` + +### LED ring and battery + +Same as external API: + +- `POST /api/led-ring` +- `GET` / `POST` `/api/battery` + +--- + +## Dashboard vs external + +| Feature | Dashboard `:8080` | External `:8081` | +|---------|-------------------|------------------| +| Client list | Via dashboard WebSocket state / CLI `clients` | WebSocket `list_clients` | +| Accel/tap **push stream** | WebSocket state when live-stream on | WebSocket `set_stream` / `set_tap_stream` | +| Accel stream enable | REST `PUT .../accel-stream` | WebSocket `set_accel_stream` | +| Tap notify | REST `PUT .../tap-notify` | WebSocket `set_tap_notify` | +| LED / battery | REST | REST + WebSocket on `:8081` | + +--- + +## UI mapping + +| UI action | REST / CLI | +|-----------|------------| +| Nur Master deadzone | `POST /api/deadzone` `client_id: 0` or CLI `deadzone -set -client 0` | +| Einzelner Slave | `client_id: ` | +| Alle Slaves deadzone | `all_clients` + `slaves_only` on POST | +| Unicast test | `POST /api/unicast-test` | +| Tap notify S/D/T | `PUT /api/clients/{id}/tap-notify` | +| Tap receive (UI) | Live stream + tap notify; see WebSocket doc for external API | diff --git a/goTool/docs/API_WEBSOCKET.md b/goTool/docs/API_WEBSOCKET.md new file mode 100644 index 0000000..c7613e9 --- /dev/null +++ b/goTool/docs/API_WEBSOCKET.md @@ -0,0 +1,348 @@ +# WebSocket API + +`go run . -port /dev/ttyUSB0 serve` exposes two WebSocket endpoints. They share the same UART link but serve different purposes. + +| URL | Port (default) | Role | +|-----|----------------|------| +| `ws://localhost:8080/ws` | Dashboard (`-addr`) | Server → client only: full `DashboardState` JSON (~2 s poll + live-stream accel/tap) | +| `ws://localhost:8081/ws` | External API (`-api-addr`) | Request/response commands + optional **accel** / **tap** push streams | + +Disable the external server with `-api-addr ""`. + +CLI overview and UART commands: [`../README.md`](../README.md). HTTP endpoints: [`API_REST.md`](API_REST.md). + +--- + +## External API (`:8081/ws`) + +### Connection flow + +1. Connect → server sends **`hello`** (receive off; lists available commands). +2. Send JSON commands → server replies with a matching `*_status` or `client_list` message (one reply per command). +3. After `set_stream` / `set_tap_stream` with `enable: true`, the server may send **`accel`** and/or **`tap`** messages **without** a prior command (push stream). + +Commands and stream pushes are multiplexed on one socket. While streaming, always parse `type` and branch (status vs sample vs error). + +### Two layers (accel and tap) + +| Layer | Commands | Effect | +|-------|----------|--------| +| **Firmware (ESP-NOW)** | `set_accel_stream`, `set_tap_notify` | Per `client_id`: slave sends accel or tap kinds to the master | +| **This connection (host)** | `set_stream`, `set_tap_stream` | Whether **you** receive push JSON and at what rate (`interval_ms`, 1 ms … 10 s) | + +- **Accel UART polling** runs only if at least one connection has `receive_accel: true` **and** at least one slave streams accel (`set_accel_stream` or dashboard). +- **Tap UART polling** runs only if at least one connection has `receive_tap: true` (`set_tap_stream`). `set_tap_notify` alone does **not** poll. + +Typical sequence: + +1. `list_clients` → slave IDs +2. Per slave: `set_accel_stream` / `set_tap_notify` as needed +3. `set_stream` and/or `set_tap_stream` with `"enable": true` +4. Read push messages in a loop + +There is **no per-slave filter** on push messages: each `accel` contains all cached slaves; each `tap` contains all visible events. Filter by `client_id` in your app. + +--- + +## Push stream messages + +These are the samples you get after enabling receive. Interval is per WebSocket connection; the server UART poll uses the **minimum** `interval_ms` among all subscribers that want accel or tap. + +### `accel` (type `"accel"`) + +Sent only when `set_stream` has `enable: true`, a slave streams accel, and the poll tick fires for this connection. + +**Success** — all slaves with a cache entry on the master (not only those with `valid: true`): + +```json +{ + "type": "accel", + "t": 1716900123456789012, + "success": true, + "clients": [ + { + "client_id": 16, + "valid": true, + "x": 12, + "y": -34, + "z": 16384, + "age_ms": 8 + }, + { + "client_id": 42, + "valid": false + } + ] +} +``` + +| Field | Meaning | +|-------|---------| +| `t` | Unix timestamp in **nanoseconds** when the host read the cache | +| `success` | `true` if `CACHE_STATUS` succeeded | +| `clients[]` | One entry per slave slot in the master cache | +| `client_id` | ESP-NOW client id (same as `list_clients`) | +| `valid` | `false` if no sample yet or stale; omit `x`/`y`/`z` when false | +| `x`, `y`, `z` | Raw accelerometer LSB (BMA456, ±2 g scale on the pod) | +| `age_ms` | Milliseconds since the master received this sample | + +**Failure** (e.g. UART busy): + +```json +{ + "type": "accel", + "t": 1716900123456789012, + "success": false, + "error": "uart busy" +} +``` + +No `clients` array on failure. + +### `tap` (type `"tap"`) + +Sent only when `set_tap_stream` has `enable: true` and there is at least one event to show. + +Events appear when the master cache reports a new tap. Each event stays in push payloads for **`tap_display_min_ms`** (2000 ms, also in `hello`) after the API first saw it, even if the hardware age grows. + +**Success**: + +```json +{ + "type": "tap", + "t": 1716900123456789012, + "success": true, + "events": [ + { + "client_id": 16, + "valid": true, + "kind": "single", + "age_ms": 3, + "shown_at_ms": 1717000000123 + } + ] +} +``` + +| Field | Meaning | +|-------|---------| +| `t` | Unix timestamp in **nanoseconds** (poll time) | +| `events[]` | All taps currently “on screen” for the API | +| `client_id` | Slave that tapped | +| `kind` | `"single"`, `"double"`, or `"triple"` | +| `age_ms` | Age in the master cache when read | +| `shown_at_ms` | Unix **milliseconds** when this host first included the event | + +If no events are visible, **no** `tap` message is sent on that tick (unlike accel, which can send empty `clients` only on success with cache data). + +**Failure**: + +```json +{ + "type": "tap", + "t": 1716900123456789012, + "success": false, + "error": "uart busy" +} +``` + +--- + +## Commands (request → response) + +Send one JSON object per message. Field `type` selects the command. + +### `hello` (server → client, on connect) + +```json +{ + "type": "hello", + "serial_port": "/dev/ttyUSB0", + "interval_ms": 16, + "tap_display_min_ms": 2000, + "note": "set_tap_notify configures slave S/D/T only; set_tap_stream enables tap polling/push", + "commands": [ + "list_clients", + "set_stream", "get_stream", + "set_accel_stream", "get_accel_stream", + "set_tap_stream", "get_tap_stream", + "set_tap_notify", "get_tap_notify", + "set_led_ring", "get_battery" + ] +} +``` + +### `list_clients` + +Request: `{"type":"list_clients"}` + +Response `client_list`: + +```json +{ + "type": "client_list", + "success": true, + "clients": [ + { + "id": 16, + "mac": "aa:bb:cc:dd:ee:10", + "version": 1, + "available": true, + "used": true, + "last_ping": 1234, + "last_success_ping": 1200, + "accel_stream": false, + "tap_notify_single": false, + "tap_notify_double": false, + "tap_notify_triple": false + } + ] +} +``` + +### `set_stream` / `get_stream` (receive accel on this connection) + +```json +{"type":"set_stream","enable":true,"interval_ms":32} +{"type":"get_stream"} +``` + +Response `stream_status`: + +```json +{"type":"stream_status","receive_accel":true,"interval_ms":32,"success":true} +``` + +### `set_accel_stream` / `get_accel_stream` (firmware, per slave) + +`client_id` required (> 0). + +```json +{"type":"set_accel_stream","client_id":16,"enable":true} +{"type":"get_accel_stream","client_id":16} +``` + +Response `accel_stream_status`: + +```json +{"type":"accel_stream_status","client_id":16,"enabled":true,"success":true} +``` + +### `set_tap_stream` / `get_tap_stream` (receive tap on this connection) + +```json +{"type":"set_tap_stream","enable":true,"interval_ms":16} +{"type":"get_tap_stream"} +``` + +Response `tap_stream_status`: + +```json +{"type":"tap_stream_status","receive_tap":true,"interval_ms":16,"success":true} +``` + +### `set_tap_notify` / `get_tap_notify` (firmware, per slave) + +Per client: `single`, `double_tap`, `triple` required on set. + +```json +{"type":"set_tap_notify","client_id":16,"single":true,"double_tap":false,"triple":false} +``` + +Broadcast: `"all_clients": true` with the three booleans. + +Response `tap_notify_status`: + +```json +{ + "type": "tap_notify_status", + "client_id": 16, + "success": true, + "single": true, + "double_tap": false, + "triple": false +} +``` + +### `set_led_ring` + +Same JSON body as [`POST /api/led-ring`](API_REST.md#led-ring) with `"type":"set_led_ring"` added. Reply: `led_ring_status`. + +### `get_battery` + +Body: `{"type":"get_battery","all_clients":true}` or `"client_id":16`. Default if omitted: all clients. + +Reply: `battery_status` with `samples[]` (see REST doc). + +--- + +## Examples + +### Accel stream + +```python +import asyncio, json, websockets + +async def main(): + async with websockets.connect("ws://127.0.0.1:8081/ws") as ws: + print(await ws.recv()) # hello + await ws.send(json.dumps({"type": "list_clients"})) + clients = json.loads(await ws.recv())["clients"] + for c in clients: + if not c.get("available"): + continue + await ws.send(json.dumps({ + "type": "set_accel_stream", "client_id": c["id"], "enable": True + })) + await ws.recv() # accel_stream_status + await ws.send(json.dumps({"type": "set_stream", "enable": True, "interval_ms": 16})) + await ws.recv() # stream_status + while True: + msg = json.loads(await ws.recv()) + if msg.get("type") != "accel": + continue + if not msg.get("success"): + print("error:", msg.get("error")) + continue + for c in msg.get("clients", []): + if c.get("valid"): + print(c["client_id"], c["x"], c["y"], c["z"], "age", c.get("age_ms")) + +asyncio.run(main()) +``` + +### Tap stream + +```python +import asyncio, json, websockets + +async def main(): + async with websockets.connect("ws://127.0.0.1:8081/ws") as ws: + print(await ws.recv()) # hello + await ws.send(json.dumps({ + "type": "set_tap_notify", "client_id": 16, + "single": True, "double_tap": False, "triple": False + })) + await ws.recv() # tap_notify_status + await ws.send(json.dumps({"type": "set_tap_stream", "enable": True, "interval_ms": 16})) + await ws.recv() # tap_stream_status + while True: + msg = json.loads(await ws.recv()) + if msg.get("type") == "tap" and msg.get("events"): + for e in msg["events"]: + print(e["client_id"], e["kind"], "age", e.get("age_ms")) + +asyncio.run(main()) +``` + +--- + +## Dashboard WebSocket (`:8080/ws`) + +Read-only from the browser’s perspective: the server pushes JSON whenever state changes. Clients do not send commands on this socket (messages are ignored). + +Payload shape: `DashboardState` — `updated_at`, `serial_port`, `uart_connected`, `live_stream`, `master`, `clients[]` (id, mac, accel, tap notify flags, battery, etc.). Accel/tap samples appear here when **Live stream** is enabled in the UI (`PUT /api/live-stream`). + +During OTA, additional messages with `"type":"ota_progress"` may appear on the same socket. + +Configure slaves via REST on `:8080` ([`API_REST.md`](API_REST.md)), not via this WebSocket. diff --git a/goTool/main.go b/goTool/main.go index c9834c7..109c4e6 100644 --- a/goTool/main.go +++ b/goTool/main.go @@ -17,9 +17,7 @@ func usage() { fmt.Fprintf(os.Stderr, " clients registered ESP-NOW slaves on the master\n") fmt.Fprintf(os.Stderr, " deadzone get/set accelerometer deadzone (LSB)\n") fmt.Fprintf(os.Stderr, " tap-notify get/set which tap kinds notify via ESP-NOW\n") - fmt.Fprintf(os.Stderr, " tap read cached tap events from master\n") - fmt.Fprintf(os.Stderr, " accel read cached slave accel snapshot from master\n") - fmt.Fprintf(os.Stderr, " cache-status combined accel + tap cache (one UART round-trip)\n") + fmt.Fprintf(os.Stderr, " cache-status subscribed accel + tap cache (one UART round-trip)\n") fmt.Fprintf(os.Stderr, " unicast-test send ESP-NOW unicast test to one slave\n") fmt.Fprintf(os.Stderr, " test run automated scenario (see testdata/)\n") fmt.Fprintf(os.Stderr, " serve web dashboard (Bootstrap + WebSocket)\n") @@ -54,7 +52,7 @@ func main() { os.Exit(2) } runErr = runServe(*portName, *baud, flag.Args()[1:]) - case "version", "clients", "client-info", "deadzone", "accel-deadzone", "tap-notify", "tap_notify", "tap", "accel", "accel-read", "accel_read", "cache-status", "cache_status", "unicast-test", "unicast_test", "led-ring", "led_ring", "find-me", "find_me", "restart", "ota", "ota-progress", "ota_progress": + case "version", "clients", "client-info", "deadzone", "accel-deadzone", "tap-notify", "tap_notify", "cache-status", "cache_status", "unicast-test", "unicast_test", "led-ring", "led_ring", "find-me", "find_me", "restart", "ota", "ota-progress", "ota_progress": if *portName == "" { fmt.Fprintf(os.Stderr, "command %q requires -port\n\n", cmd) usage() @@ -74,10 +72,6 @@ func main() { runErr = runDeadzone(sp, flag.Args()[1:]) case "tap-notify", "tap_notify": runErr = runTapNotify(sp, flag.Args()[1:]) - case "tap": - runErr = runTapSnapshot(sp, flag.Args()[1:]) - case "accel", "accel-read", "accel_read": - runErr = runAccel(sp) case "cache-status", "cache_status": runErr = runCacheStatus(sp) case "unicast-test", "unicast_test": diff --git a/goTool/pb/uart_messages.pb.go b/goTool/pb/uart_messages.pb.go index 9aeb138..923c75f 100644 --- a/goTool/pb/uart_messages.pb.go +++ b/goTool/pb/uart_messages.pb.go @@ -41,11 +41,9 @@ const ( MessageType_OTA_SLAVE_PROGRESS MessageType = 21 MessageType_FIND_ME MessageType = 22 MessageType_RESTART MessageType = 23 - MessageType_ACCEL_SNAPSHOT MessageType = 24 MessageType_ACCEL_STREAM MessageType = 25 MessageType_BATTERY_STATUS MessageType = 26 MessageType_TAP_NOTIFY MessageType = 27 - MessageType_TAP_SNAPSHOT MessageType = 28 // * Combined cached accel + tap poll (one UART round-trip, ~16 ms cadence). MessageType_CACHE_STATUS MessageType = 29 ) @@ -70,11 +68,9 @@ var ( 21: "OTA_SLAVE_PROGRESS", 22: "FIND_ME", 23: "RESTART", - 24: "ACCEL_SNAPSHOT", 25: "ACCEL_STREAM", 26: "BATTERY_STATUS", 27: "TAP_NOTIFY", - 28: "TAP_SNAPSHOT", 29: "CACHE_STATUS", } MessageType_value = map[string]int32{ @@ -95,11 +91,9 @@ var ( "OTA_SLAVE_PROGRESS": 21, "FIND_ME": 22, "RESTART": 23, - "ACCEL_SNAPSHOT": 24, "ACCEL_STREAM": 25, "BATTERY_STATUS": 26, "TAP_NOTIFY": 27, - "TAP_SNAPSHOT": 28, "CACHE_STATUS": 29, } ) @@ -209,16 +203,12 @@ type UartMessage struct { // *UartMessage_EspnowFindMeResponse // *UartMessage_RestartRequest // *UartMessage_RestartResponse - // *UartMessage_AccelSnapshotRequest - // *UartMessage_AccelSnapshotResponse // *UartMessage_AccelStreamRequest // *UartMessage_AccelStreamResponse // *UartMessage_BatteryStatusRequest // *UartMessage_BatteryStatusResponse // *UartMessage_TapNotifyRequest // *UartMessage_TapNotifyResponse - // *UartMessage_TapSnapshotRequest - // *UartMessage_TapSnapshotResponse // *UartMessage_CacheStatusRequest // *UartMessage_CacheStatusResponse Payload isUartMessage_Payload `protobuf_oneof:"payload"` @@ -459,24 +449,6 @@ func (x *UartMessage) GetRestartResponse() *RestartResponse { return nil } -func (x *UartMessage) GetAccelSnapshotRequest() *AccelSnapshotRequest { - if x != nil { - if x, ok := x.Payload.(*UartMessage_AccelSnapshotRequest); ok { - return x.AccelSnapshotRequest - } - } - return nil -} - -func (x *UartMessage) GetAccelSnapshotResponse() *AccelSnapshotResponse { - if x != nil { - if x, ok := x.Payload.(*UartMessage_AccelSnapshotResponse); ok { - return x.AccelSnapshotResponse - } - } - return nil -} - func (x *UartMessage) GetAccelStreamRequest() *AccelStreamRequest { if x != nil { if x, ok := x.Payload.(*UartMessage_AccelStreamRequest); ok { @@ -531,24 +503,6 @@ func (x *UartMessage) GetTapNotifyResponse() *TapNotifyResponse { return nil } -func (x *UartMessage) GetTapSnapshotRequest() *TapSnapshotRequest { - if x != nil { - if x, ok := x.Payload.(*UartMessage_TapSnapshotRequest); ok { - return x.TapSnapshotRequest - } - } - return nil -} - -func (x *UartMessage) GetTapSnapshotResponse() *TapSnapshotResponse { - if x != nil { - if x, ok := x.Payload.(*UartMessage_TapSnapshotResponse); ok { - return x.TapSnapshotResponse - } - } - return nil -} - func (x *UartMessage) GetCacheStatusRequest() *CacheStatusRequest { if x != nil { if x, ok := x.Payload.(*UartMessage_CacheStatusRequest); ok { @@ -655,14 +609,6 @@ type UartMessage_RestartResponse struct { RestartResponse *RestartResponse `protobuf:"bytes,22,opt,name=restart_response,json=restartResponse,proto3,oneof"` } -type UartMessage_AccelSnapshotRequest struct { - AccelSnapshotRequest *AccelSnapshotRequest `protobuf:"bytes,23,opt,name=accel_snapshot_request,json=accelSnapshotRequest,proto3,oneof"` -} - -type UartMessage_AccelSnapshotResponse struct { - AccelSnapshotResponse *AccelSnapshotResponse `protobuf:"bytes,24,opt,name=accel_snapshot_response,json=accelSnapshotResponse,proto3,oneof"` -} - type UartMessage_AccelStreamRequest struct { AccelStreamRequest *AccelStreamRequest `protobuf:"bytes,25,opt,name=accel_stream_request,json=accelStreamRequest,proto3,oneof"` } @@ -687,14 +633,6 @@ type UartMessage_TapNotifyResponse struct { TapNotifyResponse *TapNotifyResponse `protobuf:"bytes,30,opt,name=tap_notify_response,json=tapNotifyResponse,proto3,oneof"` } -type UartMessage_TapSnapshotRequest struct { - TapSnapshotRequest *TapSnapshotRequest `protobuf:"bytes,31,opt,name=tap_snapshot_request,json=tapSnapshotRequest,proto3,oneof"` -} - -type UartMessage_TapSnapshotResponse struct { - TapSnapshotResponse *TapSnapshotResponse `protobuf:"bytes,32,opt,name=tap_snapshot_response,json=tapSnapshotResponse,proto3,oneof"` -} - type UartMessage_CacheStatusRequest struct { CacheStatusRequest *CacheStatusRequest `protobuf:"bytes,33,opt,name=cache_status_request,json=cacheStatusRequest,proto3,oneof"` } @@ -745,10 +683,6 @@ func (*UartMessage_RestartRequest) isUartMessage_Payload() {} func (*UartMessage_RestartResponse) isUartMessage_Payload() {} -func (*UartMessage_AccelSnapshotRequest) isUartMessage_Payload() {} - -func (*UartMessage_AccelSnapshotResponse) isUartMessage_Payload() {} - func (*UartMessage_AccelStreamRequest) isUartMessage_Payload() {} func (*UartMessage_AccelStreamResponse) isUartMessage_Payload() {} @@ -761,10 +695,6 @@ func (*UartMessage_TapNotifyRequest) isUartMessage_Payload() {} func (*UartMessage_TapNotifyResponse) isUartMessage_Payload() {} -func (*UartMessage_TapSnapshotRequest) isUartMessage_Payload() {} - -func (*UartMessage_TapSnapshotResponse) isUartMessage_Payload() {} - func (*UartMessage_CacheStatusRequest) isUartMessage_Payload() {} func (*UartMessage_CacheStatusResponse) isUartMessage_Payload() {} @@ -1698,52 +1628,7 @@ func (x *BatteryStatusResponse) GetSamples() []*BatterySample { return nil } -// Host → master: read cached accel samples from slaves (only while stream enabled). -// client_id 0 = all registered slaves; otherwise one slave. -type AccelSnapshotRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ClientId uint32 `protobuf:"varint,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AccelSnapshotRequest) Reset() { - *x = AccelSnapshotRequest{} - mi := &file_uart_messages_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AccelSnapshotRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AccelSnapshotRequest) ProtoMessage() {} - -func (x *AccelSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[16] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AccelSnapshotRequest.ProtoReflect.Descriptor instead. -func (*AccelSnapshotRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{16} -} - -func (x *AccelSnapshotRequest) GetClientId() uint32 { - if x != nil { - return x.ClientId - } - return 0 -} - +// * Legacy host-side sample shape (dashboard helpers); use CACHE_STATUS on the wire. type AccelSample struct { state protoimpl.MessageState `protogen:"open.v1"` ClientId uint32 `protobuf:"varint,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` @@ -1759,7 +1644,7 @@ type AccelSample struct { func (x *AccelSample) Reset() { *x = AccelSample{} - mi := &file_uart_messages_proto_msgTypes[17] + mi := &file_uart_messages_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1771,7 +1656,7 @@ func (x *AccelSample) String() string { func (*AccelSample) ProtoMessage() {} func (x *AccelSample) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[17] + mi := &file_uart_messages_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1784,7 +1669,7 @@ func (x *AccelSample) ProtoReflect() protoreflect.Message { // Deprecated: Use AccelSample.ProtoReflect.Descriptor instead. func (*AccelSample) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{17} + return file_uart_messages_proto_rawDescGZIP(), []int{16} } func (x *AccelSample) GetClientId() uint32 { @@ -1829,50 +1714,6 @@ func (x *AccelSample) GetAgeMs() uint32 { return 0 } -type AccelSnapshotResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Samples []*AccelSample `protobuf:"bytes,1,rep,name=samples,proto3" json:"samples,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *AccelSnapshotResponse) Reset() { - *x = AccelSnapshotResponse{} - mi := &file_uart_messages_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *AccelSnapshotResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AccelSnapshotResponse) ProtoMessage() {} - -func (x *AccelSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[18] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AccelSnapshotResponse.ProtoReflect.Descriptor instead. -func (*AccelSnapshotResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{18} -} - -func (x *AccelSnapshotResponse) GetSamples() []*AccelSample { - if x != nil { - return x.Samples - } - return nil -} - // * Host → master: enable/disable tap ESP-NOW notify per slave (single/double/triple). type TapNotifyRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1888,7 +1729,7 @@ type TapNotifyRequest struct { func (x *TapNotifyRequest) Reset() { *x = TapNotifyRequest{} - mi := &file_uart_messages_proto_msgTypes[19] + mi := &file_uart_messages_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1900,7 +1741,7 @@ func (x *TapNotifyRequest) String() string { func (*TapNotifyRequest) ProtoMessage() {} func (x *TapNotifyRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[19] + mi := &file_uart_messages_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1913,7 +1754,7 @@ func (x *TapNotifyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TapNotifyRequest.ProtoReflect.Descriptor instead. func (*TapNotifyRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{19} + return file_uart_messages_proto_rawDescGZIP(), []int{17} } func (x *TapNotifyRequest) GetWrite() bool { @@ -1972,7 +1813,7 @@ type TapNotifyResponse struct { func (x *TapNotifyResponse) Reset() { *x = TapNotifyResponse{} - mi := &file_uart_messages_proto_msgTypes[20] + mi := &file_uart_messages_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1984,7 +1825,7 @@ func (x *TapNotifyResponse) String() string { func (*TapNotifyResponse) ProtoMessage() {} func (x *TapNotifyResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[20] + mi := &file_uart_messages_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1997,7 +1838,7 @@ func (x *TapNotifyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TapNotifyResponse.ProtoReflect.Descriptor instead. func (*TapNotifyResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{20} + return file_uart_messages_proto_rawDescGZIP(), []int{18} } func (x *TapNotifyResponse) GetClientId() uint32 { @@ -2042,51 +1883,7 @@ func (x *TapNotifyResponse) GetTriple() bool { return false } -// * Host → master: read cached tap events (discarded after reply or when age > 16 ms). -type TapSnapshotRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ClientId uint32 `protobuf:"varint,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *TapSnapshotRequest) Reset() { - *x = TapSnapshotRequest{} - mi := &file_uart_messages_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *TapSnapshotRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TapSnapshotRequest) ProtoMessage() {} - -func (x *TapSnapshotRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[21] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TapSnapshotRequest.ProtoReflect.Descriptor instead. -func (*TapSnapshotRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{21} -} - -func (x *TapSnapshotRequest) GetClientId() uint32 { - if x != nil { - return x.ClientId - } - return 0 -} - +// * Legacy tap event shape (dashboard helpers); use CACHE_STATUS on the wire. type TapEvent struct { state protoimpl.MessageState `protogen:"open.v1"` ClientId uint32 `protobuf:"varint,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` @@ -2099,7 +1896,7 @@ type TapEvent struct { func (x *TapEvent) Reset() { *x = TapEvent{} - mi := &file_uart_messages_proto_msgTypes[22] + mi := &file_uart_messages_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2111,7 +1908,7 @@ func (x *TapEvent) String() string { func (*TapEvent) ProtoMessage() {} func (x *TapEvent) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[22] + mi := &file_uart_messages_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2124,7 +1921,7 @@ func (x *TapEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use TapEvent.ProtoReflect.Descriptor instead. func (*TapEvent) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{22} + return file_uart_messages_proto_rawDescGZIP(), []int{19} } func (x *TapEvent) GetClientId() uint32 { @@ -2155,50 +1952,6 @@ func (x *TapEvent) GetAgeMs() uint32 { return 0 } -type TapSnapshotResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Events []*TapEvent `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *TapSnapshotResponse) Reset() { - *x = TapSnapshotResponse{} - mi := &file_uart_messages_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *TapSnapshotResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TapSnapshotResponse) ProtoMessage() {} - -func (x *TapSnapshotResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[23] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TapSnapshotResponse.ProtoReflect.Descriptor instead. -func (*TapSnapshotResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{23} -} - -func (x *TapSnapshotResponse) GetEvents() []*TapEvent { - if x != nil { - return x.Events - } - return nil -} - // * Host → master: one-shot read of subscribed cached slave data (no request body). type CacheStatusRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -2208,7 +1961,7 @@ type CacheStatusRequest struct { func (x *CacheStatusRequest) Reset() { *x = CacheStatusRequest{} - mi := &file_uart_messages_proto_msgTypes[24] + mi := &file_uart_messages_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2220,7 +1973,7 @@ func (x *CacheStatusRequest) String() string { func (*CacheStatusRequest) ProtoMessage() {} func (x *CacheStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[24] + mi := &file_uart_messages_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2233,22 +1986,211 @@ func (x *CacheStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CacheStatusRequest.ProtoReflect.Descriptor instead. func (*CacheStatusRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{24} + return file_uart_messages_proto_rawDescGZIP(), []int{20} +} + +// * Accel slice inside CACHE_STATUS (no client_id — use parent CacheClientStatus). +type CacheClientAccel struct { + state protoimpl.MessageState `protogen:"open.v1"` + Valid bool `protobuf:"varint,1,opt,name=valid,proto3" json:"valid,omitempty"` + X int32 `protobuf:"zigzag32,2,opt,name=x,proto3" json:"x,omitempty"` + Y int32 `protobuf:"zigzag32,3,opt,name=y,proto3" json:"y,omitempty"` + Z int32 `protobuf:"zigzag32,4,opt,name=z,proto3" json:"z,omitempty"` + AgeMs uint32 `protobuf:"varint,5,opt,name=age_ms,json=ageMs,proto3" json:"age_ms,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CacheClientAccel) Reset() { + *x = CacheClientAccel{} + mi := &file_uart_messages_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CacheClientAccel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CacheClientAccel) ProtoMessage() {} + +func (x *CacheClientAccel) ProtoReflect() protoreflect.Message { + mi := &file_uart_messages_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CacheClientAccel.ProtoReflect.Descriptor instead. +func (*CacheClientAccel) Descriptor() ([]byte, []int) { + return file_uart_messages_proto_rawDescGZIP(), []int{21} +} + +func (x *CacheClientAccel) GetValid() bool { + if x != nil { + return x.Valid + } + return false +} + +func (x *CacheClientAccel) GetX() int32 { + if x != nil { + return x.X + } + return 0 +} + +func (x *CacheClientAccel) GetY() int32 { + if x != nil { + return x.Y + } + return 0 +} + +func (x *CacheClientAccel) GetZ() int32 { + if x != nil { + return x.Z + } + return 0 +} + +func (x *CacheClientAccel) GetAgeMs() uint32 { + if x != nil { + return x.AgeMs + } + return 0 +} + +// * Tap slice inside CACHE_STATUS; only present when a pending tap was consumed. +type CacheClientTap struct { + state protoimpl.MessageState `protogen:"open.v1"` + Kind TapKind `protobuf:"varint,1,opt,name=kind,proto3,enum=alox.TapKind" json:"kind,omitempty"` + AgeMs uint32 `protobuf:"varint,2,opt,name=age_ms,json=ageMs,proto3" json:"age_ms,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CacheClientTap) Reset() { + *x = CacheClientTap{} + mi := &file_uart_messages_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CacheClientTap) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CacheClientTap) ProtoMessage() {} + +func (x *CacheClientTap) ProtoReflect() protoreflect.Message { + mi := &file_uart_messages_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CacheClientTap.ProtoReflect.Descriptor instead. +func (*CacheClientTap) Descriptor() ([]byte, []int) { + return file_uart_messages_proto_rawDescGZIP(), []int{22} +} + +func (x *CacheClientTap) GetKind() TapKind { + if x != nil { + return x.Kind + } + return TapKind_TAP_NONE +} + +func (x *CacheClientTap) GetAgeMs() uint32 { + if x != nil { + return x.AgeMs + } + return 0 +} + +// * One slave with accel and/or tap notify enabled; only subscribed fields are set. +type CacheClientStatus struct { + state protoimpl.MessageState `protogen:"open.v1"` + ClientId uint32 `protobuf:"varint,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + Accel *CacheClientAccel `protobuf:"bytes,2,opt,name=accel,proto3" json:"accel,omitempty"` + Tap *CacheClientTap `protobuf:"bytes,3,opt,name=tap,proto3" json:"tap,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CacheClientStatus) Reset() { + *x = CacheClientStatus{} + mi := &file_uart_messages_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CacheClientStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CacheClientStatus) ProtoMessage() {} + +func (x *CacheClientStatus) ProtoReflect() protoreflect.Message { + mi := &file_uart_messages_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CacheClientStatus.ProtoReflect.Descriptor instead. +func (*CacheClientStatus) Descriptor() ([]byte, []int) { + return file_uart_messages_proto_rawDescGZIP(), []int{23} +} + +func (x *CacheClientStatus) GetClientId() uint32 { + if x != nil { + return x.ClientId + } + return 0 +} + +func (x *CacheClientStatus) GetAccel() *CacheClientAccel { + if x != nil { + return x.Accel + } + return nil +} + +func (x *CacheClientStatus) GetTap() *CacheClientTap { + if x != nil { + return x.Tap + } + return nil } type CacheStatusResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - // * Slaves with accel_stream_enabled. - Accel []*AccelSample `protobuf:"bytes,1,rep,name=accel,proto3" json:"accel,omitempty"` - // * Slaves with any tap notify flag; pending taps are consumed (like TAP_SNAPSHOT). - Taps []*TapEvent `protobuf:"bytes,2,rep,name=taps,proto3" json:"taps,omitempty"` + // * Slaves with accel_stream and/or tap notify; omitted fields are not subscribed. + Clients []*CacheClientStatus `protobuf:"bytes,1,rep,name=clients,proto3" json:"clients,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *CacheStatusResponse) Reset() { *x = CacheStatusResponse{} - mi := &file_uart_messages_proto_msgTypes[25] + mi := &file_uart_messages_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2260,7 +2202,7 @@ func (x *CacheStatusResponse) String() string { func (*CacheStatusResponse) ProtoMessage() {} func (x *CacheStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[25] + mi := &file_uart_messages_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2273,19 +2215,12 @@ func (x *CacheStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CacheStatusResponse.ProtoReflect.Descriptor instead. func (*CacheStatusResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{25} + return file_uart_messages_proto_rawDescGZIP(), []int{24} } -func (x *CacheStatusResponse) GetAccel() []*AccelSample { +func (x *CacheStatusResponse) GetClients() []*CacheClientStatus { if x != nil { - return x.Accel - } - return nil -} - -func (x *CacheStatusResponse) GetTaps() []*TapEvent { - if x != nil { - return x.Taps + return x.Clients } return nil } @@ -2300,7 +2235,7 @@ type EspNowUnicastTestRequest struct { func (x *EspNowUnicastTestRequest) Reset() { *x = EspNowUnicastTestRequest{} - mi := &file_uart_messages_proto_msgTypes[26] + mi := &file_uart_messages_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2312,7 +2247,7 @@ func (x *EspNowUnicastTestRequest) String() string { func (*EspNowUnicastTestRequest) ProtoMessage() {} func (x *EspNowUnicastTestRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[26] + mi := &file_uart_messages_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2325,7 +2260,7 @@ func (x *EspNowUnicastTestRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EspNowUnicastTestRequest.ProtoReflect.Descriptor instead. func (*EspNowUnicastTestRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{26} + return file_uart_messages_proto_rawDescGZIP(), []int{25} } func (x *EspNowUnicastTestRequest) GetClientId() uint32 { @@ -2352,7 +2287,7 @@ type EspNowUnicastTestResponse struct { func (x *EspNowUnicastTestResponse) Reset() { *x = EspNowUnicastTestResponse{} - mi := &file_uart_messages_proto_msgTypes[27] + mi := &file_uart_messages_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2364,7 +2299,7 @@ func (x *EspNowUnicastTestResponse) String() string { func (*EspNowUnicastTestResponse) ProtoMessage() {} func (x *EspNowUnicastTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[27] + mi := &file_uart_messages_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2377,7 +2312,7 @@ func (x *EspNowUnicastTestResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EspNowUnicastTestResponse.ProtoReflect.Descriptor instead. func (*EspNowUnicastTestResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{27} + return file_uart_messages_proto_rawDescGZIP(), []int{26} } func (x *EspNowUnicastTestResponse) GetSuccess() bool { @@ -2424,7 +2359,7 @@ type LedRingProgressRequest struct { func (x *LedRingProgressRequest) Reset() { *x = LedRingProgressRequest{} - mi := &file_uart_messages_proto_msgTypes[28] + mi := &file_uart_messages_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2436,7 +2371,7 @@ func (x *LedRingProgressRequest) String() string { func (*LedRingProgressRequest) ProtoMessage() {} func (x *LedRingProgressRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[28] + mi := &file_uart_messages_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2449,7 +2384,7 @@ func (x *LedRingProgressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LedRingProgressRequest.ProtoReflect.Descriptor instead. func (*LedRingProgressRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{28} + return file_uart_messages_proto_rawDescGZIP(), []int{27} } func (x *LedRingProgressRequest) GetMode() uint32 { @@ -2550,7 +2485,7 @@ type LedRingProgressResponse struct { func (x *LedRingProgressResponse) Reset() { *x = LedRingProgressResponse{} - mi := &file_uart_messages_proto_msgTypes[29] + mi := &file_uart_messages_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2562,7 +2497,7 @@ func (x *LedRingProgressResponse) String() string { func (*LedRingProgressResponse) ProtoMessage() {} func (x *LedRingProgressResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[29] + mi := &file_uart_messages_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2575,7 +2510,7 @@ func (x *LedRingProgressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LedRingProgressResponse.ProtoReflect.Descriptor instead. func (*LedRingProgressResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{29} + return file_uart_messages_proto_rawDescGZIP(), []int{28} } func (x *LedRingProgressResponse) GetSuccess() bool { @@ -2630,7 +2565,7 @@ type EspNowFindMeRequest struct { func (x *EspNowFindMeRequest) Reset() { *x = EspNowFindMeRequest{} - mi := &file_uart_messages_proto_msgTypes[30] + mi := &file_uart_messages_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2642,7 +2577,7 @@ func (x *EspNowFindMeRequest) String() string { func (*EspNowFindMeRequest) ProtoMessage() {} func (x *EspNowFindMeRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[30] + mi := &file_uart_messages_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2655,7 +2590,7 @@ func (x *EspNowFindMeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EspNowFindMeRequest.ProtoReflect.Descriptor instead. func (*EspNowFindMeRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{30} + return file_uart_messages_proto_rawDescGZIP(), []int{29} } func (x *EspNowFindMeRequest) GetClientId() uint32 { @@ -2675,7 +2610,7 @@ type EspNowFindMeResponse struct { func (x *EspNowFindMeResponse) Reset() { *x = EspNowFindMeResponse{} - mi := &file_uart_messages_proto_msgTypes[31] + mi := &file_uart_messages_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2687,7 +2622,7 @@ func (x *EspNowFindMeResponse) String() string { func (*EspNowFindMeResponse) ProtoMessage() {} func (x *EspNowFindMeResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[31] + mi := &file_uart_messages_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2700,7 +2635,7 @@ func (x *EspNowFindMeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EspNowFindMeResponse.ProtoReflect.Descriptor instead. func (*EspNowFindMeResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{31} + return file_uart_messages_proto_rawDescGZIP(), []int{30} } func (x *EspNowFindMeResponse) GetSuccess() bool { @@ -2727,7 +2662,7 @@ type RestartRequest struct { func (x *RestartRequest) Reset() { *x = RestartRequest{} - mi := &file_uart_messages_proto_msgTypes[32] + mi := &file_uart_messages_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2739,7 +2674,7 @@ func (x *RestartRequest) String() string { func (*RestartRequest) ProtoMessage() {} func (x *RestartRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[32] + mi := &file_uart_messages_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2752,7 +2687,7 @@ func (x *RestartRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestartRequest.ProtoReflect.Descriptor instead. func (*RestartRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{32} + return file_uart_messages_proto_rawDescGZIP(), []int{31} } func (x *RestartRequest) GetClientId() uint32 { @@ -2772,7 +2707,7 @@ type RestartResponse struct { func (x *RestartResponse) Reset() { *x = RestartResponse{} - mi := &file_uart_messages_proto_msgTypes[33] + mi := &file_uart_messages_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2784,7 +2719,7 @@ func (x *RestartResponse) String() string { func (*RestartResponse) ProtoMessage() {} func (x *RestartResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[33] + mi := &file_uart_messages_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2797,7 +2732,7 @@ func (x *RestartResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestartResponse.ProtoReflect.Descriptor instead. func (*RestartResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{33} + return file_uart_messages_proto_rawDescGZIP(), []int{32} } func (x *RestartResponse) GetSuccess() bool { @@ -2824,7 +2759,7 @@ type OtaStartPayload struct { func (x *OtaStartPayload) Reset() { *x = OtaStartPayload{} - mi := &file_uart_messages_proto_msgTypes[34] + mi := &file_uart_messages_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2836,7 +2771,7 @@ func (x *OtaStartPayload) String() string { func (*OtaStartPayload) ProtoMessage() {} func (x *OtaStartPayload) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[34] + mi := &file_uart_messages_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2849,7 +2784,7 @@ func (x *OtaStartPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use OtaStartPayload.ProtoReflect.Descriptor instead. func (*OtaStartPayload) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{34} + return file_uart_messages_proto_rawDescGZIP(), []int{33} } func (x *OtaStartPayload) GetTotalSize() uint32 { @@ -2870,7 +2805,7 @@ type OtaPayload struct { func (x *OtaPayload) Reset() { *x = OtaPayload{} - mi := &file_uart_messages_proto_msgTypes[35] + mi := &file_uart_messages_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2882,7 +2817,7 @@ func (x *OtaPayload) String() string { func (*OtaPayload) ProtoMessage() {} func (x *OtaPayload) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[35] + mi := &file_uart_messages_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2895,7 +2830,7 @@ func (x *OtaPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use OtaPayload.ProtoReflect.Descriptor instead. func (*OtaPayload) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{35} + return file_uart_messages_proto_rawDescGZIP(), []int{34} } func (x *OtaPayload) GetSeq() uint32 { @@ -2921,7 +2856,7 @@ type OtaEndPayload struct { func (x *OtaEndPayload) Reset() { *x = OtaEndPayload{} - mi := &file_uart_messages_proto_msgTypes[36] + mi := &file_uart_messages_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2933,7 +2868,7 @@ func (x *OtaEndPayload) String() string { func (*OtaEndPayload) ProtoMessage() {} func (x *OtaEndPayload) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[36] + mi := &file_uart_messages_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2946,7 +2881,7 @@ func (x *OtaEndPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use OtaEndPayload.ProtoReflect.Descriptor instead. func (*OtaEndPayload) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{36} + return file_uart_messages_proto_rawDescGZIP(), []int{35} } // Device → host status (also used as ACK after each 4 KiB written). @@ -2963,7 +2898,7 @@ type OtaStatusPayload struct { func (x *OtaStatusPayload) Reset() { *x = OtaStatusPayload{} - mi := &file_uart_messages_proto_msgTypes[37] + mi := &file_uart_messages_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2975,7 +2910,7 @@ func (x *OtaStatusPayload) String() string { func (*OtaStatusPayload) ProtoMessage() {} func (x *OtaStatusPayload) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[37] + mi := &file_uart_messages_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2988,7 +2923,7 @@ func (x *OtaStatusPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use OtaStatusPayload.ProtoReflect.Descriptor instead. func (*OtaStatusPayload) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{37} + return file_uart_messages_proto_rawDescGZIP(), []int{36} } func (x *OtaStatusPayload) GetStatus() uint32 { @@ -3029,7 +2964,7 @@ type OtaSlaveProgressRequest struct { func (x *OtaSlaveProgressRequest) Reset() { *x = OtaSlaveProgressRequest{} - mi := &file_uart_messages_proto_msgTypes[38] + mi := &file_uart_messages_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3041,7 +2976,7 @@ func (x *OtaSlaveProgressRequest) String() string { func (*OtaSlaveProgressRequest) ProtoMessage() {} func (x *OtaSlaveProgressRequest) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[38] + mi := &file_uart_messages_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3054,7 +2989,7 @@ func (x *OtaSlaveProgressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OtaSlaveProgressRequest.ProtoReflect.Descriptor instead. func (*OtaSlaveProgressRequest) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{38} + return file_uart_messages_proto_rawDescGZIP(), []int{37} } func (x *OtaSlaveProgressRequest) GetClientId() uint32 { @@ -3078,7 +3013,7 @@ type OtaSlaveProgressEntry struct { func (x *OtaSlaveProgressEntry) Reset() { *x = OtaSlaveProgressEntry{} - mi := &file_uart_messages_proto_msgTypes[39] + mi := &file_uart_messages_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3090,7 +3025,7 @@ func (x *OtaSlaveProgressEntry) String() string { func (*OtaSlaveProgressEntry) ProtoMessage() {} func (x *OtaSlaveProgressEntry) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[39] + mi := &file_uart_messages_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3103,7 +3038,7 @@ func (x *OtaSlaveProgressEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use OtaSlaveProgressEntry.ProtoReflect.Descriptor instead. func (*OtaSlaveProgressEntry) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{39} + return file_uart_messages_proto_rawDescGZIP(), []int{38} } func (x *OtaSlaveProgressEntry) GetClientId() uint32 { @@ -3154,7 +3089,7 @@ type OtaSlaveProgressResponse struct { func (x *OtaSlaveProgressResponse) Reset() { *x = OtaSlaveProgressResponse{} - mi := &file_uart_messages_proto_msgTypes[40] + mi := &file_uart_messages_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3166,7 +3101,7 @@ func (x *OtaSlaveProgressResponse) String() string { func (*OtaSlaveProgressResponse) ProtoMessage() {} func (x *OtaSlaveProgressResponse) ProtoReflect() protoreflect.Message { - mi := &file_uart_messages_proto_msgTypes[40] + mi := &file_uart_messages_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3179,7 +3114,7 @@ func (x *OtaSlaveProgressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use OtaSlaveProgressResponse.ProtoReflect.Descriptor instead. func (*OtaSlaveProgressResponse) Descriptor() ([]byte, []int) { - return file_uart_messages_proto_rawDescGZIP(), []int{40} + return file_uart_messages_proto_rawDescGZIP(), []int{39} } func (x *OtaSlaveProgressResponse) GetActive() bool { @@ -3221,7 +3156,7 @@ var File_uart_messages_proto protoreflect.FileDescriptor const file_uart_messages_proto_rawDesc = "" + "\n" + - "\x13uart_messages.proto\x12\x04alox\x1a\fnanopb.proto\"\xb6\x14\n" + + "\x13uart_messages.proto\x12\x04alox\x1a\fnanopb.proto\"\xec\x11\n" + "\vUartMessage\x12%\n" + "\x04type\x18\x01 \x01(\x0e2\x11.alox.MessageTypeR\x04type\x12,\n" + "\vack_payload\x18\x02 \x01(\v2\t.alox.AckH\x00R\n" + @@ -3248,17 +3183,13 @@ const file_uart_messages_proto_rawDesc = "" + "\x16espnow_find_me_request\x18\x13 \x01(\v2\x19.alox.EspNowFindMeRequestH\x00R\x13espnowFindMeRequest\x12S\n" + "\x17espnow_find_me_response\x18\x14 \x01(\v2\x1a.alox.EspNowFindMeResponseH\x00R\x14espnowFindMeResponse\x12?\n" + "\x0frestart_request\x18\x15 \x01(\v2\x14.alox.RestartRequestH\x00R\x0erestartRequest\x12B\n" + - "\x10restart_response\x18\x16 \x01(\v2\x15.alox.RestartResponseH\x00R\x0frestartResponse\x12R\n" + - "\x16accel_snapshot_request\x18\x17 \x01(\v2\x1a.alox.AccelSnapshotRequestH\x00R\x14accelSnapshotRequest\x12U\n" + - "\x17accel_snapshot_response\x18\x18 \x01(\v2\x1b.alox.AccelSnapshotResponseH\x00R\x15accelSnapshotResponse\x12L\n" + + "\x10restart_response\x18\x16 \x01(\v2\x15.alox.RestartResponseH\x00R\x0frestartResponse\x12L\n" + "\x14accel_stream_request\x18\x19 \x01(\v2\x18.alox.AccelStreamRequestH\x00R\x12accelStreamRequest\x12O\n" + "\x15accel_stream_response\x18\x1a \x01(\v2\x19.alox.AccelStreamResponseH\x00R\x13accelStreamResponse\x12R\n" + "\x16battery_status_request\x18\x1b \x01(\v2\x1a.alox.BatteryStatusRequestH\x00R\x14batteryStatusRequest\x12U\n" + "\x17battery_status_response\x18\x1c \x01(\v2\x1b.alox.BatteryStatusResponseH\x00R\x15batteryStatusResponse\x12F\n" + "\x12tap_notify_request\x18\x1d \x01(\v2\x16.alox.TapNotifyRequestH\x00R\x10tapNotifyRequest\x12I\n" + "\x13tap_notify_response\x18\x1e \x01(\v2\x17.alox.TapNotifyResponseH\x00R\x11tapNotifyResponse\x12L\n" + - "\x14tap_snapshot_request\x18\x1f \x01(\v2\x18.alox.TapSnapshotRequestH\x00R\x12tapSnapshotRequest\x12O\n" + - "\x15tap_snapshot_response\x18 \x01(\v2\x19.alox.TapSnapshotResponseH\x00R\x13tapSnapshotResponse\x12L\n" + "\x14cache_status_request\x18! \x01(\v2\x18.alox.CacheStatusRequestH\x00R\x12cacheStatusRequest\x12O\n" + "\x15cache_status_response\x18\" \x01(\v2\x19.alox.CacheStatusResponseH\x00R\x13cacheStatusResponseB\t\n" + "\apayload\"\x05\n" + @@ -3329,18 +3260,14 @@ const file_uart_messages_proto_rawDesc = "" + "\x06age_ms\x18\x04 \x01(\rR\x05ageMs\"g\n" + "\x15BatteryStatusResponse\x12\x18\n" + "\asuccess\x18\x01 \x01(\bR\asuccess\x124\n" + - "\asamples\x18\x02 \x03(\v2\x13.alox.BatterySampleB\x05\x92?\x02\x10\x11R\asamples\"3\n" + - "\x14AccelSnapshotRequest\x12\x1b\n" + - "\tclient_id\x18\x01 \x01(\rR\bclientId\"\x81\x01\n" + + "\asamples\x18\x02 \x03(\v2\x13.alox.BatterySampleB\x05\x92?\x02\x10\x11R\asamples\"\x81\x01\n" + "\vAccelSample\x12\x1b\n" + "\tclient_id\x18\x01 \x01(\rR\bclientId\x12\x14\n" + "\x05valid\x18\x02 \x01(\bR\x05valid\x12\f\n" + "\x01x\x18\x03 \x01(\x11R\x01x\x12\f\n" + "\x01y\x18\x04 \x01(\x11R\x01y\x12\f\n" + "\x01z\x18\x05 \x01(\x11R\x01z\x12\x15\n" + - "\x06age_ms\x18\x06 \x01(\rR\x05ageMs\"K\n" + - "\x15AccelSnapshotResponse\x122\n" + - "\asamples\x18\x01 \x03(\v2\x11.alox.AccelSampleB\x05\x92?\x02\x10\x10R\asamples\"\xb5\x01\n" + + "\x06age_ms\x18\x06 \x01(\rR\x05ageMs\"\xb5\x01\n" + "\x10TapNotifyRequest\x12\x14\n" + "\x05write\x18\x01 \x01(\bR\x05write\x12\x1b\n" + "\tclient_id\x18\x02 \x01(\rR\bclientId\x12\x1f\n" + @@ -3357,20 +3284,28 @@ const file_uart_messages_proto_rawDesc = "" + "\x06single\x18\x04 \x01(\bR\x06single\x12\x1d\n" + "\n" + "double_tap\x18\x05 \x01(\bR\tdoubleTap\x12\x16\n" + - "\x06triple\x18\x06 \x01(\bR\x06triple\"1\n" + - "\x12TapSnapshotRequest\x12\x1b\n" + - "\tclient_id\x18\x01 \x01(\rR\bclientId\"w\n" + + "\x06triple\x18\x06 \x01(\bR\x06triple\"w\n" + "\bTapEvent\x12\x1b\n" + "\tclient_id\x18\x01 \x01(\rR\bclientId\x12\x14\n" + "\x05valid\x18\x02 \x01(\bR\x05valid\x12!\n" + "\x04kind\x18\x03 \x01(\x0e2\r.alox.TapKindR\x04kind\x12\x15\n" + - "\x06age_ms\x18\x04 \x01(\rR\x05ageMs\"D\n" + - "\x13TapSnapshotResponse\x12-\n" + - "\x06events\x18\x01 \x03(\v2\x0e.alox.TapEventB\x05\x92?\x02\x10\x10R\x06events\"\x14\n" + - "\x12CacheStatusRequest\"p\n" + - "\x13CacheStatusResponse\x12.\n" + - "\x05accel\x18\x01 \x03(\v2\x11.alox.AccelSampleB\x05\x92?\x02\x10\x10R\x05accel\x12)\n" + - "\x04taps\x18\x02 \x03(\v2\x0e.alox.TapEventB\x05\x92?\x02\x10\x10R\x04taps\"I\n" + + "\x06age_ms\x18\x04 \x01(\rR\x05ageMs\"\x14\n" + + "\x12CacheStatusRequest\"i\n" + + "\x10CacheClientAccel\x12\x14\n" + + "\x05valid\x18\x01 \x01(\bR\x05valid\x12\f\n" + + "\x01x\x18\x02 \x01(\x11R\x01x\x12\f\n" + + "\x01y\x18\x03 \x01(\x11R\x01y\x12\f\n" + + "\x01z\x18\x04 \x01(\x11R\x01z\x12\x15\n" + + "\x06age_ms\x18\x05 \x01(\rR\x05ageMs\"J\n" + + "\x0eCacheClientTap\x12!\n" + + "\x04kind\x18\x01 \x01(\x0e2\r.alox.TapKindR\x04kind\x12\x15\n" + + "\x06age_ms\x18\x02 \x01(\rR\x05ageMs\"\x86\x01\n" + + "\x11CacheClientStatus\x12\x1b\n" + + "\tclient_id\x18\x01 \x01(\rR\bclientId\x12,\n" + + "\x05accel\x18\x02 \x01(\v2\x16.alox.CacheClientAccelR\x05accel\x12&\n" + + "\x03tap\x18\x03 \x01(\v2\x14.alox.CacheClientTapR\x03tap\"O\n" + + "\x13CacheStatusResponse\x128\n" + + "\aclients\x18\x01 \x03(\v2\x17.alox.CacheClientStatusB\x05\x92?\x02\x10\x10R\aclients\"I\n" + "\x18EspNowUnicastTestRequest\x12\x1b\n" + "\tclient_id\x18\x01 \x01(\rR\bclientId\x12\x10\n" + "\x03seq\x18\x02 \x01(\rR\x03seq\"G\n" + @@ -3441,7 +3376,7 @@ const file_uart_messages_proto_rawDesc = "" + "\x0faggregate_bytes\x18\x03 \x01(\rR\x0eaggregateBytes\x12\x1f\n" + "\vslave_count\x18\x04 \x01(\rR\n" + "slaveCount\x12:\n" + - "\x06slaves\x18\x05 \x03(\v2\x1b.alox.OtaSlaveProgressEntryB\x05\x92?\x02\x10\x10R\x06slaves*\x8b\x03\n" + + "\x06slaves\x18\x05 \x03(\v2\x1b.alox.OtaSlaveProgressEntryB\x05\x92?\x02\x10\x10R\x06slaves*\xf1\x02\n" + "\vMessageType\x12\v\n" + "\aUNKNOWN\x10\x00\x12\a\n" + "\x03ACK\x10\x01\x12\b\n" + @@ -3460,14 +3395,12 @@ const file_uart_messages_proto_rawDesc = "" + "\x10OTA_START_ESPNOW\x10\x14\x12\x16\n" + "\x12OTA_SLAVE_PROGRESS\x10\x15\x12\v\n" + "\aFIND_ME\x10\x16\x12\v\n" + - "\aRESTART\x10\x17\x12\x12\n" + - "\x0eACCEL_SNAPSHOT\x10\x18\x12\x10\n" + + "\aRESTART\x10\x17\x12\x10\n" + "\fACCEL_STREAM\x10\x19\x12\x12\n" + "\x0eBATTERY_STATUS\x10\x1a\x12\x0e\n" + "\n" + "TAP_NOTIFY\x10\x1b\x12\x10\n" + - "\fTAP_SNAPSHOT\x10\x1c\x12\x10\n" + - "\fCACHE_STATUS\x10\x1d*G\n" + + "\fCACHE_STATUS\x10\x1d\"\x04\b\x18\x10\x18\"\x04\b\x1c\x10\x1c*G\n" + "\aTapKind\x12\f\n" + "\bTAP_NONE\x10\x00\x12\x0e\n" + "\n" + @@ -3490,7 +3423,7 @@ func file_uart_messages_proto_rawDescGZIP() []byte { } var file_uart_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_uart_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_uart_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 40) var file_uart_messages_proto_goTypes = []any{ (MessageType)(0), // 0: alox.MessageType (TapKind)(0), // 1: alox.TapKind @@ -3510,31 +3443,30 @@ var file_uart_messages_proto_goTypes = []any{ (*LipoReading)(nil), // 15: alox.LipoReading (*BatterySample)(nil), // 16: alox.BatterySample (*BatteryStatusResponse)(nil), // 17: alox.BatteryStatusResponse - (*AccelSnapshotRequest)(nil), // 18: alox.AccelSnapshotRequest - (*AccelSample)(nil), // 19: alox.AccelSample - (*AccelSnapshotResponse)(nil), // 20: alox.AccelSnapshotResponse - (*TapNotifyRequest)(nil), // 21: alox.TapNotifyRequest - (*TapNotifyResponse)(nil), // 22: alox.TapNotifyResponse - (*TapSnapshotRequest)(nil), // 23: alox.TapSnapshotRequest - (*TapEvent)(nil), // 24: alox.TapEvent - (*TapSnapshotResponse)(nil), // 25: alox.TapSnapshotResponse - (*CacheStatusRequest)(nil), // 26: alox.CacheStatusRequest - (*CacheStatusResponse)(nil), // 27: alox.CacheStatusResponse - (*EspNowUnicastTestRequest)(nil), // 28: alox.EspNowUnicastTestRequest - (*EspNowUnicastTestResponse)(nil), // 29: alox.EspNowUnicastTestResponse - (*LedRingProgressRequest)(nil), // 30: alox.LedRingProgressRequest - (*LedRingProgressResponse)(nil), // 31: alox.LedRingProgressResponse - (*EspNowFindMeRequest)(nil), // 32: alox.EspNowFindMeRequest - (*EspNowFindMeResponse)(nil), // 33: alox.EspNowFindMeResponse - (*RestartRequest)(nil), // 34: alox.RestartRequest - (*RestartResponse)(nil), // 35: alox.RestartResponse - (*OtaStartPayload)(nil), // 36: alox.OtaStartPayload - (*OtaPayload)(nil), // 37: alox.OtaPayload - (*OtaEndPayload)(nil), // 38: alox.OtaEndPayload - (*OtaStatusPayload)(nil), // 39: alox.OtaStatusPayload - (*OtaSlaveProgressRequest)(nil), // 40: alox.OtaSlaveProgressRequest - (*OtaSlaveProgressEntry)(nil), // 41: alox.OtaSlaveProgressEntry - (*OtaSlaveProgressResponse)(nil), // 42: alox.OtaSlaveProgressResponse + (*AccelSample)(nil), // 18: alox.AccelSample + (*TapNotifyRequest)(nil), // 19: alox.TapNotifyRequest + (*TapNotifyResponse)(nil), // 20: alox.TapNotifyResponse + (*TapEvent)(nil), // 21: alox.TapEvent + (*CacheStatusRequest)(nil), // 22: alox.CacheStatusRequest + (*CacheClientAccel)(nil), // 23: alox.CacheClientAccel + (*CacheClientTap)(nil), // 24: alox.CacheClientTap + (*CacheClientStatus)(nil), // 25: alox.CacheClientStatus + (*CacheStatusResponse)(nil), // 26: alox.CacheStatusResponse + (*EspNowUnicastTestRequest)(nil), // 27: alox.EspNowUnicastTestRequest + (*EspNowUnicastTestResponse)(nil), // 28: alox.EspNowUnicastTestResponse + (*LedRingProgressRequest)(nil), // 29: alox.LedRingProgressRequest + (*LedRingProgressResponse)(nil), // 30: alox.LedRingProgressResponse + (*EspNowFindMeRequest)(nil), // 31: alox.EspNowFindMeRequest + (*EspNowFindMeResponse)(nil), // 32: alox.EspNowFindMeResponse + (*RestartRequest)(nil), // 33: alox.RestartRequest + (*RestartResponse)(nil), // 34: alox.RestartResponse + (*OtaStartPayload)(nil), // 35: alox.OtaStartPayload + (*OtaPayload)(nil), // 36: alox.OtaPayload + (*OtaEndPayload)(nil), // 37: alox.OtaEndPayload + (*OtaStatusPayload)(nil), // 38: alox.OtaStatusPayload + (*OtaSlaveProgressRequest)(nil), // 39: alox.OtaSlaveProgressRequest + (*OtaSlaveProgressEntry)(nil), // 40: alox.OtaSlaveProgressEntry + (*OtaSlaveProgressResponse)(nil), // 41: alox.OtaSlaveProgressResponse } var file_uart_messages_proto_depIdxs = []int32{ 0, // 0: alox.UartMessage.type:type_name -> alox.MessageType @@ -3543,50 +3475,46 @@ var file_uart_messages_proto_depIdxs = []int32{ 5, // 3: alox.UartMessage.version_response:type_name -> alox.VersionResponse 7, // 4: alox.UartMessage.client_info_response:type_name -> alox.ClientInfoResponse 9, // 5: alox.UartMessage.client_input_response:type_name -> alox.ClientInputResponse - 36, // 6: alox.UartMessage.ota_start:type_name -> alox.OtaStartPayload - 37, // 7: alox.UartMessage.ota_payload:type_name -> alox.OtaPayload - 38, // 8: alox.UartMessage.ota_end:type_name -> alox.OtaEndPayload - 39, // 9: alox.UartMessage.ota_status:type_name -> alox.OtaStatusPayload + 35, // 6: alox.UartMessage.ota_start:type_name -> alox.OtaStartPayload + 36, // 7: alox.UartMessage.ota_payload:type_name -> alox.OtaPayload + 37, // 8: alox.UartMessage.ota_end:type_name -> alox.OtaEndPayload + 38, // 9: alox.UartMessage.ota_status:type_name -> alox.OtaStatusPayload 10, // 10: alox.UartMessage.accel_deadzone_request:type_name -> alox.AccelDeadzoneRequest 11, // 11: alox.UartMessage.accel_deadzone_response:type_name -> alox.AccelDeadzoneResponse - 28, // 12: alox.UartMessage.espnow_unicast_test_request:type_name -> alox.EspNowUnicastTestRequest - 29, // 13: alox.UartMessage.espnow_unicast_test_response:type_name -> alox.EspNowUnicastTestResponse - 40, // 14: alox.UartMessage.ota_slave_progress_request:type_name -> alox.OtaSlaveProgressRequest - 42, // 15: alox.UartMessage.ota_slave_progress_response:type_name -> alox.OtaSlaveProgressResponse - 30, // 16: alox.UartMessage.led_ring_progress_request:type_name -> alox.LedRingProgressRequest - 31, // 17: alox.UartMessage.led_ring_progress_response:type_name -> alox.LedRingProgressResponse - 32, // 18: alox.UartMessage.espnow_find_me_request:type_name -> alox.EspNowFindMeRequest - 33, // 19: alox.UartMessage.espnow_find_me_response:type_name -> alox.EspNowFindMeResponse - 34, // 20: alox.UartMessage.restart_request:type_name -> alox.RestartRequest - 35, // 21: alox.UartMessage.restart_response:type_name -> alox.RestartResponse - 18, // 22: alox.UartMessage.accel_snapshot_request:type_name -> alox.AccelSnapshotRequest - 20, // 23: alox.UartMessage.accel_snapshot_response:type_name -> alox.AccelSnapshotResponse - 12, // 24: alox.UartMessage.accel_stream_request:type_name -> alox.AccelStreamRequest - 13, // 25: alox.UartMessage.accel_stream_response:type_name -> alox.AccelStreamResponse - 14, // 26: alox.UartMessage.battery_status_request:type_name -> alox.BatteryStatusRequest - 17, // 27: alox.UartMessage.battery_status_response:type_name -> alox.BatteryStatusResponse - 21, // 28: alox.UartMessage.tap_notify_request:type_name -> alox.TapNotifyRequest - 22, // 29: alox.UartMessage.tap_notify_response:type_name -> alox.TapNotifyResponse - 23, // 30: alox.UartMessage.tap_snapshot_request:type_name -> alox.TapSnapshotRequest - 25, // 31: alox.UartMessage.tap_snapshot_response:type_name -> alox.TapSnapshotResponse - 26, // 32: alox.UartMessage.cache_status_request:type_name -> alox.CacheStatusRequest - 27, // 33: alox.UartMessage.cache_status_response:type_name -> alox.CacheStatusResponse - 6, // 34: alox.ClientInfoResponse.clients:type_name -> alox.ClientInfo - 8, // 35: alox.ClientInputResponse.clients:type_name -> alox.ClientInput - 15, // 36: alox.BatterySample.lipo1:type_name -> alox.LipoReading - 15, // 37: alox.BatterySample.lipo2:type_name -> alox.LipoReading - 16, // 38: alox.BatteryStatusResponse.samples:type_name -> alox.BatterySample - 19, // 39: alox.AccelSnapshotResponse.samples:type_name -> alox.AccelSample - 1, // 40: alox.TapEvent.kind:type_name -> alox.TapKind - 24, // 41: alox.TapSnapshotResponse.events:type_name -> alox.TapEvent - 19, // 42: alox.CacheStatusResponse.accel:type_name -> alox.AccelSample - 24, // 43: alox.CacheStatusResponse.taps:type_name -> alox.TapEvent - 41, // 44: alox.OtaSlaveProgressResponse.slaves:type_name -> alox.OtaSlaveProgressEntry - 45, // [45:45] is the sub-list for method output_type - 45, // [45:45] is the sub-list for method input_type - 45, // [45:45] is the sub-list for extension type_name - 45, // [45:45] is the sub-list for extension extendee - 0, // [0:45] is the sub-list for field type_name + 27, // 12: alox.UartMessage.espnow_unicast_test_request:type_name -> alox.EspNowUnicastTestRequest + 28, // 13: alox.UartMessage.espnow_unicast_test_response:type_name -> alox.EspNowUnicastTestResponse + 39, // 14: alox.UartMessage.ota_slave_progress_request:type_name -> alox.OtaSlaveProgressRequest + 41, // 15: alox.UartMessage.ota_slave_progress_response:type_name -> alox.OtaSlaveProgressResponse + 29, // 16: alox.UartMessage.led_ring_progress_request:type_name -> alox.LedRingProgressRequest + 30, // 17: alox.UartMessage.led_ring_progress_response:type_name -> alox.LedRingProgressResponse + 31, // 18: alox.UartMessage.espnow_find_me_request:type_name -> alox.EspNowFindMeRequest + 32, // 19: alox.UartMessage.espnow_find_me_response:type_name -> alox.EspNowFindMeResponse + 33, // 20: alox.UartMessage.restart_request:type_name -> alox.RestartRequest + 34, // 21: alox.UartMessage.restart_response:type_name -> alox.RestartResponse + 12, // 22: alox.UartMessage.accel_stream_request:type_name -> alox.AccelStreamRequest + 13, // 23: alox.UartMessage.accel_stream_response:type_name -> alox.AccelStreamResponse + 14, // 24: alox.UartMessage.battery_status_request:type_name -> alox.BatteryStatusRequest + 17, // 25: alox.UartMessage.battery_status_response:type_name -> alox.BatteryStatusResponse + 19, // 26: alox.UartMessage.tap_notify_request:type_name -> alox.TapNotifyRequest + 20, // 27: alox.UartMessage.tap_notify_response:type_name -> alox.TapNotifyResponse + 22, // 28: alox.UartMessage.cache_status_request:type_name -> alox.CacheStatusRequest + 26, // 29: alox.UartMessage.cache_status_response:type_name -> alox.CacheStatusResponse + 6, // 30: alox.ClientInfoResponse.clients:type_name -> alox.ClientInfo + 8, // 31: alox.ClientInputResponse.clients:type_name -> alox.ClientInput + 15, // 32: alox.BatterySample.lipo1:type_name -> alox.LipoReading + 15, // 33: alox.BatterySample.lipo2:type_name -> alox.LipoReading + 16, // 34: alox.BatteryStatusResponse.samples:type_name -> alox.BatterySample + 1, // 35: alox.TapEvent.kind:type_name -> alox.TapKind + 1, // 36: alox.CacheClientTap.kind:type_name -> alox.TapKind + 23, // 37: alox.CacheClientStatus.accel:type_name -> alox.CacheClientAccel + 24, // 38: alox.CacheClientStatus.tap:type_name -> alox.CacheClientTap + 25, // 39: alox.CacheStatusResponse.clients:type_name -> alox.CacheClientStatus + 40, // 40: alox.OtaSlaveProgressResponse.slaves:type_name -> alox.OtaSlaveProgressEntry + 41, // [41:41] is the sub-list for method output_type + 41, // [41:41] is the sub-list for method input_type + 41, // [41:41] is the sub-list for extension type_name + 41, // [41:41] is the sub-list for extension extendee + 0, // [0:41] is the sub-list for field type_name } func init() { file_uart_messages_proto_init() } @@ -3616,16 +3544,12 @@ func file_uart_messages_proto_init() { (*UartMessage_EspnowFindMeResponse)(nil), (*UartMessage_RestartRequest)(nil), (*UartMessage_RestartResponse)(nil), - (*UartMessage_AccelSnapshotRequest)(nil), - (*UartMessage_AccelSnapshotResponse)(nil), (*UartMessage_AccelStreamRequest)(nil), (*UartMessage_AccelStreamResponse)(nil), (*UartMessage_BatteryStatusRequest)(nil), (*UartMessage_BatteryStatusResponse)(nil), (*UartMessage_TapNotifyRequest)(nil), (*UartMessage_TapNotifyResponse)(nil), - (*UartMessage_TapSnapshotRequest)(nil), - (*UartMessage_TapSnapshotResponse)(nil), (*UartMessage_CacheStatusRequest)(nil), (*UartMessage_CacheStatusResponse)(nil), } @@ -3635,7 +3559,7 @@ func file_uart_messages_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_uart_messages_proto_rawDesc), len(file_uart_messages_proto_rawDesc)), NumEnums: 2, - NumMessages: 41, + NumMessages: 40, NumExtensions: 0, NumServices: 0, }, diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index f693e08..bfdc377 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -18,10 +18,8 @@ idf_component_register( "cmd/cmd_version.c" "cmd/cmd_client_info.c" "cmd/cmd_accel_deadzone.c" - "cmd/cmd_accel_snapshot.c" "cmd/cmd_accel_stream.c" "cmd/cmd_tap_notify.c" - "cmd/cmd_tap_snapshot.c" "cmd/cmd_cache_status.c" "cmd/cmd_espnow_unicast_test.c" "cmd/cmd_espnow_find_me.c" diff --git a/main/README.md b/main/README.md index dd6f1d2..9dee202 100644 --- a/main/README.md +++ b/main/README.md @@ -222,10 +222,9 @@ Host and master speak nanopb-encoded `UartMessage` inside UART frames (byte 0 = | 21 | `OTA_SLAVE_PROGRESS` | Implemented (`cmd/cmd_ota_slave_progress.c`) — query per-slave ESP-NOW OTA progress | | 22 | `FIND_ME` | Implemented (`cmd/cmd_espnow_find_me.c`) — `client_id=0` local ring, `>0` ESP-NOW to slave | | 23 | `RESTART` | Implemented (`cmd/cmd_restart.c`) — `client_id=0` reboot master, `>0` ESP-NOW reboot slave | -| 24 | `ACCEL_SNAPSHOT` | Implemented (`cmd/cmd_accel_snapshot.c`) — cached slave accel from ESP-NOW stream | +| 25 | `ACCEL_STREAM` | Implemented — enable/disable slave ESP-NOW accel stream to master | | 27 | `TAP_NOTIFY` | Implemented (`cmd/cmd_tap_notify.c`) — get/set which tap kinds notify via ESP-NOW | -| 28 | `TAP_SNAPSHOT` | Implemented (`cmd/cmd_tap_snapshot.c`) — consume cached tap events from master registry | -| 29 | `CACHE_STATUS` | Implemented (`cmd/cmd_cache_status.c`) — combined accel + tap cache in one UART round-trip | +| 29 | `CACHE_STATUS` | Implemented (`cmd/cmd_cache_status.c`) — subscribed accel + tap cache (one UART round-trip) | Regenerate C code: @@ -319,29 +318,6 @@ Sets the **software** deadzone used by `bosch456.c` when logging accel (see [BMA **Response:** `accel_deadzone_response` with applied `deadzone`, `success`, and `slaves_updated` (ESP-NOW count). -### ACCEL_SNAPSHOT command - -Read **cached** accelerometer samples on the **master** (one entry per registered slave). Slaves send `ESPNOW_ACCEL_SAMPLE` to the master every **16 ms** (`esp_now_comm.c`); the master stores the latest value per client in `client_registry.c`. - -**Request:** framed `18` (`0x18`) + optional `accel_snapshot_request` (`client_id`: `0` = all slaves, `>0` = one id). - -**Response:** `accel_snapshot_response.samples[]`: - -| Field | Meaning | -|-------|---------| -| `client_id` | Slave id (registry) | -| `valid` | At least one ESP-NOW sample received since boot | -| `x`, `y`, `z` | Raw BMA456 LSB (±2g) | -| `age_ms` | Ms since last sample from that slave | - -Host: - -```bash -go run . -port /dev/ttyUSB0 accel -``` - -External API (`serve -api-addr :8081`) polls this command every 16 ms and streams JSON over WebSocket. - ### TAP_NOTIFY command Configure which BMA456 tap kinds a **slave** forwards to the master over ESP-NOW. The slave only sends `ESPNOW_TAP_EVENT` when the matching notify flag is enabled (set locally on the slave via ESP-NOW). @@ -364,41 +340,30 @@ go run . -port /dev/ttyUSB0 tap-notify -client 16 -set -single go run . -port /dev/ttyUSB0 tap-notify -client 16 ``` -### TAP_SNAPSHOT command - -Read **cached** tap events on the **master** (one pending event per slave). Slaves send `ESPNOW_TAP_EVENT` on tap; the master stores the latest value per client in `client_registry.c` for up to **16 ms** (`CLIENT_REGISTRY_TAP_MAX_AGE_MS`). Each snapshot **consumes** fresh events (cleared after read). - ### CACHE_STATUS command -Fast combined poll for host tools at **16 ms** or faster: one UART frame, no request body (command id `0x1d` only). +Read **cached** accel and/or tap data on the **master** in one UART round-trip. Slaves send `ESPNOW_ACCEL_SAMPLE` every **16 ms** when streaming; tap events arrive via `ESPNOW_TAP_EVENT` and are held up to **16 ms** (`CLIENT_REGISTRY_TAP_MAX_AGE_MS`). Pending taps are **consumed** on read (like the former `TAP_SNAPSHOT`). -**Response:** `cache_status_response` with: +**Request:** framed `1d` (`0x1d`) only — no body (`CacheStatusRequest` empty). -- `accel[]` — same as `ACCEL_SNAPSHOT`, only clients with `accel_stream_enabled` -- `taps[]` — same as `TAP_SNAPSHOT`, only clients with any tap notify flag; pending taps are consumed +**Response:** `cache_status_response.clients[]` — one entry per slave with `accel_stream_enabled` and/or any tap-notify flag: -The master walks `client_registry` once per request (`cmd/cmd_cache_status.c`). Prefer this over separate `ACCEL_SNAPSHOT` + `TAP_SNAPSHOT` when polling both streams. +| Field | When present | +|-------|----------------| +| `client_id` | Always (for listed slaves) | +| `accel` | Slave has accel stream on (`valid`, `x`/`y`/`z`, `age_ms` when sample fresh) | +| `tap` | Tap notify on **and** a pending tap was consumed (`kind`, `age_ms`) | -Only slaves with at least one tap-notify flag enabled are included. +Unsubscribed submessages are omitted on the wire (proto3 defaults). The master walks `client_registry` once per request (`cmd/cmd_cache_status.c`). -**Request:** framed `1c` (`0x1c`) + optional `tap_snapshot_request` (`client_id`: `0` = all, `>0` = one id). - -**Response:** `tap_snapshot_response.events[]`: - -| Field | Meaning | -|-------|---------| -| `client_id` | Slave id (registry) | -| `valid` | Fresh tap available (≤16 ms) | -| `kind` | `TAP_SINGLE`, `TAP_DOUBLE`, or `TAP_TRIPLE` | -| `age_ms` | Ms since tap was received on master | - -Host tools poll this only when **receive** is enabled (dashboard tap column, WebSocket `set_tap_stream`). They keep events visible for **2 s** in the UI/API after first sight. +Host tools poll this at **16 ms** when live-stream / WebSocket receive is enabled. Tap events stay visible for **2 s** in the UI/API after first sight. ```bash -go run . -port /dev/ttyUSB0 tap -go run . -port /dev/ttyUSB0 tap -client 16 +go run . -port /dev/ttyUSB0 cache-status ``` +External API (`serve -api-addr :8081`) uses the same command for WebSocket `accel` / `tap` push. + ### ESPNOW_UNICAST_TEST command Minimal master→slave ESP-NOW unicast check (no BMA456). Use this before debugging `ACCEL_DEADZONE` unicast. @@ -564,10 +529,8 @@ Target: ESP32-S3. Close serial monitor on the UART adapter port before running ` | `cmd/cmd_client_info.c/h` | CLIENT_INFO handler | | `client_registry.c/h` | Registered slave table | | `bosch456.c/h` | BMA456H I2C driver, accel poll, on-demand read, tap INT, deadzone filter | -| `cmd/cmd_accel_snapshot.c` | UART `ACCEL_SNAPSHOT` — cached slave accel | | `cmd/cmd_tap_notify.c` | UART `TAP_NOTIFY` — ESP-NOW tap notify config | -| `cmd/cmd_tap_snapshot.c` | UART `TAP_SNAPSHOT` — consume cached tap events | -| `cmd/cmd_cache_status.c` | UART `CACHE_STATUS` — combined accel + tap cache poll | +| `cmd/cmd_cache_status.c` | UART `CACHE_STATUS` — subscribed accel + tap cache poll | | `board_input.c/h` | Taster GPIO12, LiPo ADC on GPIO1 / GPIO12 | | `pod_settings.c/h` | NVS persistence (accel deadzone, …) | | `led_ring.c/h` | LED ring (digit display, progress bar) | diff --git a/main/cmd/cmd_accel_snapshot.c b/main/cmd/cmd_accel_snapshot.c deleted file mode 100644 index 521a71d..0000000 --- a/main/cmd/cmd_accel_snapshot.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "client_registry.h" -#include "cmd_accel_snapshot.h" -#include "uart_cmd.h" - -static const char *TAG = "[ACCEL_SNAP]"; - -static void fill_accel_snapshot(alox_AccelSnapshotResponse *out, - uint32_t filter_client_id) { - if (out == NULL) { - return; - } - - out->samples_count = 0; - size_t count = client_registry_count(); - - for (size_t i = 0; i < count; i++) { - const client_info_t *client = client_registry_at(i); - if (client == NULL) { - continue; - } - if (filter_client_id != 0 && client->id != filter_client_id) { - continue; - } - if (!client->accel_stream_enabled) { - continue; - } - if (out->samples_count >= - sizeof(out->samples) / sizeof(out->samples[0])) { - break; - } - - alox_AccelSample *sample = &out->samples[out->samples_count++]; - sample->client_id = client->id; - sample->valid = client->accel_valid; - sample->x = client->accel_x; - sample->y = client->accel_y; - sample->z = client->accel_z; - if (client->accel_valid) { - sample->age_ms = client_registry_ms_since(client->accel_updated_at); - } - } -} - -static void handle_accel_snapshot(const uint8_t *data, size_t len) { - uint32_t filter_client_id = 0; - - if (len > 0) { - alox_UartMessage req; - if (uart_cmd_decode(data, len, &req) == ESP_OK) { - alox_AccelSnapshotRequest *snap_req = UART_CMD_REQ( - &req, alox_UartMessage_accel_snapshot_request_tag, accel_snapshot_request); - if (snap_req != NULL) { - filter_client_id = snap_req->client_id; - } - } - } - - alox_UartMessage response; - uart_cmd_init_response(&response, alox_MessageType_ACCEL_SNAPSHOT, - alox_UartMessage_accel_snapshot_response_tag); - fill_accel_snapshot(&response.payload.accel_snapshot_response, filter_client_id); - - uart_cmd_send(&response, TAG); -} - -void cmd_accel_snapshot_register(void) { - uart_cmd_register(alox_MessageType_ACCEL_SNAPSHOT, handle_accel_snapshot); -} diff --git a/main/cmd/cmd_accel_snapshot.h b/main/cmd/cmd_accel_snapshot.h deleted file mode 100644 index 0f43396..0000000 --- a/main/cmd/cmd_accel_snapshot.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CMD_ACCEL_SNAPSHOT_H -#define CMD_ACCEL_SNAPSHOT_H - -void cmd_accel_snapshot_register(void); - -#endif diff --git a/main/cmd/cmd_cache_status.c b/main/cmd/cmd_cache_status.c index 0c26589..a9ceb0b 100644 --- a/main/cmd/cmd_cache_status.c +++ b/main/cmd/cmd_cache_status.c @@ -28,8 +28,7 @@ static void fill_cache_status(alox_CacheStatusResponse *out) { return; } - out->accel_count = 0; - out->taps_count = 0; + out->clients_count = 0; size_t count = client_registry_count(); for (size_t i = 0; i < count; i++) { @@ -38,31 +37,41 @@ static void fill_cache_status(alox_CacheStatusResponse *out) { continue; } - if (client->accel_stream_enabled && - out->accel_count < sizeof(out->accel) / sizeof(out->accel[0])) { - alox_AccelSample *sample = &out->accel[out->accel_count++]; - sample->client_id = client->id; - sample->valid = client->accel_valid; - sample->x = client->accel_x; - sample->y = client->accel_y; - sample->z = client->accel_z; + const bool want_accel = client->accel_stream_enabled; + const bool want_tap = tap_notify_any(client); + if (!want_accel && !want_tap) { + continue; + } + if (out->clients_count >= + sizeof(out->clients) / sizeof(out->clients[0])) { + break; + } + + alox_CacheClientStatus *entry = &out->clients[out->clients_count++]; + entry->client_id = client->id; + entry->has_accel = false; + entry->has_tap = false; + + if (want_accel) { + entry->has_accel = true; + entry->accel.valid = client->accel_valid; if (client->accel_valid) { - sample->age_ms = client_registry_ms_since(client->accel_updated_at); + entry->accel.x = client->accel_x; + entry->accel.y = client->accel_y; + entry->accel.z = client->accel_z; + entry->accel.age_ms = + client_registry_ms_since(client->accel_updated_at); } } - if (tap_notify_any(client) && - out->taps_count < sizeof(out->taps) / sizeof(out->taps[0])) { + if (want_tap) { uint32_t kind = 0; uint32_t age_ms = 0; - if (!client_registry_take_tap(client->id, &kind, &age_ms)) { - continue; + if (client_registry_take_tap(client->id, &kind, &age_ms)) { + entry->has_tap = true; + entry->tap.kind = tap_kind_from_registry(kind); + entry->tap.age_ms = age_ms; } - alox_TapEvent *event = &out->taps[out->taps_count++]; - event->client_id = client->id; - event->valid = true; - event->kind = tap_kind_from_registry(kind); - event->age_ms = age_ms; } } } diff --git a/main/cmd/cmd_handler.c b/main/cmd/cmd_handler.c index 10d8434..d04b2eb 100644 --- a/main/cmd/cmd_handler.c +++ b/main/cmd/cmd_handler.c @@ -48,16 +48,12 @@ static const char *message_type_name(uint16_t id) { return "FIND_ME"; case alox_MessageType_RESTART: return "RESTART"; - case alox_MessageType_ACCEL_SNAPSHOT: - return "ACCEL_SNAPSHOT"; case alox_MessageType_ACCEL_STREAM: return "ACCEL_STREAM"; case alox_MessageType_BATTERY_STATUS: return "BATTERY_STATUS"; case alox_MessageType_TAP_NOTIFY: return "TAP_NOTIFY"; - case alox_MessageType_TAP_SNAPSHOT: - return "TAP_SNAPSHOT"; case alox_MessageType_CACHE_STATUS: return "CACHE_STATUS"; default: diff --git a/main/cmd/cmd_tap_snapshot.c b/main/cmd/cmd_tap_snapshot.c deleted file mode 100644 index 85eaf9e..0000000 --- a/main/cmd/cmd_tap_snapshot.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "client_registry.h" -#include "cmd_tap_snapshot.h" -#include "uart_cmd.h" - -static const char *TAG = "[TAP_SNAP]"; - -static alox_TapKind tap_kind_from_registry(uint32_t kind) { - switch (kind) { - case 1: - return alox_TapKind_TAP_SINGLE; - case 2: - return alox_TapKind_TAP_DOUBLE; - case 3: - return alox_TapKind_TAP_TRIPLE; - default: - return alox_TapKind_TAP_NONE; - } -} - -static bool tap_notify_any(const client_info_t *client) { - return client != NULL && - (client->tap_notify_single || client->tap_notify_double || - client->tap_notify_triple); -} - -static void fill_tap_snapshot(alox_TapSnapshotResponse *out, - uint32_t filter_client_id) { - if (out == NULL) { - return; - } - - out->events_count = 0; - size_t count = client_registry_count(); - - for (size_t i = 0; i < count; i++) { - const client_info_t *client = client_registry_at(i); - if (client == NULL) { - continue; - } - if (filter_client_id != 0 && client->id != filter_client_id) { - continue; - } - if (!tap_notify_any(client)) { - continue; - } - if (out->events_count >= sizeof(out->events) / sizeof(out->events[0])) { - break; - } - - uint32_t kind = 0; - uint32_t age_ms = 0; - if (!client_registry_take_tap(client->id, &kind, &age_ms)) { - continue; - } - - alox_TapEvent *event = &out->events[out->events_count++]; - event->client_id = client->id; - event->valid = true; - event->kind = tap_kind_from_registry(kind); - event->age_ms = age_ms; - } -} - -static void handle_tap_snapshot(const uint8_t *data, size_t len) { - uint32_t filter_client_id = 0; - - if (len > 0) { - alox_UartMessage req; - if (uart_cmd_decode(data, len, &req) == ESP_OK) { - alox_TapSnapshotRequest *snap_req = UART_CMD_REQ( - &req, alox_UartMessage_tap_snapshot_request_tag, tap_snapshot_request); - if (snap_req != NULL) { - filter_client_id = snap_req->client_id; - } - } - } - - alox_UartMessage response; - uart_cmd_init_response(&response, alox_MessageType_TAP_SNAPSHOT, - alox_UartMessage_tap_snapshot_response_tag); - fill_tap_snapshot(&response.payload.tap_snapshot_response, filter_client_id); - - uart_cmd_send(&response, TAG); -} - -void cmd_tap_snapshot_register(void) { - uart_cmd_register(alox_MessageType_TAP_SNAPSHOT, handle_tap_snapshot); -} diff --git a/main/cmd/cmd_tap_snapshot.h b/main/cmd/cmd_tap_snapshot.h deleted file mode 100644 index cd66ff7..0000000 --- a/main/cmd/cmd_tap_snapshot.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CMD_TAP_SNAPSHOT_H -#define CMD_TAP_SNAPSHOT_H - -void cmd_tap_snapshot_register(void); - -#endif diff --git a/main/powerpod.c b/main/powerpod.c index 9d666a7..d3b19c3 100644 --- a/main/powerpod.c +++ b/main/powerpod.c @@ -1,10 +1,8 @@ #include "app_config.h" #include "cmd_handler.h" #include "cmd_accel_deadzone.h" -#include "cmd_accel_snapshot.h" #include "cmd_accel_stream.h" #include "cmd_tap_notify.h" -#include "cmd_tap_snapshot.h" #include "cmd_cache_status.h" #include "cmd_espnow_unicast_test.h" #include "cmd_espnow_find_me.h" @@ -183,10 +181,8 @@ void app_main(void) { cmd_version_register(); cmd_client_info_register(); cmd_accel_deadzone_register(); - cmd_accel_snapshot_register(); cmd_accel_stream_register(); cmd_tap_notify_register(); - cmd_tap_snapshot_register(); cmd_cache_status_register(); cmd_espnow_unicast_test_register(); cmd_espnow_find_me_register(); diff --git a/main/proto/uart_messages.pb.c b/main/proto/uart_messages.pb.c index 25e9f94..632918d 100644 --- a/main/proto/uart_messages.pb.c +++ b/main/proto/uart_messages.pb.c @@ -54,33 +54,30 @@ PB_BIND(alox_BatterySample, alox_BatterySample, AUTO) PB_BIND(alox_BatteryStatusResponse, alox_BatteryStatusResponse, 2) -PB_BIND(alox_AccelSnapshotRequest, alox_AccelSnapshotRequest, AUTO) - - PB_BIND(alox_AccelSample, alox_AccelSample, AUTO) -PB_BIND(alox_AccelSnapshotResponse, alox_AccelSnapshotResponse, 2) - - PB_BIND(alox_TapNotifyRequest, alox_TapNotifyRequest, AUTO) PB_BIND(alox_TapNotifyResponse, alox_TapNotifyResponse, AUTO) -PB_BIND(alox_TapSnapshotRequest, alox_TapSnapshotRequest, AUTO) - - PB_BIND(alox_TapEvent, alox_TapEvent, AUTO) -PB_BIND(alox_TapSnapshotResponse, alox_TapSnapshotResponse, 2) - - PB_BIND(alox_CacheStatusRequest, alox_CacheStatusRequest, AUTO) +PB_BIND(alox_CacheClientAccel, alox_CacheClientAccel, AUTO) + + +PB_BIND(alox_CacheClientTap, alox_CacheClientTap, AUTO) + + +PB_BIND(alox_CacheClientStatus, alox_CacheClientStatus, AUTO) + + PB_BIND(alox_CacheStatusResponse, alox_CacheStatusResponse, 2) diff --git a/main/proto/uart_messages.pb.h b/main/proto/uart_messages.pb.h index 1bc69ca..e79e886 100644 --- a/main/proto/uart_messages.pb.h +++ b/main/proto/uart_messages.pb.h @@ -28,11 +28,9 @@ typedef enum _alox_MessageType { alox_MessageType_OTA_SLAVE_PROGRESS = 21, alox_MessageType_FIND_ME = 22, alox_MessageType_RESTART = 23, - alox_MessageType_ACCEL_SNAPSHOT = 24, alox_MessageType_ACCEL_STREAM = 25, alox_MessageType_BATTERY_STATUS = 26, alox_MessageType_TAP_NOTIFY = 27, - alox_MessageType_TAP_SNAPSHOT = 28, /* * Combined cached accel + tap poll (one UART round-trip, ~16 ms cadence). */ alox_MessageType_CACHE_STATUS = 29 } alox_MessageType; @@ -154,12 +152,7 @@ typedef struct _alox_BatteryStatusResponse { alox_BatterySample samples[17]; } alox_BatteryStatusResponse; -/* Host → master: read cached accel samples from slaves (only while stream enabled). - client_id 0 = all registered slaves; otherwise one slave. */ -typedef struct _alox_AccelSnapshotRequest { - uint32_t client_id; -} alox_AccelSnapshotRequest; - +/* * Legacy host-side sample shape (dashboard helpers); use CACHE_STATUS on the wire. */ typedef struct _alox_AccelSample { uint32_t client_id; bool valid; @@ -170,11 +163,6 @@ typedef struct _alox_AccelSample { uint32_t age_ms; } alox_AccelSample; -typedef struct _alox_AccelSnapshotResponse { - pb_size_t samples_count; - alox_AccelSample samples[16]; -} alox_AccelSnapshotResponse; - /* * Host → master: enable/disable tap ESP-NOW notify per slave (single/double/triple). */ typedef struct _alox_TapNotifyRequest { bool write; @@ -194,11 +182,7 @@ typedef struct _alox_TapNotifyResponse { bool triple; } alox_TapNotifyResponse; -/* * Host → master: read cached tap events (discarded after reply or when age > 16 ms). */ -typedef struct _alox_TapSnapshotRequest { - uint32_t client_id; -} alox_TapSnapshotRequest; - +/* * Legacy tap event shape (dashboard helpers); use CACHE_STATUS on the wire. */ typedef struct _alox_TapEvent { uint32_t client_id; bool valid; @@ -206,23 +190,39 @@ typedef struct _alox_TapEvent { uint32_t age_ms; } alox_TapEvent; -typedef struct _alox_TapSnapshotResponse { - pb_size_t events_count; - alox_TapEvent events[16]; -} alox_TapSnapshotResponse; - /* * Host → master: one-shot read of subscribed cached slave data (no request body). */ typedef struct _alox_CacheStatusRequest { char dummy_field; } alox_CacheStatusRequest; +/* * Accel slice inside CACHE_STATUS (no client_id — use parent CacheClientStatus). */ +typedef struct _alox_CacheClientAccel { + bool valid; + int32_t x; + int32_t y; + int32_t z; + uint32_t age_ms; +} alox_CacheClientAccel; + +/* * Tap slice inside CACHE_STATUS; only present when a pending tap was consumed. */ +typedef struct _alox_CacheClientTap { + alox_TapKind kind; + uint32_t age_ms; +} alox_CacheClientTap; + +/* * One slave with accel and/or tap notify enabled; only subscribed fields are set. */ +typedef struct _alox_CacheClientStatus { + uint32_t client_id; + bool has_accel; + alox_CacheClientAccel accel; + bool has_tap; + alox_CacheClientTap tap; +} alox_CacheClientStatus; + typedef struct _alox_CacheStatusResponse { - /* * Slaves with accel_stream_enabled. */ - pb_size_t accel_count; - alox_AccelSample accel[16]; - /* * Slaves with any tap notify flag; pending taps are consumed (like TAP_SNAPSHOT). */ - pb_size_t taps_count; - alox_TapEvent taps[16]; + /* * Slaves with accel_stream and/or tap notify; omitted fields are not subscribed. */ + pb_size_t clients_count; + alox_CacheClientStatus clients[16]; } alox_CacheStatusResponse; typedef struct _alox_EspNowUnicastTestRequest { @@ -363,16 +363,12 @@ typedef struct _alox_UartMessage { alox_EspNowFindMeResponse espnow_find_me_response; alox_RestartRequest restart_request; alox_RestartResponse restart_response; - alox_AccelSnapshotRequest accel_snapshot_request; - alox_AccelSnapshotResponse accel_snapshot_response; alox_AccelStreamRequest accel_stream_request; alox_AccelStreamResponse accel_stream_response; alox_BatteryStatusRequest battery_status_request; alox_BatteryStatusResponse battery_status_response; alox_TapNotifyRequest tap_notify_request; alox_TapNotifyResponse tap_notify_response; - alox_TapSnapshotRequest tap_snapshot_request; - alox_TapSnapshotResponse tap_snapshot_response; alox_CacheStatusRequest cache_status_request; alox_CacheStatusResponse cache_status_response; } payload; @@ -410,15 +406,15 @@ extern "C" { - - - #define alox_TapEvent_kind_ENUMTYPE alox_TapKind +#define alox_CacheClientTap_kind_ENUMTYPE alox_TapKind + + @@ -453,16 +449,15 @@ extern "C" { #define alox_LipoReading_init_default {0, 0} #define alox_BatterySample_init_default {0, false, alox_LipoReading_init_default, false, alox_LipoReading_init_default, 0} #define alox_BatteryStatusResponse_init_default {0, 0, {alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default, alox_BatterySample_init_default}} -#define alox_AccelSnapshotRequest_init_default {0} #define alox_AccelSample_init_default {0, 0, 0, 0, 0, 0} -#define alox_AccelSnapshotResponse_init_default {0, {alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default}} #define alox_TapNotifyRequest_init_default {0, 0, 0, 0, 0, 0} #define alox_TapNotifyResponse_init_default {0, 0, 0, 0, 0, 0} -#define alox_TapSnapshotRequest_init_default {0} #define alox_TapEvent_init_default {0, 0, _alox_TapKind_MIN, 0} -#define alox_TapSnapshotResponse_init_default {0, {alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default}} #define alox_CacheStatusRequest_init_default {0} -#define alox_CacheStatusResponse_init_default {0, {alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default, alox_AccelSample_init_default}, 0, {alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default, alox_TapEvent_init_default}} +#define alox_CacheClientAccel_init_default {0, 0, 0, 0, 0} +#define alox_CacheClientTap_init_default {_alox_TapKind_MIN, 0} +#define alox_CacheClientStatus_init_default {0, false, alox_CacheClientAccel_init_default, false, alox_CacheClientTap_init_default} +#define alox_CacheStatusResponse_init_default {0, {alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default, alox_CacheClientStatus_init_default}} #define alox_EspNowUnicastTestRequest_init_default {0, 0} #define alox_EspNowUnicastTestResponse_init_default {0, 0} #define alox_LedRingProgressRequest_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} @@ -494,16 +489,15 @@ extern "C" { #define alox_LipoReading_init_zero {0, 0} #define alox_BatterySample_init_zero {0, false, alox_LipoReading_init_zero, false, alox_LipoReading_init_zero, 0} #define alox_BatteryStatusResponse_init_zero {0, 0, {alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero, alox_BatterySample_init_zero}} -#define alox_AccelSnapshotRequest_init_zero {0} #define alox_AccelSample_init_zero {0, 0, 0, 0, 0, 0} -#define alox_AccelSnapshotResponse_init_zero {0, {alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero}} #define alox_TapNotifyRequest_init_zero {0, 0, 0, 0, 0, 0} #define alox_TapNotifyResponse_init_zero {0, 0, 0, 0, 0, 0} -#define alox_TapSnapshotRequest_init_zero {0} #define alox_TapEvent_init_zero {0, 0, _alox_TapKind_MIN, 0} -#define alox_TapSnapshotResponse_init_zero {0, {alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero}} #define alox_CacheStatusRequest_init_zero {0} -#define alox_CacheStatusResponse_init_zero {0, {alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero, alox_AccelSample_init_zero}, 0, {alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero, alox_TapEvent_init_zero}} +#define alox_CacheClientAccel_init_zero {0, 0, 0, 0, 0} +#define alox_CacheClientTap_init_zero {_alox_TapKind_MIN, 0} +#define alox_CacheClientStatus_init_zero {0, false, alox_CacheClientAccel_init_zero, false, alox_CacheClientTap_init_zero} +#define alox_CacheStatusResponse_init_zero {0, {alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero, alox_CacheClientStatus_init_zero}} #define alox_EspNowUnicastTestRequest_init_zero {0, 0} #define alox_EspNowUnicastTestResponse_init_zero {0, 0} #define alox_LedRingProgressRequest_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} @@ -568,14 +562,12 @@ extern "C" { #define alox_BatterySample_age_ms_tag 4 #define alox_BatteryStatusResponse_success_tag 1 #define alox_BatteryStatusResponse_samples_tag 2 -#define alox_AccelSnapshotRequest_client_id_tag 1 #define alox_AccelSample_client_id_tag 1 #define alox_AccelSample_valid_tag 2 #define alox_AccelSample_x_tag 3 #define alox_AccelSample_y_tag 4 #define alox_AccelSample_z_tag 5 #define alox_AccelSample_age_ms_tag 6 -#define alox_AccelSnapshotResponse_samples_tag 1 #define alox_TapNotifyRequest_write_tag 1 #define alox_TapNotifyRequest_client_id_tag 2 #define alox_TapNotifyRequest_all_clients_tag 3 @@ -588,14 +580,21 @@ extern "C" { #define alox_TapNotifyResponse_single_tag 4 #define alox_TapNotifyResponse_double_tap_tag 5 #define alox_TapNotifyResponse_triple_tag 6 -#define alox_TapSnapshotRequest_client_id_tag 1 #define alox_TapEvent_client_id_tag 1 #define alox_TapEvent_valid_tag 2 #define alox_TapEvent_kind_tag 3 #define alox_TapEvent_age_ms_tag 4 -#define alox_TapSnapshotResponse_events_tag 1 -#define alox_CacheStatusResponse_accel_tag 1 -#define alox_CacheStatusResponse_taps_tag 2 +#define alox_CacheClientAccel_valid_tag 1 +#define alox_CacheClientAccel_x_tag 2 +#define alox_CacheClientAccel_y_tag 3 +#define alox_CacheClientAccel_z_tag 4 +#define alox_CacheClientAccel_age_ms_tag 5 +#define alox_CacheClientTap_kind_tag 1 +#define alox_CacheClientTap_age_ms_tag 2 +#define alox_CacheClientStatus_client_id_tag 1 +#define alox_CacheClientStatus_accel_tag 2 +#define alox_CacheClientStatus_tap_tag 3 +#define alox_CacheStatusResponse_clients_tag 1 #define alox_EspNowUnicastTestRequest_client_id_tag 1 #define alox_EspNowUnicastTestRequest_seq_tag 2 #define alox_EspNowUnicastTestResponse_success_tag 1 @@ -664,16 +663,12 @@ extern "C" { #define alox_UartMessage_espnow_find_me_response_tag 20 #define alox_UartMessage_restart_request_tag 21 #define alox_UartMessage_restart_response_tag 22 -#define alox_UartMessage_accel_snapshot_request_tag 23 -#define alox_UartMessage_accel_snapshot_response_tag 24 #define alox_UartMessage_accel_stream_request_tag 25 #define alox_UartMessage_accel_stream_response_tag 26 #define alox_UartMessage_battery_status_request_tag 27 #define alox_UartMessage_battery_status_response_tag 28 #define alox_UartMessage_tap_notify_request_tag 29 #define alox_UartMessage_tap_notify_response_tag 30 -#define alox_UartMessage_tap_snapshot_request_tag 31 -#define alox_UartMessage_tap_snapshot_response_tag 32 #define alox_UartMessage_cache_status_request_tag 33 #define alox_UartMessage_cache_status_response_tag 34 @@ -701,16 +696,12 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,espnow_find_me_request,payload.espno X(a, STATIC, ONEOF, MESSAGE, (payload,espnow_find_me_response,payload.espnow_find_me_response), 20) \ X(a, STATIC, ONEOF, MESSAGE, (payload,restart_request,payload.restart_request), 21) \ X(a, STATIC, ONEOF, MESSAGE, (payload,restart_response,payload.restart_response), 22) \ -X(a, STATIC, ONEOF, MESSAGE, (payload,accel_snapshot_request,payload.accel_snapshot_request), 23) \ -X(a, STATIC, ONEOF, MESSAGE, (payload,accel_snapshot_response,payload.accel_snapshot_response), 24) \ X(a, STATIC, ONEOF, MESSAGE, (payload,accel_stream_request,payload.accel_stream_request), 25) \ X(a, STATIC, ONEOF, MESSAGE, (payload,accel_stream_response,payload.accel_stream_response), 26) \ X(a, STATIC, ONEOF, MESSAGE, (payload,battery_status_request,payload.battery_status_request), 27) \ X(a, STATIC, ONEOF, MESSAGE, (payload,battery_status_response,payload.battery_status_response), 28) \ X(a, STATIC, ONEOF, MESSAGE, (payload,tap_notify_request,payload.tap_notify_request), 29) \ X(a, STATIC, ONEOF, MESSAGE, (payload,tap_notify_response,payload.tap_notify_response), 30) \ -X(a, STATIC, ONEOF, MESSAGE, (payload,tap_snapshot_request,payload.tap_snapshot_request), 31) \ -X(a, STATIC, ONEOF, MESSAGE, (payload,tap_snapshot_response,payload.tap_snapshot_response), 32) \ X(a, STATIC, ONEOF, MESSAGE, (payload,cache_status_request,payload.cache_status_request), 33) \ X(a, STATIC, ONEOF, MESSAGE, (payload,cache_status_response,payload.cache_status_response), 34) #define alox_UartMessage_CALLBACK NULL @@ -736,16 +727,12 @@ X(a, STATIC, ONEOF, MESSAGE, (payload,cache_status_response,payload.cache_ #define alox_UartMessage_payload_espnow_find_me_response_MSGTYPE alox_EspNowFindMeResponse #define alox_UartMessage_payload_restart_request_MSGTYPE alox_RestartRequest #define alox_UartMessage_payload_restart_response_MSGTYPE alox_RestartResponse -#define alox_UartMessage_payload_accel_snapshot_request_MSGTYPE alox_AccelSnapshotRequest -#define alox_UartMessage_payload_accel_snapshot_response_MSGTYPE alox_AccelSnapshotResponse #define alox_UartMessage_payload_accel_stream_request_MSGTYPE alox_AccelStreamRequest #define alox_UartMessage_payload_accel_stream_response_MSGTYPE alox_AccelStreamResponse #define alox_UartMessage_payload_battery_status_request_MSGTYPE alox_BatteryStatusRequest #define alox_UartMessage_payload_battery_status_response_MSGTYPE alox_BatteryStatusResponse #define alox_UartMessage_payload_tap_notify_request_MSGTYPE alox_TapNotifyRequest #define alox_UartMessage_payload_tap_notify_response_MSGTYPE alox_TapNotifyResponse -#define alox_UartMessage_payload_tap_snapshot_request_MSGTYPE alox_TapSnapshotRequest -#define alox_UartMessage_payload_tap_snapshot_response_MSGTYPE alox_TapSnapshotResponse #define alox_UartMessage_payload_cache_status_request_MSGTYPE alox_CacheStatusRequest #define alox_UartMessage_payload_cache_status_response_MSGTYPE alox_CacheStatusResponse @@ -862,11 +849,6 @@ X(a, STATIC, REPEATED, MESSAGE, samples, 2) #define alox_BatteryStatusResponse_DEFAULT NULL #define alox_BatteryStatusResponse_samples_MSGTYPE alox_BatterySample -#define alox_AccelSnapshotRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, client_id, 1) -#define alox_AccelSnapshotRequest_CALLBACK NULL -#define alox_AccelSnapshotRequest_DEFAULT NULL - #define alox_AccelSample_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, client_id, 1) \ X(a, STATIC, SINGULAR, BOOL, valid, 2) \ @@ -877,12 +859,6 @@ X(a, STATIC, SINGULAR, UINT32, age_ms, 6) #define alox_AccelSample_CALLBACK NULL #define alox_AccelSample_DEFAULT NULL -#define alox_AccelSnapshotResponse_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, MESSAGE, samples, 1) -#define alox_AccelSnapshotResponse_CALLBACK NULL -#define alox_AccelSnapshotResponse_DEFAULT NULL -#define alox_AccelSnapshotResponse_samples_MSGTYPE alox_AccelSample - #define alox_TapNotifyRequest_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, BOOL, write, 1) \ X(a, STATIC, SINGULAR, UINT32, client_id, 2) \ @@ -903,11 +879,6 @@ X(a, STATIC, SINGULAR, BOOL, triple, 6) #define alox_TapNotifyResponse_CALLBACK NULL #define alox_TapNotifyResponse_DEFAULT NULL -#define alox_TapSnapshotRequest_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, UINT32, client_id, 1) -#define alox_TapSnapshotRequest_CALLBACK NULL -#define alox_TapSnapshotRequest_DEFAULT NULL - #define alox_TapEvent_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, client_id, 1) \ X(a, STATIC, SINGULAR, BOOL, valid, 2) \ @@ -916,24 +887,40 @@ X(a, STATIC, SINGULAR, UINT32, age_ms, 4) #define alox_TapEvent_CALLBACK NULL #define alox_TapEvent_DEFAULT NULL -#define alox_TapSnapshotResponse_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, MESSAGE, events, 1) -#define alox_TapSnapshotResponse_CALLBACK NULL -#define alox_TapSnapshotResponse_DEFAULT NULL -#define alox_TapSnapshotResponse_events_MSGTYPE alox_TapEvent - #define alox_CacheStatusRequest_FIELDLIST(X, a) \ #define alox_CacheStatusRequest_CALLBACK NULL #define alox_CacheStatusRequest_DEFAULT NULL +#define alox_CacheClientAccel_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, BOOL, valid, 1) \ +X(a, STATIC, SINGULAR, SINT32, x, 2) \ +X(a, STATIC, SINGULAR, SINT32, y, 3) \ +X(a, STATIC, SINGULAR, SINT32, z, 4) \ +X(a, STATIC, SINGULAR, UINT32, age_ms, 5) +#define alox_CacheClientAccel_CALLBACK NULL +#define alox_CacheClientAccel_DEFAULT NULL + +#define alox_CacheClientTap_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, kind, 1) \ +X(a, STATIC, SINGULAR, UINT32, age_ms, 2) +#define alox_CacheClientTap_CALLBACK NULL +#define alox_CacheClientTap_DEFAULT NULL + +#define alox_CacheClientStatus_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, client_id, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, accel, 2) \ +X(a, STATIC, OPTIONAL, MESSAGE, tap, 3) +#define alox_CacheClientStatus_CALLBACK NULL +#define alox_CacheClientStatus_DEFAULT NULL +#define alox_CacheClientStatus_accel_MSGTYPE alox_CacheClientAccel +#define alox_CacheClientStatus_tap_MSGTYPE alox_CacheClientTap + #define alox_CacheStatusResponse_FIELDLIST(X, a) \ -X(a, STATIC, REPEATED, MESSAGE, accel, 1) \ -X(a, STATIC, REPEATED, MESSAGE, taps, 2) +X(a, STATIC, REPEATED, MESSAGE, clients, 1) #define alox_CacheStatusResponse_CALLBACK NULL #define alox_CacheStatusResponse_DEFAULT NULL -#define alox_CacheStatusResponse_accel_MSGTYPE alox_AccelSample -#define alox_CacheStatusResponse_taps_MSGTYPE alox_TapEvent +#define alox_CacheStatusResponse_clients_MSGTYPE alox_CacheClientStatus #define alox_EspNowUnicastTestRequest_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, client_id, 1) \ @@ -1059,15 +1046,14 @@ extern const pb_msgdesc_t alox_BatteryStatusRequest_msg; extern const pb_msgdesc_t alox_LipoReading_msg; extern const pb_msgdesc_t alox_BatterySample_msg; extern const pb_msgdesc_t alox_BatteryStatusResponse_msg; -extern const pb_msgdesc_t alox_AccelSnapshotRequest_msg; extern const pb_msgdesc_t alox_AccelSample_msg; -extern const pb_msgdesc_t alox_AccelSnapshotResponse_msg; extern const pb_msgdesc_t alox_TapNotifyRequest_msg; extern const pb_msgdesc_t alox_TapNotifyResponse_msg; -extern const pb_msgdesc_t alox_TapSnapshotRequest_msg; extern const pb_msgdesc_t alox_TapEvent_msg; -extern const pb_msgdesc_t alox_TapSnapshotResponse_msg; extern const pb_msgdesc_t alox_CacheStatusRequest_msg; +extern const pb_msgdesc_t alox_CacheClientAccel_msg; +extern const pb_msgdesc_t alox_CacheClientTap_msg; +extern const pb_msgdesc_t alox_CacheClientStatus_msg; extern const pb_msgdesc_t alox_CacheStatusResponse_msg; extern const pb_msgdesc_t alox_EspNowUnicastTestRequest_msg; extern const pb_msgdesc_t alox_EspNowUnicastTestResponse_msg; @@ -1102,15 +1088,14 @@ extern const pb_msgdesc_t alox_OtaSlaveProgressResponse_msg; #define alox_LipoReading_fields &alox_LipoReading_msg #define alox_BatterySample_fields &alox_BatterySample_msg #define alox_BatteryStatusResponse_fields &alox_BatteryStatusResponse_msg -#define alox_AccelSnapshotRequest_fields &alox_AccelSnapshotRequest_msg #define alox_AccelSample_fields &alox_AccelSample_msg -#define alox_AccelSnapshotResponse_fields &alox_AccelSnapshotResponse_msg #define alox_TapNotifyRequest_fields &alox_TapNotifyRequest_msg #define alox_TapNotifyResponse_fields &alox_TapNotifyResponse_msg -#define alox_TapSnapshotRequest_fields &alox_TapSnapshotRequest_msg #define alox_TapEvent_fields &alox_TapEvent_msg -#define alox_TapSnapshotResponse_fields &alox_TapSnapshotResponse_msg #define alox_CacheStatusRequest_fields &alox_CacheStatusRequest_msg +#define alox_CacheClientAccel_fields &alox_CacheClientAccel_msg +#define alox_CacheClientTap_fields &alox_CacheClientTap_msg +#define alox_CacheClientStatus_fields &alox_CacheClientStatus_msg #define alox_CacheStatusResponse_fields &alox_CacheStatusResponse_msg #define alox_EspNowUnicastTestRequest_fields &alox_EspNowUnicastTestRequest_msg #define alox_EspNowUnicastTestResponse_fields &alox_EspNowUnicastTestResponse_msg @@ -1139,16 +1124,17 @@ extern const pb_msgdesc_t alox_OtaSlaveProgressResponse_msg; #define alox_AccelDeadzoneRequest_size 16 #define alox_AccelDeadzoneResponse_size 20 #define alox_AccelSample_size 32 -#define alox_AccelSnapshotRequest_size 6 -#define alox_AccelSnapshotResponse_size 544 #define alox_AccelStreamRequest_size 12 #define alox_AccelStreamResponse_size 16 #define alox_Ack_size 0 #define alox_BatterySample_size 32 #define alox_BatteryStatusRequest_size 8 #define alox_BatteryStatusResponse_size 580 +#define alox_CacheClientAccel_size 26 +#define alox_CacheClientStatus_size 44 +#define alox_CacheClientTap_size 8 #define alox_CacheStatusRequest_size 0 -#define alox_CacheStatusResponse_size 832 +#define alox_CacheStatusResponse_size 736 #define alox_ClientInput_size 22 #define alox_EspNowFindMeRequest_size 6 #define alox_EspNowFindMeResponse_size 8 @@ -1169,8 +1155,6 @@ extern const pb_msgdesc_t alox_OtaSlaveProgressResponse_msg; #define alox_TapEvent_size 16 #define alox_TapNotifyRequest_size 16 #define alox_TapNotifyResponse_size 20 -#define alox_TapSnapshotRequest_size 6 -#define alox_TapSnapshotResponse_size 288 #ifdef __cplusplus } /* extern "C" */ diff --git a/main/proto/uart_messages.proto b/main/proto/uart_messages.proto index 29b459f..eee51e8 100644 --- a/main/proto/uart_messages.proto +++ b/main/proto/uart_messages.proto @@ -22,11 +22,11 @@ enum MessageType { OTA_SLAVE_PROGRESS = 21; FIND_ME = 22; RESTART = 23; - ACCEL_SNAPSHOT = 24; + reserved 24; ACCEL_STREAM = 25; BATTERY_STATUS = 26; TAP_NOTIFY = 27; - TAP_SNAPSHOT = 28; + reserved 28; /** Combined cached accel + tap poll (one UART round-trip, ~16 ms cadence). */ CACHE_STATUS = 29; } @@ -55,16 +55,12 @@ message UartMessage { EspNowFindMeResponse espnow_find_me_response = 20; RestartRequest restart_request = 21; RestartResponse restart_response = 22; - AccelSnapshotRequest accel_snapshot_request = 23; - AccelSnapshotResponse accel_snapshot_response = 24; AccelStreamRequest accel_stream_request = 25; AccelStreamResponse accel_stream_response = 26; BatteryStatusRequest battery_status_request = 27; BatteryStatusResponse battery_status_response = 28; TapNotifyRequest tap_notify_request = 29; TapNotifyResponse tap_notify_response = 30; - TapSnapshotRequest tap_snapshot_request = 31; - TapSnapshotResponse tap_snapshot_response = 32; CacheStatusRequest cache_status_request = 33; CacheStatusResponse cache_status_response = 34; } @@ -174,12 +170,7 @@ message BatteryStatusResponse { repeated BatterySample samples = 2 [(nanopb).max_count = 17]; } -// Host → master: read cached accel samples from slaves (only while stream enabled). -// client_id 0 = all registered slaves; otherwise one slave. -message AccelSnapshotRequest { - uint32 client_id = 1; -} - +/** Legacy host-side sample shape (dashboard helpers); use CACHE_STATUS on the wire. */ message AccelSample { uint32 client_id = 1; bool valid = 2; @@ -190,10 +181,6 @@ message AccelSample { uint32 age_ms = 6; } -message AccelSnapshotResponse { - repeated AccelSample samples = 1 [(nanopb).max_count = 16]; -} - /** Host → master: enable/disable tap ESP-NOW notify per slave (single/double/triple). */ message TapNotifyRequest { bool write = 1; @@ -220,11 +207,7 @@ enum TapKind { TAP_TRIPLE = 3; } -/** Host → master: read cached tap events (discarded after reply or when age > 16 ms). */ -message TapSnapshotRequest { - uint32 client_id = 1; -} - +/** Legacy tap event shape (dashboard helpers); use CACHE_STATUS on the wire. */ message TapEvent { uint32 client_id = 1; bool valid = 2; @@ -232,18 +215,34 @@ message TapEvent { uint32 age_ms = 4; } -message TapSnapshotResponse { - repeated TapEvent events = 1 [(nanopb).max_count = 16]; -} - /** Host → master: one-shot read of subscribed cached slave data (no request body). */ message CacheStatusRequest {} +/** Accel slice inside CACHE_STATUS (no client_id — use parent CacheClientStatus). */ +message CacheClientAccel { + bool valid = 1; + sint32 x = 2; + sint32 y = 3; + sint32 z = 4; + uint32 age_ms = 5; +} + +/** Tap slice inside CACHE_STATUS; only present when a pending tap was consumed. */ +message CacheClientTap { + TapKind kind = 1; + uint32 age_ms = 2; +} + +/** One slave with accel and/or tap notify enabled; only subscribed fields are set. */ +message CacheClientStatus { + uint32 client_id = 1; + CacheClientAccel accel = 2; + CacheClientTap tap = 3; +} + message CacheStatusResponse { - /** Slaves with accel_stream_enabled. */ - repeated AccelSample accel = 1 [(nanopb).max_count = 16]; - /** Slaves with any tap notify flag; pending taps are consumed (like TAP_SNAPSHOT). */ - repeated TapEvent taps = 2 [(nanopb).max_count = 16]; + /** Slaves with accel_stream and/or tap notify; omitted fields are not subscribed. */ + repeated CacheClientStatus clients = 1 [(nanopb).max_count = 16]; } message EspNowUnicastTestRequest {