home-services/README.md
Nik Afiq b54a747467
All checks were successful
CI / test (push) Successful in 5s
CI / build-ai-gateway (push) Successful in 53s
CI / build-ha-gateway (push) Successful in 42s
CI / build-discord-bot (push) Successful in 40s
feat: add switch control functionality to the Home Assistant integration
- Implemented TurnOn, TurnOff, and Toggle methods in the gRPC client for switch control.
- Added corresponding methods in the CommandApp to handle user commands for turning switches on, off, and toggling.
- Created unit tests for the new switch control methods in CommandApp and SwitchApp.
- Updated the HAGateway interface to include switch control methods.
- Enhanced the SwitchGRPC service to handle switch control requests and return appropriate responses.
- Added integration tests for the switch service to ensure correct behavior and error handling.
2026-07-22 23:44:35 +09:00

5.1 KiB

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:

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 control and switch discovery
  • Stubs event streaming
  • Supports optional mTLS when TLS_DIR is set
  • Exposes gRPC health checks and reflection

See 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.

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.

Repo Structure

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:

go work sync

Regenerate protobuf code after changing files under proto/:

buf generate

Run services in separate terminals:

cp ha-gateway/.env.example ha-gateway/.env
cd ha-gateway
go run ./cmd/gateway
cp ai-gateway/.env.example ai-gateway/.env
cd ai-gateway
go run ./cmd/gateway
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:

go test ./ha-gateway/... ./ai-gateway/... ./discord-bot/...

Build service binaries from the workspace root:

go build ./ha-gateway/... ./ai-gateway/... ./discord-bot/...

Build container images from the workspace root:

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:

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

grpcurl -plaintext -d '{"entity_id":"switch.fan"}' \
  localhost:50051 ha.v1.SwitchService/TurnOn

With ai-gateway running locally:

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.