latest changes
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Hendrik Sokolowski 2023-11-11 01:12:57 +01:00
parent 81d7598bd7
commit 6c7d9704bd
39 changed files with 1344 additions and 497 deletions

View file

@ -3,10 +3,10 @@
"agenix": {
"inputs": {
"darwin": [
"nix-darwin"
"darwin"
],
"nixpkgs": [
"nixpkgs"
"nixos"
]
},
"locked": {
@ -23,13 +23,33 @@
"type": "github"
}
},
"deploy-rs": {
"darwin": {
"inputs": {
"nixpkgs": [
"nixos"
]
},
"locked": {
"lastModified": 1699437533,
"narHash": "sha256-lMoPz9c89CpPVuJ95OFFesM9JagCF0soGbQatj3ZhqM=",
"owner": "LnL7",
"repo": "nix-darwin",
"rev": "eb2b9b64238349bd351561e32e260cac15db6f9a",
"type": "github"
},
"original": {
"owner": "LnL7",
"repo": "nix-darwin",
"type": "github"
}
},
"deploy": {
"inputs": {
"flake-compat": [
"flake-compat"
],
"nixpkgs": [
"nixpkgs"
"nixos"
],
"utils": "utils"
},
@ -47,6 +67,68 @@
"type": "github"
}
},
"devshell": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"digga",
"nixpkgs"
]
},
"locked": {
"lastModified": 1671489820,
"narHash": "sha256-qoei5HDJ8psd1YUPD7DhbHdhLIT9L2nadscp4Qk37uk=",
"owner": "numtide",
"repo": "devshell",
"rev": "5aa3a8039c68b4bf869327446590f4cdf90bb634",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"digga": {
"inputs": {
"darwin": [
"darwin"
],
"deploy": [
"deploy"
],
"devshell": "devshell",
"flake-compat": [
"flake-compat"
],
"flake-utils": "flake-utils_2",
"flake-utils-plus": "flake-utils-plus",
"home-manager": [
"home"
],
"nixlib": [
"nixos"
],
"nixpkgs": [
"nixos"
],
"nixpkgs-unstable": "nixpkgs-unstable"
},
"locked": {
"lastModified": 1674947971,
"narHash": "sha256-6gKqegJHs72jnfFP9g2sihl4fIZgtKgKuqU2rCkIdGY=",
"owner": "pub-solar",
"repo": "digga",
"rev": "2da608bd8afb48afef82c6b1b6d852a36094a497",
"type": "github"
},
"original": {
"owner": "pub-solar",
"ref": "fix/bootstrap-iso",
"repo": "digga",
"type": "github"
}
},
"factorio-pr": {
"locked": {
"lastModified": 1676729025,
@ -66,11 +148,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
@ -79,28 +161,78 @@
"type": "github"
}
},
"flake-parts": {
"flake-utils": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils-plus": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
"flake-utils": [
"digga",
"flake-utils"
]
},
"locked": {
"lastModified": 1698882062,
"narHash": "sha256-HkhafUayIqxXyHH1X8d9RDl1M2CkFgZLjKD3MzabiEo=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "8c9fa2545007b49a5db5f650ae91f227672c3877",
"lastModified": 1654029967,
"narHash": "sha256-my3GQ3mQIw/1f6GPV1IhUZrcYQSWh0YJAMPNBjhXJDw=",
"owner": "gytis-ivaskevicius",
"repo": "flake-utils-plus",
"rev": "6271cf3842ff9c8a9af9e3508c547f86bc77d199",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"owner": "gytis-ivaskevicius",
"ref": "refs/pull/120/head",
"repo": "flake-utils-plus",
"type": "github"
}
},
"home-manager": {
"flake-utils_2": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"fork": {
"locked": {
"lastModified": 1692960587,
"narHash": "sha256-39SKGdhn8jKKkdqhULbCvQOpdUPE9NNJpy5HTB++Jvg=",
"owner": "teutat3s",
"repo": "nixpkgs",
"rev": "312709dd70684f52496580e533d58645526b1c90",
"type": "github"
},
"original": {
"owner": "teutat3s",
"ref": "nvfetcher-fix",
"repo": "nixpkgs",
"type": "github"
}
},
"home": {
"inputs": {
"nixpkgs": [
"nixpkgs"
"nixos"
]
},
"locked": {
@ -118,18 +250,18 @@
"type": "github"
}
},
"master": {
"latest": {
"locked": {
"lastModified": 1699660051,
"narHash": "sha256-aAdBhxHIiD0Y2LGqidTMw2ywKofRza8RwVqQodnsZIA=",
"lastModified": 1699099776,
"narHash": "sha256-X09iKJ27mGsGambGfkKzqvw5esP1L/Rf8H3u3fCqIiU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "02f05fceedefc00f90ecf27bda9e94ed2318aa50",
"rev": "85f1ba3e51676fa8cc604a3d863d729026a6b8eb",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "master",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
@ -137,7 +269,7 @@
"musnix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
"nixos"
]
},
"locked": {
@ -154,58 +286,7 @@
"type": "github"
}
},
"nix-darwin": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1699569089,
"narHash": "sha256-MdOnyXrmMdVU9o7GpcbWKgehoK9L76ihp8rTikPcC1k=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "c8f385766ba076a096caa794309c40f89894d88a",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"nixos-flake": {
"locked": {
"lastModified": 1698598244,
"narHash": "sha256-YbvPFt+9CbCiqnuS0dTx+P+W1YRCqzhLXen94sef3Kk=",
"owner": "srid",
"repo": "nixos-flake",
"rev": "f6b7757ad88483afca306c9f3bf387887fba7284",
"type": "github"
},
"original": {
"owner": "srid",
"repo": "nixos-flake",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1683965003,
"narHash": "sha256-DrzSdOnLv/yFBvS2FqmwBA2xIbN/Lny/WlxHyoLR9zE=",
"owner": "nixos",
"repo": "nixos-hardware",
"rev": "81cd886719e10d4822b2a6caa96e95d56cc915ef",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs": {
"nixos": {
"locked": {
"lastModified": 1699291058,
"narHash": "sha256-5ggduoaAMPHUy4riL+OrlAZE14Kh7JWX4oLEs22ZqfU=",
@ -221,43 +302,22 @@
"type": "github"
}
},
"nixpkgs-hensoko": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"nixos-hardware": {
"locked": {
"lastModified": 1666884246,
"narHash": "sha256-nSiYCIlMiYodY7GPCFPMF6YHVS2RM/XQZwn2Zrhu2eU=",
"ref": "master",
"rev": "f1863fb8e3866c1559ca885e1b319ea82baecdbb",
"revCount": 23,
"type": "git",
"url": "https://git.b12f.io/hensoko/nixpkgs"
},
"original": {
"type": "git",
"url": "https://git.b12f.io/hensoko/nixpkgs"
}
},
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1698611440,
"narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735",
"lastModified": 1699159446,
"narHash": "sha256-cL63IjsbPl2otS7R4kdXbVOJOXYMpGw5KGZoWgdCuCM=",
"owner": "nixos",
"repo": "nixos-hardware",
"rev": "627bc9b88256379578885a7028c9e791c29fb581",
"type": "github"
},
"original": {
"dir": "lib",
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"owner": "nixos",
"repo": "nixos-hardware",
"type": "github"
}
},
"nixpkgs_2": {
"nixpkgs": {
"locked": {
"lastModified": 1654994491,
"narHash": "sha256-HFu3HTFFFcZSKImuiki3q+MLvcc85hRgYvW+sXmH8LE=",
@ -273,31 +333,31 @@
"type": "github"
}
},
"root": {
"nixpkgs-hensoko": {
"inputs": {
"agenix": "agenix",
"deploy-rs": "deploy-rs",
"factorio-pr": "factorio-pr",
"flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"home-manager": "home-manager",
"master": "master",
"musnix": "musnix",
"nix-darwin": "nix-darwin",
"nixos-flake": "nixos-flake",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs",
"nixpkgs-hensoko": "nixpkgs-hensoko",
"unstable": "unstable"
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1666884246,
"narHash": "sha256-nSiYCIlMiYodY7GPCFPMF6YHVS2RM/XQZwn2Zrhu2eU=",
"ref": "master",
"rev": "f1863fb8e3866c1559ca885e1b319ea82baecdbb",
"revCount": 23,
"type": "git",
"url": "https://git.b12f.io/hensoko/nixpkgs"
},
"original": {
"type": "git",
"url": "https://git.b12f.io/hensoko/nixpkgs"
}
},
"unstable": {
"nixpkgs-unstable": {
"locked": {
"lastModified": 1699099776,
"narHash": "sha256-X09iKJ27mGsGambGfkKzqvw5esP1L/Rf8H3u3fCqIiU=",
"lastModified": 1672791794,
"narHash": "sha256-mqGPpGmwap0Wfsf3o2b6qHJW1w2kk/I6cGCGIU+3t6o=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "85f1ba3e51676fa8cc604a3d863d729026a6b8eb",
"rev": "9813adc7f7c0edd738c6bdd8431439688bb0cb3d",
"type": "github"
},
"original": {
@ -307,6 +367,23 @@
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"darwin": "darwin",
"deploy": "deploy",
"digga": "digga",
"factorio-pr": "factorio-pr",
"flake-compat": "flake-compat",
"fork": "fork",
"home": "home",
"latest": "latest",
"musnix": "musnix",
"nixos": "nixos",
"nixos-hardware": "nixos-hardware",
"nixpkgs-hensoko": "nixpkgs-hensoko"
}
},
"utils": {
"locked": {
"lastModified": 1667395993,

View file

@ -6,6 +6,8 @@
}: {
boot.loader.systemd-boot.enable = lib.mkForce false;
#pub-solar.concourse-server.enable = true;
time.timeZone = "Europe/Berlin";
services.openssh.ports = [2222];

40
hosts/chonk/garage.nix Normal file
View file

@ -0,0 +1,40 @@
{ pkgs, config, lib, self, ... }:
{
age.secrets.garage_rpc_token = {
file = "${self}/secrets/chonk_garage_rpc_secret.age";
owner = "garage";
group = "garage";
};
networking.firewall.interfaces.wg0.allowedTCPPorts = [ 3900 3901 ];
users.groups.garage = {};
users.users.garage = {
group = "garage";
isSystemUser = true;
};
# overwrite dynamicuser
systemd.services.garage.serviceConfig = {
User = "garage";
Group = "garage";
DynamicUser = false;
StateDirectory = lib.mkForce null;
};
services.garage = {
enable = true;
package = pkgs.garage_0_8;
settings = {
replication_mode = "1";
rpc_bind_addr = "[::]:3901";
rpc_secret_file = config.age.secrets.garage_rpc_token.path;
s3_api = {
api_bind_addr = "[::]:3900";
s3_region = "garage";
root_domain = ".s3.gssws.de";
};
};
};
}

View file

@ -8,30 +8,35 @@
...
}: {
boot.initrd.availableKernelModules = ["ehci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"];
boot.initrd.kernelModules = ["raid1"];
boot.kernelModules = ["kvm-intel"];
boot.extraModulePackages = [];
boot.extraModprobeConfig = "options kvm_intel nested=1";
boot.initrd.luks.forceLuksSupportInInitrd = true;
boot.kernelPackages = pkgs.linuxPackages_6_1;
boot.kernelParams = [ "ip=80.244.242.2::80.244.242.1:255.255.255.248:chonk::off" ];
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/disk/by-id/usb-SanDisk_Cruzer_Blade_03025429121421051300-0:0";
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-uuid/9e13c8ea-96d3-45b1-85f4-d1a61233da6f";
#keyFile = "/dev/disk/by-id/usb-SanDisk_Cruzer_Blade_04020116120721075123-0:0-part1";
#fallbackToPassword = true;
#bypassWorkqueues = true;
boot.loader.grub = {
enable = true;
device = "/dev/disk/by-id/usb-SanDisk_Cruzer_Blade_03025429121421051300-0:0";
};
boot.initrd.network = {
boot.supportedFilesystems = [ "zfs" ];
boot.initrd = {
systemd.enable = true;
luks = {
forceLuksSupportInInitrd = true;
devices."cryptroot" = {
device = "/dev/disk/by-uuid/9e13c8ea-96d3-45b1-85f4-d1a61233da6f";
};
};
network = {
enable = true;
ssh = {
enable = true;
port = 22;
port = 2234;
authorizedKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAqkqMYgncrnczcW/0PY+Z+FmNXXpgw6D9JWTTwiainy hensoko@hensoko-tp-work"];
hostKeys = [/etc/secrets/initrd/ssh_host_ed25519_key];
};
@ -39,30 +44,30 @@
echo 'cryptsetup-askpass' >> /root/.profile
'';
};
boot.initrd.systemd.enable = true;
boot.initrd.services.swraid = {
services.swraid = {
enable = true;
mdadmConf = ''
ARRAY /dev/md/0 metadata=1.2 name=data:0 UUID=1156202f:835af09b:2e05e02a:a1869d1c
ARRAY /dev/md/debian:0 metadata=1.2 name=debian:0 UUID=1156202f:835af09b:2e05e02a:a1869d1c
'';
};
};
fileSystems."/" = {
fileSystems = {
"/" = {
device = "/dev/disk/by-label/root";
fsType = "ext4";
};
fileSystems."/boot" = {
"/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "ext4";
};
fileSystems."/mnt/internal" = {
"/mnt/internal" = {
device = "/dev/disk/by-uuid/3563f624-f8ed-4664-95d0-ca8b9db1c60a";
fsType = "ext4";
};
};
swapDevices = [
{device = "/dev/disk/by-label/swap";}
@ -78,6 +83,7 @@
};
networking = {
hostId = "c418ba82";
defaultGateway = {
address = "80.244.242.1";
interface = "br0";

View file

@ -38,6 +38,7 @@
"data.gssws.de"
"mail.hosting.de"
"blog.fefe.de"
# hosting.de
"ovh2.goekal.de"
"83.151.16.16"
@ -59,6 +60,13 @@
"95.129.51.51"
"185.11.137.122"
"79.140.41.12"
# pub.solar
"pub.solar"
"git.pub.solar"
"auth.pub.solar"
"cloud.pub.solar"
"collabora.pub.solar"
];
};
};

View file

@ -7,7 +7,7 @@
pub-solar.home-assistant = {
enable = true;
extraComponents = ["androidtv" "fritz" "fritzbox" "fritzbox_callmonitor" "met" "mqtt"];
extraComponents = ["androidtv" "brother" "ffmpeg" "fritz" "fritzbox" "fritzbox_callmonitor" "met" "mqtt" "zeroconf"];
extraPackages = python3Packages:
with python3Packages; [
# androidtv
@ -81,19 +81,16 @@
];
};
default_config = {};
energy = {};
frontend = {};
history = {};
"automation ui" = "!include automations.yaml";
map = {};
my = {};
mobile_app = {};
network = {};
notify = {};
person = {};
ssdp = {};
sun = {};
system_health = {};
zeroconf = {};
};
};
}

View file

@ -16,6 +16,16 @@ in
networking.firewall.allowedTCPPorts = [ resticListenPort ];
systemd.mounts = [
{
what = "/dev/mapper/crypt-backup";
where = "/opt/backup/hdd";
type = "ext4";
}
];
systemd.services."container@backup".unitConfig.RequiresMountsFor = ["/opt/backup/hdd"];
containers."backup" = {
autoStart = true;
ephemeral = true;
@ -52,26 +62,4 @@ in
system.stateVersion = "22.11";
};
};
#virtualisation.oci-containers = {
# backend = "docker";
# containers = {
# backup-ssh = {
# image = "linuxserver/openssh-server:arm64v8-latest";
# ports = [ "32222:2222" ];
#
# environment = {
# PUBLIC_KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOTpA7OHfZhl1wsbvydLNMtMx4q64fz+ojIAZpVUJEMI root@cube";
# USER_NAME = "backup";
# TZ = "Europe/Berlin";
# PUID = "911";
# PGID = "911";
# };
#
# volumes = [
# "/opt/backup/hdd/restic:/data/hdd/restic"
# ];
# };
# };
#};
}

View file

@ -11,6 +11,9 @@
./backup.nix
./home-controller.nix
./paperless.nix
./owntone.nix
./jellyfin.nix
./photoprism.nix
];
time.timeZone = "Europe/Berlin";
@ -18,13 +21,46 @@
boot.plymouth.enable = lib.mkForce false;
pub-solar.nextcloud.enable = lib.mkForce false;
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
networking.interfaces.wlan0.useDHCP = false;
networking = {
vlans = {
vlan102 = {
id = 102;
interface = "eth0";
}; # iot vlan
vlan104 = {
id = 104;
interface = "eth0";
}; # media vlan
};
interfaces = {
eth0 = {
useDHCP = true;
mtu = 1460;
};
vlan102 = {
mtu = 1460;
ipv4.addresses = [{
address = "172.16.0.12";
prefixLength = 24;
}];
};
vlan104 = {
mtu = 1460;
ipv4.addresses = [{
address = "10.42.0.12";
prefixLength = 24;
}];
};
};
};
networking.networkmanager.enable = false;
networking.firewall.allowedTCPPorts = [3689];
networking.firewall.allowedUDPPorts = [1900];
networking.firewall = {
allowedUDPPorts = [1900];
};
virtualisation.podman.enable = true;

View file

@ -13,7 +13,7 @@
];
boot.initrd.availableKernelModules = ["xhci_pci" "usbhid" "usb_storage" "uas"];
boot.kernelPackages = pkgs.linuxPackages_6_1;
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.kernelParams = ["usb-storage.quirks=2109:0716:ouw,174c:55aa:u,2109:2813:ouw,2109:0813:ouw"];
boot.loader = {
@ -52,6 +52,19 @@
{device = "/dev/disk/by-label/swap";}
];
hardware = {
raspberry-pi."4".apply-overlays-dtmerge.enable = true;
deviceTree = {
enable = true;
filter = "*rpi-4-*.dtb";
};
};
environment.systemPackages = with pkgs; [
libraspberrypi
raspberrypi-eeprom
];
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
}

41
hosts/cox/jellyfin.nix Normal file
View file

@ -0,0 +1,41 @@
{ config, pkgs, ... }:
{
#boot.kernelModules = [ "v4l2loopback" ];
#boot.extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
systemd.mounts = [
{
what = "/dev/mapper/crypt-media";
where = "/opt/media";
type = "ext4";
}
{
what = "/dev/mapper/crypt-movies";
where = "/opt/media/media/video/movies";
type = "ext4";
}
{
what = "/dev/mapper/crypt-tvshows";
where = "/opt/media/media/video/tv-shows";
type = "ext4";
}
];
systemd.services.jellyfin.unitConfig.RequiresMountsFor = [
"/opt/media"
"/opt/media/media/video/movies"
"/opt/media/media/video/tv-shows"
];
users.users.jellyfin.extraGroups = [ "video" ];
environment.systemPackages = [ pkgs.jellyfin-ffmpeg ];
services.jellyfin = {
enable = true;
openFirewall = true;
};
}

37
hosts/cox/owntone.nix Normal file
View file

@ -0,0 +1,37 @@
{ config, ... }:
let
owntoneConfigDir = "/opt/media/config/owntone";
owntoneMusicDir = "/opt/media/media";
in
{
networking.firewall.allowedTCPPorts = [
3688 # websocket
3689 # http
6600 # mpd
13988 # airplay
13989 # airplay
];
systemd.services."podman-owntone".unitConfig.RequiresMountsFor = [
owntoneConfigDir
owntoneMusicDir
];
virtualisation.oci-containers.containers."owntone" = {
image = "linuxserver/daapd";
autoStart = true;
extraOptions = ["--network=host"];
environment = {
PUID = "1000";
PGID = "1000";
TZ = "Europe/Berlin";
};
volumes = [
"${owntoneConfigDir}:/config"
"${owntoneMusicDir}:/music"
];
};
}

View file

@ -3,6 +3,14 @@
config,
...
}: {
systemd.mounts = [
{
what = "/dev/mapper/crypt-documents";
where = "/opt/documents";
type = "ext4";
}
];
pub-solar.paperless = {
enable = true;
hostStateDir = "/opt/documents/paperless";

37
hosts/cox/photoprism.nix Normal file
View file

@ -0,0 +1,37 @@
{ lib, ... }:
{
systemd.services.photoprism = {
unitConfig.RequiresMountsFor = [ "/opt/media/photoprism" ];
serviceConfig = {
DynamicUser = lib.mkForce false;
User = "photoprism";
Group = "photoprism";
};
};
services.nginx.virtualHosts."cox.lan".locations."/photoprism" = {
proxyPass = "http://127.0.0.1:18899";
proxyWebsockets = true;
};
users.users.photoprism = {
group = "photoprism";
isSystemUser = true;
};
users.groups.photoprism = {};
services.photoprism = {
enable = true;
originalsPath = "/opt/media/photoprism/originals";
storagePath = "/opt/media/photoprism/data";
importPath = "/opt/media/photoprism/import";
port = 18899;
address = "127.0.0.1";
settings = {
PHOTOPRISM_DEFAULT_LOCALE = "de";
PHOTOPRISM_SITE_URL = "http://cox.lan/photoprism";
PHOTOPRISM_TRUSTED_PROXY = "127.0.0.1/8";
};
};
}

View file

@ -13,7 +13,9 @@ python311.pkgs.buildPythonPackage rec {
pythonImportsCheck = [ "pytest" "flake8" ];
propagatedBuildInputs = with python311.pkgs; [
pytest
aiodns
aiohttp
flake8
pytest
];
}

View file

@ -1,5 +1,8 @@
{ ... }:
let
camIp = "10.0.42.31";
in
{
networking.firewall.allowedTCPPorts = [80 5000 8554 8555];
@ -8,11 +11,11 @@
# settings = {
# streams = {
# burgi_cam = [
# "rtsp://admin:XpkFk5Df912VWSwM@10.0.42.60:554/Streaming/Channels/101/?transportmode=unicast"
# "rtsp://admin:XpkFk5Df912VWSwM@${camIp}: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"
# "rtsp://admin:XpkFk5Df912VWSwM@${camIp}:554/Streaming/Channels/102/?transportmode=unicast"
# ];
# };
# webrtc = {
@ -22,14 +25,14 @@
#};
services.frigate = {
enable = true;
enable = false;
hostname = "frigate";
settings = {
cameras.burgi = {
ffmpeg = {
inputs = [
{
path = "rtsp://admin:XpkFk5Df912VWSwM@10.0.42.60:554/Streaming/Channels/101/?transportmode=unicast";
path = "rtsp://admin:XpkFk5Df912VWSwM@${camIp}:554/Streaming/Channels/101/?transportmode=unicast";
#path = "rtsp://127.0.0.1:8554/burgi_cam";
#input_args = "preset-rtsp-restream";
roles = [
@ -38,7 +41,7 @@
];
}
{
path = "rtsp://admin:XpkFk5Df912VWSwM@10.0.42.60:554/Streaming/Channels/102/?transportmode=unicast";
path = "rtsp://admin:XpkFk5Df912VWSwM@${camIp}:554/Streaming/Channels/102/?transportmode=unicast";
#path = "rtsp://127.0.0.1:8554/burgi_cam_sub";
#input_args = "preset-rtsp-restream";
roles = [

View file

@ -13,12 +13,7 @@
];
boot.initrd.availableKernelModules = ["xhci_pci" "usbhid" "usb_storage" "uas"];
boot.initrd.kernelModules = [];
boot.kernelModules = [];
boot.extraModulePackages = [];
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.supportedFilesystems = [];
boot.loader.grub = {
enable = true;

View file

@ -0,0 +1,58 @@
{
action = rec {
callService = service: entity: {
service = service;
target.entity_id = entity;
};
delayed = f: delay: [
{delay.seconds = delay;}
(f)
];
turnOn = entity: callService "homeassistant.turn_on" entity;
turnOff = entity: callService "homeassistant.turn_off" entity;
};
condition = {
state = entity: state: {
condition = "state";
entity_id = entity;
state = state;
};
stateNot = entity: state: {
condition = "not";
conditions = [{
condition = "state";
entity_id = entity;
state = state;
}];
};
};
trigger = {
state = entity: {
platform = "state";
entity_id = entity;
};
stateFrom = entity: stateFrom: {
platform = "state";
entity_id = entity;
from = stateFrom;
};
stateTo = entity: stateTo: {
platform = "state";
entity_id = entity;
to = stateTo;
};
stateNotTo = entity: stateNotTo: {
platform = "state";
entity_id = entity;
not_to = stateNotTo;
};
};
}

View file

@ -0,0 +1,26 @@
let
mapSegments = [
{id = 1; name = "Hendrik";}
{id = 2; name = "Schlafzimmer";}
{id = 3; name = "Badezimmer";}
{id = 4; name = "Toilette";}
{id = 5; name = "Flur";}
{id = 6; name = "Vorratsraum";}
{id = 7; name = "Küche";}
{id = 8; name = "Caro";}
{id = 9; name = "Wohnzimmer";}
];
mkCustomize = id: [
{
name = "input_boolean.vacuum_segment_${toString id}";
value = {
room_id = id;
};
}
];
mkCustomizes = ms: builtins.concatMap (s: (mkCustomize s.id)) ms;
in
builtins.listToAttrs (mkCustomizes mapSegments)

View file

@ -0,0 +1,95 @@
let
helper = import ./home-assistant-automation-helpers.nix;
entityLightSleepingHoursNotBefore = "light_sleeping_hours_not_before";
entityLightSleepingHoursNotAfter = "light_sleeping_hours_not_after";
entityLightDarkHoursNotBefore = "light_dark_hours_not_before";
entityLightDarkHoursNotAfter = "light_dark_hours_not_after";
conditionalAutomation = slug: triggers: conditions: actions: {
alias = "Light: ${slug}";
id = "light_automation_${slug}";
trigger = triggers;
condition = conditions;
action = actions;
};
automation = slug: triggers: actions: (conditionalAutomation slug triggers [] actions);
lightOnOnMovement = room: opts: (conditionalAutomation
"${room}_movement_turn_on"
(map (e: helper.trigger.stateTo e "on") opts.triggers)
opts.conditions
(map (e: helper.action.turnOn e) opts.entities)
);
# switch off light when trigger entity switches to off and all given trigger
# entities are not in state "on" (prevents hassle with unavailable state)
lightOffAfterMovement = room: opts: (conditionalAutomation
"${room}_movement_turn_off"
(map (e: helper.trigger.stateTo e "off") opts.triggers)
(map (e: helper.condition.stateNot e "on") opts.triggers)
(map (e: helper.action.turnOff e) opts.entities)
);
outsideSleepingHoursCondition = [{
condition = "not";
conditions = [{
condition = "time";
after = "input_datetime.${entityLightSleepingHoursNotBefore}";
before = "input_datetime.${entityLightSleepingHoursNotAfter}";
}];
}];
withinDarkHoursCondition = [{
condition = "time";
after = "input_datetime.${entityLightDarkHoursNotBefore}";
before = "input_datetime.${entityLightDarkHoursNotAfter}";
}];
roomEntitiesMap = {
# should switch on when its dark outside but not when someone sleeps
flur = {
triggers = ["binary_sensor.pir_flur_1_occupancy" "binary_sensor.pir_flur_2_occupancy"];
entities = ["light.flur_deckenlicht"];
conditions = [] ++ withinDarkHoursCondition ++ outsideSleepingHoursCondition;
};
#kueche = {
# triggers = [];
# entites = [];
# conditions = [] ++ withinDarkHoursCondition;
#};
# should switch on every time
vorratsraum = {
triggers = ["binary_sensor.pir_vorratsraum_occupancy"];
entities = ["light.vorratsraum_deckenlicht"];
conditions = [];
};
};
in
{
input_datetime = {
"${entityLightDarkHoursNotBefore}" = {
name = "TIME Light: Dark hours start not before";
has_date = false;
has_time = true;
};
"${entityLightDarkHoursNotAfter}" = {
name = "TIME Light: Dark hours start not after";
has_date = false;
has_time = true;
};
"${entityLightSleepingHoursNotBefore}" = {
name = "TIME Light: Sleeping hours start not before";
has_date = false;
has_time = true;
};
"${entityLightSleepingHoursNotAfter}" = {
name = "TIME Light: Sleeping hours start not after";
has_date = false;
has_time = true;
};
};
automation = [] ++
(builtins.attrValues (builtins.mapAttrs (r: o: lightOnOnMovement r o) roomEntitiesMap)) ++
(builtins.attrValues (builtins.mapAttrs (r: o: lightOffAfterMovement r o) roomEntitiesMap));
}

View file

@ -0,0 +1,67 @@
let
vacuumName = "IdenticalVeneratedCat";
entityVacuum = "vacuum.valetudo_identicalveneratedcat";
mapSegments = [
{id = 1; name = "Hendrik";}
{id = 2; name = "Schlafzimmer";}
{id = 3; name = "Badezimmer";}
{id = 4; name = "Toilette";}
{id = 5; name = "Flur";}
{id = 6; name = "Vorratsraum";}
{id = 7; name = "Küche";}
{id = 8; name = "Caro";}
{id = 9; name = "Wohnzimmer";}
];
mkBooleanHelper = id: name: [
{
name = "vacuum_segment_${toString id}";
value = {
name = name;
};
}
];
mkBooleanHelpers = ms: builtins.concatMap (s: (mkBooleanHelper s.id s.name)) ms;
in
{
input_boolean = builtins.listToAttrs (mkBooleanHelpers mapSegments);
group = {
vacuum_rooms = {
name = "Vacuum Rooms";
entities = builtins.concatMap (s: ["input_boolean.vacuum_segment_${toString s.id}"]) mapSegments;
};
};
script = {
vacuum_clean_segments = {
mode = "single";
alias = "vacuum_clean_segments";
icon = "mdi:arrow-right";
sequence = [{
service = "script.turn_on";
target = {
entity_id = "script.vacuum_clean_segments_message";
};
data = {
variables = {
segments = "{{expand(\"group.vacuum_rooms\") | selectattr(\"state\",\"eq\",\"on\") | map(attribute=\"attributes.room_id\") | list | to_json}}";
};
};
}];
};
vacuum_clean_segments_message = {
alias = "vacuum_clean_segments_message";
mode = "single";
sequence = [{
service = "mqtt.publish";
data = {
topic = "valetudo/${vacuumName}/MapSegmentationCapability/clean/set";
payload_template = ''{"segment_ids": {{segments}}}'';
};
}];
};
};
}

View file

@ -0,0 +1,246 @@
let
helper = import ./home-assistant-automation-helpers.nix;
entityMediaplayerFireTV = "media_player.wohnzimmer_firetv";
entityMediaplayerXBOX = "media_player.wohnzimmer_xbox";
entityMediaplayerZeppelin = "media_player.wohnzimmer_zeppelin";
entitySwitchTV = "switch.wohnzimmer_tv_steckdosenleiste_tv";
entitySwitchFireTV = "switch.wohnzimmer_tv_steckdosenleiste_firetv";
entitySwitchXBOX = "switch.wohnzimmer_tv_steckdosenleiste_xbox";
entitySwitchZeppelin = "switch.wohnzimmer_tv_steckdosenleiste_zeppelin";
entityActivitySelect = "wohnzimmer_tv_activity";
entityVolumeMute = "wohnzimmer_tv_volume_mute";
entityVolumeLevel = "wohnzimmer_tv_volume_level";
entityHarmonyActivitySelect = "select.wohnzimmer_harmony_activities";
activityOptionOff = "Aus";
activityOptionOffHarmony = "power_off";
activityOptionMusic = "Musik";
activityOptionFireTV = "FireTV";
activityOptionXBOX = "XBOX";
# because of tasmota
switchDelaySecondsZeppelin = 1;
switchDelaySecondsTV = 2;
switchDelaySecondsFireTV = 3;
switchDelaySecondsXBOXOn = 4;
switchDelaySecondsXBOXOff = 60; # because it needs longer to shut down
mkAutomationCondition = slug: triggers: conditions: actions: {
alias = "Wohnzimmer TV: ${slug}";
id = "wohnzimmer_tv_automation_${slug}";
trigger = triggers;
condition = conditions;
action = actions;
};
mkAutomation = slug: triggers: actions: (mkAutomationCondition slug triggers [] actions);
rokuButtonPressed = key: {
platform = "event";
event_type = "roku_command";
event_data = {
type = "keypress";
key = key;
};
};
mkRokuVolumeAutomation = key: action: mkAutomation
"roku_vol_${action}"
[(rokuButtonPressed key)]
[(helper.action.callService "input_number.${action}" "input_number.${entityVolumeLevel}")];
tvSelect = option: {
service = "input_select.select_option";
target.entity_id = "input_select.${entityActivitySelect}";
data.option = option;
};
harmonySelect = option: {
service = "select.select_option";
target.entity_id = entityHarmonyActivitySelect;
data.option = option;
};
tvChangedTo = stateTo: (helper.trigger.stateTo "input_select.${entityActivitySelect}" stateTo);
tvChangedNotTo = stateNotTo: (helper.trigger.stateNotTo "input_select.${entityActivitySelect}" stateNotTo);
harmonyChangedTo = stateTo: (helper.trigger.stateTo entityHarmonyActivitySelect stateTo);
harmonyChangedNotTo = stateNotTo: (helper.trigger.stateNotTo entityHarmonyActivitySelect stateNotTo);
in
{
input_boolean = {
"${entityVolumeMute}" = {
name = "Wohnzimmer TV Mute";
icon = "mdi:volume-mute";
};
};
input_number = {
"${entityVolumeLevel}" = {
name = "Wohnzimmer TV Lautstärke";
icon = "mdi:volume-high";
unit_of_measurement = "%";
min = "0.0";
max = "1.0";
step = "0.01";
};
};
input_select = {
"${entityActivitySelect}" = {
name = "Wohnzimmer TV Aktivität";
options = [
activityOptionOff
activityOptionMusic
activityOptionFireTV
activityOptionXBOX
];
};
};
media_player = [
{
platform = "universal";
name = "Wohnzimmer TV Universal";
device_class = "tv";
unique_id = "media_player_universal_wohnzimmer_tv";
children = [
entityMediaplayerFireTV
entityMediaplayerXBOX
entityMediaplayerZeppelin
];
active_child_template = ''
{% if is_state('input_select.${entityActivitySelect}', '${activityOptionMusic}') %}
${entityMediaplayerZeppelin}
{% elif is_state('input_select.${entityActivitySelect}', '${activityOptionFireTV}') %}
${entityMediaplayerFireTV}
{% elif is_state('input_select.${entityActivitySelect}', '${activityOptionXBOX}') %}
${entityMediaplayerXBOX}
{% endif %}
'';
state_template = ''
{% if is_state('input_select.${entityActivitySelect}', '${activityOptionMusic}') %}
{{ states('${entityMediaplayerZeppelin}') }}
{% elif is_state('input_select.${entityActivitySelect}', '${activityOptionFireTV}') %}
{{ states('${entityMediaplayerFireTV}') }}
{% elif is_state('input_select.${entityActivitySelect}', '${activityOptionXBOX}') %}
{{ states('${entityMediaplayerXBOX}') }}
{% else %}
off
{% endif %}
'';
commands = {
turn_on = tvSelect activityOptionFireTV;
turn_off = tvSelect activityOptionOff;
volume_set = helper.action.callService "input_number.set_value" "input_number.${entityVolumeLevel}" // {data.value = "{{ volume_level }}";};
volume_up = helper.action.callService "input_number.increment" "input_number.${entityVolumeLevel}";
volume_down = helper.action.callService "input_number.decrement" "input_number.${entityVolumeLevel}";
volume_mute = helper.action.callService "input_boolean.toggle" "input_boolean.${entityVolumeMute}";
};
attributes = {
is_volume_muted = "input_boolean.${entityVolumeMute}";
volume_level = "input_number.${entityVolumeLevel}";
};
}
];
automation = [
(mkRokuVolumeAutomation "Up" "increment")
(mkRokuVolumeAutomation "Down" "decrement")
(mkAutomation "roku_vol_mute" [(rokuButtonPressed "Right")] [(helper.action.callService "input_boolean.toggle" "input_boolean.${entityVolumeMute}")])
(mkAutomation "sync_off_to_harmony" [(tvChangedTo activityOptionOff)] [(harmonySelect activityOptionOffHarmony)])
(mkAutomation "sync_activity_to_harmony" [(tvChangedNotTo activityOptionOff)] [(harmonySelect "{{ trigger.to_state.state }}")])
(mkAutomation "sync_off_from_harmony" [(harmonyChangedTo activityOptionOffHarmony)] [(tvSelect activityOptionOff)])
(mkAutomation "sync_activity_from_harmony" [(harmonyChangedNotTo activityOptionOffHarmony)] [(tvSelect "{{ trigger.to_state.state }}")])
(
mkAutomationCondition
"set_speaker_volume"
[
(helper.trigger.state "input_number.${entityVolumeLevel}")
(helper.trigger.stateTo "input_boolean.${entityVolumeMute}" "off")
(helper.trigger.stateFrom entityMediaplayerZeppelin "unavailable")
]
[{
condition = "state";
entity_id = "input_boolean.${entityVolumeMute}";
state = "off";
}]
[(helper.action.callService "media_player.volume_set" entityMediaplayerZeppelin // {data.volume_level = "{{ states(\"input_number.${entityVolumeLevel}\") }}";})]
)
(
mkAutomation
"mute_speaker"
[(helper.trigger.stateTo "input_boolean.${entityVolumeMute}" "on")]
[(helper.action.callService "media_player.volume_set" entityMediaplayerZeppelin // {data.volume_level = "0";})]
)
(
mkAutomation
"switch_off_tv"
[
(tvChangedTo activityOptionOff)
(tvChangedTo activityOptionMusic)
]
(helper.action.delayed (helper.action.turnOff entitySwitchTV) switchDelaySecondsTV)
)
(
mkAutomation
"switch_off_firetv"
[
(tvChangedTo activityOptionOff)
(tvChangedTo activityOptionMusic)
(tvChangedTo activityOptionXBOX)
]
(helper.action.delayed (helper.action.turnOff entitySwitchFireTV) switchDelaySecondsFireTV)
)
(
mkAutomation
"switch_off_xbox"
[
(tvChangedTo activityOptionOff)
(tvChangedTo activityOptionMusic)
(tvChangedTo activityOptionFireTV)
]
(helper.action.delayed (helper.action.turnOff entitySwitchXBOX) switchDelaySecondsXBOXOff)
)
(
mkAutomation
"switch_off_zeppelin"
[(tvChangedTo activityOptionOff)]
(helper.action.delayed (helper.action.turnOff entitySwitchZeppelin) switchDelaySecondsZeppelin)
)
(
mkAutomation
"switch_on_tv"
[
(tvChangedTo activityOptionFireTV)
(tvChangedTo activityOptionXBOX)
]
(helper.action.delayed (helper.action.turnOn entitySwitchTV) switchDelaySecondsTV)
)
(
mkAutomation
"switch_on_firetv"
[(tvChangedTo activityOptionFireTV)]
(helper.action.delayed (helper.action.turnOn entitySwitchFireTV) switchDelaySecondsFireTV)
)
(
mkAutomation
"switch_on_xbox"
[(tvChangedTo activityOptionXBOX)]
(helper.action.delayed (helper.action.turnOn entitySwitchXBOX) switchDelaySecondsXBOXOn)
)
(
mkAutomation
"switch_on_zeppelin"
[(tvChangedNotTo activityOptionOff)]
(helper.action.delayed (helper.action.turnOn entitySwitchZeppelin) switchDelaySecondsZeppelin)
)
];
}

View file

@ -4,6 +4,7 @@
pkgs,
python3Packages,
inputs,
lib,
...
}:
@ -18,6 +19,9 @@
users.users."hass".extraGroups = ["dialout"];
networking.firewall.allowedTCPPortRanges = [{from = 40000; to = 41000;}];
networking.firewall.allowedUDPPortRanges = [{from = 40000; to = 41000;}];
pub-solar.home-assistant = {
enable = true;
extraComponents = [
@ -27,21 +31,30 @@
"apcupsd"
"androidtv"
"androidtv_remote"
"cast"
"esphome"
"emulated_hue"
"emulated_roku"
"harmony"
"homekit_controller"
"icloud"
"ipp"
"jellyfin"
"luci"
"met"
"nina"
"python_script"
"radio_browser"
"rpi_power"
"shopping_list"
"spotify"
"tasmota"
"unifi"
"upnp"
"wyoming"
"vacuum"
"xbox"
"xiaomi_aqara"
"xiaomi_miio"
"zeroconf"
@ -59,14 +72,22 @@
# dwd
dwdwfsapi
# forecast_solar
(callPackage ./forecast-solar.nix {})
# hacs
aiogithubapi
# owntone
pyatv
(callPackage ./pyforked-daapd.nix {})
# philips_airpurifier_coap
(callPackage ./aioairctrl.nix {})
# totop
# totp
pyotp
pyqrcode
];
config = {
@ -86,7 +107,16 @@
external_url = "https://ha2.gssws.de";
internal_url = "http://192.168.42.11:8123";
packages = {
package_light = (import ./home-assistant-package-light.nix);
package_vacuum = (import ./home-assistant-package-vacuum.nix);
package_wohnzimmer_tv = (import ./home-assistant-package-wohnzimmer-tv.nix);
};
customize = (import ./home-assistant-customize-vacuum.nix) // { };
};
http = {
ip_ban_enabled = false;
use_x_forwarded_for = true;
@ -112,6 +142,31 @@
}
];
emulated_hue = {
host_ip = "172.16.0.11";
listen_port = 40000;
expose_by_default = false;
entities = {
"light.light_wohnzimmer_kugel_links" = {
name = "Kugel links";
};
"light.light_wohnzimmer_kugel_rechts" = {
name = "Kugel rechts";
};
"light.light_wohnzimmer_klemmlampe" = {
name = "Klemmlampe";
};
};
};
emulated_roku = {
servers = [{
name = "Home Assistant";
host_ip = "172.16.0.11";
listen_port = 40001;
}];
};
python_script = {};
waste_collection_schedule = {
@ -133,7 +188,7 @@
name = "Home";
latitude = "52.31501090166047";
longitude = "8.910633035293603";
radius = "30";
radius = "50";
}
{
name = "DKSB";

View file

@ -1,9 +1,110 @@
{...}: {
{...}:
let
vlan101Hosts = [
# switches
{mac = "28:80:88:72:ae:60"; ip = "10.0.42.15"; hostname = "sw-wohnung";} # statically configured
{mac = "28:87:ba:24:6a:2b"; ip = "10.0.42.16"; hostname = "sw-wohnzimmer";} # statically configured
# access points
{mac = "18:e8:29:c6:29:84"; ip = "10.0.42.21"; hostname = "ap-caro";}
{mac = "e4:38:83:e7:00:10"; ip = "10.0.42.22"; hostname = "ap-hendrik";}
{mac = "e4:38:83:e7:0a:c4"; ip = "10.0.42.23"; hostname = "ap-wohnzimmer";}
# security devices
{mac = "e0:ca:3c:7d:37:5b"; ip = "10.0.42.31"; hostname = "cam-wohnzimmer";}
];
vlan102Hosts = [
{mac = "38:1a:52:04:37:d8"; ip = "172.16.0.15"; hostname = "printer";}
{mac = "3c:e9:0e:87:d2:1c"; ip = "172.16.0.21"; hostname = "nspanel-hendrik";}
{mac = "3c:e9:0e:87:ef:d0"; ip = "172.16.0.22"; hostname = "nspanel-schlafzimmer";}
{mac = "98:0c:33:fe:3d:a8"; ip = "172.16.0.23"; hostname = "nuki-wohnung";}
{mac = "c8:5c:cc:5c:54:06"; ip = "172.16.0.24"; hostname = "presence-wohnzimmer";}
{mac = "c8:5c:cc:5c:28:7b"; ip = "172.16.0.25"; hostname = "presence-hendrik";}
{mac = "04:78:63:7f:0e:bb"; ip = "172.16.0.26"; hostname = "airpurifier-wohnzimmer";}
{mac = "48:e7:29:c1:a3:f0"; ip = "172.16.0.27"; hostname = "nspanel-caro";}
{mac = "5c:c5:63:eb:e8:b8"; ip = "172.16.0.28"; hostname = "poffertjes";}
{mac = "d0:ba:e4:e7:7d:d5"; ip = "172.16.0.29"; hostname = "airpurifier-hendrik";}
{mac = "98:f4:ab:f2:43:98"; ip = "172.16.0.30"; hostname = "shelly1-flur-deckenlicht";}
{mac = "a4:cf:12:ba:72:c1"; ip = "172.16.0.31"; hostname = "shelly25-abstellraum";}
{mac = "c8:2b:96:11:10:46"; ip = "172.16.0.32"; hostname = "shelly25-badezimmer";}
{mac = "24:62:ab:41:06:f2"; ip = "172.16.0.33"; hostname = "tasmota-tv-steckdosenleiste";}
{mac = "c8:db:26:0d:4f:f4"; ip = "172.16.0.34"; hostname = "harmonyhub-tv";}
];
vlan104Hosts = [
{mac = "30:58:90:1a:3b:ef"; ip = "10.42.0.21"; hostname = "box-hendrik";}
{mac = "30:58:90:19:b5:03"; ip = "10.42.0.22"; hostname = "box-schlafzimmer";}
{mac = "30:58:90:28:7e:30"; ip = "10.42.0.23"; hostname = "box-esstisch";}
{mac = "1c:53:f9:23:d7:c4"; ip = "10.42.0.31"; hostname = "nh-hendrik";}
{mac = "1c:53:f9:14:7b:65"; ip = "10.42.0.32"; hostname = "nh-kueche";}
{mac = "1c:53:f9:1c:9e:22"; ip = "10.42.0.33"; hostname = "nh-wohnzimmer";}
{mac = "20:1f:3b:96:9f:29"; ip = "10.42.0.34"; hostname = "nm-schlafzimmer";}
{mac = "6c:ad:f8:73:a0:94"; ip = "10.42.0.35"; hostname = "cc-wohnzimmer";}
{mac = "ec:66:d1:8a:79:71"; ip = "10.42.0.36"; hostname = "zeppelin-wohnzimmer";}
{mac = "c0:91:b9:1e:2b:80"; ip = "10.42.0.37"; hostname = "firetv-wohnzimmer";}
{mac = "cc:60:c8:14:26:2c"; ip = "10.42.0.38"; hostname = "xbox-wohnzimmer";}
];
mkDnsmasqHosts = hosts : map (h : "${h.mac},${h.hostname},${h.ip}") hosts;
mkKeaHosts = hosts : map (h : { hw-address = h.mac; ip-address = h.ip; }) hosts;
mkKeaOptions = router: dns: mtu:
[
{
name = "routers";
data = "${router}";
}
{
name = "domain-name-servers";
data = "${dns}";
}
{
name = "interface-mtu";
data = "${toString mtu}";
}
];
mkKeaSubnet = interface : subnet : pool : options : hosts : {
subnet = subnet;
interface = interface;
pools = [{ pool = pool; }];
option-data = mkKeaOptions options.router options.dns options.mtu;
reservations = mkKeaHosts hosts;
};
enableKea = true;
enableDnsmasq = false;
mtu = 1500;
in
{
networking.firewall.checkReversePath = false;
networking.firewall.allowedUDPPorts = [67]; # allow dhcp request
services.kea.dhcp4 = {
enable = enableKea;
settings = {
authoritative = true;
interfaces-config = {
interfaces = ["vlan101" "vlan102" "vlan104"];
dhcp-socket-type = "raw";
};
valid-lifetime = 3600;
host-reservation-identifiers = [ "hw-address" ];
subnet4 = [
(mkKeaSubnet "vlan101" "10.0.42.0/24" "10.0.42.100 - 10.0.42.200" {router = "10.0.42.1"; dns = "10.0.42.1"; mtu = mtu;} vlan101Hosts)
(mkKeaSubnet "vlan102" "172.16.0.0/24" "172.16.0.100 - 172.16.0.200" {router = "172.16.0.1"; dns = "172.16.0.1"; mtu = mtu;} vlan102Hosts)
(mkKeaSubnet "vlan104" "10.42.0.0/24" "10.42.0.100 - 10.42.0.200" {router = "10.42.0.1"; dns = "10.42.0.1"; mtu = mtu;} vlan104Hosts)
];
};
};
services.dnsmasq = {
enable = true;
enable = enableDnsmasq;
settings = {
interface = [
"vlan101" # network
@ -21,41 +122,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-host = (mkDnsmasqHosts vlan101Hosts) ++
(mkDnsmasqHosts vlan102Hosts) ++
(mkDnsmasqHosts vlan104Hosts);
dhcp-range = [
"vlan101,10.0.42.51,10.0.42.100"
@ -65,7 +134,7 @@
dhcp-option = [
"option:dns-server,1.1.1.1"
"option:mtu,1460"
"option:mtu,${mtu}"
# vlan101
"vlan101,option:router,10.0.42.1"

View file

@ -0,0 +1,29 @@
{ pkgs, python311 }:
let
pyLibrespotJava = python311.pkgs.buildPythonPackage rec {
pname = "pylibrespot-java";
version = "0.1.0";
src = pkgs.fetchPypi {
inherit pname version;
sha256 = "DbKPW3mB5IMhj0EqLhQpZ66wGjOGWxhaXM39IjkN/yA=";
};
propagatedBuildInputs = [
python311.pkgs.aiohttp
];
};
in
python311.pkgs.buildPythonPackage rec {
pname = "pyforked-daapd";
version = "0.1.14";
src = pkgs.fetchPypi {
inherit pname version;
sha256 = "v1NOlwP8KtBsQiqwbx1y8p8lABEuEJdNhvR2kGzLxKs=";
};
propagatedBuildInputs = [
pyLibrespotJava
python311.pkgs.aiohttp
];
}

View file

@ -0,0 +1,27 @@
{ 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.fetchFromGitHub {
owner = "kongo09";
repo = "aioairctrl";
rev = "v${version}";
sha256 = "JBXh590wu85ig+LZCgG9S7y9uLOKednFJ/1UfDLz5Fo=";
};
propagatedBuildInputs = [
python311.pkgs.aiocoap
pycryptodomex
];
}

View file

@ -17,6 +17,10 @@
boot.kernelPackages = pkgs.linuxPackages_latest;
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
services.blueman.enable = true;
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-uuid/cdc29f0f-5b18-4ee7-8d38-1f4bac80b1e6";
allowDiscards = true;

View file

@ -0,0 +1,63 @@
{
lib,
config,
pkgs,
...
}:
with lib; let
psCfg = config.pub-solar;
cfg = config.pub-solar.concourse-server;
in {
options.pub-solar.concourse-server = {
enable = mkOption {
description = "Concourse server";
default = false;
};
hostStateDir = mkOption {
description = "sets the state directory on host side";
default = "/srv/concourse-server/data";
};
};
config = mkIf cfg.enable {
containers."concourse-server" = {
autoStart = true;
ephemeral = true;
bindMounts."/data" = {
hostPath = cfg.hostStateDir;
isReadOnly = false;
};
config = {
config,
pkgs,
...
}: {
nixpkgs.overlays = [ (self: super: {
concourse = self.pkgs.concourse;
}) ];
system.stateVersion = "23.05";
networking.firewall.enable = false;
services.postgresql = {
enable = true;
};
systemd.services.concourse-web = {
enable = true;
description = "concourse web";
unitConfig = {
Type = "simple";
};
serviceConfig = {
ExecStart = "${pkgs.concourse}/bin/concourse";
};
wantedBy = [ "multi-user.target" ];
};
};
};
};
}

View file

@ -20,9 +20,12 @@ in {
port = 8081;
};
permit_join = false;
homeassistant = true;
homeassistant = {
legacy_entity_attributes = false;
};
availability = true;
advanced = {
legacy_api = false;
legacy_availability_payload = false;
};
mqtt = {
@ -34,6 +37,9 @@ in {
adapter = mkIf (cfg.adapter != null) cfg.adapter;
};
groups = "groups.yaml";
ota = {
zigbee_ota_override_index_location = "/var/lib/zigbee2mqtt/index.json";
};
};
};
};

View file

@ -8,7 +8,7 @@
nix = {
# Use default version alias for nix package
package = pkgs.nix;
gc.automatic = true;
gc.automatic = lib.mkDefault false;
optimise.automatic = true;
settings = {

View file

@ -7,7 +7,9 @@ with lib; let
psCfg = config.pub-solar;
cfg = config.pub-solar.paperless;
in {
config.containers."paperless" = mkIf cfg.enable {
systemd.services."container@paperless".unitConfig.RequiresMountsFor = [cfg.hostStateDir];
containers."paperless" = mkIf cfg.enable {
autoStart = true;
ephemeral = true;
@ -96,6 +98,8 @@ in {
timerConfig.OnUnitActiveSec = "60min";
wantedBy = ["multi-user.target" "timers.target"];
};
system.stateVersion = "23.05";
};
};
}

View file

@ -30,17 +30,16 @@ in {
home-manager = with pkgs;
pkgs.lib.setAttrByPath ["users" psCfg.user.name] {
home.packages = [
watson
blesh
exa
jump
] ++ lib.optionals (!cfg.lite) [
ack
asciinema
bat
blesh
exa
fd
gh
glow
jump
(nnn.overrideAttrs (o: {
patches =
(o.patches or [])
@ -53,6 +52,11 @@ in {
watson
];
programs.starship = {
enable = true;
settings = import ./starship.toml.nix;
};
programs.bash = import ./bash {
inherit config;
inherit pkgs;

View file

@ -4,12 +4,9 @@ channels: final: prev: {
inherit
(channels.latest)
nixd
appflowy
docker_24
;
inherit
(channels.factorio-pr)
factorio
home-assistant
;
inherit

View file

@ -1,230 +0,0 @@
{
"F-Sy-H": {
"cargoLocks": null,
"extract": null,
"name": "F-Sy-H",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "z-shell",
"repo": "F-Sy-H",
"rev": "81315330ff4eb4bc13b03fe6ec5bbb6fee0f27ac",
"sha256": "sha256-2b/O/1SIhKgqHYjwy7yPCEb3EMXgkIvOk+FC4PbuQ8c=",
"type": "github"
},
"version": "81315330ff4eb4bc13b03fe6ec5bbb6fee0f27ac"
},
"instant-nvim-nvfetcher": {
"cargoLocks": null,
"extract": null,
"name": "instant-nvim-nvfetcher",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "jbyuki",
"repo": "instant.nvim",
"rev": "294b6d08143b3db8f9db7f606829270149e1a786",
"sha256": "sha256-DXJWji/NR8ZCxe014rD51v3EHJHMhRQeOoI3SsY8mR4=",
"type": "github"
},
"version": "294b6d08143b3db8f9db7f606829270149e1a786"
},
"manix": {
"cargoLocks": null,
"extract": null,
"name": "manix",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "mlvzk",
"repo": "manix",
"rev": "d08e7ca185445b929f097f8bfb1243a8ef3e10e4",
"sha256": "sha256-GqPuYscLhkR5E2HnSFV4R48hCWvtM3C++3zlJhiK/aw=",
"type": "github"
},
"version": "d08e7ca185445b929f097f8bfb1243a8ef3e10e4"
},
"ohmyzsh": {
"cargoLocks": null,
"extract": null,
"name": "ohmyzsh",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "ohmyzsh",
"repo": "ohmyzsh",
"rev": "4181e8a2cc936bc7b7a89d674bf261023159ed35",
"sha256": "sha256-kne/2ErEqUqBx1xzQrvk6scrhOZYJDlUnNOlx0MbqNQ=",
"type": "github"
},
"version": "4181e8a2cc936bc7b7a89d674bf261023159ed35"
},
"powerlevel10k": {
"cargoLocks": null,
"extract": null,
"name": "powerlevel10k",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "romkatv",
"repo": "powerlevel10k",
"rev": "35165798a83e2e4f2f0aa6c820e2f7fba23e0179",
"sha256": "sha256-tThgRiE0iZH84yTSGtNxfFemLocbg71McAKyT7YWG8U=",
"type": "github"
},
"version": "35165798a83e2e4f2f0aa6c820e2f7fba23e0179"
},
"rnix-lsp-nvfetcher": {
"cargoLocks": null,
"extract": null,
"name": "rnix-lsp-nvfetcher",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "nix-community",
"repo": "rnix-lsp",
"rev": "95d40673fe43642e2e1144341e86d0036abd95d9",
"sha256": "sha256-F0s0m62S5bHNVWNHLZD6SeHiLrsDx98VQbRjDyIu+qQ=",
"type": "github"
},
"version": "95d40673fe43642e2e1144341e86d0036abd95d9"
},
"vim-apprentice-nvfetcher": {
"cargoLocks": null,
"extract": null,
"name": "vim-apprentice-nvfetcher",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "romainl",
"repo": "Apprentice",
"rev": "9942d0bb0a5d82f7a24450b00051c1f2cc008659",
"sha256": "sha256-Xs+vTdnihNbBFPOKsW+NB40pqN9eaadqzc0DIeNoOFo=",
"type": "github"
},
"version": "9942d0bb0a5d82f7a24450b00051c1f2cc008659"
},
"vim-beautify-nvfetcher": {
"cargoLocks": null,
"extract": null,
"name": "vim-beautify-nvfetcher",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "zeekay",
"repo": "vim-beautify",
"rev": "e0691483927dc5a0c051433602397419f9628623",
"sha256": "sha256-QPTCl6KaGcAjTS5yVDov9yxmv0fDaFoPLMsrtVIG6GQ=",
"type": "github"
},
"version": "e0691483927dc5a0c051433602397419f9628623"
},
"vim-caddyfile-nvfetcher": {
"cargoLocks": null,
"extract": null,
"name": "vim-caddyfile-nvfetcher",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "isobit",
"repo": "vim-caddyfile",
"rev": "24fe0720551883e407cb70ae1d7c03f162d1d5a0",
"sha256": "sha256-rRYv3vnt31g7hNTxttTD6BWdv5JJ+ko3rPNyDUEOZ9o=",
"type": "github"
},
"version": "24fe0720551883e407cb70ae1d7c03f162d1d5a0"
},
"vim-workspace-nvfetcher": {
"cargoLocks": null,
"extract": null,
"name": "vim-workspace-nvfetcher",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "thaerkh",
"repo": "vim-workspace",
"rev": "c26b473f9b073f24bacecd38477f44c5cd1f5a62",
"sha256": "sha256-XV7opLyfkHIDO0+JJaO/x0za0gsHuklrzapTGdLHJmI=",
"type": "github"
},
"version": "c26b473f9b073f24bacecd38477f44c5cd1f5a62"
},
"vimagit-nvfetcher": {
"cargoLocks": null,
"extract": null,
"name": "vimagit-nvfetcher",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "jreybert",
"repo": "vimagit",
"rev": "308650ddc1e9a94e49fae0ea04bbc1c45f23d4c4",
"sha256": "sha256-fhazQQqyFaO0fdoeNI9nBshwTDhKNHH262H/QThtuO0=",
"type": "github"
},
"version": "308650ddc1e9a94e49fae0ea04bbc1c45f23d4c4"
},
"zsh-nix-shell": {
"cargoLocks": null,
"extract": null,
"name": "zsh-nix-shell",
"passthru": null,
"pinned": false,
"src": {
"deepClone": false,
"fetchSubmodules": false,
"leaveDotGit": false,
"name": null,
"owner": "chisui",
"repo": "zsh-nix-shell",
"rev": "af6f8a266ea1875b9a3e86e14796cadbe1cfbf08",
"sha256": "sha256-BjgMhILEL/qdgfno4LR64LSB8n9pC9R+gG7IQWwgyfQ=",
"type": "github"
},
"version": "af6f8a266ea1875b9a3e86e14796cadbe1cfbf08"
}
}

21
pkgs/concourse.nix Normal file
View file

@ -0,0 +1,21 @@
self:
with self;
stdenv.mkDerivation rec {
pname = "concourse";
version = "7.10.0";
buildInputs = [
];
src = fetchTarball {
inherit version;
url = "https://github.com/concourse/concourse/releases/download/v${version}/concourse-${version}-linux-amd64.tgz";
sha256 = "";
};
phases = ["installPhase"];
installPhase = ''
mkdir -p $out/bin/
cp concourse/bin/* $out/bin/
'';
}

View file

@ -3,6 +3,7 @@ with final; {
# keep sources this first
sources = prev.callPackage (import ./_sources/generated.nix) {};
# then, call packages with `final.callPackage`
concourse = import ./concourse.nix final;
import-gtk-settings = writeShellScriptBin "import-gtk-settings" (import ./import-gtk-settings.nix final);
lgcl = writeShellScriptBin "lgcl" (import ./lgcl.nix final);
mailto-mutt = writeShellScriptBin "mailto-mutt" (import ./mailto-mutt.nix final);

View file

@ -0,0 +1,13 @@
age-encryption.org/v1
-> ssh-ed25519 hPyiJw Ip6mcFDyrPdGZiXZp8J7bDruJSvTIElf8ligYZ70YG4
Hc4GfqP7pPaodrM7fmjNWI/eD8fa2FoS1VbhmTxOYjw
-> ssh-ed25519 YFSOsg XakKNGSkB1fsaWZvqblI9fmsTXofW5T29yrcvuWclBc
NksfMfA2D6GgfSoTQoj7BRXhf+sqLKVxFWljWg72XiQ
-> ssh-ed25519 iHV63A axHU3NCfQrxbQKlpL0D1uUCZ9ovKNnABYwzl2MPqhlw
AKVkfejM49H+kD7ZPB6gUOyhA4OeGgovFo9tvt1x4hc
-> ssh-ed25519 Oya/Zw U8OGXSvciVRupv1h5z/OjJbVQYMdQKW5H18S0U0rFhw
y2C5ZesGsbhx/KJhf/Km+x26yL7FJFl/dRPos3a6arU
-> cZ"-grease r2$$~# V=
v8RbfnzpQyQVco6u2TW/ijXnk9CWUrs4nPCi
--- dXdYdEVGow044KgF/hW+D8oPRrct/87hsntZQI+J4es
ö3ZzIAƒ<41>Il‡w¾6änuh«_—ÿ§–+;<3B>r«³ê®:˜äidD1óþÏö<C38F><32>©ÄLÛýã<C3A3>Yî¤àÜÎ~AšðLê»ø…”Ç žƒ˜íTê<54>Ê

View file

@ -58,6 +58,8 @@ in {
"chonk_authelia_storage_encryption_key.age".publicKeys = users ++ [system_chonk];
"chonk_authelia_jwt_secret.age".publicKeys = users ++ [system_chonk];
"chonk_garage_rpc_secret.age".publicKeys = users ++ [system_chonk];
"home_controller_ringo_wireguard_key.age".publicKeys = users ++ [system_ringo];
"home_controller_k3s_server_token.age".publicKeys = users ++ systems_home_controller;

View file

@ -48,7 +48,7 @@ in {
thunderbird
wdisplays
gnucash
appflowy
];
};
}