{ pkgs, lib, config, ... }: let writeYaml = (pkgs.formats.yaml {}).generate; switches = writeYaml "switches.yaml" [ { platform = "wake_on_lan"; mac = "88:AE:DD:0F:2A:1E"; host = "tv.lan"; name = "TV Power"; turn_off.action = "shell_command.turn_off_tv"; } ]; in { virtualisation.oci-containers.containers.home-assistant = { volumes = [ "/data/dirty/home-assistant:/config" "${switches}:/config/switches.yaml" "${config.sops.secrets.power-management-key.path}:/root/.ssh/power-management-key" ]; environment.TZ = "Europe/Berlin"; image = "ghcr.io/home-assistant/home-assistant:2024.10"; ports = [ "127.0.0.1:8123:8123" ]; extraOptions = [ # TODO: Fix the path of the zigbee controller using udev "--device=/dev/serial/by-id/usb-Silicon_Labs_Sonoff_Zigbee_3.0_USB_Dongle_Plus_0001-if00-port0" "--device=/dev/ttyUSB0" "--cap-add=CAP_NET_RAW,CAP_NET_BIND_SERVICE" "--network=home-assistant" "--ip=192.168.1.10" "--dns=192.168.1.1" ]; }; # Podman network for home-assistant # # Use 192.168.1.8/28 as a subnet, because my router already reserves the first 100 addresses # of 192.168.1.0/24, so 192.168.1.8/28 - 192.168.1.15/28 should be good environment.etc."containers/networks/home-assistant.json" = { source = (pkgs.formats.json {}).generate "home-assistant.json" { dns_enabled = false; driver = "macvlan"; id = "0000000000000000000000000000000000000000000000000000000000000001"; internal = false; ipam_options = {driver = "host-local";}; ipv6_enabled = false; name = "home-assistant"; network_interface = "eno1"; subnets = [ { subnet = "192.168.1.0/24"; gateway = "192.168.1.1"; "lease_range" = { "start_ip" = "192.168.1.10"; "end_ip" = "192.168.1.14"; }; } ]; }; }; # TODO: This does not work without manually creating the device using `ip link add ha-shim link eno1 type macvlan mode bridge` from [here](https://blog.oddbit.com/post/2018-03-12-using-docker-macvlan-networks/) systemd.network = { enable = true; netdevs."50-home-assistant-shim" = { enable = true; macvlanConfig.Mode = "bridge"; netdevConfig = { Name = "ha-shim"; Description = "A shim for communicating with the home-assistant podman network"; Kind = "macvlan"; }; }; networks."60-home-assistant-shim" = { enable = true; name = "ha-shim"; matchConfig.Name = "ha-shim"; networkConfig = { Description = "A shim for communicating with the home-assistant podman network"; Address = ["192.168.1.9/28"]; DNS = ["192.168.1.1"]; }; routes = lib.singleton { Destination = "192.168.1.8/28"; }; linkConfig.RequiredFamilyForOnline = "ipv4"; }; links."60-eno1" = { enable = true; matchConfig.Name = "eno1"; # linkConfig seems broken extraConfig = '' [Link] MACVLAN=ha-shim RequiredForOnline=no ''; }; }; # TODO: Fix for the above # TODO: This might just work with networking.useNetworkd being true.. systemd.services.create-ha-shim-netdev = { enable = true; description = "Create the ha-shim device because systemd-networkd fails"; wantedBy = ["network.target"]; script = '' #!/bin/sh ${pkgs.iproute2}/bin/ip link add ha-shim link eno1 type macvlan mode bridge ''; serviceConfig = { Type = "simple"; }; }; # Configure nginx reverse proxy services.nginx.virtualHosts."config.tammena.me" = { addSSL = true; sslTrustedCertificate = pkgs.writeText "ca.crt" (builtins.readFile ../../../secrets/ca.crt); sslCertificateKey = config.sops.secrets."certificate-key-config-tammena-me".path; sslCertificate = pkgs.writeText "config-tammena-me.crt" (builtins.readFile ../../../secrets/pub/config-tammena-me.crt); serverAliases = [ "config.home" ]; locations."/" = { proxyPass = "http://192.168.1.10:8123"; proxyWebsockets = true; }; }; # Secrets sops.secrets."certificate-key-config-tammena-me" = { owner = config.users.users.nginx.name; mode = "0400"; }; sops.secrets.power-management-key = { owner = config.users.users.root.name; mode = "0400"; }; }