mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 14:50:40 +02:00
252 lines
7.2 KiB
Nix
252 lines
7.2 KiB
Nix
{
|
|
config,
|
|
globals,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
homeassistantDomain = "home.${globals.domains.personal}";
|
|
fritzboxDomain = "fritzbox.${globals.domains.personal}";
|
|
in
|
|
{
|
|
imports = [ ./hass-modbus/mennekes-amtron-xtra.nix ];
|
|
|
|
globals.wireguard.proxy-home.hosts.${config.node.name}.firewallRuleForNode.ward-web-proxy.allowedTCPPorts =
|
|
[
|
|
config.services.home-assistant.config.http.server_port
|
|
];
|
|
|
|
environment.persistence."/persist".directories = [
|
|
{
|
|
directory = config.services.home-assistant.configDir;
|
|
user = "hass";
|
|
group = "hass";
|
|
mode = "0700";
|
|
}
|
|
];
|
|
|
|
globals.services.home-assistant.domain = homeassistantDomain;
|
|
# globals.monitoring.http.homeassistant = {
|
|
# url = "https://${homeasisstantDomain}";
|
|
# expectedBodyRegex = "homeassistant";
|
|
# network = "internet";
|
|
# };
|
|
|
|
services.matter-server = {
|
|
enable = true;
|
|
logLevel = "debug";
|
|
};
|
|
|
|
topology.self.services.home-assistant.info = "https://${homeassistantDomain}";
|
|
services.home-assistant = {
|
|
enable = true;
|
|
extraComponents = [
|
|
"esphome"
|
|
"forecast_solar"
|
|
"fritzbox"
|
|
"matter"
|
|
"met"
|
|
"mqtt"
|
|
"ollama"
|
|
"radio_browser"
|
|
"shelly"
|
|
"soundtouch" # Bose SoundTouch
|
|
"spotify"
|
|
"wake_word"
|
|
"webostv" # LG WebOS TV
|
|
"whisper"
|
|
"wyoming"
|
|
"zha"
|
|
];
|
|
|
|
customComponents = with pkgs.home-assistant-custom-components; [
|
|
(pkgs.home-assistant.python.pkgs.callPackage ./hass-components/ha-bambulab.nix { })
|
|
dwd
|
|
waste_collection_schedule
|
|
];
|
|
|
|
customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [
|
|
(pkgs.callPackage ./hass-lovelace/config-template-card/package.nix { })
|
|
(pkgs.callPackage ./hass-lovelace/hui-element/package.nix { })
|
|
apexcharts-card
|
|
bubble-card
|
|
button-card
|
|
card-mod
|
|
clock-weather-card
|
|
hourly-weather
|
|
lg-webos-remote-control
|
|
mini-graph-card
|
|
multiple-entity-row
|
|
mushroom
|
|
weather-card
|
|
weather-chart-card
|
|
];
|
|
|
|
config = {
|
|
default_config = { };
|
|
http = {
|
|
server_host = [ "0.0.0.0" ];
|
|
server_port = 8123;
|
|
use_x_forwarded_for = true;
|
|
trusted_proxies = [ globals.wireguard.proxy-home.hosts.ward-web-proxy.ipv4 ];
|
|
};
|
|
|
|
zha.zigpy_config.source_routing = true;
|
|
|
|
homeassistant = {
|
|
name = "!secret ha_name";
|
|
latitude = "!secret ha_latitude";
|
|
longitude = "!secret ha_longitude";
|
|
elevation = "!secret ha_elevation";
|
|
currency = "EUR";
|
|
time_zone = "Europe/Berlin";
|
|
unit_system = "metric";
|
|
external_url = "https://${homeassistantDomain}";
|
|
internal_url = "https://${homeassistantDomain}";
|
|
packages.manual = "!include manual.yaml";
|
|
};
|
|
|
|
lovelace.mode = "yaml";
|
|
|
|
frontend = {
|
|
themes = "!include_dir_merge_named themes";
|
|
};
|
|
"automation ui" = "!include automations.yaml";
|
|
"scene" = "!include scenes.yaml";
|
|
|
|
influxdb = {
|
|
api_version = 2;
|
|
host = "localhost";
|
|
port = "8086";
|
|
max_retries = 10;
|
|
ssl = false;
|
|
verify_ssl = false;
|
|
token = "!secret influxdb_token";
|
|
organization = "home";
|
|
bucket = "hass";
|
|
};
|
|
|
|
waste_collection_schedule = {
|
|
sources = [
|
|
{
|
|
name = "ics";
|
|
args.url = "!secret muell_ics_url";
|
|
calendar_title = "Abfalltermine";
|
|
customize = [
|
|
{
|
|
type = "Restmüll 2-wöchentlich";
|
|
alias = "Restmüll";
|
|
}
|
|
{
|
|
type = "Papiertonne 4-wöchentlich";
|
|
alias = "Papiermüll";
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
|
|
sensor = [
|
|
{
|
|
platform = "waste_collection_schedule";
|
|
name = "restmuell_upcoming";
|
|
value_template = "{{value.types|join(\", \")}}|{{value.daysTo}}|{{value.date.strftime(\"%d.%m.%Y\")}}|{{value.date.strftime(\"%a\")}}";
|
|
types = [ "Restmüll" ];
|
|
}
|
|
{
|
|
platform = "waste_collection_schedule";
|
|
name = "papiermuell_upcoming";
|
|
value_template = "{{value.types|join(\", \")}}|{{value.daysTo}}|{{value.date.strftime(\"%d.%m.%Y\")}}|{{value.date.strftime(\"%a\")}}";
|
|
types = [ "Papiermüll" ];
|
|
}
|
|
];
|
|
};
|
|
|
|
extraPackages =
|
|
python3Packages: with python3Packages; [
|
|
adguardhome
|
|
aioelectricitymaps
|
|
dwdwfsapi
|
|
fritzconnection
|
|
getmac
|
|
gtts
|
|
psycopg2
|
|
pyatv
|
|
pyipp
|
|
pymodbus
|
|
zlib-ng
|
|
];
|
|
};
|
|
|
|
age.secrets."home-assistant-secrets.yaml" = {
|
|
rekeyFile = ./secrets/home-assistant-secrets.yaml.age;
|
|
owner = "hass";
|
|
};
|
|
|
|
systemd.services.home-assistant = {
|
|
serviceConfig.LoadCredential = [
|
|
"hass-influxdb-token:${config.age.secrets.hass-influxdb-token.path}"
|
|
];
|
|
preStart = lib.mkBefore ''
|
|
if [[ -e ${config.services.home-assistant.configDir}/secrets.yaml ]]; then
|
|
rm ${config.services.home-assistant.configDir}/secrets.yaml
|
|
fi
|
|
|
|
# Update influxdb token
|
|
# We don't use -i because it would require chown with is a @privileged syscall
|
|
INFLUXDB_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/hass-influxdb-token")" \
|
|
${lib.getExe pkgs.yq-go} '.influxdb_token = strenv(INFLUXDB_TOKEN)' \
|
|
${
|
|
config.age.secrets."home-assistant-secrets.yaml".path
|
|
} > ${config.services.home-assistant.configDir}/secrets.yaml
|
|
|
|
touch -a ${config.services.home-assistant.configDir}/{automations,scenes,scripts,manual}.yaml
|
|
'';
|
|
};
|
|
|
|
# Connect to fritzbox via https proxy (to ensure valid cert)
|
|
networking.hosts.${globals.net.home-lan.vlans.services.hosts.ward-web-proxy.ipv4} = [
|
|
fritzboxDomain
|
|
];
|
|
|
|
networking.hosts.${globals.wireguard.proxy-home.hosts.ward-adguardhome.ipv4} = [
|
|
"adguardhome.internal"
|
|
];
|
|
|
|
nodes.ward-web-proxy = {
|
|
services.nginx = {
|
|
upstreams."home-assistant" = {
|
|
servers."${
|
|
globals.wireguard.proxy-home.hosts.${config.node.name}.ipv4
|
|
}:${toString config.services.home-assistant.config.http.server_port}" =
|
|
{ };
|
|
extraConfig = ''
|
|
zone home-assistant 64k;
|
|
keepalive 2;
|
|
'';
|
|
};
|
|
virtualHosts.${homeassistantDomain} = {
|
|
forceSSL = true;
|
|
useACMEWildcardHost = true;
|
|
locations."/" = {
|
|
proxyPass = "http://home-assistant";
|
|
proxyWebsockets = true;
|
|
};
|
|
extraConfig = ''
|
|
allow ${globals.net.home-lan.vlans.home.cidrv4};
|
|
allow ${globals.net.home-lan.vlans.home.cidrv6};
|
|
allow ${globals.net.home-lan.vlans.devices.cidrv4};
|
|
allow ${globals.net.home-lan.vlans.devices.cidrv6};
|
|
# Self-traffic (needed for media in Voice PE)
|
|
allow ${globals.net.home-lan.vlans.services.hosts.sausebiene.ipv4};
|
|
allow ${globals.net.home-lan.vlans.services.hosts.sausebiene.ipv6};
|
|
# Firezone traffic
|
|
allow ${globals.net.home-lan.vlans.services.hosts.ward.ipv4};
|
|
allow ${globals.net.home-lan.vlans.services.hosts.ward.ipv6};
|
|
deny all;
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
}
|