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
- The service loads
.env, configures logging and telemetry, and starts gRPC onGRPC_PORT. - App services are wired to a Home Assistant REST adapter.
- Light and switch discovery caches are refreshed during startup when possible.
- gRPC clients call entity, light, switch, or event services.
- The adapter maps requests to Home Assistant REST state and service calls.
gRPC API
Contracts are defined under proto/ha/v1.
Implemented:
EntityService.GetStateEntityService.ListStatesLightService.TurnOnLightService.TurnOffLightService.ToggleLightService.ListLightsSwitchService.ListSwitches
Stubbed:
SwitchService.TurnOnSwitchService.TurnOffSwitchService.ToggleEventService
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
When TLS_DIR is set, the directory must contain tls.crt, tls.key, and
ca.crt.
Local Run
cp .env.example .env
go run ./cmd/gateway
Run from ha-gateway/ so godotenv loads ha-gateway/.env.
For local plaintext development:
GRPC_PORT=50051
HA_BASE_URL=http://ha.home.arpa:8123
HA_TOKEN=<long-lived-token>
TLS_DIR=
Smoke Checks
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
go test ./...
go build ./...
Build the container image from the workspace root:
docker build -f ha-gateway/Dockerfile -t ha-gateway:dev .
Optionally pass a build version:
docker build -f ha-gateway/Dockerfile --build-arg VERSION=$(git rev-parse --short HEAD) -t ha-gateway:dev .
Package Map
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.
EventServiceis 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.