{ lib, pkgs, config, ... }: let configDir = "/var/lib/hass"; db_user = "hass"; in { options.host.home-assistant = { enable = lib.mkEnableOption "should home-assistant be enabled on this computer"; subdomain = lib.mkOption { type = lib.types.str; description = "subdomain of base domain that home-assistant will be hosted at"; default = "home-assistant"; }; }; config = lib.mkIf config.host.home-assistant.enable (lib.mkMerge [ { systemd.tmpfiles.rules = [ "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" ]; services.home-assistant = { enable = true; package = (pkgs.home-assistant.override { extraPackages = py: with py; [psycopg2]; }) .overrideAttrs (oldAttrs: { doInstallCheck = false; }); configDir = configDir; extraComponents = [ "met" "radio_browser" "isal" "zha" "jellyfin" "webostv" "tailscale" "syncthing" "sonos" "analytics_insights" "unifi" "minecraft_server" "openweathermap" ]; config = { http = { server_port = 8082; use_x_forwarded_for = true; trusted_proxies = ["127.0.0.1" "::1"]; ip_ban_enabled = true; login_attempts_threshold = 10; }; recorder.db_url = "postgresql://@/${db_user}"; "automation manual" = []; "automation ui" = "!include automations.yaml"; }; extraPackages = python3Packages: with python3Packages; [ hassil numpy gtts ]; }; systemd.services.home-assistant = { requires = [ "postgresql.service" ]; }; host = { reverse_proxy.subdomains.${config.host.home-assistant.subdomain} = { target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; websockets = true; extraConfig = '' add_header Upgrade $http_upgrade; add_header Connection \"upgrade\"; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering off; proxy_read_timeout 90; ''; }; postgres = { enable = true; extraUsers = { ${db_user} = { isClient = true; createUser = true; }; }; extraDatabases = { ${db_user} = { name = db_user; }; }; }; }; } (lib.mkIf config.host.impermanence.enable { assertions = [ { assertion = config.services.home-assistant.configDir == configDir; message = "home assistant config directory does not match persistence"; } ]; environment.persistence."/persist/system/root" = { enable = true; hideMounts = true; directories = [ { directory = configDir; user = "hass"; group = "hass"; } ]; }; }) ]); }