generated from rmcguire/go-server-with-otel
add set mode option
This commit is contained in:
@@ -16,14 +16,27 @@ Exporter for Rheem EcoNet / Rheemcloud water heaters, built on the
|
||||
HTTP/gRPC server startup. The client is stateless REST, so `ShutdownFunc` is
|
||||
effectively a no-op (the poll goroutine stops on ctx cancel).
|
||||
- `pkg/econet/econetclient/` — a minimal EcoNet REST client (ClearBlade
|
||||
backend). `client.go` does the 3 REST calls (auth → `getUserDataForApp` →
|
||||
backend). `client.go` does the read REST calls (auth → `getUserDataForApp` →
|
||||
`dynamicAction` usage) and caches a snapshot under an `RWMutex`; `device.go`
|
||||
decodes the `@...` datapoints into a flat `Device` struct (ported from
|
||||
kevinburke/rheemcloud-go, minus MQTT). `Devices()` is empty until the first
|
||||
`Refresh` succeeds — consumers just see an empty list (no nil-guarding).
|
||||
**No MQTT**, so `WiFiSignal` and `Running`/`RunningState` stay zero.
|
||||
- **Writes (SetMode)**: `Client.SetMode` changes a unit's operating mode by
|
||||
publishing a desired-state message over ClearBlade's REST publish endpoint
|
||||
(`POST /message/{systemKey}/publish`, topic `user/{account_id}/device/desired`,
|
||||
payload `{transactionId, device_name, serial_number, "@MODE": <idx>}`). This
|
||||
is the HTTP equivalent of the app's MQTT publish — **no MQTT client needed**.
|
||||
`@MODE` is an *index* into the device's reported mode list, so `device.go`
|
||||
retains that list (`modeEnumText`) and maps a slug → index (`modeIndex`);
|
||||
supported modes are device-specific (`Device.SupportedModes`). The change is
|
||||
**applied asynchronously** — the new mode only shows up on a later `Refresh`,
|
||||
and a 200 from publish means "accepted", not "applied".
|
||||
- `pkg/econet/econetgrpc/` — `EconetService` gRPC impl (`ListDevices`,
|
||||
`GetDevice`) + `deviceToProto`. Does **not** own a client; it's injected.
|
||||
`GetDevice`, `SetMode`) + `deviceToProto`. Does **not** own a client; it's
|
||||
injected. `SetMode` maps the proto `Mode` enum → client slug; note MCP calls
|
||||
it in-process and so **bypass the protovalidate interceptor** (the gRPC/REST
|
||||
paths don't), hence `SetMode` re-checks the enum itself.
|
||||
- `pkg/econet/econetmcpgen/` — **active** MCP server at `/api/mcp`. Registers
|
||||
the tools generated by protoc-gen-go-mcp (`api/econet/v1alpha1/v1alpha1mcp/`)
|
||||
against our go-sdk `*mcp.Server` via the `runtime/gosdk` adapter, forwarding
|
||||
@@ -90,3 +103,11 @@ Creds are configured via `ECONET_EMAIL` / `ECONET_PASSWORD`. Run
|
||||
(streamable HTTP; POST to `/api/mcp/` with trailing slash — bare `/api/mcp`
|
||||
307-redirects). The REST gateway needs `grpcGatewayPathStrip: true` in
|
||||
config.yaml (otherwise the `/api` prefix isn't stripped and routes 404).
|
||||
|
||||
`SetMode` (write) can be driven three ways once a real device is loaded:
|
||||
`grpcurl -plaintext -d '{"serial_number":"<sn>","mode":"MODE_HEAT_PUMP"}' :8081 econet.v1alpha1.EconetService/SetMode`,
|
||||
`POST /api/v1alpha1/devices/<sn>/mode` with `{"mode":"MODE_HEAT_PUMP"}`, or the
|
||||
MCP `econet_v1alpha1_EconetService_SetMode` tool. **Unverified against a live
|
||||
account**: whether the user token is authorized to publish over REST (same
|
||||
authority as MQTT, but Rheem's topic ACL is untested) — this is the one thing
|
||||
that can't be confirmed without a real unit.
|
||||
|
||||
Reference in New Issue
Block a user