{ pkgs, lib, config, ... }: let nginxEnabled = config.mod.nginx.enable; in { hardware.bluetooth.enable = true; virtualisation.oci-containers = { backend = "podman"; containers.homeassistant = { image = "ghcr.io/home-assistant/home-assistant:stable"; volumes = [ "/home/alex/.config/home-assistant:/config" # Pass in bluetooth "/run/dbus:/run/dbus:ro" ]; environment.TZ = "Europe/Stockholm"; extraOptions = [ "--network=host" # Allows HA to perform low-level network operations (scan/reset adapter) "--cap-add=NET_ADMIN" "--cap-add=NET_RAW" # Pass in Zigbee antenna "--device=/dev/serial/by-id/usb-Nabu_Casa_ZBT-2_9C139EAAD464-if00:/dev/ttyACM0" ]; }; }; services = { blueman.enable = true; nginx = lib.mkIf nginxEnabled { recommendedProxySettings = true; virtualHosts."ha.ppp.pm" = { forceSSL = true; useACMEHost = "ha.ppp.pm"; extraConfig = '' proxy_buffering off; ''; locations."/" = { proxyPass = "http://127.0.0.1:8123"; proxyWebsockets = true; }; }; }; }; systemd.user = { timers = { "update-hetzner-ha-dns" = { unitConfig = { Description = "updates Hetzner DNS for home-assistant"; }; timerConfig = { Unit = "update-hetzner-ha-dns.service"; OnCalendar = "*-*-* *:00/30:00"; Persistent = true; }; wantedBy = [ "timers.target" ]; }; }; services = { "update-hetzner-ha-dns" = { unitConfig = { Description = "updates Hetzner DNS for home-assistant"; }; serviceConfig = { Type = "exec"; EnvironmentFile = config.age.secrets.hetzner-dns.path; }; path = [ pkgs.curl pkgs.coreutils # For `cat` ]; script = '' LAST_IP_FILE="/tmp/hetzner-dns-ha-ip" INTERFACE="enp3s0" CURRENT_IP=$(curl -s --fail --interface "$INTERFACE" ifconfig.me) LAST_IP="" if [[ -f "$LAST_IP_FILE" ]]; then LAST_IP=$(cat "$LAST_IP_FILE") fi if [[ "$CURRENT_IP" == "$LAST_IP" ]]; then echo "IP unchanged, NOOP update." exit 0 else echo "checking DNS" curl \ -H "Authorization: Bearer $HETZNER_API_TOKEN" \ "https://api.hetzner.cloud/v1/zones/ppp.pm/rrsets/ha/A" fi ''; }; }; }; age = { secrets = { "hetzner-dns".file = ../../../../secrets/manatee/hetzner-dns.age; }; }; }