Home Assistant
- Source: https://github.com/home-assistant/core
- License: Apache 2.0
- Alternatives: openHAB, Domoticz, Node-RED
Open-source home automation platform. Integrates with thousands of devices and services, supports local processing, and serves as the event bus for voice-triggered automations.
Home Assistant is a complementary service — nothing else in the stack talks to it, so it can run on its own machine or its own schedule without affecting anything. That matters more here than for most: if you're using a Zigbee or Z-Wave stick, HA needs to live on the machine that stick is plugged into, which may not be the machine running the rest of the stack. It still comes up from the repo root with everything else (./existential.sh && docker compose up -d) — being complementary means you can move it, not that it needs separate commands.
See the blog post Optimizing my life, now with Home Assistant for a real-world setup walkthrough.
Getting Started
- Enable the service in
.env.shared:EXIST_IS_SERVICES_HOMEASSISTANT=true - Run
./existential.shto render templates and regenerate the compose file - Start the container:
docker compose up -d homeassistant
- Open
https://homeassistant.EXIST_DOMAINand complete the onboarding wizard to create your admin account
Home Assistant generates its own configuration.yaml on first boot inside the homeassistant_config volume — no manual pre-configuration needed.
Hardware Access
If you're connecting USB hardware (Zigbee sticks, Z-Wave controllers, etc.), uncomment privileged: true in docker-compose.yml and add the device path:
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
Identify the device path on the host:
ls /dev/serial/by-id/
Voice
Home Assistant's Assist pipeline speaks the Wyoming protocol — a small, line-oriented TCP protocol — not HTTP. That is why the stack ships two purpose-built services for it rather than reusing WhisperX and Chatterbox, which are HTTP services HA cannot drive:
| Service | Port | |
|---|---|---|
| Speech → text | wyoming-whisper | 10300 |
| Text → speech | wyoming-piper | 10200 |
Both run on CPU by design. The GPU is already holding the chat model and the embedding model; a GPU voice model would evict them mid-answer, and a spoken reply needs to land immediately anyway.
Wiring it up
Neither service has a web UI or a <slug>.<domain> hostname — Wyoming is raw
TCP, so there is nothing for Caddy to front. You add them inside HA:
- Settings → Devices & Services → Add Integration → Wyoming Protocol
- Host
wyoming-whisper, port10300 - Repeat for host
wyoming-piper, port10200
- Host
- Settings → Voice assistants → Add assistant
- Speech-to-text: the wyoming-whisper entry
- Text-to-speech: the wyoming-piper entry
- Conversation agent: Ollama, pointed at
http://ollama:11434
The models are chosen globally in .env.shared — EXIST_MODEL_STT,
EXIST_MODEL_STT_LANGUAGE and EXIST_MODEL_TTS_VOICE. See
How it works for the full model-selection block.
Long-Lived Access Token
Many integrations (HAwake, Tasker via TaskerHA, external scripts) need a long-lived access token:
- HA → Profile (bottom-left avatar) → Long-Lived Access Tokens → Create Token
- Copy and store the token securely — it's only shown once
Automations
HA automations are defined in YAML or via the UI under Settings → Automations & Scenes.
See HAwake → Home Assistant → Tasker for a complete example of using a custom wake word to trigger Tasker actions through HA.
Services
| Endpoint | URL |
|---|---|
| Web Interface | https://homeassistant.EXIST_DOMAIN |
| REST API | https://homeassistant.EXIST_DOMAIN/api/ |
Debugging
# Container logs
docker logs homeassistant
# Configuration check (run inside the container)
docker exec homeassistant python -m homeassistant --script check_config --config /config
# Recent HA log entries
docker exec homeassistant tail -n 100 /config/home-assistant.log