# ha-gateway `ha-gateway` is the internal gRPC boundary for Home Assistant. It exposes a small protobuf API to other home services and keeps Home Assistant tokens and REST details out of clients. ## Runtime Flow 1. The service loads `.env`, configures logging and telemetry, and starts gRPC on `GRPC_PORT`. 2. App services are wired to a Home Assistant REST adapter. 3. Light and switch discovery caches are refreshed during startup when possible. 4. gRPC clients call entity, light, switch, or event services. 5. The adapter maps requests to Home Assistant REST state and service calls. ## gRPC API Contracts are defined under [proto/ha/v1](https://gitea.nik4nao.com/nik/home-services/src/branch/main/proto/ha/v1). Implemented: - `EntityService.GetState` - `EntityService.ListStates` - `LightService.TurnOn` - `LightService.TurnOff` - `LightService.Toggle` - `LightService.ListLights` - `SwitchService.ListSwitches` Stubbed: - `SwitchService.TurnOn` - `SwitchService.TurnOff` - `SwitchService.Toggle` - `EventService` The server also registers gRPC health checks and reflection. ## Configuration Environment variables: | Variable | Default | Description | | --- | --- | --- | | `GRPC_PORT` | `50051` | gRPC listen port | | `HA_BASE_URL` | empty | Home Assistant base URL, for example `http://ha.home.arpa:8123` | | `HA_TOKEN` | required | Home Assistant long-lived access token | | `TLS_DIR` | empty | Enables mTLS for the gRPC server when set | | `OTEL_ENDPOINT` | empty | OTLP gRPC collector endpoint; empty disables telemetry | | `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, or `error` | | `LOG_FORMAT` | `json` | `json` or `text` | Example env file: [.env.example](https://gitea.nik4nao.com/nik/home-services/src/branch/main/ha-gateway/.env.example) When `TLS_DIR` is set, the directory must contain `tls.crt`, `tls.key`, and `ca.crt`. ## Local Run ```bash cp .env.example .env go run ./cmd/gateway ``` Run from `ha-gateway/` so `godotenv` loads `ha-gateway/.env`. For local plaintext development: ```text GRPC_PORT=50051 HA_BASE_URL=http://ha.home.arpa:8123 HA_TOKEN= TLS_DIR= ``` ## Smoke Checks ```bash grpcurl -plaintext -d '{"domain":"light"}' \ localhost:50051 ha.v1.EntityService/ListStates grpcurl -plaintext -d '{}' localhost:50051 ha.v1.LightService/ListLights grpcurl -plaintext -d '{"entity_id":"light.living_room","brightness_pct":80}' \ localhost:50051 ha.v1.LightService/TurnOn grpcurl -plaintext -d '{}' localhost:50051 grpc.health.v1.Health/Check ``` ## Test And Build ```bash go test ./... go build ./... ``` Build the container image from the workspace root: ```bash docker build -f ha-gateway/Dockerfile -t ha-gateway:dev . ``` Optionally pass a build version: ```bash docker build -f ha-gateway/Dockerfile --build-arg VERSION=$(git rev-parse --short HEAD) -t ha-gateway:dev . ``` ## Package Map ```text cmd/gateway/ # process entrypoint and wiring internal/adapters/primary/grpc/ # gRPC service implementations internal/adapters/secondary/ha/ # Home Assistant REST adapter internal/app/ # entity, light, and switch orchestration internal/config/ # environment loading internal/core/domain/ # domain types internal/core/ports/ # driving and driven interfaces internal/logger/ # slog setup internal/telemetry/ # OpenTelemetry setup ``` ## Limitations - Switch control RPCs return not implemented. - `EventService` is registered but not implemented. - Home Assistant WebSocket event streaming is still a TODO. - Keep this service internal or protect it with mTLS; it does not implement separate app-layer authorization.