Files
ouranos/docs/hass.md
Robert Helewka b4d60f2f38 docs: rewrite README with structured overview and quick start guide
Replaces the minimal project description with a comprehensive README
including a component overview table, quick start instructions, common
Ansible operations, and links to detailed documentation. Aligns with
Red Panda Approval™ standards.
2026-03-03 12:49:06 +00:00

7.7 KiB

Home Assistant

Overview

Home Assistant is an open-source home automation platform. In the Agathos sandbox it runs as a native Python application inside a virtual environment, backed by PostgreSQL for state recording and fronted by HAProxy for TLS termination.

Host: Oberon
Role: container_orchestration
Port: 8123
URL: https://hass.ouranos.helu.ca

Architecture

┌──────────┐  HTTPS   ┌──────────────┐  HTTP   ┌──────────────┐
│  Client  │────────▶│  HAProxy     │────────▶│  Home        │
│          │         │  (Titania)   │         │  Assistant   │
└──────────┘         │  :443 TLS    │         │  (Oberon)    │
                     └──────────────┘         │  :8123       │
                                              └──────┬───────┘
                                                     │
                                   ┌─────────────────┼─────────────────┐
                                   │                 │                 │
                              ┌────▼─────┐    ┌──────▼──────┐   ┌─────▼─────┐
                              │PostgreSQL│    │  Alloy      │   │ Prometheus│
                              │(Portia)  │    │  (Oberon)   │   │(Prospero) │
                              │ :5432    │    │  scrape     │   │  remote   │
                              │ recorder │    │  /api/prom  │   │  write    │
                              └──────────┘    └─────────────┘   └───────────┘

Ansible Deployment

Playbook

cd ansible
ansible-playbook hass/deploy.yml

Files

File Purpose
hass/deploy.yml Main deployment playbook
hass/configuration.yaml.j2 Home Assistant configuration
hass/requirements.txt.j2 Python package pinning
hass/hass.service.j2 Systemd service unit

Variables

Host Variables (host_vars/oberon.incus.yml)

Variable Description Value
hass_user System user hass
hass_group System group hass
hass_directory Install directory /srv/hass
hass_media_directory Media storage /srv/hass/media
hass_port HTTP listen port 8123
hass_version Pinned HA release 2026.2.0
hass_db_host PostgreSQL host portia.incus
hass_db_port PostgreSQL port 5432
hass_db_name Database name hass
hass_db_user Database user hass
hass_db_password Database password {{ vault_hass_db_password }}
hass_metrics_token Prometheus bearer token {{ vault_hass_metrics_token }}

Host Variables (host_vars/portia.incus.yml)

Variable Description
hass_db_name Database name on Portia
hass_db_user Database user on Portia
hass_db_password {{ vault_hass_db_password }}

Vault Variables (group_vars/all/vault.yml)

Variable Description
vault_hass_db_password PostgreSQL password for hass database
vault_hass_metrics_token Long-Lived Access Token for Prometheus scraping

Configuration

PostgreSQL Recorder

Home Assistant uses the recorder integration to persist entity states and events to PostgreSQL on Portia instead of the default SQLite. Configured in configuration.yaml.j2:

recorder:
  db_url: "postgresql://hass:<password>@portia.incus:5432/hass"
  purge_keep_days: 30
  commit_interval: 1

The database and user are provisioned by postgresql/deploy.yml alongside other service databases.

HTTP / Reverse Proxy

HAProxy on Titania terminates TLS and forwards to Oberon:8123. The http block in configuration.yaml.j2 configures trusted proxies so HA correctly reads X-Forwarded-For headers:

http:
  server_port: 8123
  use_x_forwarded_for: true
  trusted_proxies:
    - 10.0.0.0/8

HAProxy Backend

Defined in host_vars/titania.incus.yml under haproxy_backends:

Setting Value
Subdomain hass
Backend oberon.incus:8123
Health path /api/
Timeout 300s (WebSocket support)

The wildcard TLS certificate (*.ouranos.helu.ca) covers hass.ouranos.helu.ca automatically — no certificate changes required.

Authentication

Home Assistant uses its native homeassistant auth provider (built-in username/password). HA does not support OIDC/OAuth2 natively, so Casdoor SSO integration is not available.

On first deployment, HA will present an onboarding wizard to create the initial admin user.

Monitoring

Prometheus Metrics

Home Assistant exposes Prometheus metrics at /api/prometheus. The Alloy agent on Oberon scrapes this endpoint with bearer token authentication and remote-writes to Prometheus on Prospero.

Setting Value
Metrics path /api/prometheus
Scrape interval 60s
Auth Bearer token (Long-Lived Access Token)

⚠️ Two-Phase Metrics Bootstrapping:

The vault_hass_metrics_token must be a Home Assistant Long-Lived Access Token, which can only be generated from the HA web UI after the initial deployment:

  1. Deploy Home Assistant: ansible-playbook hass/deploy.yml
  2. Complete the onboarding wizard at https://hass.ouranos.helu.ca
  3. Navigate to Profile → Security → Long-Lived Access Tokens → Create Token
  4. Store the token in vault: vault_hass_metrics_token: "<token>"
  5. Redeploy Alloy to pick up the token: ansible-playbook alloy/deploy.yml

Until the token is created, the Alloy hass scrape will fail silently.

Loki Logs

Systemd journal logs are collected by Alloy's loki.source.journal and shipped to Loki on Prospero.

# Query in Grafana Explore
{job="systemd", hostname="oberon"} |= "hass"

Operations

Start / Stop

sudo systemctl start hass
sudo systemctl stop hass
sudo systemctl restart hass

Health Check

curl http://localhost:8123/api/

Logs

journalctl -u hass -f

Version Upgrade

  1. Update hass_version in host_vars/oberon.incus.yml
  2. Run: ansible-playbook hass/deploy.yml

The playbook will reinstall the pinned version via pip and restart the service.

Troubleshooting

Common Issues

Symptom Cause Resolution
Service won't start Missing Python deps Check pip install output in deploy log
Database connection error Portia unreachable Verify PostgreSQL is running: ansible-playbook postgresql/deploy.yml
502 via HAProxy HA not listening Check systemctl status hass on Oberon
Metrics scrape failing Missing/invalid token Generate Long-Lived Access Token from HA UI (see Monitoring section)

Debug Mode

# Check service status
sudo systemctl status hass

# View recent logs
journalctl -u hass --since "5 minutes ago"

# Test database connectivity from Oberon
psql -h portia.incus -U hass -d hass -c "SELECT 1"

References