diff --git a/README.md b/README.md index 7b18909..5d6c327 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,4 @@ -## home-manager -https://github.com/nix-community/home-manager - -For a systematic overview of Home Manager and its available options, please see -- the [Home Manager manual](https://nix-community.github.io/home-manager/index.html) and -- the [Home Manager configuration options](https://nix-community.github.io/home-manager/options.html). - +# jalr's NixOS Configuration ## Install a new host @@ -59,3 +53,8 @@ gpg --edit-key $key gpg> trust Your decision? 5 ``` + +## Debugging boot issues + +1. Add `rd.systemd.debug_shell` kernel parameter +2. Press CTRL+ALT+F9 to switch to root shell diff --git a/flake.lock b/flake.lock index 83e4427..0525c8c 100644 --- a/flake.lock +++ b/flake.lock @@ -28,11 +28,11 @@ ] }, "locked": { - "lastModified": 1726524467, - "narHash": "sha256-xkPPPvfHhHK7BNX5ZrQ9N6AIEixCmFzRZHduDf0zv30=", + "lastModified": 1731060864, + "narHash": "sha256-aYE7oAYZ+gPU1mPNhM0JwLAQNgjf0/JK1BF1ln2KBgk=", "owner": "nix-community", "repo": "disko", - "rev": "22ee467a54a3ab7fa9d637ccad5330c6c087e9dc", + "rev": "5e40e02978e3bd63c2a6a9fa6fa8ba0e310e747f", "type": "github" }, "original": { @@ -183,11 +183,11 @@ ] }, "locked": { - "lastModified": 1725515722, - "narHash": "sha256-+gljgHaflZhQXtr3WjJrGn8NXv7MruVPAORSufuCFnw=", + "lastModified": 1729448365, + "narHash": "sha256-oquZeWTYWTr5IxfwEzgsxjtD8SSFZYLdO9DaQb70vNU=", "owner": "nix-community", "repo": "gomod2nix", - "rev": "1c6fd4e862bf2f249c9114ad625c64c6c29a8a08", + "rev": "5d387097aa716f35dd99d848dc26d8d5b62a104c", "type": "github" }, "original": { @@ -203,11 +203,11 @@ ] }, "locked": { - "lastModified": 1725703823, - "narHash": "sha256-tDgM4d8mLK0Hd6YMB2w1BqMto1XBXADOzPEaLl10VI4=", + "lastModified": 1726989464, + "narHash": "sha256-Vl+WVTJwutXkimwGprnEtXc/s/s8sMuXzqXaspIGlwM=", "owner": "nix-community", "repo": "home-manager", - "rev": "208df2e558b73b6a1f0faec98493cb59a25f62ba", + "rev": "2f23fa308a7c067e52dfcc30a0758f47043ec176", "type": "github" }, "original": { @@ -275,11 +275,11 @@ ] }, "locked": { - "lastModified": 1703863825, - "narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=", + "lastModified": 1729742964, + "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=", "owner": "nix-community", "repo": "nix-github-actions", - "rev": "5163432afc817cf8bd1f031418d1869e4c9d5547", + "rev": "e04df33f62cdcf93d73e9a04142464753a16db67", "type": "github" }, "original": { @@ -298,11 +298,11 @@ "nixpkgs-stable": "nixpkgs-stable_2" }, "locked": { - "lastModified": 1725513492, - "narHash": "sha256-tyMUA6NgJSvvQuzB7A1Sf8+0XCHyfSPRx/b00o6K0uo=", + "lastModified": 1730814269, + "narHash": "sha256-fWPHyhYE6xvMI1eGY3pwBTq85wcy1YXqdzTZF+06nOg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "7570de7b9b504cfe92025dd1be797bf546f66528", + "rev": "d70155fdc00df4628446352fc58adc640cd705c2", "type": "github" }, "original": { @@ -314,11 +314,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1726489388, - "narHash": "sha256-JBHtN+n1HzKawpnOQAz6jdgvrtYV9c/kyzgoIdguQGo=", + "lastModified": 1730919458, + "narHash": "sha256-yMO0T0QJlmT/x4HEyvrCyigGrdYfIXX3e5gWqB64wLg=", "owner": "nixos", "repo": "nixos-hardware", - "rev": "dc8b0296f68f72f3fe77469c549a6f098555c2e9", + "rev": "e1cc1f6483393634aee94514186d21a4871e78d7", "type": "github" }, "original": { @@ -330,11 +330,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1726320982, - "narHash": "sha256-RuVXUwcYwaUeks6h3OLrEmg14z9aFXdWppTWPMTwdQw=", + "lastModified": 1730963269, + "narHash": "sha256-rz30HrFYCHiWEBCKHMffHbMdWJ35hEkcRVU0h7ms3x0=", "owner": "nixos", "repo": "nixpkgs", - "rev": "8f7492cce28977fbf8bd12c72af08b1f6c7c3e49", + "rev": "83fb6c028368e465cd19bb127b86f971a5e41ebc", "type": "github" }, "original": { @@ -362,11 +362,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1720386169, - "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", + "lastModified": 1730741070, + "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", + "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3", "type": "github" }, "original": { @@ -378,11 +378,11 @@ }, "nixpkgs-stable_3": { "locked": { - "lastModified": 1725762081, - "narHash": "sha256-vNv+aJUW5/YurRy1ocfvs4q/48yVESwlC/yHzjkZSP8=", + "lastModified": 1730602179, + "narHash": "sha256-efgLzQAWSzJuCLiCaQUCDu4NudNlHdg2NzGLX5GYaEY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "dc454045f5b5d814e5862a6d057e7bb5c29edc05", + "rev": "3c2f1c4ca372622cb2f9de8016c9a0b1cbd0f37c", "type": "github" }, "original": { @@ -394,11 +394,11 @@ }, "nixpkgsMaster": { "locked": { - "lastModified": 1726573629, - "narHash": "sha256-O4fWqykLSQrGcNmx7HCElAmrYC6riGbhdCzk1dmj4qs=", + "lastModified": 1731260124, + "narHash": "sha256-BEOxhi+NnklFH0J+Zcar4p8iOzj/Qvm216JXYAvAreA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "06e78ca76feaa97082b905d330265d495eefc9f7", + "rev": "44bbe5ddad08599cb6556157c1e20242b5d9a0b2", "type": "github" }, "original": { @@ -410,11 +410,11 @@ }, "nur": { "locked": { - "lastModified": 1726569072, - "narHash": "sha256-x33fIaVSJGc/kLiXh+a8x97GrMN1DtnRd8Ar50sDaNs=", + "lastModified": 1731258665, + "narHash": "sha256-DVFTn7Ol69nWLSFwnBj/2T3wptOC97MH4i5NHlkQrzk=", "owner": "nix-community", "repo": "NUR", - "rev": "48b58426a0fb447bad367813e742247dc860bed6", + "rev": "5b5350f16cefe83e1a3ed3f30d69b6af654f0d52", "type": "github" }, "original": { @@ -436,11 +436,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1726394406, - "narHash": "sha256-RUzT5OUT+sCNl/fA4u6u/SPc1Bye7MU96Vtu6jksfxs=", + "lastModified": 1731205797, + "narHash": "sha256-F7N1mxH1VrkVNHR3JGNMRvp9+98KYO4b832KS8Gl2xI=", "owner": "nix-community", "repo": "poetry2nix", - "rev": "a0cbe913ce184bef7cd739f75ba5d123e1f41ef2", + "rev": "f554d27c1544d9c56e5f1f8e2b8aff399803674e", "type": "github" }, "original": { @@ -526,11 +526,11 @@ "nixpkgs-stable": "nixpkgs-stable_3" }, "locked": { - "lastModified": 1726524647, - "narHash": "sha256-qis6BtOOBBEAfUl7FMHqqTwRLB61OL5OFzIsOmRz2J4=", + "lastModified": 1731213149, + "narHash": "sha256-jR8i6nFLmSmm0cIoeRQ8Q4EBARa3oGaAtEER/OMMxus=", "owner": "Mic92", "repo": "sops-nix", - "rev": "e2d404a7ea599a013189aa42947f66cede0645c8", + "rev": "f1675e3b0e1e663a4af49be67ecbc9e749f85eb7", "type": "github" }, "original": { @@ -591,11 +591,11 @@ ] }, "locked": { - "lastModified": 1719749022, - "narHash": "sha256-ddPKHcqaKCIFSFc/cvxS14goUhCOAwsM1PbMr0ZtHMg=", + "lastModified": 1730120726, + "narHash": "sha256-LqHYIxMrl/1p3/kvm2ir925tZ8DkI0KA10djk8wecSk=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "8df5ff62195d4e67e2264df0b7f5e8c9995fd0bd", + "rev": "9ef337e492a5555d8e17a51c911ff1f02635be15", "type": "github" }, "original": { diff --git a/hosts/aluminium/configuration.nix b/hosts/aluminium/configuration.nix index 7e843b6..cdd652a 100644 --- a/hosts/aluminium/configuration.nix +++ b/hosts/aluminium/configuration.nix @@ -74,9 +74,6 @@ "voice" ]; }; - firewall.extraForwardRules = '' - tcp flags syn tcp option maxseg size set rt mtu - ''; firewall.extraInputRules = '' iifname "voice" udp dport 5059 accept ip saddr 217.10.68.150 udp dport 5060 accept @@ -119,6 +116,16 @@ }; }; + networking.nftables.tables.pppoe = { + family = "ip"; + content = '' + chain clamp { + type filter hook forward priority mangle; + oifname "ppp0" tcp flags syn tcp option maxseg size set rt mtu comment "clamp MSS to Path MTU" + } + ''; + }; + zramSwap = { enable = true; algorithm = "zstd"; diff --git a/hosts/aluminium/ports.nix b/hosts/aluminium/ports.nix index f1d126f..34bfdaf 100644 --- a/hosts/aluminium/ports.nix +++ b/hosts/aluminium/ports.nix @@ -9,5 +9,6 @@ custom-utils.validatePortAttrset { home-assistant.tcp = 8123; nginx-http.tcp = 80; nginx-https.tcp = 443; - unifi.tcp = 8443; + unifi-inform.tcp = 8080; + unifi-ui.tcp = 8443; } diff --git a/hosts/aluminium/services/asterisk/default.nix b/hosts/aluminium/services/asterisk/default.nix index ccc0e79..c6d8cd7 100644 --- a/hosts/aluminium/services/asterisk/default.nix +++ b/hosts/aluminium/services/asterisk/default.nix @@ -188,6 +188,10 @@ in to = rtp.end; } ]; + interfaces.voice = { + allowedTCPPorts = [ 5060 ]; + allowedUDPPorts = [ 5060 ]; + }; }; systemd.services."asterisk-reload-endpoint@" = { diff --git a/hosts/aluminium/services/default.nix b/hosts/aluminium/services/default.nix index 7ce0f6e..8639a37 100644 --- a/hosts/aluminium/services/default.nix +++ b/hosts/aluminium/services/default.nix @@ -7,6 +7,7 @@ ./esphome ./home-assistant.nix ./nginx.nix + ./ntp.nix ./unifi-controller.nix ]; } diff --git a/hosts/aluminium/services/dnsmasq.nix b/hosts/aluminium/services/dnsmasq.nix index 6363be1..ff4549a 100644 --- a/hosts/aluminium/services/dnsmasq.nix +++ b/hosts/aluminium/services/dnsmasq.nix @@ -39,6 +39,9 @@ in "2001:470:20::2" # ordns.he.net "74.82.42.42" # ordns.he.net ]; + dhcp-option = [ + "option:ntp-server,192.168.0.1" + ]; }; }; diff --git a/hosts/aluminium/services/home-assistant.nix b/hosts/aluminium/services/home-assistant.nix index 79974ef..2395ff9 100644 --- a/hosts/aluminium/services/home-assistant.nix +++ b/hosts/aluminium/services/home-assistant.nix @@ -5,7 +5,57 @@ in { services.home-assistant = { enable = true; - lovelaceConfig = { }; + lovelaceConfig = { + title = "Home"; + views = [ + { + path = "default_view"; + title = "Home"; + cards = [ + { + title = "Heizung"; + type = "entities"; + entities = [ + { entity = "sensor.guntamaticbiostar_betrieb"; } + { entity = "sensor.guntamaticbiostar_pufferladung"; } + { entity = "sensor.guntamaticbiostar_puffer_oben"; } + { entity = "sensor.guntamaticbiostar_puffer_unten"; } + { entity = "sensor.guntamaticbiostar_kesseltemperatur"; } + { entity = "sensor.guntamaticbiostar_vorlauf_ist_1"; } + { entity = "sensor.guntamaticbiostar_aussentemperatur"; } + { entity = "sensor.guntamaticbiostar_co2_gehalt"; } + { entity = "select.guntamaticbiostar_program"; } + { entity = "sensor.guntamaticbiostar_programm"; } + { entity = "sensor.guntamaticbiostar_programm_hk1"; } + { entity = "sensor.guntamaticbiostar_rucklauftemperatur"; } + { entity = "sensor.guntamaticbiostar_servicezeit"; } + ]; + } + { + type = "grid"; + square = false; + columns = 1; + cards = [ + { + title = "Wasserbett"; + type = "entities"; + entities = [ + { + entity = "sensor.waterbed_temperatur"; + name = "Temperatur"; + } + ]; + } + { + type = "thermostat"; + entity = "climate.waterbed_temperatur"; + } + ]; + } + ]; + } + ]; + }; extraComponents = [ # See https://www.home-assistant.io/integrations "esphome" @@ -33,6 +83,38 @@ in }; default_config = { }; "automation nix" = [ + { + alias = "Nachschüren"; + description = "Benachrichtigung auf iPad bei Wechsel auf Teillast"; + mode = "single"; + trigger = [ + { + platform = "state"; + entity_id = [ "sensor.guntamaticbiostar_betrieb" ]; + from = "VOLLLAST"; + to = "TEILLAST"; + } + ]; + condition = [ + { + condition = "numeric_state"; + entity_id = "sensor.guntamaticbiostar_pufferladung"; + below = "80"; + } + ]; + action = [ + { + device_id = "5612874405fa2ee539ad4518a1bb8e34"; + domain = "mobile_app"; + type = "notify"; + message = '' + Kessel läuft auf Teillast und Puffer ist unter 80%. Vielleicht willst du + nachschüren. + ''; + title = "Nachschüren?"; + } + ]; + } ]; "automation ui" = "!include automations.yaml"; "scene nix" = [ diff --git a/hosts/aluminium/services/ntp.nix b/hosts/aluminium/services/ntp.nix new file mode 100644 index 0000000..aed11f4 --- /dev/null +++ b/hosts/aluminium/services/ntp.nix @@ -0,0 +1,13 @@ +{ lib, pkgs, ... }: +{ + services.chrony = { + enable = true; + extraConfig = '' + allow 192.168.0.0/24 + allow 192.168.10.0/24 + leapsectz right/UTC + ''; + }; + networking.firewall.interfaces.lechner.allowedUDPPorts = [ 123 ]; + networking.firewall.interfaces.heizung.allowedUDPPorts = [ 123 ]; +} diff --git a/hosts/aluminium/services/unifi-controller.nix b/hosts/aluminium/services/unifi-controller.nix index a97eda8..16489c6 100644 --- a/hosts/aluminium/services/unifi-controller.nix +++ b/hosts/aluminium/services/unifi-controller.nix @@ -9,6 +9,7 @@ in unifiPackage = pkgs.unifi8; }; networking.firewall.interfaces.lechner.allowedTCPPorts = [ - ports.unifi.tcp + ports.unifi-inform.tcp + ports.unifi-ui.tcp ]; } diff --git a/hosts/iron/configuration.nix b/hosts/iron/configuration.nix index d2a78b8..80a60f2 100644 --- a/hosts/iron/configuration.nix +++ b/hosts/iron/configuration.nix @@ -15,7 +15,7 @@ let "bpool/nixos/root" = "/boot"; "rpool/filebitch" = "/filebitch"; "rpool/navidrome" = "/var/lib/private/navidrome"; - "rpool/navidrome/music" = "/var/lib/private/navidrome/music"; + "rpool/navidrome/music" = "/var/lib/navidrome/music"; "rpool/nixos/home" = "/home"; "rpool/nixos/root" = "/"; "rpool/nixos/var/lib" = "/var/lib"; @@ -141,7 +141,7 @@ with lib; { allowDiscards = true; keyFileSize = 4096; keyFile = "/dev/disk/by-id/usb-jalr_RAM_Mass_Storage_DE6270431F6F342C-0:0"; - keyFileTimeout = 5; + keyFileTimeout = 60; }; }) disks @@ -234,7 +234,5 @@ with lib; { priority = 1; }; - - jalr.libvirt.enable = true; }; } diff --git a/hosts/iron/secrets.yaml b/hosts/iron/secrets.yaml index 4e19154..cfc9d5a 100644 --- a/hosts/iron/secrets.yaml +++ b/hosts/iron/secrets.yaml @@ -10,7 +10,7 @@ dkim-keys: synapse-turn-shared-secret: ENC[AES256_GCM,data:Q1XRds3Zud1kYkvD6s9WUzP+kNDNsxB5SHd6oCAaLCHhHhYENSAYTZOF+rGjCPNyKFL0e/A=,iv:zScRQrz+pXHNUh/BGOaV+TVnDR3wu1Z/UO1zXarKwtA=,tag:ckpVziE+yb0FjctcT7tAkg==,type:str] matrix-sliding-sync: ENC[AES256_GCM,data:CmR8Q5NL1m+eixenK4u1n3MfVh49/Q3ZIRmWfSbuFMr3u79rIGrtFf2EjaThCwBHQyXdYw1wyTouxhGZql1Fcp/HYma8u4w5nJOaJa1TXg==,iv:/kFqA/+kpCkhHZKJdhadjH11pZwh4MFiQPjY96t8M5k=,tag:aZkDCcbtonHMTv4TdBv1sQ==,type:str] rmfakecloud: ENC[AES256_GCM,data:ktKBKb6cRv1VF8tRvXIpxIy9hPinVPKK05mgvYzz18PEdcrCLpldm5xf7ffHtY5XzDOAMXDCiz6x4xyv7071frrF0spOEPnIzVhxwG8H2Ck=,iv:qJdHjv0RziAs4G9UGeRwGQ4GE5kaObJWpIYWpRKhr9c=,tag:PXgvU1hZK/gvWGyFJaHekg==,type:str] -esphome: ENC[AES256_GCM,data:ufIZkZo1aP/Th/8a+9srkJBqLqPQI/ymElIEBmTKzqsJ3HE/mx9QJ1aH0vGVed9W/wSJ+7+huFpB+pNAebJMohK/fAmAVG3lzgT0wKWw8g4u33VHb6X8FIW6q1+CYRnOCQsocgM4EX26YfzaxVpw9P4PF/abwB1bVzr9xnEL2JdJfstzxnR70dKO88WTolykysc443iDW80i0scH+sCh8JIfDrV+V0l3jT+woAeTw1VA0hFa5x9i3tdfrHpzc/sN1/OW6F1CsMVS2pwUTkr7pKp5nfjxhEPi94iLMmakm0XWPZpay2213FQEUYiRqCIGmD1Oiyq0nSVcOAkc66TNwsqrdPCkCL8OPTXuTd+yIfAuU3267kUMNcN2A9kqGMx4Inj8JGlmvxuoQueuXIA4gvVFhJFBdovpl10HY/YkG/cGM0gazfF2+5xG93RgD9Uryq1g61XTFOkOaH7XtGs8Q13xnnXVwfq2pK/vnx9kQkgXJJQRU1Ng8PAg+Rw1VK6bzVz5ugj6q1ei56orNy4A8FU1z1aGyChfPT3XPaDwLr0pEXvc2Vz/6CxAosSpNHIQ6fO0XBM7nvIs/2jHZssXSVo2iwYRZsgZft60cg0FfBmDyc3QH6pVjYhoQGsBlfQt5CtW7XX3rJjQTcDLfzUlO8Ykax7TXZKnDcvtNonRm45bmV+1CqS9KLrBHouWN0axtweabAVW8dld9EnL3CrclE/RbTI0nPOR00S+Ip7wNuBto30yTACxaPHYF79izHu4rQjmm2N5Jt+nI8maEVva6IbAog16NUw6fYDaMwBDeSszBZm0BwNMf36EP/Mcp+MXrBfP1kOYe6HGjftMRDky83XYvP6Cx7FJcPXIZdsMQydxsXB3LKroFqoS2HsHBnCgQbbraQ5UWi40vKXANlKbgFcutqkATvoPW6Hbh07vfiLVfDeuHU9DUCFlgK7KHPWk/g+Uo+TUmgTVKNhbGU/vFu/9h4kIrbf/ocqL/tyMjwA5Yp9e0rQCez8w5Zqfbtqm4N1WB518Q7p52r8C+yLBAua7yB0gAc7SENXWFafkbHClchZXi3c0hY64YvuweDp8G/bPFT/yLuY/yBvA3F2G3CxZXzCMvhMVQfm2yzJeOL20vWumZ8LuIaXJ/13AzLp+lUrc8RmJvU/Hrp6xsEqzXz34qMiBNUR1BKjNAS86WJ1rzD3QtejeETGDwsw016jNbyIMcShgxiEMHnD6HXzWnfTv2fO5xICiAG/VMm5h+vC3MweW2XO01P3O0/Rq/OSy3R8ZlEFErlhR1HiXhc2CdxuuxqDySi0/rP/Jpxf25Zi8mY9YBTFlV0T9ApzJoTwlobMmmxHmqq+vQSKAxLq0lJ/bpO+8utchHbnQNUICveCkX4w+rK9Vnls3zbiLTBnsf+J4y5zpLZ5HkDCUNcEnD29ZR30IYoBTLUG3PlfyH++rLl5ynW5QKUWLnUdjvf9ZwS2veFAZw6tfHelzjkZ5tps5BkjS8YAi/x70Jw4qs3fzZudq6Lej4fsMdkBnYSSN2s7Sc3A1,iv:jSR/M4KS+cZMQgtTZWtPcpmKFD5QNr7s8ClAbXzpR2s=,tag:sp3BnZi+b9WuIiCPapG6Bw==,type:str] +esphome: ENC[AES256_GCM,data:QyPrVPhqvaCfx7oRmJ14EFpEIpQRwlLwTABK9qTP/wYcoflFsorNAmIoTiX/4KziQl050ByztnjIhrsxFx2dN6dv+RiLVWP+k0G63rfeS5gxe8QSgzsEtWWaUk3DE87i20DUusj1/B6yUsMApMohjaufuVzReL2MtVSVgtDUS6nVqGnRubrdujAxyRWvjQtamWBa1fjz39U876F10KMUYB+iGtObfNJGH18lAQ1arKEUQQSl8u1vNJuZiKqFhzxcu/IF6AhJgcKmCi2nrcEgbrv4ZwOcJ7+VG29qY7C4LCeAU4wOWJmtnCSf9osSwzR5hFco46L3Y8k0XXEOiEAJl+8ZLNKqQJpShh9wioMrj9XNpX/PvGCpBLTHsXTCGktDdbK/RLEGZnnL0s6If7Qs0XTwWZEe0q4IsltfdWJdZQWbvlY58ooUkK55wml/SlpuHgSdY6pOp/bOnBwvIrh/962DWtSXDxNnvps4Qy0eRUtpS2G6+rLIXXkq7KlSUg/A5XRNWbLGX5u7pJuvJ5xlldFW+tb1rqyrKXGIGra3Y6Ib4Z17znmajMSIeQItChj8UsOqlcHaCI5s8kDFjafJfpTTtAm0mj2cBFYmWHC/WR1YAtd2mrffr258CShtO+eeAqhSSTopIL637udKaY1Vto1dVReTmK24ANopQOaxnTtFjBdQaeluP4PAWrAGADBio1iwjsWIQlr0vnMjSBd0JcnW0Q3i+/5zhQfaEzZ6FQXOs05+l7ryLrGgBbyM2FRLTuAWBsv5yv3lz8FiSGVNaLMW5rofZpFvX0oa7P9HyU/RIpUzx307VBsIJlzrW2NgWvc9iLHLHWJDa7xcemGTvZDp/0BujYHeYYfVViPtVcCicLvDLikgtJRlkdPmyRoMSx0o3taoPsYoVZielo5EZpLiaLwuCNnCk2fRxAgPUa4+zGhZc2Z/BrOvK7sxcyIXEYRrZ8Ti2iNQJthNNb1CzSUXpdpSZtFi1jjiC45V0dlg/lSqrkRjyA9DpGbegt3WpO/6X+uc9vSAgR4f/0xNngTKzCfFV+fyUJXffpje9fQhQnecsTDjjc3aLiESqc3mx8MP6gHI9fS8z8PU72t+4tJxe8hjo7VWlInOVKV9zp9Tn+P4Ez1MebPJRlrwHGSVFsPhKct+CgzE+Q0B3vvcWyQfdJHeFCPWsTWmcCUoJf61fQO/3JwZI8YE3HET+NsRoxVHTl099LzWWCbrfT4uN3+O3VQbceLM+KxKCLVGNEHKlF8NHCIk4KCWhKNwhXvuMjf4GgtYbENFn1QbmiQFpYfIl8FA8PZVk7x+dzuROL4NpIKaBfrg34LQnxFpc2YCBnEsmsJVPybR5ZHC8eDL7JdVSg+FhvOxzBkvCeQjG8746/t0HJYPucisFCmP1isGpcn8Eku+BT/2XocHsUwpyo+RQoruWKwkLtnCHeaGSszqWzugSGXU4b4T2HB2yU9ORpt6uP+wbtc49GeMHrUGiO+w6BQm3TzPEZ0XMh4+8iayGhbd8T213C72sHpo5eCbv7C2zE/3dxHr2/+xtfstQFRuMPhq/r/4aqkeGKTwWEBcOwD1knlnbXo5OZsdvX9SeqF+mno/uDxZW00QqaWiQz89SWLGHtC4gjbE2wU2IpiGZMTOtNieOrjjCfdX3ZkrhA==,iv:Qn0nDrXRCOJaTJJBK6/PEGbhS1pbB0dTZYakgha5wJQ=,tag:8GeYWlsxgAGfFL61V5CwXg==,type:str] home-assistant: ENC[AES256_GCM,data:wcFMxDdRCHf/shO9v2WaGgrsa9J2WP62xFs=,iv:9ckeIO62cFZUo8fPyQj445CrJVTooNlwLapM/oTsrkk=,tag:mlfxtXDPsB3T79P9BX9oJQ==,type:str] sops: kms: [] @@ -27,8 +27,8 @@ sops: SU1USkxFUUY2NVhmUHBhZkdrNDR1Q0kKiXIicInELRjDR3tuyA+lnXeCcd9lYvbV GnBRGPM7BNO/6AA7HhAei48Kt+XE6+jQX66yTXyviKhK7Lpjrlb2YQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-09-11T16:10:31Z" - mac: ENC[AES256_GCM,data:7STJaln+9X6xZFAyLSoMCw2PKNiRr4GNhxGbZRPRf+nKfkFh7wJRS3YWVrxd9iOonSPsuHfPnBrAPiq7ILXqwfjNcyf2HtOIPxHz0utE6b0X7KvEwmLSRMOQG9rpsETE5UBQ+DgtU9IwZzTXgh9CGZpHWQAPeOI+lK4OKLlXvkk=,iv:E++ECn4SJy43lW5RWxjSDc7dj0LWDXIuO+5fVFE3+zU=,tag:QFvao9PWSllzXXhGwFQgrw==,type:str] + lastmodified: "2024-11-08T17:10:15Z" + mac: ENC[AES256_GCM,data:bCkqwd22O4K1Ivix4JWEY+RAiPB+8NP3y2KrDEeGXR3R03t6Xi2S+tXLKh9MBp0/jatUS2COs1tY0+hL2quC7rjpv25hufA+7oHA+jASgglD+5lKnc1OGpvBt4eMCszYorIKOP55glLLMn8WmYAPQm5PDPnfNtwZwEs1zmwffjA=,iv:YR38y2za5FrTr+t7hminVStO9/Z9zFbKoBRtuzrl+rI=,tag:ci5MZ2cjRjc8HYKJy11Jbg==,type:str] pgp: - created_at: "2024-01-31T01:20:30Z" enc: |- diff --git a/hosts/iron/services/default.nix b/hosts/iron/services/default.nix index 86ff156..40087e5 100644 --- a/hosts/iron/services/default.nix +++ b/hosts/iron/services/default.nix @@ -16,5 +16,6 @@ ./remarkable.nix ./sturzbach.nix ./unifi-controller.nix + ./whatsapp.nix ]; } diff --git a/hosts/iron/services/esphome/default.nix b/hosts/iron/services/esphome/default.nix index 53a3c0f..0e81496 100644 --- a/hosts/iron/services/esphome/default.nix +++ b/hosts/iron/services/esphome/default.nix @@ -2,9 +2,6 @@ args@{ lib, pkgs, config, custom-utils, ... }: let ports = import ../../ports.nix args; cfg = config.services.esphome; - devices = [ - ./yeelight-meteorite.yaml - ]; cfgdir = pkgs.stdenvNoCC.mkDerivation { name = "esphome-config"; src = ./devices; @@ -22,18 +19,14 @@ in { sops.secrets.esphome = { sopsFile = ../../secrets.yaml; + restartUnits = [ config.systemd.services.esphome.name ]; }; services.esphome = { enable = true; address = "127.0.0.1"; port = ports.esphome.tcp; - package = pkgs.master.esphome; - #package = pkgs.esphome.overrideAttrs (attrs: { - # makeWrapperArgs = attrs.makeWrapperArgs ++ [ - # "--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ pkgs.stdenv.cc.cc.lib ]}" - # ]; - #}); + package = pkgs.esphome; }; systemd.services.esphome = { @@ -41,13 +34,13 @@ in "PLATFORMIO_CORE_DIR" = lib.mkForce "/tmp/.platformio"; }; serviceConfig = { - BindPaths = [ - "/var/lib/esphome" - "/var/lib/private/esphome" - ]; BindReadOnlyPaths = [ "/nix/store" - "${cfgdir}" + cfgdir + "%d/secrets.yaml:/var/lib/esphome/secrets.yaml" + ]; + BindPaths = [ + "/var/lib/esphome" ]; DeviceAllow = [ "char-ttyACM rw" @@ -55,8 +48,7 @@ in "char-ttyUSB rw" ]; ExecStartPre = [ - "${pkgs.rsync}/bin/rsync -a --delete --exclude=.esphome --exclude=.platformio --exclude=.gitignore '${cfgdir}/' '/var/lib/esphome/'" - "${pkgs.coreutils}/bin/ln -snf '%d/secrets.yaml' '/var/lib/esphome/secrets.yaml'" + "${pkgs.rsync}/bin/rsync -a --delete --checksum --exclude secrets.yaml --exclude=.esphome --exclude=.platformio --exclude=.gitignore '${cfgdir}/' '/var/lib/esphome/'" ]; LoadCredential = "secrets.yaml:${config.sops.secrets.esphome.path}"; PrivateTmp = true; diff --git a/hosts/iron/services/esphome/devices/badspiegel.yaml b/hosts/iron/services/esphome/devices/badspiegel.yaml index 9f8989c..2ee052b 100644 --- a/hosts/iron/services/esphome/devices/badspiegel.yaml +++ b/hosts/iron/services/esphome/devices/badspiegel.yaml @@ -15,7 +15,7 @@ esphome: color_temperature: 2700 K esp32: - board: wemos_d1_uno32 + board: az-delivery-devkit-v4 framework: type: arduino version: recommended @@ -41,16 +41,16 @@ wifi: output: - platform: ledc - pin: GPIO17 + pin: GPIO33 id: output_background_warm - platform: ledc - pin: GPIO25 + pin: GPIO32 id: output_background_cold - platform: ledc - pin: GPIO16 + pin: GPIO25 id: output_front_warm - platform: ledc - pin: GPIO26 + pin: GPIO14 id: output_front_cold light: @@ -77,39 +77,50 @@ switch: - platform: gpio name: "Heating" id: heating - pin: GPIO2 + pin: GPIO26 icon: "mdi:thermometer" - platform: gpio name: "Soundsystem" id: soundsystem - pin: GPIO4 + pin: GPIO23 icon: "mdi:speaker" esp32_touch: # setup_mode: true + +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + - platform: dht + pin: GPIO22 + temperature: + name: "Temperatur" + id: temperature + humidity: + name: "Feuchtigkeit" + id: humidity + accuracy_decimals: 1 + update_interval: 60s + binary_sensor: # ESP32 touch pins: 4, 13, 27, 32, 33 -# - platform: esp32_touch -# name: "touch pad GPIO13" -# pin: GPIO13 -# threshold: 1000 -# on_press: -# internal: true - platform: esp32_touch - name: "touch pad GPIO12" - pin: GPIO12 - threshold: 900 + name: "touch pad GPIO13" + pin: GPIO13 + threshold: 923 on_press: then: - light.toggle: id: front_light internal: true - platform: esp32_touch - name: "touch pad GPIO14" - pin: GPIO14 - threshold: 900 + name: "touch pad GPIO27" + pin: GPIO27 + threshold: 1125 on_press: then: - light.toggle: id: background_light + internal: true diff --git a/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml b/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml index 0edcf9f..802e77f 100644 --- a/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml +++ b/hosts/iron/services/esphome/devices/chinafrickeldeckenleuchte.yaml @@ -5,6 +5,11 @@ esp8266: logger: +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + bp5758d: data_pin: GPIO4 clock_pin: GPIO5 diff --git a/hosts/iron/services/esphome/devices/fussbodenheizung.yaml b/hosts/iron/services/esphome/devices/fussbodenheizung.yaml index 30ff9ce..616f5a5 100644 --- a/hosts/iron/services/esphome/devices/fussbodenheizung.yaml +++ b/hosts/iron/services/esphome/devices/fussbodenheizung.yaml @@ -56,6 +56,9 @@ switch: icon: "mdi:electric-switch" sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s - platform: dht pin: GPIO2 temperature: @@ -72,50 +75,60 @@ sensor: - platform: homeassistant id: humidity_kitchen entity_id: sensor.kueche_leiste_feuchtigkeit + - platform: homeassistant + id: temperature_bathroom + entity_id: sensor.badspiegel_temperatur + - platform: homeassistant + id: humidity_bathroom + entity_id: sensor.badspiegel_feuchtigkeit climate: - #- platform: thermostat - # name: "Bad" - # #sensor: heating_livingroom - # #humidity_sensor: - # min_heating_off_time: 300s - # min_heating_run_time: 300s - # min_idle_time: 30s - # heat_action: - # - switch.turn_on: relay_1 - # idle_action: - # - switch.turn_off: relay_1 - # default_preset: zuhause - # on_boot_restore_from: memory - # preset: - # - name: zuhause - # default_target_temperature_low: 22 °C - # - name: abwesend - # default_target_temperature_low: 16 °C - #- platform: thermostat - # name: "Schlafzimmer" - # #sensor: heating_livingroom - # #humidity_sensor: - # min_heating_off_time: 300s - # min_heating_run_time: 300s - # min_idle_time: 30s - # heat_action: - # - switch.turn_on: relay_2 - # idle_action: - # - switch.turn_off: relay_2 - # default_preset: zuhause - # on_boot_restore_from: memory - # preset: - # - name: zuhause - # default_target_temperature_low: 16 °C - # - name: abwesend - # default_target_temperature_low: 15 °C + - platform: thermostat + name: "Bad" + sensor: temperature_bathroom + humidity_sensor: humidity_bathroom + min_heating_off_time: 1s + min_heating_run_time: 1s + min_idle_time: 30s + heat_action: + - switch.turn_on: relay_1 + idle_action: + - switch.turn_off: relay_1 + default_preset: zuhause + on_boot_restore_from: memory + preset: + - name: morgens + default_target_temperature_low: 23 °C + - name: zuhause + default_target_temperature_low: 20 °C + - name: abwesend + default_target_temperature_low: 16 °C + - platform: thermostat + name: "Schlafzimmer" + #sensor: heating_livingroom + #humidity_sensor: + sensor: temperature_local # FIXME + humidity_sensor: humidity # FIXME + min_heating_off_time: 1s + min_heating_run_time: 1s + min_idle_time: 30s + heat_action: + - switch.turn_on: relay_2 + idle_action: + - switch.turn_off: relay_2 + default_preset: zuhause + on_boot_restore_from: memory + preset: + - name: zuhause + default_target_temperature_low: 16 °C + - name: abwesend + default_target_temperature_low: 15 °C - platform: thermostat name: "West" sensor: temperature_kitchen humidity_sensor: humidity_kitchen - min_heating_off_time: 300s - min_heating_run_time: 300s + min_heating_off_time: 1s + min_heating_run_time: 1s min_idle_time: 30s heat_action: - switch.turn_on: relay_3 @@ -132,8 +145,8 @@ climate: name: "Mitte" sensor: temperature_local humidity_sensor: humidity - min_heating_off_time: 300s - min_heating_run_time: 300s + min_heating_off_time: 1s + min_heating_run_time: 1s min_idle_time: 30s heat_action: - switch.turn_on: relay_4 @@ -150,8 +163,8 @@ climate: name: "Ost" sensor: temperature_local # FIXME #humidity_sensor: - min_heating_off_time: 300s - min_heating_run_time: 300s + min_heating_off_time: 1s + min_heating_run_time: 1s min_idle_time: 30s heat_action: - switch.turn_on: relay_5 diff --git a/hosts/iron/services/esphome/devices/kueche-leiste.yaml b/hosts/iron/services/esphome/devices/kueche-leiste.yaml index de9d8cb..3b8f396 100644 --- a/hosts/iron/services/esphome/devices/kueche-leiste.yaml +++ b/hosts/iron/services/esphome/devices/kueche-leiste.yaml @@ -62,6 +62,9 @@ light: gamma_correct: 0 sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s - platform: dht pin: GPIO5 temperature: diff --git a/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml b/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml index 0141c46..737d62e 100644 --- a/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml +++ b/hosts/iron/services/esphome/devices/led-panel-schreibtisch.yaml @@ -39,6 +39,11 @@ esp32: logger: +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + output: - platform: ledc pin: GPIO1 diff --git a/hosts/iron/services/esphome/devices/pflanzenleuchte.yaml b/hosts/iron/services/esphome/devices/pflanzenleuchte.yaml index d961943..d66b2b2 100644 --- a/hosts/iron/services/esphome/devices/pflanzenleuchte.yaml +++ b/hosts/iron/services/esphome/devices/pflanzenleuchte.yaml @@ -27,6 +27,11 @@ wifi: fast_connect: On output_power: 8.5 +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + output: - platform: ledc pin: GPIO0 diff --git a/hosts/iron/services/esphome/devices/pinspot.yaml b/hosts/iron/services/esphome/devices/pinspot.yaml new file mode 100644 index 0000000..98fc572 --- /dev/null +++ b/hosts/iron/services/esphome/devices/pinspot.yaml @@ -0,0 +1,52 @@ +esphome: + name: "pinspot" + friendly_name: "Pinspot" + platformio_options: + board_build.flash_mode: dio + +esp32: + board: esp32-c3-devkitm-1 + variant: ESP32C3 + framework: + type: esp-idf + +logger: + +api: + encryption: + key: !secret apikey_pinspot + +ota: + password: !secret otapass_pinspot + +wifi: + ssid: !secret wifi_ssid_bw + password: !secret wifi_password_bw + domain: .iot.bw.jalr.de + enable_on_boot: True + fast_connect: On + output_power: 8.5 + +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + +output: + - platform: ledc + pin: GPIO1 + id: output_led_brightness + min_power: 0.028 + zero_means_zero: true + - platform: ledc + pin: GPIO4 + inverted: true + id: output_led_colortemp + +light: + - platform: color_temperature + name: "Pinspot" + color_temperature: output_led_colortemp + brightness: output_led_brightness + cold_white_color_temperature: 6000 K + warm_white_color_temperature: 2700 K diff --git a/hosts/iron/services/esphome/devices/tuerschloss.yaml b/hosts/iron/services/esphome/devices/tuerschloss.yaml index b662b56..71863cf 100644 --- a/hosts/iron/services/esphome/devices/tuerschloss.yaml +++ b/hosts/iron/services/esphome/devices/tuerschloss.yaml @@ -27,6 +27,11 @@ wifi: fast_connect: On output_power: 8.5 +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + output: - platform: gpio pin: diff --git a/hosts/iron/services/esphome/devices/tuersprechanlage.yaml b/hosts/iron/services/esphome/devices/tuersprechanlage.yaml index cb676ad..cc0ede7 100644 --- a/hosts/iron/services/esphome/devices/tuersprechanlage.yaml +++ b/hosts/iron/services/esphome/devices/tuersprechanlage.yaml @@ -29,10 +29,15 @@ wifi: power_save_mode: none output_power: 10 +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + binary_sensor: - platform: gpio name: Etagenklingel - id: etagenklingel + id: floor_bell pin: number: GPIO16 mode: @@ -43,7 +48,7 @@ binary_sensor: - platform: gpio name: Treppenlicht - id: treppenlicht + id: staircase_light pin: number: GPIO18 mode: @@ -52,19 +57,39 @@ binary_sensor: filters: - invert - delayed_off: 10s + on_press: + then: + - output.turn_on: output_staircase_light_ssr + - delay: 200ms + - output.turn_off: output_staircase_light_ssr output: - platform: gpio pin: GPIO15 - id: btn_door + id: output_door_opener + - platform: ledc + pin: + number: GPIO33 + inverted: true + id: output_staircase_light_ssr + frequency: 50000 + min_power: 0 + max_power: 0.12 button: - platform: template name: "Türöffner" - id: tueroeffner + id: btn_tueroeffner icon: mdi:lock-open on_press: - - logger.log: "Button pressed" - - output.turn_on: btn_door + - output.turn_on: output_door_opener - delay: 500ms - - output.turn_off: btn_door + - output.turn_off: output_door_opener + - platform: template + name: "Treppenlicht" + id: btn_staircase_light + icon: mdi:stairs + on_press: + - output.turn_on: output_staircase_light_ssr + - delay: 200ms + - output.turn_off: output_staircase_light_ssr diff --git a/hosts/iron/services/esphome/devices/waschmaschine.yaml b/hosts/iron/services/esphome/devices/waschmaschine.yaml index 8e4f376..82e25a3 100644 --- a/hosts/iron/services/esphome/devices/waschmaschine.yaml +++ b/hosts/iron/services/esphome/devices/waschmaschine.yaml @@ -27,6 +27,9 @@ external_components: components: [ miele_w433 ] sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s - platform: miele_w433 enable_7segment_pin: 27 clock_pin: 14 @@ -38,4 +41,83 @@ sensor: name: "in Betrieb" current_operation: name: "aktueller Vorgang" + id: current_operation +number: + - platform: template + name: "Waschmittelmenge" + id: detergent_dosing + min_value: 25.0 + max_value: 150.0 + step: 1 + unit_of_measurement: "ml" + icon: 'mdi:cup-water' + restore_value: true + initial_value: 75.0 + optimistic: true + - platform: template + name: "Waschmittelvorrat" + id: detergent_supply + min_value: 0.0 + max_value: 5000 + step: 1.0 + unit_of_measurement: "ml" + icon: 'mdi:cup-water' + restore_value: true + initial_value: 0 + optimistic: true + +stepper: + - platform: a4988 + id: detergent_stepper + step_pin: GPIO32 + sleep_pin: GPIO33 + dir_pin: GPIO25 # not used + max_speed: 600 steps/s + acceleration: 125 steps/s^2 + deceleration: 125 steps/s^2 + +globals: + - id: dosing_enabled + type: bool + restore_value: false + initial_value: 'true' + +interval: + - interval: 1s + then: + if: + condition: + and: + #- lambda: return id(current_operation).state == "Einw/Vorwäsche"; + - lambda: return id(current_operation).state == "Waschen"; + - lambda: return id(dosing_enabled); + then: + - lambda: &dosing |- + float dose = id(detergent_dosing).state; + float current_supply = id(detergent_supply).state; + if (current_supply >= dose) { + id(detergent_stepper).set_target(dose * 125); + id(detergent_stepper).report_position(0); + id(detergent_supply).publish_state(current_supply - dose); + ESP_LOGD("custom", "Waschmitteldosierung durchgeführt: %.2f ml, verbleibender Vorrat: %.2f ml", dose, current_supply - dose); + } else { + ESP_LOGW("custom", "Nicht genug Waschmittelvorrat! Aktueller Vorrat: %.2f ml, gewünschte Dosierung: %.2f ml", current_supply, dose); + } + - lambda: |- + id(dosing_enabled) = false; + - interval: 1s + then: + if: + condition: + lambda: return id(current_operation).state == "Knitterschutz/Ende"; + then: + - lambda: |- + id(dosing_enabled) = true; + +button: + - platform: template + name: "Waschmitteldosierung auslösen" + icon: "mdi:cup-water" + on_press: + - lambda: *dosing diff --git a/hosts/iron/services/esphome/devices/yeelight-meteorite.yaml b/hosts/iron/services/esphome/devices/yeelight-meteorite.yaml index 842fceb..e6b1a4b 100644 --- a/hosts/iron/services/esphome/devices/yeelight-meteorite.yaml +++ b/hosts/iron/services/esphome/devices/yeelight-meteorite.yaml @@ -36,6 +36,11 @@ wifi: gateway: 10.20.0.1 subnet: 255.255.240.0 +sensor: + - platform: wifi_signal + name: "WiFi Signal Sensor" + update_interval: 60s + output: - platform: ledc pin: GPIO19 diff --git a/hosts/iron/services/matrix.nix b/hosts/iron/services/matrix.nix index 79a184d..93e413d 100644 --- a/hosts/iron/services/matrix.nix +++ b/hosts/iron/services/matrix.nix @@ -28,17 +28,6 @@ in host = "turn.jalr.de"; sharedSecretFile = config.sops.secrets.synapse-turn-shared-secret.path; }; - mautrix-whatsapp = { - enable = true; - port = ports.mautrix-whatsapp.tcp; - settings.bridge.permissions = { - # Only one user since using the name from the address book does not - # work with multiple users - #"@jalr:jalr.de" = 100; - "@jalr:jalr.de" = "admin"; - "jalr.de" = "user"; - }; - }; mautrix-signal = { enable = true; port = ports.mautrix-signal.tcp; diff --git a/hosts/iron/services/navidrome.nix b/hosts/iron/services/navidrome.nix index 4f1044a..755f26c 100644 --- a/hosts/iron/services/navidrome.nix +++ b/hosts/iron/services/navidrome.nix @@ -7,6 +7,7 @@ let Address = "127.0.0.1"; Port = ports.navidrome.tcp; DevActivityPanel = false; + MusicFolder = "/var/lib/navidrome/music"; }; passwordEncryptionKeyFile = config.sops.secrets.navidrome-password-encryption-key.path; configFile = (pkgs.formats.json { }).generate "navidrome.json" settings; diff --git a/hosts/iron/services/whatsapp.nix b/hosts/iron/services/whatsapp.nix new file mode 100644 index 0000000..ae88ae2 --- /dev/null +++ b/hosts/iron/services/whatsapp.nix @@ -0,0 +1,88 @@ +args@{ config, pkgs, custom-utils, ... }: + +let + ports = import ../ports.nix args; + shutdownAndroidVm = pkgs.writeShellScript "shutdown-android-vm" '' + set -e + export PATH=${pkgs.lib.makeBinPath [pkgs.libvirt pkgs.gnused pkgs.android-tools]} + + if [ "$(virsh domstate "$1")" = "running" ]; then + host="$(virsh -q domifaddr --domain "$1" | sed -n -r 's#.*ipv4\s*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/[0-9]+$#\1#p')" + port=5555 + adb connect "$host:$port" + adb -s "$host:$port" shell -- reboot -p + fi + ''; + vmName = "Bliss-v16"; +in +{ + jalr.matrix.mautrix-whatsapp = { + enable = true; + port = ports.mautrix-whatsapp.tcp; + settings.bridge.permissions = { + # Only one user since using the name from the address book does not + # work with multiple users + #"@jalr:jalr.de" = 100; + "@jalr:jalr.de" = "admin"; + "jalr.de" = "user"; + }; + }; + + jalr.libvirt.enable = true; + + systemd.services.libvirt-guests.serviceConfig.ExecStop = [ + "" + "${shutdownAndroidVm} ${vmName}" + "${pkgs.libvirt}/libexec/libvirt-guests.sh stop" + ]; + + systemd.services."whatsapp@" = { + description = "Start Android VM, wait for WhatsApp and shut down VM."; + serviceConfig = { + Type = "oneshot"; + }; + environment.VM = "%i"; + script = '' + export PATH=${pkgs.lib.makeBinPath [pkgs.libvirt pkgs.gnused pkgs.android-tools pkgs.coreutils]} + + domstate="$(virsh domstate "$VM")" + + if [ "$domstate" != "running" ]; then + virsh start "$VM" + fi + + echo "Wait until IP of Android VM is known" + while :; do + host="$(virsh -q domifaddr --domain "$VM" | sed -n -r 's#.*ipv4\s*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/[0-9]+$#\1#p')" + if [ "$host" ]; then + break + fi + sleep 1 + done + + port=5555 + adb connect "$host:$port" + + echo "Waiting for WhatsApp" + while ! adb -s "$host:$port" shell -- pgrep com.whatsapp > /dev/null; do + sleep 1 + done + + echo "Sleeping..." + sleep 5m + + echo "Shutting down Android" + adb -s "$host:$port" shell -- reboot -p + ''; + }; + systemd.timers."whatsapp-${vmName}" = { + description = "Start Android VM to run WhatsApp"; + after = [ "network.target" ]; + wantedBy = [ "timers.target" ]; + timerConfig = { + Persistent = true; + OnCalendar = "*-*-* 2:00:00"; + Unit = "whatsapp@${vmName}.service"; + }; + }; +} diff --git a/hosts/magnesium/ports.nix b/hosts/magnesium/ports.nix index 0fa666e..7401906 100644 --- a/hosts/magnesium/ports.nix +++ b/hosts/magnesium/ports.nix @@ -5,9 +5,10 @@ custom-utils.validatePortAttrset { coturn-plain = { tcp = [ 3478 3479 ]; udp = [ 3478 3479 ]; }; coturn-relay.udp.range = [ 49160 49200 ]; coturn-tls = { tcp = [ 5349 5350 ]; udp = [ 5349 5350 ]; }; + forgejo-ssh.tcp = 2022; mosquitto.tcp = 1883; nginx-http.tcp = 80; nginx-https.tcp = 443; + ntfy.tcp = 12474; wireguard-public-ip-tunnel.udp = 51000; - forgejo-ssh.tcp = 2022; } diff --git a/hosts/magnesium/services/default.nix b/hosts/magnesium/services/default.nix index 9737c6c..ab5d185 100644 --- a/hosts/magnesium/services/default.nix +++ b/hosts/magnesium/services/default.nix @@ -4,6 +4,7 @@ ./forgejo.nix ./gitlab-runner.nix ./mosquitto.nix + ./ntfy.nix ./public-ip-tunnel.nix ./webserver.nix ]; diff --git a/hosts/magnesium/services/forgejo.nix b/hosts/magnesium/services/forgejo.nix index 98042a7..9eef90f 100644 --- a/hosts/magnesium/services/forgejo.nix +++ b/hosts/magnesium/services/forgejo.nix @@ -49,6 +49,10 @@ in }; log.level = "Warn"; }; + dump = { + enable = true; + type = "tar.zst"; + }; }; networking.firewall.allowedTCPPorts = [ cfg.settings.server.SSH_PORT ]; diff --git a/hosts/magnesium/services/ntfy.nix b/hosts/magnesium/services/ntfy.nix new file mode 100644 index 0000000..4533c26 --- /dev/null +++ b/hosts/magnesium/services/ntfy.nix @@ -0,0 +1,34 @@ +args@{ lib, pkgs, config, custom-utils, ... }: +let + cfg = config.services.ntfy-sh; + ports = import ../ports.nix args; + domain = "ntfy.jalr.de"; + datadir = "/var/lib/ntfy-sh"; +in +{ + # ntfy access --auth-file /var/lib/private/ntfy-sh/user.db '*' 'up*' write-only + + services.ntfy-sh = { + enable = true; + settings = { + listen-http = "127.0.0.1:${toString ports.ntfy.tcp}"; + base-url = "https://${domain}"; + behind-proxy = true; + #web-root = "disable"; + #auth-default-access = "read-only"; + attachment-cache-dir = "${datadir}/attachments"; + auth-file = "${datadir}/user.db"; + cache-file = "${datadir}/cache-file.db"; + }; + }; + services.nginx.virtualHosts."${domain}" = { + enableACME = true; + forceSSL = true; + kTLS = true; + locations."/" = { + proxyPass = "http://${cfg.settings.listen-http}/"; + recommendedProxySettings = true; + proxyWebsockets = true; + }; + }; +} diff --git a/modules/qbittorrent/default.nix b/modules/qbittorrent/default.nix index 810685b..6065479 100644 --- a/modules/qbittorrent/default.nix +++ b/modules/qbittorrent/default.nix @@ -59,7 +59,7 @@ in serviceConfig = { Restart = "always"; - ExecStart = "${pkgs.qbittorrent-nox}/bin/qbittorrent-nox --profile=${cfg.configDir} --webui-port=${toString cfg.webuiPort}"; + ExecStart = "${pkgs.master.qbittorrent-nox}/bin/qbittorrent-nox --profile=${cfg.configDir} --webui-port=${toString cfg.webuiPort}"; User = "qbittorrent"; Group = "qbittorrent"; diff --git a/modules/sway.nix b/modules/sway.nix index a35ca05..181f95d 100644 --- a/modules/sway.nix +++ b/modules/sway.nix @@ -28,4 +28,6 @@ lib.mkIf (config.jalr.gui.enable && config.jalr.gui.desktop == "sway") { }; icons.enable = true; }; + + programs.wshowkeys.enable = true; } diff --git a/pkgs/vesc-tool/firmware.nix b/pkgs/vesc-tool/firmware.nix index 9db0fdc..dba61cf 100644 --- a/pkgs/vesc-tool/firmware.nix +++ b/pkgs/vesc-tool/firmware.nix @@ -12,8 +12,8 @@ stdenv.mkDerivation rec { src = fetchFromGitHub { owner = "vedderb"; repo = "bldc"; - rev = "dd3b97b041c325acfb95ac1adb550d28390ea253"; - sha256 = "2Zex2FNkedO4wjG05CQIyVFU0i0/+O9V3LzsxHZOnvg="; + rev = "b6e53d3f28e9fd7a54b266c149abbf8a1c23f80a"; + sha256 = "4Q0sAEglXONL6InlVfwVKtQ2ZXKGhfrVLBevnWyjXZ0="; fetchSubmodules = true; }; @@ -33,7 +33,9 @@ stdenv.mkDerivation rec { ( cd bldc chmod +w . - make -j $NIX_BUILD_CORES fw_410 fw_60 + # print targets: + # make; false + make -j $NIX_BUILD_CORES fw_410 fw_60_mk3 python package_firmware.py ) mkdir -p $out diff --git a/pkgs/vesc-tool/tool.nix b/pkgs/vesc-tool/tool.nix index 3cb591d..b20d1b2 100644 --- a/pkgs/vesc-tool/tool.nix +++ b/pkgs/vesc-tool/tool.nix @@ -12,9 +12,8 @@ stdenv.mkDerivation { src = fetchFromGitHub { owner = "vedderb"; repo = "vesc_tool"; - rev = "211f5d317542a3674df638405485a143a23f67ce"; - sha256 = "liF2JbcrRtVPSySJhY7CHRghsBV3gKRGD40pKVD19wE="; - + rev = "033c95697ec970413ff5c1dbb1988758563d630b"; + sha256 = "LIIE3Z5eoU6mUXmudbRr1iLA3l7338/CsSK8W/iwgf0="; fetchSubmodules = true; }; @@ -34,9 +33,7 @@ stdenv.mkDerivation { dontConfigure = true; buildPhase = '' - for f in ${vesc-firmware}/*; do - ln -s "$f" res/firmwares/ - done + cp -r ${vesc-firmware}/* res/firmwares/ qmake -config release "CONFIG += release_lin build_platinum" make clean make -j $NIX_BUILD_CORES diff --git a/users/README.md b/users/README.md index e245e64..50675ba 100644 --- a/users/README.md +++ b/users/README.md @@ -1,2 +1,7 @@ -# Documentation -[Home Manager Manual](https://rycee.gitlab.io/home-manager/) +# Home Manager +The user configuration is managed by [Home Manager](https://github.com/nix-community/home-manager) + +For a systematic overview of Home Manager and its available options, please see +- the [Home Manager manual](https://nix-community.github.io/home-manager/index.html) and +- the [Home Manager configuration options](https://nix-community.github.io/home-manager/options.html). + diff --git a/users/jalr/modules/alacritty.nix b/users/jalr/modules/alacritty.nix index 3c82e32..77f3b5b 100644 --- a/users/jalr/modules/alacritty.nix +++ b/users/jalr/modules/alacritty.nix @@ -114,7 +114,7 @@ let scrolling.history = 100000; - window.opacity = 0.95; + window.opacity = 0.9; }; settings = { dark = commonSettings // { diff --git a/users/jalr/modules/communication/element-desktop.nix b/users/jalr/modules/communication/element-desktop.nix index c210a98..d634e21 100644 --- a/users/jalr/modules/communication/element-desktop.nix +++ b/users/jalr/modules/communication/element-desktop.nix @@ -4,6 +4,10 @@ let profiles = { "digitaler-dienst" = { description = "Digitaler Dienst"; + icon = pkgs.fetchurl { + url = "https://matrix.digitaler-dienst.gmbh/_matrix/media/v3/thumbnail/digitaler-dienst.gmbh/kfUmmNxpmbsLtdIRvZcxkWAh?width=256&height=256"; + sha256 = "uSxx9avx3I/rDzFnwgEZUwLVktsTeZiSWcDHjPzcUtw="; + }; }; "private" = { description = "private"; @@ -11,10 +15,6 @@ let }; in lib.mkIf nixosConfig.jalr.gui.enable { - home.packages = with pkgs; [ - element-desktop - ]; - # Create an empty directory in nix store # as we want to use Element only with `--profile-dir` xdg.configFile.Element = { @@ -22,21 +22,33 @@ lib.mkIf nixosConfig.jalr.gui.enable { target = "Element"; }; - xdg.desktopEntries = lib.attrsets.mapAttrs' - (name: value: lib.attrsets.nameValuePair "element-desktop-${name}" + (name: value: lib.attrsets.nameValuePair "element-desktop-${name}" ( + let + package = ( + if value ? icon then + pkgs.element-desktop.overrideAttrs + (oldAttrs: { + patchPhase = oldAttrs.patchPhase or "" + '' + rm build/icons/* res/img/* + cp ${value.icon} res/img/element.png + ''; + }) + else pkgs.element-desktop + ); + in { categories = [ "Network" "InstantMessaging" "Chat" ]; exec = toString (pkgs.writeShellScript "element-desktop-${name}" '' - exec element-desktop --profile-dir "$HOME/.config/element-profiles/${name}" + exec "${package}/bin/element-desktop" --profile-dir "$HOME/.config/element-profiles/${name}" ''); genericName = "Matrix Client"; - icon = "element"; + icon = "${package}/share/element/img/element.png"; mimeType = [ "x-scheme-handler/element" ]; name = "Element ${value.description}"; terminal = false; type = "Application"; } - ) + )) profiles; } diff --git a/users/jalr/modules/default.nix b/users/jalr/modules/default.nix index eb4a37f..eaa4602 100644 --- a/users/jalr/modules/default.nix +++ b/users/jalr/modules/default.nix @@ -21,7 +21,7 @@ ./kicad.nix ./mpv.nix ./mute-indicator.nix - ./mycli.nix + ./mycli ./neo.nix ./neovim.nix ./nix-index.nix diff --git a/users/jalr/modules/fish.nix b/users/jalr/modules/fish.nix index 63c7692..0ca1af4 100644 --- a/users/jalr/modules/fish.nix +++ b/users/jalr/modules/fish.nix @@ -171,6 +171,7 @@ xdg.configFile."fish/completions/mycli.fish".text = '' complete -e -c mycli + complete -c mycli -f complete -c mycli -f -s h -l host -d "Host address of the database." complete -c mycli -f -s P -l port -d "Port number to use for connection." complete -c mycli -f -s u -l user -d "User name to connect to the database." @@ -193,6 +194,10 @@ complete -c mycli -f -s d -l dsn -r -a '(mycli --list-dsn)' ''; + xdg.configFile."fish/completions/myssh.fish".text = '' + complete -c myssh -f -a '(myssh --list)' + ''; + xdg.configFile."fish/completions/just.fish".source = pkgs.runCommand "just-fish-completions" { } '' ${pkgs.just}/bin/just --completions fish > $out ''; diff --git a/users/jalr/modules/mycli.nix b/users/jalr/modules/mycli/default.nix similarity index 93% rename from users/jalr/modules/mycli.nix rename to users/jalr/modules/mycli/default.nix index bcc9dd1..f688679 100644 --- a/users/jalr/modules/mycli.nix +++ b/users/jalr/modules/mycli/default.nix @@ -6,7 +6,7 @@ let ) ini; - solarized = import ./solarized.nix; + solarized = import ../solarized.nix; config = { main = { @@ -133,8 +133,18 @@ let }; in { - home.packages = with pkgs; [ - mycli + home.packages = [ + pkgs.mycli + (pkgs.stdenv.mkDerivation { + name = "myssh"; + propagatedBuildInputs = [ + (pkgs.python3.withPackages (pp: with pp; [ + pyyaml + ])) + ]; + dontUnpack = true; + installPhase = "install -Dm755 ${./myssh.py} $out/bin/myssh"; + }) ]; xdg.configFile = lib.attrsets.mapAttrs' diff --git a/users/jalr/modules/mycli/myssh.py b/users/jalr/modules/mycli/myssh.py new file mode 100755 index 0000000..c79b430 --- /dev/null +++ b/users/jalr/modules/mycli/myssh.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +import argparse +import json +import os +import subprocess +import sys +import yaml + + +def get_db_connecition_from_typo3_config(ssh_host, ssh_user, config_file): + php_code = """ + 1 + } + + +def connect(connection_name, connection): + if "t3_config" in connection: + db = get_db_connecition_from_typo3_config( + connection["ssh_host"], connection["ssh_user"], connection["t3_config"] + ) + db_host = db["host"] + db_user = db["user"] + db_password = db["password"] + db_name = db["dbname"] + elif "staging_level" in connection: + env = get_db_connection_from_env_file( + connection["ssh_host"], connection["ssh_user"], connection["staging_level"] + ) + db_host = env["TYPO3_DB_HOST"] + db_user = env["TYPO3_DB_USER"] + db_password = env["TYPO3_DB_PASSWORD"] + db_name = env["TYPO3_DB_DATABASE"] + + os.execl( + "/usr/bin/env", + "env", + "mycli", + "--prompt", + f"{connection_name}>", + "--ssh-user", + connection["ssh_user"], + "--ssh-host", + connection["ssh_host"], + "-h", + db_host, + "-u", + db_user, + "-p", + db_password, + db_name, + ) + + +def read_config(path): + with open(path, "r") as fh: + config = yaml.safe_load(fh.read()) + + return config + + +def main(): + connections = read_config(os.path.expanduser("~/.config/mycli/connections.yaml")) + + parser = argparse.ArgumentParser() + parser.add_argument("--list", action="store_true") + parser.add_argument("connection", type=str, nargs="?") + + args = vars(parser.parse_args()) + + if args["list"]: + print("\n".join(connections.keys())) + + if args["connection"] is not None: + connect(args["connection"], connections[args["connection"]]) + + +if __name__ == "__main__": + main() diff --git a/users/jalr/modules/neovim.nix b/users/jalr/modules/neovim.nix index ee25579..ad9fe28 100644 --- a/users/jalr/modules/neovim.nix +++ b/users/jalr/modules/neovim.nix @@ -227,4 +227,7 @@ in setlocal spell setlocal colorcolumn=81 ''; + xdg.configFile."nvim/ftplugin/sshconfig.vim".text = '' + setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab + ''; } diff --git a/users/jalr/modules/python.nix b/users/jalr/modules/python.nix index 9a620b3..d73b0e3 100644 --- a/users/jalr/modules/python.nix +++ b/users/jalr/modules/python.nix @@ -1,8 +1,10 @@ { nixosConfig, lib, pkgs, ... }: lib.mkIf nixosConfig.jalr.workstation.enable { home.packages = with pkgs; [ - python3 - python3Packages.virtualenv - python3Packages.ipython + (python3.withPackages (pp: with pp; [ + ipython + pyyaml + virtualenv + ])) ]; } diff --git a/users/jalr/modules/sway/default.nix b/users/jalr/modules/sway/default.nix index b53f2fb..e878052 100644 --- a/users/jalr/modules/sway/default.nix +++ b/users/jalr/modules/sway/default.nix @@ -286,6 +286,13 @@ in criteria = { app_id = "firefox"; title = "Firefox — Sharing Indicator"; }; command = "kill"; } + { + criteria = { + app_id = "firefox-esr"; + title = "Extension: \\\\(Tree Style Tab\\\\) - Close tabs\\\\? — Mozilla Firefox"; + }; + command = "floating enable"; + } ]; window.border = 2;