nixos/hosts/faunus-ater/modules/home-assistant.nix

148 lines
4.4 KiB
Nix

{
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";
};
}