- Added ClimateApp to handle climate entity operations including turning on/off, adjusting temperature, and setting HVAC modes. - Implemented caching mechanism for climate entities to optimize state retrieval. - Created domain model for Climate with attributes such as current temperature, target temperature, and HVAC modes. - Developed unit tests for ClimateApp to ensure functionality and correctness. feat: add RemoteApp for SwitchBot commands - Introduced RemoteApp to facilitate sending commands to SwitchBot devices. - Implemented SendCommand method for executing device commands without state management. chore: update configuration for SwitchBot integration - Added SwitchBotToken and SwitchBotSecret to configuration for enabling SwitchBot Cloud commands. feat: define gRPC services for Climate and Remote operations - Created climate.proto and remote.proto files to define gRPC services for climate management and remote command execution. - Implemented corresponding request and response message structures for gRPC interactions.
4.3 KiB
4.3 KiB
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 and, when
SWITCHBOT_TOKEN/SWITCHBOT_SECRETare set, a SwitchBot Cloud adapter. - Light, switch, and climate discovery caches are refreshed during startup when possible.
- gRPC clients call entity, light, switch, climate, remote, or event services.
- The adapter maps requests to Home Assistant REST state/service calls, or
for
RemoteService, signed SwitchBot Cloud Open API requests.
gRPC API
Contracts are defined under proto/ha/v1.
Implemented:
EntityService.GetStateEntityService.ListStatesLightService.TurnOnLightService.TurnOffLightService.ToggleLightService.ListLightsSwitchService.TurnOnSwitchService.TurnOffSwitchService.ToggleSwitchService.ListSwitchesClimateService.TurnOnClimateService.TurnOffClimateService.IncreaseTemperatureClimateService.DecreaseTemperatureClimateService.SetHVACModeClimateService.ListClimatesRemoteService.SendCommand
Stubbed:
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 |
SWITCHBOT_TOKEN |
empty | optional; enables SwitchBot Cloud custom IR commands |
SWITCHBOT_SECRET |
empty | optional; enables SwitchBot Cloud custom IR commands |
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 ha.v1.ClimateService/ListClimates
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/adapters/secondary/switchbot/ # SwitchBot Cloud Open API adapter
internal/app/ # entity, light, switch, climate, and remote 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
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.