- Updated LLMClient interface to support model-specific generation and model listing. - Integrated model store and validator into the command application for managing AI models. - Implemented commands for setting, getting, and listing active AI models in Discord. - Enhanced AI query handling to utilize the selected model and return model information in responses. - Added caching mechanism for model validation to improve performance. - Introduced gRPC methods for listing available AI models in the ai-gateway. - Updated protobuf definitions to include model-related fields and messages. - Added tests for model store and validator functionalities.
home-services
home-services is a Go mono-repo for internal home-control services built
around a gRPC gateway for Home Assistant. Discord and Alexa clients are meant
to talk to the gateway instead of integrating with Home Assistant directly.
Architecture
The repo uses hexagonal architecture:
- the core domain is plain Go data and interfaces
- adapters at the edges handle gRPC, HTTP, Discord, telemetry, and logging
- dependencies point inward only
That means the business logic does not need to know about Discord, protobuf transport details, or Home Assistant HTTP specifics.
Service relationship
Discord bot ->\
\
-> ha-gateway -> Home Assistant
/
Alexa bridge ->/
discord-botis an internal gRPC client ofha-gatewayalexa-bridgeis planned as another internal gRPC client ofha-gatewayha-gatewayis the only service that talks to Home Assistant directly
Proto-first design
All service contracts are defined in proto/ha/v1/. Generated Go code is
committed under gen/ and used by both clients and servers.
This gives every service the same:
- RPC method names
- request and response message types
- protobuf serialization rules
- gRPC client/server bindings
Services
ha-gateway
ha-gateway is the single internal gRPC gateway to Home Assistant. It should
not be exposed publicly.
- Port:
50051 - Deployment model: internal-only, typically ClusterIP
- Implemented:
EntityService:GetState,ListStatesLightService:TurnOn,TurnOff,Toggle,ListLightsSwitchService:ListSwitches
- Stubbed:
SwitchService:TurnOn,TurnOff,ToggleEventService
- Observability:
- structured logging via
slog LOG_FORMAT=jsonis suitable for production log pipelinesLOG_FORMAT=textis more readable locally- OpenTelemetry traces and metrics export over OTLP gRPC
- structured logging via
Config:
| Variable | Default | Description |
|---|---|---|
GRPC_PORT |
50051 |
gRPC listen port |
HA_BASE_URL |
empty | Base URL for Home Assistant |
HA_TOKEN |
none | Home Assistant long-lived access token |
OTEL_ENDPOINT |
empty | OTLP gRPC collector endpoint; empty disables telemetry |
LOG_LEVEL |
info |
debug, info, warn, or error |
LOG_FORMAT |
json |
json or text |
Auth:
Inbound auth is not implemented yet. The current recommendation is mTLS between internal services. A per-client API key interceptor is a possible alternative for simpler environments.
discord-bot
discord-bot provides Discord slash commands for home control and discovery.
- Connects to
ha-gatewayover internal gRPC - Supports slash-command control for lights
- Supports list/discovery responses for lights and switches
- Observability:
- structured logging via
slog - OpenTelemetry traces and metrics via OTLP gRPC
- structured logging via
Config:
| Variable | Default | Description |
|---|---|---|
DISCORD_TOKEN |
none | Discord bot token |
GUILD_ID |
empty | Guild-scoped command registration target |
HA_GATEWAY_ADDR |
none | gRPC address of ha-gateway |
OTEL_ENDPOINT |
empty | OTLP gRPC collector endpoint; empty disables telemetry |
LOG_LEVEL |
info |
debug, info, warn, or error |
LOG_FORMAT |
json |
json or text |
Auth:
No additional app-layer auth is implemented yet. The bot currently relies on Discord authentication and the internal network boundary.
alexa-bridge
alexa-bridge is a planned public HTTPS webhook service that will:
- validate Alexa request signatures
- translate Alexa directives into gRPC calls to
ha-gateway - keep
ha-gatewayoff the public internet
Status:
- stubbed concept only
- not implemented in this repo yet
Repo Structure
home-services/
├── proto/ # Source of truth for protobuf service contracts
│ └── ha/v1/
├── gen/ # Committed generated Go protobuf/gRPC code; do not edit
├── ha-gateway/
│ ├── cmd/gateway/ # Process entrypoint and startup wiring
│ └── internal/
│ ├── core/ # Pure domain and port definitions, no framework logic
│ ├── app/ # Orchestration between ports
│ ├── adapters/ # gRPC handlers, HA client, and other I/O
│ ├── logger/ # Context-aware slog helpers
│ └── telemetry/ # OpenTelemetry setup and shutdown
├── discord-bot/
│ ├── cmd/bot/ # Process entrypoint and Discord session wiring
│ └── internal/
│ ├── app/ # Command orchestration and formatting
│ ├── adapters/ # Discord interaction handlers and gRPC client
│ ├── core/ports/driven/ # App-facing ha-gateway contract
│ ├── logger/ # Context-aware slog helpers
│ └── telemetry/ # OpenTelemetry setup and shutdown
├── buf.yaml # Buf module config
├── buf.gen.yaml # Buf generation config
└── go.work # Go workspace for local module development
Local Development
Prerequisites:
- Go
1.26+ bufgrpcurl- a running Home Assistant instance
Setup:
# Clone and set up workspace
git clone https://gitea.nik4nao.com/nik/home-services
cd home-services
go work sync
# Regenerate proto (only needed if .proto files change)
buf generate
# Configure ha-gateway
cp ha-gateway/.env.example ha-gateway/.env
# Edit ha-gateway/.env — set HA_BASE_URL and HA_TOKEN
# Run ha-gateway
cd ha-gateway && go run ./cmd/gateway
# Run discord-bot (separate terminal)
cd discord-bot && go run ./cmd/bot
Smoke testing with grpcurl:
# List all lights
grpcurl -plaintext -d '{"domain":"light"}' \
localhost:50051 ha.v1.EntityService/ListStates
# Turn on a light
grpcurl -plaintext -d '{"entity_id":"light.living_room","brightness_pct":80}' \
localhost:50051 ha.v1.LightService/TurnOn
Building
# Build ha-gateway image (run from repo root)
docker build -f ha-gateway/Dockerfile -t ha-gateway:dev .
# Build discord-bot image
docker build -f discord-bot/Dockerfile -t discord-bot:dev .
What's Next
- Auth: mTLS between services using an internal cert-manager CA
- SwitchService control implementation
- EventService with Home Assistant WebSocket fan-out broker
alexa-bridgeimplementation- Gitea CI pipeline for automated build and push