# home-services `home-services` is a Go workspace for internal home-control services. It keeps Home Assistant behind a gRPC gateway, adds an AI command gateway backed by Ollama, and exposes both through a Discord slash-command bot. ## Architecture The services follow hexagonal architecture: - `internal/core` contains domain types and ports - `internal/app` contains use-case orchestration - `internal/adapters` contains gRPC, Discord, Home Assistant, Ollama, logging, and telemetry edges - dependencies point inward toward the app and core packages Service flow: ```text Discord users | v discord-bot -----> ha-gateway -----> Home Assistant REST API | v ai-gateway ------> Ollama | v ha-gateway ``` The protobuf contracts live under `proto/`. Generated Go code is committed under `gen/` and shared by all modules through the Go workspace. ## Services ### `ha-gateway` Internal gRPC gateway for Home Assistant. - Default port: `50051` - Talks to Home Assistant through the REST API - Implements entity state lookup and discovery - Implements light control and light discovery - Implements switch discovery - Stubs switch control and event streaming - Supports optional mTLS when `TLS_DIR` is set - Exposes gRPC health checks and reflection See [ha-gateway/README.md](https://gitea.nik4nao.com/nik/home-services/src/branch/main/ha-gateway/README.md). ### `ai-gateway` Internal gRPC gateway for AI-assisted home commands. - Default port: `50052` - Calls Ollama for intent extraction and model listing - Calls `ha-gateway` for light discovery and light actions - Caches light discovery results for prompt context - Supports optional mTLS when `TLS_DIR` is set - Exposes gRPC health checks; reflection is enabled in debug logs See [ai-gateway/README.md](https://gitea.nik4nao.com/nik/home-services/src/branch/main/ai-gateway/README.md). ### `discord-bot` Discord slash-command process for home control. - Registers `/light`, `/switch`, and `/ai` commands - Calls `ha-gateway` for direct Home Assistant commands - Calls `ai-gateway` for free-form AI queries and model management - Supports optional mTLS for gateway clients when `TLS_DIR` is set See [discord-bot/README.md](https://gitea.nik4nao.com/nik/home-services/src/branch/main/discord-bot/README.md). ## Repo Structure ```text home-services/ ├── ai-gateway/ # AI gRPC gateway backed by Ollama and ha-gateway ├── discord-bot/ # Discord slash-command bot ├── gen/ # Committed generated protobuf/gRPC Go code ├── ha-gateway/ # Home Assistant gRPC gateway ├── proto/ # Source protobuf contracts ├── buf.gen.yaml # Buf generation config ├── buf.yaml # Buf module config └── go.work # Go workspace ``` ## Local Development Prerequisites: - Go `1.26+` - `buf`, when changing `.proto` files - `grpcurl`, for manual gRPC checks - Home Assistant with a long-lived access token - Ollama, if running AI queries - A Discord application and bot token, if running `discord-bot` Set up dependencies: ```bash go work sync ``` Regenerate protobuf code after changing files under `proto/`: ```bash buf generate ``` Run services in separate terminals: ```bash cp ha-gateway/.env.example ha-gateway/.env cd ha-gateway go run ./cmd/gateway ``` ```bash cp ai-gateway/.env.example ai-gateway/.env cd ai-gateway go run ./cmd/gateway ``` ```bash cp discord-bot/.env.example discord-bot/.env cd discord-bot go run ./cmd/bot ``` Each service loads `.env` from its current working directory, so run commands from the service directory when using the example env files. ## Test And Build Run tests from the workspace root: ```bash go test ./ha-gateway/... ./ai-gateway/... ./discord-bot/... ``` Build service binaries from the workspace root: ```bash go build ./ha-gateway/... ./ai-gateway/... ./discord-bot/... ``` Build container images from the workspace root: ```bash docker build -f ha-gateway/Dockerfile -t ha-gateway:dev . docker build -f ai-gateway/Dockerfile -t ai-gateway:dev . docker build -f discord-bot/Dockerfile -t discord-bot:dev . ``` ## gRPC Smoke Checks With `ha-gateway` running locally: ```bash grpcurl -plaintext -d '{"domain":"light"}' \ localhost:50051 ha.v1.EntityService/ListStates grpcurl -plaintext -d '{"entity_id":"light.living_room","brightness_pct":80}' \ localhost:50051 ha.v1.LightService/TurnOn ``` With `ai-gateway` running locally: ```bash grpcurl -plaintext -d '{"text":"turn on the desk lamp","source":"local"}' \ localhost:50052 ai.v1.AIService/Query grpcurl -plaintext -d '{}' localhost:50052 ai.v1.AIService/ListModels ``` ## Configuration Notes - `LOG_FORMAT=json` is the production default; `LOG_FORMAT=text` is easier locally. - `OTEL_ENDPOINT` enables OTLP gRPC traces and metrics. Leave it empty for local no-op telemetry. - `TLS_DIR` enables mTLS. The directory must contain `tls.crt`, `tls.key`, and `ca.crt`. - Inbound app-layer authorization is not implemented. Keep the gateways on a trusted internal network or use mTLS.