Extend home-assistant, add dhcp-server, add frigate, add avahi-reflector

This commit is contained in:
Hendrik Sokolowski 2023-10-01 22:23:58 +02:00
parent b5118aa1d4
commit 6adbbbeaa4
13 changed files with 504 additions and 113 deletions

View file

@ -0,0 +1,24 @@
{ pkgs, python311 }:
let
pycryptodomex = python311.pkgs.buildPythonPackage rec {
pname = "pycryptodomex";
version = "3.18.0";
src = pkgs.fetchPypi {
inherit pname version;
sha256 = "Pj7LX+l558G7ACflGDQKz37mBBXXkpXlJR0Txo3eV24=";
};
};
in
python311.pkgs.buildPythonPackage rec {
pname = "aioairctrl";
version = "0.2.4";
src = pkgs.fetchPypi {
inherit pname version;
sha256 = "BIJWwMQq3QQjhyO0TSw+C6muyr3Oyv6UHr/Y3iYqRUM=";
};
propagatedBuildInputs = with python311.pkgs; [
aiocoap
pycryptodomex
];
}

View file

@ -0,0 +1,8 @@
{...}: {
services.avahi = {
enable = true;
allowInterfaces = ["eth0" "vlan102" "vlan104"];
reflector = true;
publish.enable = true;
};
}

View file

@ -1,6 +1,3 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ {
config, config,
pkgs, pkgs,
@ -8,17 +5,23 @@
... ...
}: { }: {
imports = [ imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
./network.nix
./network-dhcp.nix
./avahi-reflector.nix
./unifi.nix
./home-controller.nix ./home-controller.nix
./tang-container.nix
./home-assistant.nix ./home-assistant.nix
./frigate.nix
# ./tang-container.nix
]; ];
boot.loader.timeout = 0; boot.loader.timeout = 0;
boot.loader.systemd-boot.enable = lib.mkForce false;
boot.loader.generic-extlinux-compatible.enable = lib.mkForce false; boot.loader.generic-extlinux-compatible.enable = lib.mkForce false;
boot.loader.grub = { boot.loader.grub = {
enable = true; enable = true;
efiSupport = true; efiSupport = true;
@ -26,42 +29,7 @@
device = "nodev"; device = "nodev";
}; };
# Set your time zone.
time.timeZone = "Europe/Berlin"; time.timeZone = "Europe/Berlin";
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
networking.interfaces.wlan0.useDHCP = false;
networking.networkmanager.enable = lib.mkForce false;
boot.loader.systemd-boot.enable = lib.mkForce false;
nix = {
#package = pkgs.nixFlakes;
extraOptions = lib.optionalString (config.nix.package == pkgs.nixFlakes) "experimental-features = nix-command flakes";
};
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
vim
wget
];
# Open ports in the firewall.
networking.firewall.allowedTCPPorts = [2380 6443];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
# networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.11"; # Did you read the comment? system.stateVersion = "22.11"; # Did you read the comment?
} }

View file

@ -1,6 +1,7 @@
{ suites, ... }: {suites, ...}: {
{ imports =
imports = [ [
./giggles.nix ./giggles.nix
] ++ suites.giggles; ]
++ suites.giggles;
} }

73
hosts/giggles/frigate.nix Normal file
View file

@ -0,0 +1,73 @@
{ ... }:
{
networking.firewall.allowedTCPPorts = [80 5000 8554 8555];
#services.go2rtc = {
# enable = true;
# settings = {
# streams = {
# burgi_cam = [
# "rtsp://admin:XpkFk5Df912VWSwM@10.0.42.60:554/Streaming/Channels/101/?transportmode=unicast"
# "ffmpeg:burgi_cam_sub#audio=opus"
# ];
# burgi_cam_sub = [
# "rtsp://admin:XpkFk5Df912VWSwM@10.0.42.60:554/Streaming/Channels/102/?transportmode=unicast"
# ];
# };
# webrtc = {
# candidates = [ "192.168.42.11:8555" ];
# };
# };
#};
services.frigate = {
enable = true;
hostname = "frigate";
settings = {
cameras.burgi = {
ffmpeg = {
inputs = [
{
path = "rtsp://admin:XpkFk5Df912VWSwM@10.0.42.60:554/Streaming/Channels/101/?transportmode=unicast";
#path = "rtsp://127.0.0.1:8554/burgi_cam";
#input_args = "preset-rtsp-restream";
roles = [
"record"
"rtmp"
];
}
{
path = "rtsp://admin:XpkFk5Df912VWSwM@10.0.42.60:554/Streaming/Channels/102/?transportmode=unicast";
#path = "rtsp://127.0.0.1:8554/burgi_cam_sub";
#input_args = "preset-rtsp-restream";
roles = [
"detect"
];
}
];
};
detect = {
width = 1280;
height = 720;
fps = 5;
};
};
objects.track = [ "person" "dog" ];
mqtt = {
enabled = true;
host = "127.0.0.1";
user = "frigate";
password = "rDAnboXJhW8K2OJlPI5KpZhggPJusA==";
};
rtmp.enabled = true;
#detectors.coral = {
# type = "edgetpu";
# device = "usb";
#};
};
};
}

View file

@ -1,10 +1,13 @@
{ config, pkgs, lib, ... }: {
with lib; config,
let pkgs,
lib,
...
}:
with lib; let
psCfg = config.pub-solar; psCfg = config.pub-solar;
xdg = config.home-manager.users."${psCfg.user.name}".xdg; xdg = config.home-manager.users."${psCfg.user.name}".xdg;
in in {
{
imports = [ imports = [
./configuration.nix ./configuration.nix
]; ];

View file

@ -1,20 +1,24 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
imports = config,
[ (modulesPath + "/installer/scan/not-detected.nix") lib,
]; pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "usbhid" "usb_storage" "uas" ]; boot.initrd.availableKernelModules = ["xhci_pci" "usbhid" "usb_storage" "uas"];
boot.initrd.kernelModules = [ ]; boot.initrd.kernelModules = [];
boot.kernelModules = [ ]; boot.kernelModules = [];
boot.extraModulePackages = [ ]; boot.extraModulePackages = [];
boot.kernelPackages = pkgs.linuxPackages_latest; boot.kernelPackages = pkgs.linuxPackages_latest;
boot.supportedFilesystems = [ ]; boot.supportedFilesystems = [];
boot.loader.grub = { boot.loader.grub = {
enable = true; enable = true;
@ -36,19 +40,19 @@
bypassWorkqueues = true; bypassWorkqueues = true;
}; };
fileSystems."/" = fileSystems."/" = {
{ device = "/dev/disk/by-label/root"; device = "/dev/disk/by-label/root";
fsType = "ext4"; fsType = "ext4";
}; };
fileSystems."/boot" = fileSystems."/boot" = {
{ device = "/dev/disk/by-label/boot"; device = "/dev/disk/by-label/boot";
fsType = "vfat"; fsType = "vfat";
}; };
swapDevices = swapDevices = [
[ { device = "/dev/disk/by-label/swap"; } {device = "/dev/disk/by-label/swap";}
]; ];
networking.interfaces.enabcm6e4ei0.useDHCP = true; networking.interfaces.enabcm6e4ei0.useDHCP = true;

View file

@ -2,8 +2,12 @@
self, self,
config, config,
pkgs, pkgs,
python3Packages,
inputs,
... ...
}: { }:
{
age.secrets.home-assistant_giggles_secrets = { age.secrets.home-assistant_giggles_secrets = {
file = "${self}/secrets/home-assistant_giggles_secrets.age"; file = "${self}/secrets/home-assistant_giggles_secrets.age";
path = "${config.services.home-assistant.configDir}/secrets.yaml"; path = "${config.services.home-assistant.configDir}/secrets.yaml";
@ -12,14 +16,55 @@
mode = "0644"; mode = "0644";
}; };
users.users."hass".extraGroups = ["dialout"];
pub-solar.home-assistant = { pub-solar.home-assistant = {
enable = true; enable = true;
extraComponents = ["met"]; extraComponents = [
extraPackages = python3Packages: "default_config"
with python3Packages; [ "homeassistant_hardware"
"homeassistant_sky_connect"
"apcupsd"
"androidtv"
"cast"
"esphome"
"homekit_controller"
"icloud"
"ipp"
"luci"
"met"
"python_script"
"rpi_power"
"shopping_list"
"spotify"
"tasmota"
"unifi"
"upnp"
"vacuum"
"xiaomi_aqara"
"xiaomi_miio"
"zeroconf"
];
extraPackages = python311Packages:
with python311Packages; [
# esphome
aiodiscover
scapy
# deutsche bahn
schiene
# dwd
dwdwfsapi
# hacs # hacs
aiogithubapi aiogithubapi
# philips_airpurifier_coap
(callPackage ./aioairctrl.nix {})
# totop # totop
pyotp pyotp
]; ];
@ -27,11 +72,20 @@
config = { config = {
homeassistant = { homeassistant = {
name = "Wohnung"; name = "Wohnung";
time_zone = "Europe/Berlin";
country = "DE";
currency = "EUR";
language = "de";
temperature_unit = "C"; temperature_unit = "C";
time_zone = "Europe/Berlin";
unit_system = "metric"; unit_system = "metric";
latitude = "52.31501090166047"; latitude = "52.31501090166047";
longitude = "8.910633035293603"; longitude = "8.910633035293603";
elevation = "59";
external_url = "https://ha2.gssws.de";
internal_url = "http://192.168.42.11:8123";
}; };
http = { http = {
ip_ban_enabled = false; ip_ban_enabled = false;
@ -44,28 +98,86 @@
]; ];
}; };
default_config = {};
energy = {}; energy = {};
frontend = {};
history = {}; "automation ui" = "!include automations.yaml";
map = {};
my = {};
mobile_app = {};
network = {};
notify = {};
person = {};
ssdp = {};
sun = {};
system_health = {};
zeroconf = {};
device_tracker = [ device_tracker = [
{ {
platform = "luci"; platform = "luci";
host = "192.168.8.1"; host = "192.168.42.1";
username = "!secret router_admin_username"; username = "!secret router_admin_username";
password = "!secret router_admin_password"; password = "!secret router_admin_password";
} }
]; ];
python_script = {};
waste_collection_schedule = {
sources = [
{
name = "jumomind_de";
args = {
service_id = "sbm";
city = "Minden";
street = "Schwerinstr.";
house_number = "17b";
};
}
];
};
zone = [
{
name = "Home";
latitude = "52.31501090166047";
longitude = "8.910633035293603";
radius = "30";
}
{
name = "DKSB";
latitude = "52.31249954762553";
longitude = "8.910920619964601";
radius = "60";
}
{
name = "Hainweg";
latitude = "52.3176809501406";
longitude = "8.890610933303835";
radius = "60";
}
{
name = "Lande";
latitude = "52.35688908037632";
longitude = "8.898582458496096";
radius = "87";
}
{
name = "Rürups";
latitude = "52.317152702118655";
longitude = "8.89446449221293";
radius = "70";
}
{
name = "Schule";
latitude = "52.30213492276748";
longitude = "8.88126075267792";
radius = "200";
}
{
name = "Sokos";
latitude = "50.92777444599559";
longitude = "6.583169284373658";
radius = "50";
}
{
name = "Wohnung Aachen";
latitude = "50.7800954893528";
longitude = "6.154607534408569";
radius = "13";
}
];
}; };
mqtt = { mqtt = {
@ -83,6 +195,49 @@
]; ];
hashedPassword = "$7$101$M0Q/s9ReWPaMy+pT$Y8t9DwmW3y74lyvYrCE+sqEcz9yGG9VaHw8vt4wVZgUVVV9muY00ymjkwsTNtaTIlnQyB7z7POPLT3PURtQfeg=="; hashedPassword = "$7$101$M0Q/s9ReWPaMy+pT$Y8t9DwmW3y74lyvYrCE+sqEcz9yGG9VaHw8vt4wVZgUVVV9muY00ymjkwsTNtaTIlnQyB7z7POPLT3PURtQfeg==";
}; };
frigate = {
acl = [
"readwrite #"
];
hashedPassword = "$7$101$BZvoqhiaWo8TbFEv$KlE8XiE9dhfNV50SoUiBjTgnvSRaCwWdouuVcN4ZeHkR7/4JufQ7adW0VhVmtpv+6V9KOPDlN3wRaV+5eVlF3Q==";
};
nuki_wohnung = {
acl = [
"readwrite #"
];
hashedPassword = "$7$101$21wWveYvOyQKNuhd$rXD8d4F+Wf4k6LDkM09bsfkQfc+iXakRaH2sygYgOQqfrJ5Egt8D+9LVKa9ZQ12HLPSHDo0bP8ygVmY6iVJCjQ==";
};
poffertjes = {
acl = [
"readwrite #"
];
hashedPassword = "$7$101$n5J9RKGzFF7bOsOH$YNPQawxsfuDZk/N6NrNzkE5rEfTRlCW5Fjpk6kgwyTg4C6Peyz4I79ii4UMSANJ8DFNsPRL1KohCcXK07SMW2w==";
};
shelly1_flur_deckenlicht = {
acl = [
"readwrite #"
];
hashedPassword = "$7$101$n0PyELB9214BiluQ$P24lJlXDpKLaGSerrp51z5UUl3wYSek9SbJN+buqoS9acrCn7s3mtSLZfeMP0JT8zXx83GJrNwlDaA0BOu00xg==";
};
shelly25_abstellraum = {
acl = [
"readwrite #"
];
hashedPassword = "$7$101$n9IcybeGEAhnoWv5$RSnkEJFgDsrKUzEaLfNIa/5v4gkTMZSAq2bb7KzWSG6zaufHdnvtDZT+q7dZ3pkBFXndKtoelmuvm7XJLJC1mg==";
};
shelly25_badezimmer = {
acl = [
"readwrite #"
];
hashedPassword = "$7$101$PNWBSZUE4Ar5dOhx$2u6dneedx7OLOjH1auoax2AC1GP4oVcXe4OAmO3riNpzXZF9V1cJ7k/GREx9/vO/ONt5PuUygilk3X4SIYnf9A==";
};
tasmota_wohnzimmer_tv_steckdosenleiste = {
acl = [
"readwrite #"
];
hashedPassword = "$7$101$cywQWWzxPUUpUqdC$Q9tjqE4bW0VaNMVKIuts/wuyFetC//PyLVcRtpaK02HxwlTPY7jWivXUBA/t8l0wGZsS8lsiOIAu8e6bHb+7Xw==";
};
}; };
}; };

View file

@ -1,11 +1,12 @@
{ pkgs, config, ... }: {
pkgs,
let config,
...
}: let
serviceAddress = "10.10.41.11"; serviceAddress = "10.10.41.11";
containerStateDir = "/data"; containerStateDir = "/data";
hostStateDir = "/srv/container/lrad"; hostStateDir = "/srv/container/lrad";
in in {
{
containers."lrad" = { containers."lrad" = {
privateNetwork = true; privateNetwork = true;
hostAddress = "10.10.41.1"; hostAddress = "10.10.41.1";
@ -16,8 +17,12 @@ in
isReadOnly = false; isReadOnly = false;
}; };
config = { config, pkgs, ... }: { config = {
networking.firewall.allowedTCPPorts = [ 63080 ]; config,
pkgs,
...
}: {
networking.firewall.allowedTCPPorts = [63080];
#users.users."tang".isSystemUser = true; #users.users."tang".isSystemUser = true;
@ -35,13 +40,12 @@ in
systemd.sockets."tangd" = { systemd.sockets."tangd" = {
enable = true; enable = true;
listenStreams = [ "63080" ]; listenStreams = ["63080"];
wantedBy = [ "sockets.target" ]; wantedBy = ["sockets.target"];
socketConfig = { socketConfig = {
Accept = true; Accept = true;
}; };
}; };
}; };
}; };
} }

View file

@ -0,0 +1,81 @@
{...}: {
networking.firewall.checkReversePath = false;
networking.firewall.allowedUDPPorts = [67]; # allow dhcp request
services.dnsmasq = {
enable = true;
settings = {
interface = [
"vlan101" # network
"vlan102" # iot
"vlan104" # media
];
no-resolv = true;
no-poll = true;
server = [
"1.1.1.1"
"9.9.9.9"
];
dhcp-authoritative = true;
dhcp-host = [
# vlan101
"18:e8:29:c6:29:84,ap-caro,10.0.42.21" # ap-caro
"e4:38:83:e7:00:10,ap-hendrik,10.0.42.22" # ap-hendrik
"e4:38:83:e7:0a:c4,ap-wohnzimmer,10.0.42.23" # ap-wohnzimmer
# vlan102
"38:1a:52:04:37:d8,printer,172.16.0.15" # printer
"3c:e9:0e:87:d2:1c,nspanel-hendrik,172.16.0.21" # nspanel_hendrik
"3c:e9:0e:87:ef:d0,nspanel-schlafzimmer,172.16.0.22" # nspanel_schlafzimmer
"98:0c:33:fe:3d:a8,nuki-wohnung,172.16.0.23" # nuki_wohnung
"c8:5c:cc:5c:54:06,presence-wohnzimmer,172.16.0.24" # presence_wohnzimmer
"c8:5c:cc:5c:28:7b,presence-hendrik,172.16.0.25" # presence_hendrik
"04:78:63:7f:0e:bb,airpurifier-wohnzimmer,172.16.0.26" # airpurifier_wohnzimmer
"48:e7:29:c1:a3:f0,nspanel-caro,172.16.0.27" # nspanel_caro
"5c:c5:63:eb:e8:b8,poffertjes,172.16.0.28" # poffertjes
"d0:ba:e4:e7:7d:d5,airpurifier-hendrik,172.16.0.29" # airpurifier_hendrik
"98:f4:ab:f2:43:98,shelly1-flur-deckenlicht,172.16.0.30" # shelly1 flur deckenlicht
"a4:cf:12:ba:72:c1,shelly25-abstellraum,172.16.0.31" # shelly25 abstellraum
"c8:2b:96:11:10:46,shelly25-badezimmer,172.16.0.32" # shelly25 badezimmer
"24:62:ab:41:06:f2,tasmota-tv-steckdosenleiste,172.16.0.33" # tasmota-tv-steckdosenleiste
# vlan104
"30:58:90:1a:3b:ef,box-hendrik,10.42.0.21" # box_hendrik
"30:58:90:19:b5:03,box-schlafzimmer,10.42.0.22" # box_schlafzimmer
"30:58:90:28:7e:30,box-esstisch,10.42.0.23" # box_esstisch
"1c:53:f9:23:d7:c4,nh-hendrik,10.42.0.31" # nh_hendrik
"1c:53:f9:14:7b:65,nh-kueche,10.42.0.32" # nh_kueche
"1c:53:f9:1c:9e:22,nh-wohnzimmer,10.42.0.33" # nh_wohnzimmer
"20:1f:3b:96:9f:29,nm-schlafzimmer,10.42.0.34" # nm_schlafzimmer
"6c:ad:f8:73:a0:94,cc-wohnzimmer,10.42.0.41" # cc_wohnzimmer
];
dhcp-range = [
"vlan101,10.0.42.51,10.0.42.100"
"vlan102,172.16.0.101,172.16.0.150"
"vlan104,10.42.0.51,10.42.0.100"
];
dhcp-option = [
"option:dns-server,1.1.1.1"
"option:mtu,1460"
# vlan101
"vlan101,option:router,10.0.42.1"
# vlan102
"vlan102,option:router,172.16.0.1"
# vlan104
"vlan104,option:router,10.42.0.1"
];
};
};
}

55
hosts/giggles/network.nix Normal file
View file

@ -0,0 +1,55 @@
{lib, ...}: {
networking = {
enableIPv6 = false;
useDHCP = false;
vlans = {
vlan101 = {
id = 101;
interface = "eth0";
}; # network vlan
vlan102 = {
id = 102;
interface = "eth0";
}; # iot vlan
vlan104 = {
id = 104;
interface = "eth0";
}; # media vlan
};
interfaces = {
eth0 = {
useDHCP = true;
mtu = 1460;
};
vlan101 = {
mtu = 1460;
ipv4.addresses = [
{
address = "10.0.42.11";
prefixLength = 24;
}
];
};
vlan102 = {
mtu = 1460;
ipv4.addresses = [
{
address = "172.16.0.11";
prefixLength = 24;
}
];
};
vlan104 = {
mtu = 1460;
ipv4.addresses = [
{
address = "10.42.0.11";
prefixLength = 24;
}
];
};
};
networkmanager.enable = lib.mkForce false;
};
}

View file

@ -1,12 +1,13 @@
{ pkgs, config, ... }: {
pkgs,
let config,
...
}: let
containerStateDir = "/data"; containerStateDir = "/data";
hostStateDir = "/opt/tangd"; hostStateDir = "/opt/tangd";
servicePort = 8081; servicePort = 8081;
in in {
{ networking.firewall.allowedTCPPorts = [servicePort];
networking.firewall.allowedTCPPorts = [ servicePort ];
containers."tang" = { containers."tang" = {
autoStart = true; autoStart = true;
@ -16,17 +17,21 @@ in
isReadOnly = false; isReadOnly = false;
}; };
config = { config, pkgs, ... }: { config = {
config,
pkgs,
...
}: {
networking.firewall.enable = false; networking.firewall.enable = false;
users.groups."_tang" = {} ; users.groups."_tang" = {};
users.users."_tang" = { users.users."_tang" = {
group = "_tang"; group = "_tang";
isSystemUser = true; isSystemUser = true;
}; };
environment.systemPackages = with pkgs; [ jose tang ]; environment.systemPackages = with pkgs; [jose tang];
systemd.services."tangd@" = { systemd.services."tangd@" = {
enable = true; enable = true;
@ -40,8 +45,8 @@ in
systemd.sockets."tangd" = { systemd.sockets."tangd" = {
enable = true; enable = true;
listenStreams = [ "${toString servicePort}" ]; listenStreams = ["${toString servicePort}"];
wantedBy = [ "sockets.target" ]; wantedBy = ["sockets.target"];
socketConfig = { socketConfig = {
Accept = true; Accept = true;
}; };
@ -49,6 +54,5 @@ in
system.stateVersion = "22.11"; system.stateVersion = "22.11";
}; };
}; };
} }

11
hosts/giggles/unifi.nix Normal file
View file

@ -0,0 +1,11 @@
{pkgs, ...}:
{
networking.firewall.allowedTCPPorts = [8443]; # open unifi web interface port
services.unifi = {
enable = true;
unifiPackage = pkgs.unifi7;
openFirewall = true;
};
}