47 Commits

Author SHA1 Message Date
mjallen18
a1bcccca09 filtering 2026-04-20 10:58:29 -05:00
mjallen18
3e5f6d6862 filtering 2026-04-20 10:56:07 -05:00
f51c362086 upd 2026-04-17 19:23:32 -05:00
mjallen18
a158d401ae filtering 2026-04-16 20:12:18 -05:00
mjallen18
95842b22f0 agh 2026-04-16 19:24:59 -05:00
mjallen18
3977227889 idk 2026-04-16 19:22:57 -05:00
mjallen18
cb8ef87229 nuc 2026-04-16 13:03:55 -05:00
mjallen18
44b3459d49 lol 2026-04-16 13:01:27 -05:00
mjallen18
c59ac2ccb6 kern 2026-04-16 12:40:03 -05:00
mjallen18
1767debfd8 upd 2026-04-16 12:38:07 -05:00
mjallen18
95f08a258e hue 2026-04-16 09:58:32 -05:00
mjallen18
c5ba5d4164 bluetooth 2026-04-15 11:39:41 -05:00
mjallen18
004eb3c29c esphome 2026-04-14 17:45:29 -05:00
mjallen18
616d357a59 cyd 2026-04-14 17:42:19 -05:00
mjallen18
d4481923a8 cyd 2026-04-14 17:38:59 -05:00
mjallen18
246f65190e cyd 2026-04-14 17:37:38 -05:00
mjallen18
b6df62a875 cyd 2026-04-14 17:31:10 -05:00
mjallen18
8d81a1d6e1 cyd 2026-04-14 17:29:22 -05:00
mjallen18
7368968fd5 cyd 2026-04-14 17:25:44 -05:00
mjallen18
9a719479bc cyd 2026-04-14 17:15:13 -05:00
mjallen18
38922cd526 cyd 2026-04-14 17:01:48 -05:00
mjallen18
26e7fffbd1 cyd 2026-04-14 16:56:12 -05:00
mjallen18
9792f86548 cyd 2026-04-14 16:54:32 -05:00
mjallen18
dd9fa58c5c cyd 2026-04-14 16:46:58 -05:00
mjallen18
db620cd22a cyd 2026-04-14 16:36:35 -05:00
mjallen18
dab3a37b0a cyd 2026-04-14 16:18:33 -05:00
mjallen18
74b1825d4d cyd 2026-04-14 16:12:54 -05:00
mjallen18
c3abeb846d ip 2026-04-13 14:22:27 -05:00
mjallen18
d676b6dc1e nuc 2026-04-13 14:11:45 -05:00
mjallen18
86fffbd512 upd 2026-04-13 13:25:52 -05:00
mjallen18
1b5f695f40 todo remove 2026-04-13 09:41:40 -05:00
mjallen18
9491c0356d grafana 2026-04-13 09:41:27 -05:00
152efb84da esp 2026-04-10 09:49:19 -05:00
26d5a8c686 esp 2026-04-10 09:48:58 -05:00
mjallen18
ee55a543fa caddy int 2026-04-09 15:01:01 -05:00
mjallen18
7cc6732a7e caddy int 2026-04-09 14:57:27 -05:00
mjallen18
b73ad049e7 darwin 2026-04-09 11:20:29 -05:00
mjallen18
5d23b3db93 .face 2026-04-09 11:03:35 -05:00
mjallen18
aa609630a1 darwin 2026-04-09 10:35:50 -05:00
mjallen18
1e1eb9886c darwin 2026-04-09 10:32:06 -05:00
9c326f5768 neb 2026-04-08 17:36:21 -05:00
e8cae7fff1 vesktop 2026-04-08 17:32:32 -05:00
88b9d5309f vesktop 2026-04-08 17:23:36 -05:00
d44d03d0b1 vesktop 2026-04-08 17:14:32 -05:00
4ac7463a1f ... 2026-04-08 16:11:17 -05:00
mjallen18
b354dc202a nas 2026-04-08 16:08:00 -05:00
mjallen18
079493b55e nas 2026-04-08 16:08:00 -05:00
53 changed files with 3132 additions and 365 deletions

175
flake.lock generated
View File

@@ -25,7 +25,7 @@
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"napalm": "napalm", "napalm": "napalm",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs-stable"
], ],
"pyproject-build-systems": "pyproject-build-systems", "pyproject-build-systems": "pyproject-build-systems",
"pyproject-nix": "pyproject-nix", "pyproject-nix": "pyproject-nix",
@@ -33,11 +33,11 @@
"uv2nix": "uv2nix" "uv2nix": "uv2nix"
}, },
"locked": { "locked": {
"lastModified": 1774079362, "lastModified": 1776085803,
"narHash": "sha256-HkoEWTxU5gNigcnhIa3GXukHqC5xGmgVaLICGUKlpdo=", "narHash": "sha256-JvvWVbXJYSY8qOReMbAOD4lxcN2cjKV6lg/jLz8CEuY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "authentik-nix", "repo": "authentik-nix",
"rev": "1f279763d8b4a9138c01f1021f53e09bc2c54eb9", "rev": "4370b561c8bafb59773ce3a518506bcf1161dbdb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -49,16 +49,16 @@
"authentik-src": { "authentik-src": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1772567399, "lastModified": 1775573258,
"narHash": "sha256-0Vpf1hj9C8r+rhrCgwoNazpQ+mwgjdjDhuoKCxYQFWw=", "narHash": "sha256-Xq7JGI/8ppIydIuWd9KRJKUrh7UpeniwvZ4NAtXbYJ4=",
"owner": "goauthentik", "owner": "goauthentik",
"repo": "authentik", "repo": "authentik",
"rev": "0dccbd4193c45c581e9fb7cd89df0c1487510f1f", "rev": "5249546862986202b901c2afd860992ec48c6ef6",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "goauthentik", "owner": "goauthentik",
"ref": "version/2026.2.1", "ref": "version/2026.2.2",
"repo": "authentik", "repo": "authentik",
"type": "github" "type": "github"
} }
@@ -151,11 +151,11 @@
"cachyos-kernel": { "cachyos-kernel": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1775145950, "lastModified": 1776183001,
"narHash": "sha256-AfVja9nvYHm0BHbuTvn+K8rKfLmPl5QjoiNecp9HOJU=", "narHash": "sha256-lvLKB5dTqjO1S/YonS9ZyWemEjO6QXtN4D76rYEYy4s=",
"owner": "CachyOS", "owner": "CachyOS",
"repo": "linux-cachyos", "repo": "linux-cachyos",
"rev": "b91624f68ceaf5394ef1571f60290dca6ba22b45", "rev": "4224303b6d7a50dd1cc3ffa78864050cc9536eec",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -167,11 +167,11 @@
"cachyos-kernel-patches": { "cachyos-kernel-patches": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1775157685, "lastModified": 1776355454,
"narHash": "sha256-g8HgH7gADoEnrBN30BK3pz7+M2pT/p3xtfRFEuEov5w=", "narHash": "sha256-b9Hc0sTxjEzDbphzS9yQqxVha/7bsPIs2cQQQvaG45E=",
"owner": "CachyOS", "owner": "CachyOS",
"repo": "kernel-patches", "repo": "kernel-patches",
"rev": "c1ba300617a12d257b5721572b9bbe28efae182f", "rev": "b5e029226df5cc30c103651072d49a7af2878202",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -584,11 +584,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775457580, "lastModified": 1776454077,
"narHash": "sha256-ikws/ssAmG20AGrEwBuwspwPlkubJu34mB+Uz2fJBJs=", "narHash": "sha256-7zSUFWsU0+jlD7WB3YAxQ84Z/iJurA5hKPm8EfEyGJk=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "5de7dbd151b0bd65d45785553d4a22d832733ffc", "rev": "565e5349208fe7d0831ef959103c9bafbeac0681",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -604,11 +604,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775457580, "lastModified": 1776454077,
"narHash": "sha256-ikws/ssAmG20AGrEwBuwspwPlkubJu34mB+Uz2fJBJs=", "narHash": "sha256-7zSUFWsU0+jlD7WB3YAxQ84Z/iJurA5hKPm8EfEyGJk=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "5de7dbd151b0bd65d45785553d4a22d832733ffc", "rev": "565e5349208fe7d0831ef959103c9bafbeac0681",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -658,11 +658,11 @@
"homebrew-cask": { "homebrew-cask": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1775484338, "lastModified": 1776469040,
"narHash": "sha256-ylzTIrXzlCDjz9R3WxFkqqZuPboaVB/W5utc00R3wR4=", "narHash": "sha256-IX5UflSmiXkJnRUCNjzBl4/HMw0NMLQqsfdwA4l0kyU=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-cask", "repo": "homebrew-cask",
"rev": "fdc3c0fbd192076460dfd1d188ef45d68305397c", "rev": "906ff3d493d3e9f50ceb5041fcc14bcfe3d63ff1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -674,11 +674,11 @@
"homebrew-core": { "homebrew-core": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1775481683, "lastModified": 1776461416,
"narHash": "sha256-3PHpmYBLRXoe6r5Bx5H8jri4gW1410Uk8H8ssDS8BOA=", "narHash": "sha256-AqxPJs6cy7ZwsS2ovNuLxUJM+2kgnEi4ECXitf6nb18=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-core", "repo": "homebrew-core",
"rev": "f43fd25bcd80d6af26670239676b830351a50144", "rev": "2aab2c98676928d65d72ce7fc2abd5c7f3634319",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -714,11 +714,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775287496, "lastModified": 1776428236,
"narHash": "sha256-tCBlt+RP85MLrMYntro/YvG7NWktbmFiyItGBo85Tf8=", "narHash": "sha256-+0SyQglnT2xUiyY07155G+O7aUWISELwqtTnfURufRU=",
"owner": "Jovian-Experiments", "owner": "Jovian-Experiments",
"repo": "Jovian-NixOS", "repo": "Jovian-NixOS",
"rev": "0a7a3feb77606db451aa10287ad4c4c8f85922f8", "rev": "eac78fc379ca47f7e21be8539c405e5fb489a857",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -757,11 +757,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775501721, "lastModified": 1776442631,
"narHash": "sha256-IU2KcBvb8tulQ8NKz3OXujzOdeWXXv63sNDTjo8gPu4=", "narHash": "sha256-8AXOo0Yhbi3jpQFe4Ql+0HZDz/p708GdrbZVepNjITo=",
"owner": "ggml-org", "owner": "ggml-org",
"repo": "llama.cpp", "repo": "llama.cpp",
"rev": "2e1f0a889e19a3922db57452268f4574c35c36e5", "rev": "45cac7ca703fb9085eae62b9121fca01d20177f6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -825,11 +825,11 @@
"nixpkgs": "nixpkgs_4" "nixpkgs": "nixpkgs_4"
}, },
"locked": { "locked": {
"lastModified": 1775239578, "lastModified": 1776386586,
"narHash": "sha256-MKJmDHlaxwBcnfCUEA89AwKOOONjOjbjHNNWdSdg5RA=", "narHash": "sha256-eVAUaL/6n8mnmBiPpEVW1NDNVSKLWhYVfycG+P0SvWU=",
"owner": "xddxdd", "owner": "xddxdd",
"repo": "nix-cachyos-kernel", "repo": "nix-cachyos-kernel",
"rev": "beaf7a533ae106c2681de2624da94707f9857f1f", "rev": "c65c3faf90ae07bae101c15ef502f0bcb06c5d74",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -886,11 +886,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775365369, "lastModified": 1775970782,
"narHash": "sha256-DgH5mveLoau20CuTnaU5RXZWgFQWn56onQ4Du2CqYoI=", "narHash": "sha256-7jt9Vpm48Yy5yAWigYpde+HxtYEpEuyzIQJF4VYehhk=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-index-database", "repo": "nix-index-database",
"rev": "cef5cf82671e749ac87d69aadecbb75967e6f6c3", "rev": "bedba5989b04614fc598af9633033b95a937933f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -943,11 +943,11 @@
"nixpkgs": "nixpkgs_7" "nixpkgs": "nixpkgs_7"
}, },
"locked": { "locked": {
"lastModified": 1775444751, "lastModified": 1776396489,
"narHash": "sha256-7rAvWDPdSyeul4E0uKuVezJMN69tutpNGpujOODAX10=", "narHash": "sha256-lF3GX4VvQzff/5gpu5WytHKd2GQXJDrWChmK+JNNRO4=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-vscode-extensions", "repo": "nix-vscode-extensions",
"rev": "ed33cc3b1eabe6c04af158dd7155c4198b6679fe", "rev": "64839596bff67e8280a2fcd829a858d88530aa6f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -962,11 +962,11 @@
"nixpkgs": "nixpkgs_8" "nixpkgs": "nixpkgs_8"
}, },
"locked": { "locked": {
"lastModified": 1774264319, "lastModified": 1776370524,
"narHash": "sha256-aAsO35YtqIdvBhCIKZ0a+OcC8wB0H1+mAoPKBY0jxeQ=", "narHash": "sha256-0Gt5qnjNkIZJdOBfu2u47zgyhYL3WmgUrguUhGSxUdk=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixos-apple-silicon", "repo": "nixos-apple-silicon",
"rev": "9fe29a63b23005acfcd1324a9e78b6241226cdb1", "rev": "f9f0650b45e31b3f6c3e2a0405fa198a286e2741",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -977,11 +977,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1775203647, "lastModified": 1775490113,
"narHash": "sha256-6MWaMLXK9QMndI94CIxeiPafi3wuO+imCtK9tfhsZdw=", "narHash": "sha256-2ZBhDNZZwYkRmefK5XLOusCJHnoeKkoN95hoSGgMxWM=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "80afbd13eea0b7c4ac188de949e1711b31c2b5f0", "rev": "c775c2772ba56e906cbeb4e0b2db19079ef11ff7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1049,22 +1049,6 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-otbr": {
"locked": {
"lastModified": 1766776257,
"narHash": "sha256-MG9DnzBn6TdAztaMPVhW9sjYj2bi9Jcux0F0fJ6LeO4=",
"owner": "mrene",
"repo": "nixpkgs",
"rev": "0c4c97066d555b7d27a0a56ee400130ec51f02ee",
"type": "github"
},
"original": {
"owner": "mrene",
"ref": "openthread-border-router",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1751048012, "lastModified": 1751048012,
@@ -1083,11 +1067,11 @@
}, },
"nixpkgs-stable_2": { "nixpkgs-stable_2": {
"locked": { "locked": {
"lastModified": 1775305101, "lastModified": 1776221942,
"narHash": "sha256-/74n1oQPtKG52Yw41cbToxspxHbYz6O3vi+XEw16Qe8=", "narHash": "sha256-FbQAeVNi7G4v3QCSThrSAAvzQTmrmyDLiHNPvTF2qFM=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "36a601196c4ebf49e035270e10b2d103fe39076b", "rev": "1766437c5509f444c1b15331e82b8b6a9b967000",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1099,27 +1083,27 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1775036866, "lastModified": 1776447299,
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=", "narHash": "sha256-fhkbQptSg6w3CG4TCxalK6UZkj4+Afsi+6p0PuofJ48=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6201e203d09599479a3b3450ed24fa81537ebc4e", "rev": "2c1b4e855f7cded41541747173c697b53c63de9b",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixos-unstable-small",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs_10": { "nixpkgs_10": {
"locked": { "locked": {
"lastModified": 1775126147, "lastModified": 1775888245,
"narHash": "sha256-J0dZU4atgcfo4QvM9D92uQ0Oe1eLTxBVXjJzdEMQpD0=", "narHash": "sha256-nwASzrRDD1JBEu/o8ekKYEXm/oJW6EMCzCRdrwcLe90=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "8d8c1fa5b412c223ffa47410867813290cdedfef", "rev": "13043924aaa7375ce482ebe2494338e058282925",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1163,11 +1147,11 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1775231746, "lastModified": 1776311487,
"narHash": "sha256-EFaDQ0rnuSjKfC/DUKHS4toV4rEBuWhSgyX2Yy0kp00=", "narHash": "sha256-9U8bL9X/0R9cZD3Uc/mN37AWvv5dB4WQqqjLRAxQfas=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0eac666efaa8a9afea2821f9efc7921b4ef39b4e", "rev": "cc1e0e027707ad53dddae39d3b3e992262c7d8c7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1243,16 +1227,16 @@
}, },
"nixpkgs_9": { "nixpkgs_9": {
"locked": { "locked": {
"lastModified": 1775036866, "lastModified": 1776447299,
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=", "narHash": "sha256-fhkbQptSg6w3CG4TCxalK6UZkj4+Afsi+6p0PuofJ48=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6201e203d09599479a3b3450ed24fa81537ebc4e", "rev": "2c1b4e855f7cded41541747173c697b53c63de9b",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixos-unstable-small",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@@ -1292,11 +1276,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1774915545, "lastModified": 1775856943,
"narHash": "sha256-COT4l/+ZddGBvrDVfPf7MEOJxV8EDKame6/aRnNIKcY=", "narHash": "sha256-b7Mp7P+q2Md5AGt4rjHfMcBykzMumFTen10ST++AuTU=",
"owner": "nix-community", "owner": "nix-community",
"repo": "plasma-manager", "repo": "plasma-manager",
"rev": "f3177b3c69fb3f03201098d7fe8ab6422cce7fc1", "rev": "a524a6160e6df89f7673ba293cf7d78b559eb1a5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1337,11 +1321,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775036584, "lastModified": 1775585728,
"narHash": "sha256-zW0lyy7ZNNT/x8JhzFHBsP2IPx7ATZIPai4FJj12BgU=", "narHash": "sha256-8Psjt+TWvE4thRKktJsXfR6PA/fWWsZ04DVaY6PUhr4=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "4e0eb042b67d863b1b34b3f64d52ceb9cd926735", "rev": "580633fa3fe5fc0379905986543fd7495481913d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1424,7 +1408,6 @@
"nixos-apple-silicon": "nixos-apple-silicon", "nixos-apple-silicon": "nixos-apple-silicon",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_9", "nixpkgs": "nixpkgs_9",
"nixpkgs-otbr": "nixpkgs-otbr",
"nixpkgs-stable": "nixpkgs-stable_2", "nixpkgs-stable": "nixpkgs-stable_2",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"plasma-manager": "plasma-manager", "plasma-manager": "plasma-manager",
@@ -1505,11 +1488,11 @@
"nixpkgs": "nixpkgs_10" "nixpkgs": "nixpkgs_10"
}, },
"locked": { "locked": {
"lastModified": 1775365543, "lastModified": 1776119890,
"narHash": "sha256-f50qrK0WwZ9z5EdaMGWOTtALgSF7yb7XwuE7LjCuDmw=", "narHash": "sha256-Zm6bxLNnEOYuS/SzrAGsYuXSwk3cbkRQZY0fJnk8a5M=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "a4ee2de76efb759fe8d4868c33dec9937897916f", "rev": "d4971dd58c6627bfee52a1ad4237637c0a2fb0cd",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1561,11 +1544,11 @@
"tinted-zed": "tinted-zed" "tinted-zed": "tinted-zed"
}, },
"locked": { "locked": {
"lastModified": 1775429060, "lastModified": 1776170745,
"narHash": "sha256-wbFF5cRxQOCzL/wHOKYm21t5AHPH2Lfp0mVPCOAvEoc=", "narHash": "sha256-Tl1aZVP5EIlT+k0+iAKH018GLHJpLz3hhJ0LNQOWxCc=",
"owner": "nix-community", "owner": "nix-community",
"repo": "stylix", "repo": "stylix",
"rev": "d27951a6539951d87f75cf0a7cda8a3a24016019", "rev": "e3861617645a43c9bbefde1aa6ac54dd0a44bfa9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -1712,11 +1695,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1775125835, "lastModified": 1775636079,
"narHash": "sha256-2qYcPgzFhnQWchHo0SlqLHrXpux5i6ay6UHA+v2iH4U=", "narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "75925962939880974e3ab417879daffcba36c4a3", "rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -1,12 +1,8 @@
{ {
inputs = rec { inputs = rec {
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11"; nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
# Fork required: openthread-border-router is not yet in nixpkgs-unstable.
# Used by modules/nixos/homeassistant/services/thread/default.nix
nixpkgs-otbr.url = "github:mrene/nixpkgs/openthread-border-router";
home-manager-unstable = { home-manager-unstable = {
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable"; inputs.nixpkgs.follows = "nixpkgs-unstable";
@@ -47,7 +43,7 @@
authentik-nix = { authentik-nix = {
url = "github:nix-community/authentik-nix"; url = "github:nix-community/authentik-nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs-stable";
}; };
disko = { disko = {

View File

@@ -30,6 +30,7 @@ in
jq jq
] ]
++ (with pkgs.${namespace}; [ ++ (with pkgs.${namespace}; [
hueforge
moondeck-buddy moondeck-buddy
]); ]);
}; };
@@ -37,7 +38,7 @@ in
${namespace} = { ${namespace} = {
sops.enable = true; sops.enable = true;
programs.opencode = enabled; programs.opencode = enabled;
# desktop.plasma = enabled; desktop.plasma = enabled;
}; };
sops.secrets = { sops.secrets = {
@@ -83,11 +84,14 @@ in
viAlias = true; viAlias = true;
vimAlias = true; vimAlias = true;
defaultEditor = true; defaultEditor = true;
withRuby = false;
withPython3 = true;
plugins = [ plugins = [
pkgs.vimPlugins.nvim-tree-lua pkgs.vimPlugins.nvim-tree-lua
{ {
plugin = pkgs.vimPlugins.vim-startify; plugin = pkgs.vimPlugins.vim-startify;
config = "let g:startify_change_to_vcs_root = 0"; config = "let g:startify_change_to_vcs_root = 0";
type = "lua";
} }
]; ];
}; };

View File

@@ -54,7 +54,7 @@ in
ryujinx.enable = true; # Switch (ryubing fork) ryujinx.enable = true; # Switch (ryubing fork)
yuzu.enable = true; # Switch (eden fork) yuzu.enable = true; # Switch (eden fork)
dolphin-emu.enable = true; # GameCube / Wii dolphin-emu.enable = true; # GameCube / Wii
cemu.enable = true; # Wii U cemu.enable = false; # Wii U
melonDS.enable = true; # DS melonDS.enable = true; # DS
citra.enable = true; # 3DS (azahar fork) citra.enable = true; # 3DS (azahar fork)
mgba.enable = true; # Game Boy / GBC mgba.enable = true; # Game Boy / GBC

View File

@@ -188,7 +188,7 @@ in
virt-manager virt-manager
vorta vorta
waydroid-helper waydroid-helper
# winboat winboat
] ]
++ (with pkgs.${namespace}; [ ++ (with pkgs.${namespace}; [
discord-krisp discord-krisp

View File

@@ -179,6 +179,8 @@
otbr = 8880; otbr = 8880;
otbrRest = 8881; otbrRest = 8881;
esphome = 6052; esphome = 6052;
zigbee2mqtt = 8080;
govee2mqtt = 4002;
}; };
}; };
}; };

View File

@@ -8,13 +8,9 @@
# lib.${namespace}.nixSettings.commonSettings # lib.${namespace}.nixSettings.commonSettings
# lib.${namespace}.nixSettings.commonGc # lib.${namespace}.nixSettings.commonGc
{ lib, ... }: { lib, ... }:
let
net = lib.mjallen.network;
in
{ {
nixSettings = { nixSettings = {
commonSubstituters = [ commonSubstituters = [
"http://${net.hosts.nas.lan}:${toString net.ports.nas.attic}/nas-cache"
"https://nixos-apple-silicon.cachix.org" "https://nixos-apple-silicon.cachix.org"
"https://nixos-raspberrypi.cachix.org" "https://nixos-raspberrypi.cachix.org"
"https://nix-community.cachix.org" "https://nix-community.cachix.org"
@@ -22,7 +18,6 @@ in
]; ];
commonTrustedPublicKeys = [ commonTrustedPublicKeys = [
"nas-cache:eK0eRVAt9QNwbkLIyOo9N5Z5+zi6ukI4mSlL196C7Yg="
"nixos-apple-silicon.cachix.org-1:8psDu5SA5dAD7qA0zMy5UT292TxeEPzIz8VVEr2Js20=" "nixos-apple-silicon.cachix.org-1:8psDu5SA5dAD7qA0zMy5UT292TxeEPzIz8VVEr2Js20="
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI=" "nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="

View File

@@ -38,12 +38,12 @@
}; };
# Make ALL external HM modules available globally # Make ALL external HM modules available globally
# Note: sops-nix, nix-index-database, and stylix are already injected
# globally via systems.modules.home in flake.nix; only darwin-specific
# modules that aren't in the global list should go here.
sharedModules = with inputs; [ sharedModules = with inputs; [
sops-nix.homeManagerModules.sops
nix-plist-manager.homeManagerModules.default nix-plist-manager.homeManagerModules.default
nix-index-database.homeModules.nix-index # Add any other darwin-specific external HM modules here
stylix.homeModules.stylix
# Add any other external HM modules here
]; ];
users."mattjallen" = lib.mkAliasDefinitions options.${namespace}.home.extraOptions; users."mattjallen" = lib.mkAliasDefinitions options.${namespace}.home.extraOptions;

View File

@@ -9,10 +9,8 @@ in
{ {
nix = { nix = {
settings = nixSettings.commonSettings // { settings = nixSettings.commonSettings // {
inherit (nixSettings) substituters = nixSettings.commonSubstituters;
commonSubstituters trusted-public-keys = nixSettings.commonTrustedPublicKeys;
commonTrustedPublicKeys
;
}; };
gc = nixSettings.commonGc; gc = nixSettings.commonGc;

View File

@@ -25,24 +25,28 @@ in
programs.plasma = { programs.plasma = {
enable = true; enable = true;
workspace = { configFile.kded5rc = {
colorScheme = "BreezeDark"; "Module-gtkconfig"."autoload" = false;
cursor = {
theme = "breeze_cursors";
size = 24;
};
iconTheme = "breeze-dark";
theme = "breeze-dark";
lookAndFeel = "org.kde.breezedark.desktop";
# Explicitly set Breeze to prevent QT_STYLE_OVERRIDE=kvantum (set by
# Stylix's qt6ct target) from being picked up by KWin/plasmashell, which
# would cause a fatal "module kvantum is not installed" QML error and
# leave the desktop blank.
widgetStyle = "Breeze";
}; };
# input.mice and input.touchpads require device-specific vendorId/productId # workspace = {
# identifiers — configure those per-host in the home config instead. # colorScheme = "BreezeDark";
# cursor = {
# theme = "breeze_cursors";
# size = 24;
# };
# iconTheme = "breeze-dark";
# theme = "breeze-dark";
# lookAndFeel = "org.kde.breezedark.desktop";
# # Explicitly set Breeze to prevent QT_STYLE_OVERRIDE=kvantum (set by
# # Stylix's qt6ct target) from being picked up by KWin/plasmashell, which
# # would cause a fatal "module kvantum is not installed" QML error and
# # leave the desktop blank.
# widgetStyle = "Breeze";
# };
# # input.mice and input.touchpads require device-specific vendorId/productId
# # identifiers — configure those per-host in the home config instead.
kscreenlocker = { kscreenlocker = {
autoLock = true; autoLock = true;
@@ -67,20 +71,20 @@ in
}; };
}; };
panels = [ # panels = [
{ # {
location = "bottom"; # location = "bottom";
floating = true; # floating = true;
height = 44; # height = 44;
widgets = [ # widgets = [
"org.kde.plasma.kickoff" # "org.kde.plasma.kickoff"
"org.kde.plasma.icontasks" # "org.kde.plasma.icontasks"
"org.kde.plasma.marginsseparator" # "org.kde.plasma.marginsseparator"
"org.kde.plasma.systemtray" # "org.kde.plasma.systemtray"
"org.kde.plasma.digitalclock" # "org.kde.plasma.digitalclock"
]; # ];
} # }
]; # ];
shortcuts = { shortcuts = {
kwin = { kwin = {

View File

@@ -37,8 +37,8 @@ in
baseURL = "http://${net.hosts.nas.lan}:${toString net.ports.nas.llamaCpp}/v1"; baseURL = "http://${net.hosts.nas.lan}:${toString net.ports.nas.llamaCpp}/v1";
}; };
models = { models = {
Qwen3-Coder-Next-Q4_0 = { "gemma-4-26B-A4B-it-UD-Q8_K_XL" = {
name = "Qwen3 Coder (local)"; name = "Gemma 4 26B-A4B (local)";
modalities = { modalities = {
input = [ input = [
"image" "image"
@@ -47,8 +47,8 @@ in
output = [ "text" ]; output = [ "text" ];
}; };
limit = { limit = {
context = 131072; context = 32768;
output = 32768; output = 8192;
}; };
}; };
}; };

View File

@@ -35,6 +35,10 @@ in
enable = true; enable = true;
wayland.enable = cfg.wayland.enable; wayland.enable = cfg.wayland.enable;
}; };
# Required for Bluetooth D-Bus policy (allows WirePlumber/PipeWire
# to communicate with bluetoothd on the system bus).
blueman.enable = true;
}; };
xdg.portal.extraPortals = [ ]; xdg.portal.extraPortals = [ ];

View File

@@ -0,0 +1,202 @@
############################################################
# SmartDisplay Bedroom
# Tiles: Lights | Lamp | Fan | Air Purifier | Closet | BedJet
############################################################
substitutions:
DIRECT_ACTIONS: "true"
ROOM_NAME: "Bedroom"
TIME_24H: "false"
# ── TILE 1 Bedroom Lights (group) ─────────────────────
TILE1_ENTITY: "light.bedroom_lights"
TILE1_STATE_ENTITY: "light.bedroom_light_1"
TILE1_TITLE: "Lights"
TILE1_ICON: "\U000F0769"
TILE1_TYPE: "light"
TILE1_TAP_ACTION: "toggle"
TILE1_LONGPRESS: "auto"
TILE1_VALUE_MODE: "auto"
TILE1_LABEL_OFF: "Off"
TILE1_LABEL_ON: "On"
TILE1_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE1_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE1_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE1_ICON_DISABLED_COLOR: "0xFEC600"
TILE1_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE1_BG_DISABLED_COLOR: "0x3a3a3a"
TILE1_TITLE_ACTIVE_COLOR: "0x000000"
TILE1_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE1_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE1_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE1_TAP_SERVICE: ""
TILE1_TAP_PARAM_KEY: ""
TILE1_TAP_PARAM_VAL: ""
TILE1_LONGPRESS_OFF_VALUE: "0"
# ── TILE 2 Bedroom Lamp ────────────────────────────────
TILE2_ENTITY: "light.bedroom_lamp"
TILE2_STATE_ENTITY: "light.bedroom_lamp"
TILE2_TITLE: "Lamp"
TILE2_ICON: "\U000F06B5"
TILE2_TYPE: "light"
TILE2_TAP_ACTION: "auto"
TILE2_LONGPRESS: "auto"
TILE2_VALUE_MODE: "auto"
TILE2_LABEL_OFF: "Off"
TILE2_LABEL_ON: "On"
TILE2_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE2_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE2_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE2_ICON_DISABLED_COLOR: "0xFEC600"
TILE2_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE2_BG_DISABLED_COLOR: "0x3a3a3a"
TILE2_TITLE_ACTIVE_COLOR: "0x000000"
TILE2_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE2_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE2_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE2_TAP_SERVICE: ""
TILE2_TAP_PARAM_KEY: ""
TILE2_TAP_PARAM_VAL: ""
TILE2_LONGPRESS_OFF_VALUE: "0"
# ── TILE 3 Bedroom Fan ─────────────────────────────────
TILE3_ENTITY: "fan.bedroom_fan"
TILE3_STATE_ENTITY: "fan.bedroom_fan"
TILE3_TITLE: "Bedroom Fan"
TILE3_ICON: "\U000F0210"
TILE3_TYPE: "fan"
TILE3_TAP_ACTION: "fan_toggle_preset"
TILE3_LONGPRESS: "auto"
TILE3_VALUE_MODE: "auto"
TILE3_LABEL_OFF: "Off"
TILE3_LABEL_ON: "On"
TILE3_CIRCLE_ACTIVE_COLOR: "0x00C5EC"
TILE3_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE3_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE3_ICON_DISABLED_COLOR: "0x00C5EC"
TILE3_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE3_BG_DISABLED_COLOR: "0x3a3a3a"
TILE3_TITLE_ACTIVE_COLOR: "0x000000"
TILE3_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE3_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE3_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE3_TAP_SERVICE: "fan.toggle"
TILE3_TAP_PARAM_KEY: ""
TILE3_TAP_PARAM_VAL: ""
TILE3_LONGPRESS_OFF_VALUE: "0"
# ── TILE 4 Air Purifier ────────────────────────────────
TILE4_ENTITY: "fan.bedroom_air_purifier"
TILE4_STATE_ENTITY: "fan.bedroom_air_purifier"
TILE4_TITLE: "Air Purifier"
TILE4_ICON: "\U000F0D43"
TILE4_TYPE: "fan"
TILE4_TAP_ACTION: "fan_toggle_preset"
TILE4_LONGPRESS: "auto"
TILE4_VALUE_MODE: "auto"
TILE4_LABEL_OFF: "Off"
TILE4_LABEL_ON: "On"
TILE4_CIRCLE_ACTIVE_COLOR: "0x00C5EC"
TILE4_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE4_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE4_ICON_DISABLED_COLOR: "0x00C5EC"
TILE4_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE4_BG_DISABLED_COLOR: "0x3a3a3a"
TILE4_TITLE_ACTIVE_COLOR: "0x000000"
TILE4_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE4_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE4_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE4_TAP_SERVICE: "fan.toggle"
TILE4_TAP_PARAM_KEY: "preset_mode"
TILE4_TAP_PARAM_VAL: "auto"
TILE4_LONGPRESS_OFF_VALUE: "0"
# ── TILE 5 Front Closet Lights ────────────────────────
TILE5_ENTITY: "light.front_closet_lights"
TILE5_STATE_ENTITY: "light.front_closet_light_1"
TILE5_TITLE: "Closet"
TILE5_ICON: "\U000F1051"
TILE5_TYPE: "light"
TILE5_TAP_ACTION: "toggle"
TILE5_LONGPRESS: "none"
TILE5_VALUE_MODE: "auto"
TILE5_LABEL_OFF: "Off"
TILE5_LABEL_ON: "On"
TILE5_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE5_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE5_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE5_ICON_DISABLED_COLOR: "0xFEC600"
TILE5_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE5_BG_DISABLED_COLOR: "0x3a3a3a"
TILE5_TITLE_ACTIVE_COLOR: "0x000000"
TILE5_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE5_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE5_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE5_TAP_SERVICE: ""
TILE5_TAP_PARAM_KEY: ""
TILE5_TAP_PARAM_VAL: ""
TILE5_LONGPRESS_OFF_VALUE: "0"
# ── TILE 6 BedJet ─────────────────────────────────────
TILE6_ENTITY: "fan.bedjet_dbbf_c222"
TILE6_STATE_ENTITY: "fan.bedjet_dbbf_c222"
TILE6_TITLE: "BedJet"
TILE6_ICON: "\U000F07E4"
TILE6_TYPE: "fan"
TILE6_TAP_ACTION: "toggle"
TILE6_LONGPRESS: "auto"
TILE6_VALUE_MODE: "percentage"
TILE6_LABEL_OFF: "Off"
TILE6_LABEL_ON: "On"
TILE6_CIRCLE_ACTIVE_COLOR: "0xFF6B35"
TILE6_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE6_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE6_ICON_DISABLED_COLOR: "0xFF6B35"
TILE6_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE6_BG_DISABLED_COLOR: "0x3a3a3a"
TILE6_TITLE_ACTIVE_COLOR: "0x000000"
TILE6_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE6_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE6_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE6_TAP_SERVICE: "fan.toggle"
TILE6_TAP_PARAM_KEY: ""
TILE6_TAP_PARAM_VAL: ""
TILE6_LONGPRESS_OFF_VALUE: "0"
packages:
hw: !include cyd-base-hw.yaml
ui: !include cyd-base-ui.yaml
esphome:
name: bedroom-display
friendly_name: BedroomDisplay
on_boot:
priority: 600
then:
- script.execute: ui_refresh
esp32:
board: esp32dev
framework:
type: arduino
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "BedroomDisplay Fallback"
password: !secret ota_password
captive_portal:

View File

@@ -0,0 +1,306 @@
############################################################
# CYD Base Hardware layer
# ESP32-2432S028 (Cheap Yellow Display)
# Include via: packages: !include cyd-base-hw.yaml
############################################################
time:
- platform: homeassistant
id: homeassistant_time
on_time:
- seconds: 0
minutes: /1
then:
- script.execute: ui_refresh
globals:
- id: active_entity
type: std::string
restore_value: no
- id: active_control_kind
type: std::string
restore_value: no
- id: active_value_suffix
type: std::string
restore_value: no
- id: overlay_slider_bg_color
type: uint32_t
restore_value: no
initial_value: '0x939391'
- id: overlay_slider_fill_color
type: uint32_t
restore_value: no
initial_value: '0xFEC600'
font:
- file: "gfonts://Roboto@500"
id: time_label
size: 18
bpp: 4
glyphs: ['0','1','2','3','4','5','6','7','8','9',':',' ','A','M','P']
- file: "gfonts://Roboto@500"
id: headline
size: 18
bpp: 4
glyphs: ['&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'ä','ö','ü','Ä','Ö','Ü','ß','/']
- file: "gfonts://Roboto@700"
id: label
size: 11
bpp: 4
glyphs: ['&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'ä','ö','ü','Ä','Ö','Ü','ß','/']
- file: "gfonts://Roboto@400"
id: sublabel
size: 11
bpp: 4
glyphs: ['&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'ä','ö','ü','Ä','Ö','Ü','ß','/','…']
- file: "gfonts://Roboto@400"
id: sublabel_big
size: 14
bpp: 4
glyphs: ['&','@','!',',','.','?','"','%','(',')','+','-','_',':','°',
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'ä','ö','ü','Ä','Ö','Ü','ß','/','…']
- file: 'fonts/materialdesignicons-webfont.ttf'
id: materialdesign_icons
size: 28
glyphs:
- "${TILE1_ICON}"
- "${TILE2_ICON}"
- "${TILE3_ICON}"
- "${TILE4_ICON}"
- "${TILE5_ICON}"
- "${TILE6_ICON}"
sensor:
- platform: wifi_signal
name: "Wifi Signal"
update_interval: 600s
- platform: uptime
name: "Uptime"
id: uptime_s
update_interval: 15s
- platform: homeassistant
id: tile1_brightness
entity_id: ${TILE1_ENTITY}
attribute: brightness
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile1_percentage
entity_id: ${TILE1_ENTITY}
attribute: percentage
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile2_brightness
entity_id: ${TILE2_ENTITY}
attribute: brightness
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile2_percentage
entity_id: ${TILE2_ENTITY}
attribute: percentage
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile3_brightness
entity_id: ${TILE3_ENTITY}
attribute: brightness
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile3_percentage
entity_id: ${TILE3_ENTITY}
attribute: percentage
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile4_brightness
entity_id: ${TILE4_ENTITY}
attribute: brightness
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile4_percentage
entity_id: ${TILE4_ENTITY}
attribute: percentage
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile5_brightness
entity_id: ${TILE5_ENTITY}
attribute: brightness
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile5_percentage
entity_id: ${TILE5_ENTITY}
attribute: percentage
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile6_brightness
entity_id: ${TILE6_ENTITY}
attribute: brightness
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile6_percentage
entity_id: ${TILE6_ENTITY}
attribute: percentage
on_value: { then: [ script.execute: ui_refresh ] }
binary_sensor:
- platform: status
name: "Node Status"
id: system_status
- platform: homeassistant
id: ha_state_tile1
entity_id: ${TILE1_STATE_ENTITY}
on_state: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: ha_state_tile2
entity_id: ${TILE2_STATE_ENTITY}
on_state: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: ha_state_tile3
entity_id: ${TILE3_STATE_ENTITY}
on_state: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: ha_state_tile4
entity_id: ${TILE4_STATE_ENTITY}
on_state: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: ha_state_tile5
entity_id: ${TILE5_STATE_ENTITY}
on_state: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: ha_state_tile6
entity_id: ${TILE6_STATE_ENTITY}
on_state: { then: [ script.execute: ui_refresh ] }
text_sensor:
- platform: template
id: smartdisplay_action
name: "${ROOM_NAME} Action"
icon: mdi:gesture-tap-button
- platform: homeassistant
id: tile1_preset
entity_id: ${TILE1_ENTITY}
attribute: preset_mode
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile2_preset
entity_id: ${TILE2_ENTITY}
attribute: preset_mode
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile3_preset
entity_id: ${TILE3_ENTITY}
attribute: preset_mode
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile4_preset
entity_id: ${TILE4_ENTITY}
attribute: preset_mode
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile5_preset
entity_id: ${TILE5_ENTITY}
attribute: preset_mode
on_value: { then: [ script.execute: ui_refresh ] }
- platform: homeassistant
id: tile6_preset
entity_id: ${TILE6_ENTITY}
attribute: preset_mode
on_value: { then: [ script.execute: ui_refresh ] }
switch:
- platform: restart
name: "Restart"
spi:
- id: lcd
clk_pin: GPIO14
mosi_pin: GPIO13
miso_pin: GPIO12
- id: my_touchscreen
clk_pin: GPIO25
mosi_pin: GPIO32
miso_pin: GPIO39
output:
- platform: ledc
pin: GPIO21
id: gpio_backlight_pwm
- platform: ledc
id: output_red
pin: GPIO4
inverted: true
- platform: ledc
id: output_green
pin: GPIO16
inverted: true
- platform: ledc
id: output_blue
pin: GPIO17
inverted: true
light:
- platform: monochromatic
output: gpio_backlight_pwm
name: "Power Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
- platform: rgb
name: LED
red: output_red
id: led
green: output_green
blue: output_blue
restore_mode: ALWAYS_OFF
touchscreen:
platform: xpt2046
id: ts_touch
spi_id: my_touchscreen
cs_pin: 33
interrupt_pin: 36
update_interval: 20ms
threshold: 300
calibration:
x_min: 280
x_max: 3860
y_min: 340
y_max: 3860
transform:
swap_xy: true
mirror_x: true
mirror_y: true
display:
- platform: ili9xxx
id: my_display
spi_id: lcd
model: ILI9341
cs_pin: 15
dc_pin: 2
invert_colors: false
update_interval: never
auto_clear_enabled: false
transform:
swap_xy: false
mirror_x: true
mirror_y: false
dimensions:
width: 320
height: 240

File diff suppressed because it is too large Load Diff

View File

@@ -12,8 +12,15 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
virtualisation.oci-containers.containers.esphome = { virtualisation.oci-containers.containers.esphome = {
autoStart = true; autoStart = true;
image = "ghcr.io/esphome/esphome:2026.2.4"; image = "ghcr.io/esphome/esphome";
ports = [ "6052:6052" ]; # host networking is required for mDNS (multicast UDP) to work so that
# ESPHome can discover devices via <name>.local and perform OTA updates
# without needing to know device IPs in advance.
extraOptions = [ "--network=host" ];
devices = [
"/dev/ttyUSB0"
];
privileged = true;
volumes = [ volumes = [
"/esphome:/config" "/esphome:/config"
# Persist the PlatformIO core dir (penv, packages, platforms) so the # Persist the PlatformIO core dir (penv, packages, platforms) so the

View File

@@ -0,0 +1,207 @@
############################################################
# SmartDisplay iOS Home appinspired Tiles UI
# Target device: ESP32-2432S028 / Cheap Yellow Display (CYD)
#
# Edit the substitutions below, then flash.
# All shared hardware/UI logic lives in:
# cyd-base-hw.yaml sensors, fonts, SPI, display, touch
# cyd-base-ui.yaml LVGL layout, scripts
############################################################
substitutions:
DIRECT_ACTIONS: "true"
ROOM_NAME: "Bedroom"
TIME_24H: "false"
# ── TILE 1 ──────────────────────────────────────────────
TILE1_ENTITY: "light.bedroom_lights"
TILE1_STATE_ENTITY: "light.bedroom_light_1"
TILE1_TITLE: "Lights"
TILE1_ICON: "\U000F0769"
TILE1_TYPE: "light"
TILE1_TAP_ACTION: "toggle"
TILE1_LONGPRESS: "auto"
TILE1_VALUE_MODE: "auto"
TILE1_LABEL_OFF: "Off"
TILE1_LABEL_ON: "On"
TILE1_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE1_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE1_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE1_ICON_DISABLED_COLOR: "0xFEC600"
TILE1_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE1_BG_DISABLED_COLOR: "0x3a3a3a"
TILE1_TITLE_ACTIVE_COLOR: "0x000000"
TILE1_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE1_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE1_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE1_TAP_SERVICE: ""
TILE1_TAP_PARAM_KEY: ""
TILE1_TAP_PARAM_VAL: ""
TILE1_LONGPRESS_OFF_VALUE: "0"
# ── TILE 2 ──────────────────────────────────────────────
TILE2_ENTITY: "light.bedroom_lamp"
TILE2_STATE_ENTITY: "light.bedroom_lamp"
TILE2_TITLE: "Lamp"
TILE2_ICON: "\U000F06B5"
TILE2_TYPE: "light"
TILE2_TAP_ACTION: "auto"
TILE2_LONGPRESS: "auto"
TILE2_VALUE_MODE: "auto"
TILE2_LABEL_OFF: "Off"
TILE2_LABEL_ON: "On"
TILE2_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE2_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE2_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE2_ICON_DISABLED_COLOR: "0xFEC600"
TILE2_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE2_BG_DISABLED_COLOR: "0x3a3a3a"
TILE2_TITLE_ACTIVE_COLOR: "0x000000"
TILE2_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE2_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE2_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE2_TAP_SERVICE: ""
TILE2_TAP_PARAM_KEY: ""
TILE2_TAP_PARAM_VAL: ""
TILE2_LONGPRESS_OFF_VALUE: "0"
# ── TILE 3 ──────────────────────────────────────────────
TILE3_ENTITY: "light.living_room_lights"
TILE3_STATE_ENTITY: "light.living_room_lights"
TILE3_TITLE: "Living Room"
TILE3_ICON: "\U000F08DD"
TILE3_TYPE: "light"
TILE3_TAP_ACTION: "auto"
TILE3_LONGPRESS: "auto"
TILE3_VALUE_MODE: "auto"
TILE3_LABEL_OFF: "Off"
TILE3_LABEL_ON: "On"
TILE3_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE3_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE3_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE3_ICON_DISABLED_COLOR: "0xFEC600"
TILE3_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE3_BG_DISABLED_COLOR: "0x3a3a3a"
TILE3_TITLE_ACTIVE_COLOR: "0x000000"
TILE3_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE3_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE3_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE3_TAP_SERVICE: ""
TILE3_TAP_PARAM_KEY: ""
TILE3_TAP_PARAM_VAL: ""
TILE3_LONGPRESS_OFF_VALUE: "0"
# ── TILE 4 ──────────────────────────────────────────────
TILE4_ENTITY: "switch.closet_lights"
TILE4_STATE_ENTITY: "switch.closet_lights"
TILE4_TITLE: "Closet Lights"
TILE4_ICON: "\U000F1051"
TILE4_TYPE: "light"
TILE4_TAP_ACTION: "auto"
TILE4_LONGPRESS: "auto"
TILE4_VALUE_MODE: "auto"
TILE4_LABEL_OFF: "Off"
TILE4_LABEL_ON: "On"
TILE4_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE4_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE4_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE4_ICON_DISABLED_COLOR: "0xFEC600"
TILE4_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE4_BG_DISABLED_COLOR: "0x3a3a3a"
TILE4_TITLE_ACTIVE_COLOR: "0x000000"
TILE4_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE4_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE4_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE4_TAP_SERVICE: ""
TILE4_TAP_PARAM_KEY: ""
TILE4_TAP_PARAM_VAL: ""
TILE4_LONGPRESS_OFF_VALUE: "0"
# ── TILE 5 ──────────────────────────────────────────────
TILE5_ENTITY: "fan.bedroom_fan"
TILE5_STATE_ENTITY: "fan.bedroom_fan"
TILE5_TITLE: "Bedroom Fan"
TILE5_ICON: "\U000F0210"
TILE5_TYPE: "fan"
TILE5_TAP_ACTION: "auto"
TILE5_LONGPRESS: "auto"
TILE5_VALUE_MODE: "auto"
TILE5_LABEL_OFF: "Off"
TILE5_LABEL_ON: "On"
TILE5_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE5_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE5_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE5_ICON_DISABLED_COLOR: "0xFEC600"
TILE5_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE5_BG_DISABLED_COLOR: "0x3a3a3a"
TILE5_TITLE_ACTIVE_COLOR: "0x000000"
TILE5_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE5_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE5_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE5_TAP_SERVICE: ""
TILE5_TAP_PARAM_KEY: ""
TILE5_TAP_PARAM_VAL: ""
TILE5_LONGPRESS_OFF_VALUE: "0"
# ── TILE 6 ──────────────────────────────────────────────
TILE6_ENTITY: "fan.bedroom_air_purifier"
TILE6_STATE_ENTITY: "fan.bedroom_air_purifier"
TILE6_TITLE: "Air Purifier"
TILE6_ICON: "\U000F0D43"
TILE6_TYPE: "fan"
TILE6_TAP_ACTION: "fan_toggle_preset"
TILE6_LONGPRESS: "auto"
TILE6_VALUE_MODE: "auto"
TILE6_LABEL_OFF: "Off"
TILE6_LABEL_ON: "On"
TILE6_CIRCLE_ACTIVE_COLOR: "0x00C5EC"
TILE6_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE6_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE6_ICON_DISABLED_COLOR: "0x00C5EC"
TILE6_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE6_BG_DISABLED_COLOR: "0x3a3a3a"
TILE6_TITLE_ACTIVE_COLOR: "0x000000"
TILE6_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE6_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE6_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE6_TAP_SERVICE: "fan.toggle"
TILE6_TAP_PARAM_KEY: "preset_mode"
TILE6_TAP_PARAM_VAL: "Auto"
TILE6_LONGPRESS_OFF_VALUE: "0"
packages:
hw: !include cyd-base-hw.yaml
ui: !include cyd-base-ui.yaml
esphome:
name: smartdisplay
friendly_name: SmartDisplay
on_boot:
priority: 600
then:
- script.execute: ui_refresh
esp32:
board: esp32dev
framework:
type: arduino
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Smartdisplay Fallback"
password: !secret ota_password
captive_portal:

View File

@@ -0,0 +1,202 @@
############################################################
# SmartDisplay Living Room
# Tiles: Lights | Air Purifier | Vacuum | TV | Speaker | Closet
############################################################
substitutions:
DIRECT_ACTIONS: "true"
ROOM_NAME: "Living Room"
TIME_24H: "false"
# ── TILE 1 Living Room Lights ──────────────────────────
TILE1_ENTITY: "light.living_room_lights"
TILE1_STATE_ENTITY: "light.living_room_light_1"
TILE1_TITLE: "Lights"
TILE1_ICON: "\U000F08DD"
TILE1_TYPE: "light"
TILE1_TAP_ACTION: "toggle"
TILE1_LONGPRESS: "auto"
TILE1_VALUE_MODE: "auto"
TILE1_LABEL_OFF: "Off"
TILE1_LABEL_ON: "On"
TILE1_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE1_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE1_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE1_ICON_DISABLED_COLOR: "0xFEC600"
TILE1_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE1_BG_DISABLED_COLOR: "0x3a3a3a"
TILE1_TITLE_ACTIVE_COLOR: "0x000000"
TILE1_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE1_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE1_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE1_TAP_SERVICE: ""
TILE1_TAP_PARAM_KEY: ""
TILE1_TAP_PARAM_VAL: ""
TILE1_LONGPRESS_OFF_VALUE: "0"
# ── TILE 2 Living Room Air Purifier ───────────────────
TILE2_ENTITY: "fan.living_room_air_purifier"
TILE2_STATE_ENTITY: "fan.living_room_air_purifier"
TILE2_TITLE: "Air Purifier"
TILE2_ICON: "\U000F0D43"
TILE2_TYPE: "fan"
TILE2_TAP_ACTION: "fan_toggle_preset"
TILE2_LONGPRESS: "auto"
TILE2_VALUE_MODE: "auto"
TILE2_LABEL_OFF: "Off"
TILE2_LABEL_ON: "On"
TILE2_CIRCLE_ACTIVE_COLOR: "0x00C5EC"
TILE2_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE2_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE2_ICON_DISABLED_COLOR: "0x00C5EC"
TILE2_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE2_BG_DISABLED_COLOR: "0x3a3a3a"
TILE2_TITLE_ACTIVE_COLOR: "0x000000"
TILE2_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE2_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE2_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE2_TAP_SERVICE: "fan.toggle"
TILE2_TAP_PARAM_KEY: "preset_mode"
TILE2_TAP_PARAM_VAL: "auto"
TILE2_LONGPRESS_OFF_VALUE: "0"
# ── TILE 3 Garbage Goober (vacuum) ────────────────────
TILE3_ENTITY: "vacuum.garbage_goober"
TILE3_STATE_ENTITY: "binary_sensor.garbage_goober_cleaning"
TILE3_TITLE: "Vacuum"
TILE3_ICON: "\U000F09A8"
TILE3_TYPE: "switch"
TILE3_TAP_ACTION: "custom"
TILE3_LONGPRESS: "none"
TILE3_VALUE_MODE: "text"
TILE3_LABEL_OFF: "Docked"
TILE3_LABEL_ON: "Cleaning"
TILE3_CIRCLE_ACTIVE_COLOR: "0x43A047"
TILE3_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE3_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE3_ICON_DISABLED_COLOR: "0x43A047"
TILE3_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE3_BG_DISABLED_COLOR: "0x3a3a3a"
TILE3_TITLE_ACTIVE_COLOR: "0x000000"
TILE3_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE3_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE3_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE3_TAP_SERVICE: "vacuum.start_pause"
TILE3_TAP_PARAM_KEY: ""
TILE3_TAP_PARAM_VAL: ""
TILE3_LONGPRESS_OFF_VALUE: "0"
# ── TILE 4 TV (remote) ────────────────────────────────
TILE4_ENTITY: "remote.living_room"
TILE4_STATE_ENTITY: "remote.living_room"
TILE4_TITLE: "TV"
TILE4_ICON: "\U000F0502"
TILE4_TYPE: "switch"
TILE4_TAP_ACTION: "custom"
TILE4_LONGPRESS: "none"
TILE4_VALUE_MODE: "text"
TILE4_LABEL_OFF: "Off"
TILE4_LABEL_ON: "On"
TILE4_CIRCLE_ACTIVE_COLOR: "0x1565C0"
TILE4_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE4_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE4_ICON_DISABLED_COLOR: "0x1565C0"
TILE4_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE4_BG_DISABLED_COLOR: "0x3a3a3a"
TILE4_TITLE_ACTIVE_COLOR: "0x000000"
TILE4_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE4_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE4_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE4_TAP_SERVICE: "remote.toggle"
TILE4_TAP_PARAM_KEY: ""
TILE4_TAP_PARAM_VAL: ""
TILE4_LONGPRESS_OFF_VALUE: "0"
# ── TILE 5 Living Room Speaker ────────────────────────
TILE5_ENTITY: "media_player.living_room_speaker"
TILE5_STATE_ENTITY: "media_player.living_room_speaker"
TILE5_TITLE: "Speaker"
TILE5_ICON: "\U000F04C3"
TILE5_TYPE: "switch"
TILE5_TAP_ACTION: "custom"
TILE5_LONGPRESS: "none"
TILE5_VALUE_MODE: "text"
TILE5_LABEL_OFF: "Off"
TILE5_LABEL_ON: "Playing"
TILE5_CIRCLE_ACTIVE_COLOR: "0x8E24AA"
TILE5_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE5_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE5_ICON_DISABLED_COLOR: "0x8E24AA"
TILE5_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE5_BG_DISABLED_COLOR: "0x3a3a3a"
TILE5_TITLE_ACTIVE_COLOR: "0x000000"
TILE5_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE5_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE5_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE5_TAP_SERVICE: "media_player.toggle"
TILE5_TAP_PARAM_KEY: ""
TILE5_TAP_PARAM_VAL: ""
TILE5_LONGPRESS_OFF_VALUE: "0"
# ── TILE 6 Front Closet Lights ────────────────────────
TILE6_ENTITY: "light.front_closet_lights"
TILE6_STATE_ENTITY: "light.front_closet_light_1"
TILE6_TITLE: "Closet"
TILE6_ICON: "\U000F1051"
TILE6_TYPE: "light"
TILE6_TAP_ACTION: "toggle"
TILE6_LONGPRESS: "none"
TILE6_VALUE_MODE: "auto"
TILE6_LABEL_OFF: "Off"
TILE6_LABEL_ON: "On"
TILE6_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE6_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE6_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE6_ICON_DISABLED_COLOR: "0xFEC600"
TILE6_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE6_BG_DISABLED_COLOR: "0x3a3a3a"
TILE6_TITLE_ACTIVE_COLOR: "0x000000"
TILE6_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE6_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE6_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE6_TAP_SERVICE: ""
TILE6_TAP_PARAM_KEY: ""
TILE6_TAP_PARAM_VAL: ""
TILE6_LONGPRESS_OFF_VALUE: "0"
packages:
hw: !include cyd-base-hw.yaml
ui: !include cyd-base-ui.yaml
esphome:
name: livingroom-display
friendly_name: LivingroomDisplay
on_boot:
priority: 600
then:
- script.execute: ui_refresh
esp32:
board: esp32dev
framework:
type: arduino
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "LivingroomDisplay Fallback"
password: !secret ota_password
captive_portal:

View File

@@ -0,0 +1,202 @@
############################################################
# SmartDisplay Pets
# Tiles: Joey Feed | Luci Feed | Litter Box | Fountain | Vacuum | Ftn Reset
############################################################
substitutions:
DIRECT_ACTIONS: "true"
ROOM_NAME: "Pets"
TIME_24H: "false"
# ── TILE 1 Joey Smart Feeder (manual feed) ─────────────
TILE1_ENTITY: "button.joey_smart_feeder_manual_feed"
TILE1_STATE_ENTITY: "binary_sensor.joey_smart_feeder_low_food"
TILE1_TITLE: "Joey Feed"
TILE1_ICON: "\U000F009A"
TILE1_TYPE: "script"
TILE1_TAP_ACTION: "custom"
TILE1_LONGPRESS: "none"
TILE1_VALUE_MODE: "text"
TILE1_LABEL_OFF: "Ready"
TILE1_LABEL_ON: "Fed"
TILE1_CIRCLE_ACTIVE_COLOR: "0xF4A820"
TILE1_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE1_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE1_ICON_DISABLED_COLOR: "0xF4A820"
TILE1_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE1_BG_DISABLED_COLOR: "0x3a3a3a"
TILE1_TITLE_ACTIVE_COLOR: "0x000000"
TILE1_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE1_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE1_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE1_TAP_SERVICE: "button.press"
TILE1_TAP_PARAM_KEY: ""
TILE1_TAP_PARAM_VAL: ""
TILE1_LONGPRESS_OFF_VALUE: "0"
# ── TILE 2 Luci Smart Feeder (manual feed) ─────────────
TILE2_ENTITY: "button.luci_smart_feeder_manual_feed"
TILE2_STATE_ENTITY: "binary_sensor.luci_smart_feeder_low_food"
TILE2_TITLE: "Luci Feed"
TILE2_ICON: "\U000F1114"
TILE2_TYPE: "script"
TILE2_TAP_ACTION: "custom"
TILE2_LONGPRESS: "none"
TILE2_VALUE_MODE: "text"
TILE2_LABEL_OFF: "Ready"
TILE2_LABEL_ON: "Fed"
TILE2_CIRCLE_ACTIVE_COLOR: "0xEC407A"
TILE2_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE2_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE2_ICON_DISABLED_COLOR: "0xEC407A"
TILE2_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE2_BG_DISABLED_COLOR: "0x3a3a3a"
TILE2_TITLE_ACTIVE_COLOR: "0x000000"
TILE2_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE2_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE2_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE2_TAP_SERVICE: "button.press"
TILE2_TAP_PARAM_KEY: ""
TILE2_TAP_PARAM_VAL: ""
TILE2_LONGPRESS_OFF_VALUE: "0"
# ── TILE 3 Litter-Robot 4 ──────────────────────────────
TILE3_ENTITY: "vacuum.litter_robot_4_litter_box"
TILE3_STATE_ENTITY: "binary_sensor.litter_robot_4_is_cleaning"
TILE3_TITLE: "Litter Box"
TILE3_ICON: "\U000F054D"
TILE3_TYPE: "switch"
TILE3_TAP_ACTION: "custom"
TILE3_LONGPRESS: "none"
TILE3_VALUE_MODE: "text"
TILE3_LABEL_OFF: "Docked"
TILE3_LABEL_ON: "Cycling"
TILE3_CIRCLE_ACTIVE_COLOR: "0x43A047"
TILE3_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE3_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE3_ICON_DISABLED_COLOR: "0x43A047"
TILE3_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE3_BG_DISABLED_COLOR: "0x3a3a3a"
TILE3_TITLE_ACTIVE_COLOR: "0x000000"
TILE3_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE3_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE3_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE3_TAP_SERVICE: "vacuum.start"
TILE3_TAP_PARAM_KEY: ""
TILE3_TAP_PARAM_VAL: ""
TILE3_LONGPRESS_OFF_VALUE: "0"
# ── TILE 4 Pet Fountain ────────────────────────────────
TILE4_ENTITY: "switch.dockstream_smart_rfid_fountain_wi_fi"
TILE4_STATE_ENTITY: "binary_sensor.dockstream_smart_rfid_fountain_indicator"
TILE4_TITLE: "Fountain"
TILE4_ICON: "\U000F0765"
TILE4_TYPE: "switch"
TILE4_TAP_ACTION: "toggle"
TILE4_LONGPRESS: "none"
TILE4_VALUE_MODE: "text"
TILE4_LABEL_OFF: "Off"
TILE4_LABEL_ON: "On"
TILE4_CIRCLE_ACTIVE_COLOR: "0x039BE5"
TILE4_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE4_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE4_ICON_DISABLED_COLOR: "0x039BE5"
TILE4_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE4_BG_DISABLED_COLOR: "0x3a3a3a"
TILE4_TITLE_ACTIVE_COLOR: "0x000000"
TILE4_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE4_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE4_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE4_TAP_SERVICE: ""
TILE4_TAP_PARAM_KEY: ""
TILE4_TAP_PARAM_VAL: ""
TILE4_LONGPRESS_OFF_VALUE: "0"
# ── TILE 5 Garbage Goober (vacuum) ────────────────────
TILE5_ENTITY: "vacuum.garbage_goober"
TILE5_STATE_ENTITY: "binary_sensor.garbage_goober_cleaning"
TILE5_TITLE: "Vacuum"
TILE5_ICON: "\U000F09A8"
TILE5_TYPE: "switch"
TILE5_TAP_ACTION: "custom"
TILE5_LONGPRESS: "none"
TILE5_VALUE_MODE: "text"
TILE5_LABEL_OFF: "Docked"
TILE5_LABEL_ON: "Cleaning"
TILE5_CIRCLE_ACTIVE_COLOR: "0x6D4C41"
TILE5_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE5_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE5_ICON_DISABLED_COLOR: "0x6D4C41"
TILE5_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE5_BG_DISABLED_COLOR: "0x3a3a3a"
TILE5_TITLE_ACTIVE_COLOR: "0x000000"
TILE5_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE5_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE5_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE5_TAP_SERVICE: "vacuum.start_pause"
TILE5_TAP_PARAM_KEY: ""
TILE5_TAP_PARAM_VAL: ""
TILE5_LONGPRESS_OFF_VALUE: "0"
# ── TILE 6 Fountain Cleaning Reset ────────────────────
TILE6_ENTITY: "button.dockstream_smart_rfid_fountain_cleaning_reset"
TILE6_STATE_ENTITY: "binary_sensor.dockstream_smart_rfid_fountain_wi_fi"
TILE6_TITLE: "Ftn. Reset"
TILE6_ICON: "\U000F0ECC"
TILE6_TYPE: "script"
TILE6_TAP_ACTION: "custom"
TILE6_LONGPRESS: "none"
TILE6_VALUE_MODE: "text"
TILE6_LABEL_OFF: "Offline"
TILE6_LABEL_ON: "Online"
TILE6_CIRCLE_ACTIVE_COLOR: "0x039BE5"
TILE6_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE6_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE6_ICON_DISABLED_COLOR: "0x039BE5"
TILE6_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE6_BG_DISABLED_COLOR: "0x3a3a3a"
TILE6_TITLE_ACTIVE_COLOR: "0x000000"
TILE6_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE6_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE6_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE6_TAP_SERVICE: "button.press"
TILE6_TAP_PARAM_KEY: ""
TILE6_TAP_PARAM_VAL: ""
TILE6_LONGPRESS_OFF_VALUE: "0"
packages:
hw: !include cyd-base-hw.yaml
ui: !include cyd-base-ui.yaml
esphome:
name: pets-display
friendly_name: PetsDisplay
on_boot:
priority: 600
then:
- script.execute: ui_refresh
esp32:
board: esp32dev
framework:
type: arduino
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "PetsDisplay Fallback"
password: !secret ota_password
captive_portal:

View File

@@ -0,0 +1,202 @@
############################################################
# SmartDisplay 3D Printer (Bambu P1P)
# Tiles: Status | Chamber Light | Pause | Cooling Fan | AMS | Stop
############################################################
substitutions:
DIRECT_ACTIONS: "true"
ROOM_NAME: "Printer"
TIME_24H: "false"
# ── TILE 1 P1P Online / Force Refresh ─────────────────
TILE1_ENTITY: "button.p1p_01s00c371400147_force_refresh_data"
TILE1_STATE_ENTITY: "binary_sensor.p1p_01s00c371400147_online"
TILE1_TITLE: "P1P Status"
TILE1_ICON: "\U000F08F5"
TILE1_TYPE: "script"
TILE1_TAP_ACTION: "custom"
TILE1_LONGPRESS: "none"
TILE1_VALUE_MODE: "text"
TILE1_LABEL_OFF: "Offline"
TILE1_LABEL_ON: "Online"
TILE1_CIRCLE_ACTIVE_COLOR: "0x43A047"
TILE1_CIRCLE_DISABLED_COLOR: "0xE53935"
TILE1_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE1_ICON_DISABLED_COLOR: "0xFFFFFF"
TILE1_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE1_BG_DISABLED_COLOR: "0x3a3a3a"
TILE1_TITLE_ACTIVE_COLOR: "0x000000"
TILE1_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE1_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE1_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE1_TAP_SERVICE: "button.press"
TILE1_TAP_PARAM_KEY: ""
TILE1_TAP_PARAM_VAL: ""
TILE1_LONGPRESS_OFF_VALUE: "0"
# ── TILE 2 Chamber Light ───────────────────────────────
TILE2_ENTITY: "light.p1p_01s00c371400147_chamber_light"
TILE2_STATE_ENTITY: "light.p1p_01s00c371400147_chamber_light"
TILE2_TITLE: "Chamber"
TILE2_ICON: "\U000F0A02"
TILE2_TYPE: "light"
TILE2_TAP_ACTION: "toggle"
TILE2_LONGPRESS: "none"
TILE2_VALUE_MODE: "text"
TILE2_LABEL_OFF: "Off"
TILE2_LABEL_ON: "On"
TILE2_CIRCLE_ACTIVE_COLOR: "0xFEC600"
TILE2_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE2_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE2_ICON_DISABLED_COLOR: "0xFEC600"
TILE2_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE2_BG_DISABLED_COLOR: "0x3a3a3a"
TILE2_TITLE_ACTIVE_COLOR: "0x000000"
TILE2_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE2_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE2_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE2_TAP_SERVICE: ""
TILE2_TAP_PARAM_KEY: ""
TILE2_TAP_PARAM_VAL: ""
TILE2_LONGPRESS_OFF_VALUE: "0"
# ── TILE 3 Pause Printing ──────────────────────────────
TILE3_ENTITY: "button.p1p_01s00c371400147_pause_printing"
TILE3_STATE_ENTITY: "binary_sensor.p1p_01s00c371400147_print_error"
TILE3_TITLE: "Pause"
TILE3_ICON: "\U000F03E4"
TILE3_TYPE: "script"
TILE3_TAP_ACTION: "custom"
TILE3_LONGPRESS: "none"
TILE3_VALUE_MODE: "text"
TILE3_LABEL_OFF: "Idle"
TILE3_LABEL_ON: "Error"
TILE3_CIRCLE_ACTIVE_COLOR: "0xE53935"
TILE3_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE3_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE3_ICON_DISABLED_COLOR: "0x7B7B6F"
TILE3_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE3_BG_DISABLED_COLOR: "0x3a3a3a"
TILE3_TITLE_ACTIVE_COLOR: "0x000000"
TILE3_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE3_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE3_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE3_TAP_SERVICE: "button.press"
TILE3_TAP_PARAM_KEY: ""
TILE3_TAP_PARAM_VAL: ""
TILE3_LONGPRESS_OFF_VALUE: "0"
# ── TILE 4 Cooling Fan ────────────────────────────────
TILE4_ENTITY: "fan.p1p_01s00c371400147_cooling_fan"
TILE4_STATE_ENTITY: "fan.p1p_01s00c371400147_cooling_fan"
TILE4_TITLE: "Cooling"
TILE4_ICON: "\U000F0210"
TILE4_TYPE: "fan"
TILE4_TAP_ACTION: "toggle"
TILE4_LONGPRESS: "auto"
TILE4_VALUE_MODE: "percentage"
TILE4_LABEL_OFF: "Off"
TILE4_LABEL_ON: "On"
TILE4_CIRCLE_ACTIVE_COLOR: "0x00C5EC"
TILE4_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE4_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE4_ICON_DISABLED_COLOR: "0x00C5EC"
TILE4_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE4_BG_DISABLED_COLOR: "0x3a3a3a"
TILE4_TITLE_ACTIVE_COLOR: "0x000000"
TILE4_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE4_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE4_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE4_TAP_SERVICE: "fan.toggle"
TILE4_TAP_PARAM_KEY: ""
TILE4_TAP_PARAM_VAL: ""
TILE4_LONGPRESS_OFF_VALUE: "0"
# ── TILE 5 AMS 1 Active ───────────────────────────────
TILE5_ENTITY: "button.p1p_01s00c371400147_force_refresh_data"
TILE5_STATE_ENTITY: "binary_sensor.p1p_01s00c371400147_ams_1_active"
TILE5_TITLE: "AMS"
TILE5_ICON: "\U000F01AE"
TILE5_TYPE: "script"
TILE5_TAP_ACTION: "custom"
TILE5_LONGPRESS: "none"
TILE5_VALUE_MODE: "text"
TILE5_LABEL_OFF: "Idle"
TILE5_LABEL_ON: "Active"
TILE5_CIRCLE_ACTIVE_COLOR: "0x8E24AA"
TILE5_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE5_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE5_ICON_DISABLED_COLOR: "0x8E24AA"
TILE5_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE5_BG_DISABLED_COLOR: "0x3a3a3a"
TILE5_TITLE_ACTIVE_COLOR: "0x000000"
TILE5_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE5_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE5_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE5_TAP_SERVICE: "button.press"
TILE5_TAP_PARAM_KEY: ""
TILE5_TAP_PARAM_VAL: ""
TILE5_LONGPRESS_OFF_VALUE: "0"
# ── TILE 6 Stop Printing (red accent) ─────────────────
TILE6_ENTITY: "button.p1p_01s00c371400147_stop_printing"
TILE6_STATE_ENTITY: "binary_sensor.p1p_01s00c371400147_online"
TILE6_TITLE: "Stop"
TILE6_ICON: "\U000F04DB"
TILE6_TYPE: "script"
TILE6_TAP_ACTION: "custom"
TILE6_LONGPRESS: "none"
TILE6_VALUE_MODE: "text"
TILE6_LABEL_OFF: "Offline"
TILE6_LABEL_ON: "Ready"
TILE6_CIRCLE_ACTIVE_COLOR: "0xE53935"
TILE6_CIRCLE_DISABLED_COLOR: "0x7B7B6F"
TILE6_ICON_ACTIVE_COLOR: "0xFFFFFF"
TILE6_ICON_DISABLED_COLOR: "0xE53935"
TILE6_BG_ACTIVE_COLOR: "0xFFFFFF"
TILE6_BG_DISABLED_COLOR: "0x3a3a3a"
TILE6_TITLE_ACTIVE_COLOR: "0x000000"
TILE6_TITLE_DISABLED_COLOR: "0xFFFFFF"
TILE6_VALUE_ACTIVE_COLOR: "0x7A7A7C"
TILE6_VALUE_DISABLED_COLOR: "0xD9D9D9"
TILE6_TAP_SERVICE: "button.press"
TILE6_TAP_PARAM_KEY: ""
TILE6_TAP_PARAM_VAL: ""
TILE6_LONGPRESS_OFF_VALUE: "0"
packages:
hw: !include cyd-base-hw.yaml
ui: !include cyd-base-ui.yaml
esphome:
name: printer-display
friendly_name: PrinterDisplay
on_boot:
priority: 600
then:
- script.execute: ui_refresh
esp32:
board: esp32dev
framework:
type: arduino
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "PrinterDisplay Fallback"
password: !secret ota_password
captive_portal:

View File

@@ -11,10 +11,6 @@ let
name = "otbr"; name = "otbr";
cfg = config.${namespace}.services.${name}; cfg = config.${namespace}.services.${name};
otbrPackage =
pkgs.callPackage "${inputs.nixpkgs-otbr}/pkgs/by-name/op/openthread-border-router/package.nix"
{ };
otbrConfig = lib.${namespace}.mkModule { otbrConfig = lib.${namespace}.mkModule {
inherit config name; inherit config name;
description = "Openthread border router"; description = "Openthread border router";
@@ -24,8 +20,9 @@ let
moduleConfig = { moduleConfig = {
services.openthread-border-router = { services.openthread-border-router = {
enable = true; enable = true;
backboneInterface = "enp2s0"; backboneInterfaces = [
package = otbrPackage; "enp2s0"
];
rest = { rest = {
inherit (cfg) listenAddress; inherit (cfg) listenAddress;
listenPort = cfg.restPort; listenPort = cfg.restPort;
@@ -45,7 +42,6 @@ let
in in
{ {
imports = [ imports = [
"${inputs.nixpkgs-otbr}/nixos/modules/services/home-automation/openthread-border-router.nix"
otbrConfig otbrConfig
]; ];
} }

View File

@@ -15,15 +15,39 @@ let
description = "Actual Personal Finance Planner"; description = "Actual Personal Finance Planner";
options = { }; options = { };
moduleConfig = { moduleConfig = {
sops = {
secrets = {
"jallen-nas/actual/client-id" = {
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
owner = "actual";
restartUnits = [ "actual.service" ];
};
"jallen-nas/actual/client-secret" = {
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
owner = "actual";
restartUnits = [ "actual.service" ];
};
};
};
services.actual = { services.actual = {
inherit (cfg) openFirewall; inherit (cfg) openFirewall;
enable = true; enable = true;
settings = { settings = {
inherit (cfg) port; inherit (cfg) port;
trustedProxies = [ config.${namespace}.network.ipv4.address ]; trustedProxies = [
config.${namespace}.network.ipv4.address
"10.0.1.4"
];
serverFiles = "${cfg.configDir}/${name}/server-files"; serverFiles = "${cfg.configDir}/${name}/server-files";
userFiles = "${cfg.configDir}/${name}/user-files"; userFiles = "${cfg.configDir}/${name}/user-files";
dataDir = "${cfg.configDir}/${name}"; dataDir = "${cfg.configDir}/${name}";
openId = {
discoveryURL = "https://authentik.mjallen.dev/application/o/actual/.well-known/openid-configuration";
client_id._secret = config.sops.secrets."jallen-nas/actual/client-id".path;
client_secret._secret = config.sops.secrets."jallen-nas/actual/client-secret".path;
server_hostname = "https://actual.mjallen.dev";
authMethod = "openid";
};
}; };
}; };

View File

@@ -13,14 +13,14 @@ let
cfg = config.${namespace}.services.ai; cfg = config.${namespace}.services.ai;
ntfyModelFailScript = pkgs.writeShellScript "update-qwen-model-notify-failure" '' ntfyModelFailScript = pkgs.writeShellScript "update-gemma-model-notify-failure" ''
HOST="$(${pkgs.hostname}/bin/hostname)" HOST="$(${pkgs.hostname}/bin/hostname)"
${pkgs.curl}/bin/curl -sf \ ${pkgs.curl}/bin/curl -sf \
--user "$NTFY_USER:$NTFY_PASSWORD" \ --user "$NTFY_USER:$NTFY_PASSWORD" \
-H "Title: Qwen model update FAILED on $HOST" \ -H "Title: Gemma model update FAILED on $HOST" \
-H "Priority: high" \ -H "Priority: high" \
-H "Tags: rotating_light,robot_face" \ -H "Tags: rotating_light,robot_face" \
-d "The daily update-qwen-model job failed. Check: journalctl -u update-qwen-model.service" \ -d "The daily update-gemma-model job failed. Check: journalctl -u update-gemma-model.service" \
"https://ntfy.mjallen.dev/builds" || true "https://ntfy.mjallen.dev/builds" || true
''; '';
@@ -30,10 +30,7 @@ let
description = "AI Services"; description = "AI Services";
options = { options = {
llama-cpp = { llama-cpp = {
model = model = mkOpt types.str "gemma-4-26B-A4B-it-UD-Q8_K_XL" "";
mkOpt types.str
"models--unsloth--gemma-4-26B-A4B-it-GGUF/snapshots/b8654b48d979f2853b7a81d6541ca64eea7dc3c5/gemma-4-26B-A4B-it-UD-Q8_K_XL"
"";
}; };
}; };
moduleConfig = { moduleConfig = {
@@ -59,21 +56,17 @@ let
model = "${cfg.configDir}/llama-cpp/models/${cfg.llama-cpp.model}.gguf"; model = "${cfg.configDir}/llama-cpp/models/${cfg.llama-cpp.model}.gguf";
package = inputs.llama-cpp.packages.${system}.rocm; package = inputs.llama-cpp.packages.${system}.rocm;
extraFlags = [ extraFlags = [
"--fit"
"on"
"--seed"
"3407"
"--temp"
"0.7"
"--top-p"
"0.9"
"--min-p"
"0.05"
"--top-k"
"30"
"--jinja" "--jinja"
"--chat-template-kwargs"
"{\"enable_thinking\":true}"
"--temp"
"1.0"
"--top-p"
"0.95"
"--top-k"
"64"
"--ctx-size" "--ctx-size"
"131072" "32768"
"--threads" "--threads"
"8" "8"
"--batch-size" "--batch-size"
@@ -81,7 +74,7 @@ let
"--gpu-layers" "--gpu-layers"
"999" "999"
"--flash-attn" "--flash-attn"
"auto" "on"
"--mlock" "--mlock"
]; ];
}; };
@@ -120,16 +113,16 @@ let
# Systemd service for automatic model updates # Systemd service for automatic model updates
systemd = { systemd = {
services = { services = {
update-qwen-model = { update-gemma-model = {
description = "Update Qwen3-Coder-Next model from HuggingFace"; description = "Update Gemma 4 model from HuggingFace";
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
ExecStart = "${pkgs.writeShellScript "update-qwen-model" '' ExecStart = "${pkgs.writeShellScript "update-gemma-model" ''
set -euo pipefail set -euo pipefail
MODEL_DIR="${cfg.configDir}/llama-cpp/models" MODEL_DIR="${cfg.configDir}/llama-cpp/models"
MODEL_NAME="${cfg.llama-cpp.model}.gguf" MODEL_NAME="${cfg.llama-cpp.model}.gguf"
REPO_ID="unsloth/Qwen3-Coder-Next-GGUF" REPO_ID="unsloth/gemma-4-26B-A4B-it-GGUF"
# Create model directory if it doesn't exist # Create model directory if it doesn't exist
mkdir -p "$MODEL_DIR" mkdir -p "$MODEL_DIR"
@@ -147,13 +140,13 @@ let
Group = "jallen-nas"; Group = "jallen-nas";
EnvironmentFile = [ config.sops.templates."ntfy.env".path ]; EnvironmentFile = [ config.sops.templates."ntfy.env".path ];
}; };
unitConfig.OnFailure = "update-qwen-model-notify-failure.service"; unitConfig.OnFailure = "update-gemma-model-notify-failure.service";
# Run daily at 3 AM # Run daily at 3 AM
startAt = "*-*-* 03:00:00"; startAt = "*-*-* 03:00:00";
}; };
update-qwen-model-notify-failure = { update-gemma-model-notify-failure = {
description = "Notify ntfy on update-qwen-model failure"; description = "Notify ntfy on update-gemma-model failure";
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
ExecStart = "${ntfyModelFailScript}"; ExecStart = "${ntfyModelFailScript}";
@@ -163,8 +156,8 @@ let
# Ensure model is available before llama-cpp starts # Ensure model is available before llama-cpp starts
llama-cpp = { llama-cpp = {
after = [ "update-qwen-model.service" ]; after = [ "update-gemma-model.service" ];
wants = [ "update-qwen-model.service" ]; wants = [ "update-gemma-model.service" ];
}; };
}; };
}; };

View File

@@ -0,0 +1,106 @@
{
config,
lib,
pkgs,
namespace,
...
}:
with lib;
let
name = "caddy-internal";
cfg = config.${namespace}.services.${name};
net = lib.${namespace}.network;
caddyPackage = pkgs.caddy.withPlugins {
plugins = [
"github.com/caddy-dns/cloudflare@v0.2.3"
];
hash = "sha256-20o+14cn/eeLuf1c8uGE1ODRZGC0oxocaIVlv4tFSvA=";
};
# Build a virtual-host block for one proxy entry.
# Access is restricted to LAN + Nebula subnets; all other clients get 403.
mkProxyBlock =
entryName: proxyCfg:
let
fqdn = "${proxyCfg.subdomain}.${net.domain}";
in
''
@${entryName} host ${fqdn}
handle @${entryName} {
@${entryName}_internal {
remote_ip ${net.subnet.lan} ${net.subnet.nebula}
host ${fqdn}
}
handle @${entryName}_internal {
reverse_proxy ${proxyCfg.upstream}
${proxyCfg.extraCaddyConfig}
}
handle {
respond "Forbidden" 403
}
}
'';
proxyBlocks = lib.concatStringsSep "\n" (
lib.mapAttrsToList mkProxyBlock (lib.filterAttrs (_: p: p.enable) cfg.proxies)
);
caddy-internal = lib.${namespace}.mkModule {
inherit config name;
description = "Internal-only Caddy reverse proxy with HTTPS via Cloudflare DNS challenge";
options = {
proxies = mkOption {
type = types.attrsOf (
types.submodule {
options = {
enable = lib.${namespace}.mkBoolOpt true "Whether to enable this proxy entry";
subdomain = lib.${namespace}.mkOpt types.str "" "Subdomain under ${net.domain}";
upstream = lib.${namespace}.mkOpt types.str "" "Upstream address (e.g. http://127.0.0.1:8123)";
extraCaddyConfig =
lib.${namespace}.mkOpt types.lines ""
"Extra Caddyfile directives for this entry";
};
}
);
default = { };
description = "Internal services to proxy, each restricted to LAN + Nebula subnets";
};
};
moduleConfig = {
services.caddy = {
enable = true;
package = caddyPackage;
environmentFile = config.sops.templates."caddy-internal.env".path;
email = "jalle008@proton.me";
enableReload = true;
globalConfig = ''
metrics
http_port 80
https_port 443
default_bind 0.0.0.0
'';
virtualHosts."*.${net.domain}" = {
extraConfig = ''
tls {
dns cloudflare {$CLOUDFLARE_DNS_API_TOKEN}
}
${proxyBlocks}
'';
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
};
};
in
{
imports = [
caddy-internal
./sops.nix
];
}

View File

@@ -0,0 +1,39 @@
{
config,
lib,
namespace,
...
}:
let
cfg = config.${namespace}.services.caddy-internal;
caddyUser = config.users.users.caddy.name;
caddyGroup = config.users.users.caddy.group;
caddySecret = {
owner = caddyUser;
group = caddyGroup;
sopsFile = lib.snowfall.fs.get-file "secrets/nuc-secrets.yaml";
restartUnits = [ "caddy.service" ];
};
in
{
config = lib.mkIf cfg.enable {
sops = {
secrets = {
# Add this key to secrets/nuc-secrets.yaml:
# nuc/caddy/cloudflare-dns-api-token: <token>
"nuc/caddy/cloudflare-dns-api-token" = caddySecret;
};
templates."caddy-internal.env" = {
content = ''
CLOUDFLARE_DNS_API_TOKEN=${config.sops.placeholder."nuc/caddy/cloudflare-dns-api-token"}
'';
owner = caddyUser;
group = caddyGroup;
restartUnits = [ "caddy.service" ];
};
};
};
}

View File

@@ -52,7 +52,7 @@ let
name = "node-exporter-full.json"; name = "node-exporter-full.json";
path = patchDashboard "node-exporter-full.json" (pkgs.fetchurl { path = patchDashboard "node-exporter-full.json" (pkgs.fetchurl {
url = "https://grafana.com/api/dashboards/1860/revisions/latest/download"; url = "https://grafana.com/api/dashboards/1860/revisions/latest/download";
sha256 = "sha256-IeQ72CZhtckDEihcVLhAFuSs77uWsZSENsdomSrWTHo="; sha256 = "sha256-GExrdAnzBtp1Ul13cvcZRbEM6iOtFrXXjEaY6g6lGYY=";
}) "ds_prometheus"; }) "ds_prometheus";
} }
{ {

View File

@@ -114,7 +114,7 @@ let
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.${namespace}.nebula-ui}/bin/nebula-ui"; ExecStart = "${pkgs.${namespace}.nebula-ui}/bin/nebula-ui";
User = name; User = name;
Group = name; GlistenAddressroup = name;
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "5s"; RestartSec = "5s";

View File

@@ -23,7 +23,7 @@ let
enable = true; enable = true;
package = pkgs.nextcloud33; package = pkgs.nextcloud33;
hostName = "cloud.mjallen.dev"; hostName = "cloud.mjallen.dev";
home = "${cfg.configDir}/nextcloud"; home = "${cfg.dataDir}/nextcloud";
datadir = "${cfg.dataDir}/nextcloud"; datadir = "${cfg.dataDir}/nextcloud";
configureRedis = true; configureRedis = true;
enableImagemagick = true; enableImagemagick = true;
@@ -147,8 +147,18 @@ let
# "Service has no ExecStart=, ExecStop=, or SuccessAction=. Refusing." # "Service has no ExecStart=, ExecStop=, or SuccessAction=. Refusing."
nextcloud = lib.mkForce { }; nextcloud = lib.mkForce { };
nextcloud-setup = { nextcloud-setup = {
after = [ "postgresql.service" ]; # Also require the NAS bcachefs mount so that ExecStartPre can create
requires = [ "postgresql.service" ]; # the store-apps and config directories on the actual NAS filesystem.
# Without this, the dirs are created on the root tmpfs overlay before
# the mount comes up, and the real NAS store-apps path never exists.
after = [
"postgresql.service"
"media-nas-main.mount"
];
requires = [
"postgresql.service"
"media-nas-main.mount"
];
serviceConfig = serviceConfig =
let let
# Extract the override.config.php store-path from the already-evaluated # Extract the override.config.php store-path from the already-evaluated
@@ -160,28 +170,121 @@ let
) null config.systemd.tmpfiles.rules; ) null config.systemd.tmpfiles.rules;
overrideStorePath = overrideStorePath =
if overrideLine != null then lib.last (lib.splitString " " overrideLine) else null; if overrideLine != null then lib.last (lib.splitString " " overrideLine) else null;
# Bootstrap config.php written when the file is absent/empty.
# Satisfies Nextcloud's Config.php writeData() guard (needs 'version')
# and the setup script's `-s` check (needs non-empty file).
# passwordsalt/secret/instanceid are intentionally left empty here —
# they must be populated manually or via SOPS before first use.
bootstrapConfig = pkgs.writeText "nextcloud-bootstrap-config.php" (
"<?php\n"
+ "$"
+ "CONFIG = [\n"
+ " 'installed' => true,\n"
+ " 'version' => '${config.services.nextcloud.package.version}',\n"
+ " 'datadirectory' => '${cfg.dataDir}/nextcloud/data',\n"
+ " 'dbtype' => 'pgsql',\n"
+ " 'dbname' => 'nextcloud',\n"
+ " 'dbhost' => '/run/postgresql',\n"
+ " 'dbuser' => 'nextcloud',\n"
+ " 'dbpassword' => "
+ "''"
+ ",\n"
+ " 'instanceid' => "
+ "''"
+ ",\n"
+ " 'passwordsalt' => "
+ "''"
+ ",\n"
+ " 'secret' => "
+ "''"
+ ",\n"
+ "];\n"
);
in in
lib.mkIf (overrideStorePath != null) { lib.mkIf (overrideStorePath != null) {
# systemd-tmpfiles refuses to create the override.config.php symlink because # systemd-tmpfiles refuses to create paths under /media/nas/main because
# /media/nas/main is owned by nix-apps (not root/nextcloud), triggering an # of an "unsafe path transition" (owned by nix-apps, not root/nextcloud).
# "unsafe path transition" error. Work around this by creating the symlink # Work around by creating the required dirs/symlinks as root ('+' prefix)
# directly as root (the '+' prefix) before the setup script's ownership check. # before the setup script's ownership check runs.
# The target store path is resolved at Nix eval time so it is always current.
ExecStartPre = [ ExecStartPre = [
( (
"+" "+"
+ pkgs.writeShellScript "nextcloud-fix-override-config" '' + pkgs.writeShellScript "nextcloud-fix-override-config" ''
dest="${cfg.dataDir}/nextcloud/config/override.config.php" ncdir="${cfg.dataDir}/nextcloud"
# Ensure required directories exist with correct ownership
for dir in "$ncdir" "$ncdir/config" "$ncdir/data" "$ncdir/store-apps"; do
if [ ! -d "$dir" ]; then
${pkgs.coreutils}/bin/mkdir -p "$dir"
fi
${pkgs.coreutils}/bin/chown nextcloud:nextcloud "$dir"
${pkgs.coreutils}/bin/chmod 0750 "$dir"
done
# override.config.php symlink (updated each generation)
dest="$ncdir/config/override.config.php"
echo "Creating symlink: $dest -> ${overrideStorePath}" echo "Creating symlink: $dest -> ${overrideStorePath}"
${pkgs.coreutils}/bin/ln -sf "${overrideStorePath}" "$dest" ${pkgs.coreutils}/bin/ln -sf "${overrideStorePath}" "$dest"
# If config.php is absent or empty, copy in a bootstrap stub.
# Nextcloud's Config.php writeData() guard requires 'version' in the
# merged cache, and the setup script's -s check requires a non-empty
# file. The real runtime settings come from override.config.php via
# array_replace_recursive; this stub just satisfies those two guards.
cfgfile="$ncdir/config/config.php"
if [ ! -s "$cfgfile" ]; then
echo "Writing bootstrap config.php"
${pkgs.coreutils}/bin/cp ${bootstrapConfig} "$cfgfile"
${pkgs.coreutils}/bin/chown nextcloud:nextcloud "$cfgfile"
${pkgs.coreutils}/bin/chmod 0640 "$cfgfile"
fi
'' ''
) )
]; ];
}; };
}; };
nextcloud-update-db = { nextcloud-update-db = {
after = [
"postgresql.service"
"media-nas-main.mount"
];
requires = [
"postgresql.service"
"media-nas-main.mount"
];
};
nextcloud-cron = {
after = [ "media-nas-main.mount" ];
requires = [ "media-nas-main.mount" ];
};
phpfpm-nextcloud = {
after = [ "media-nas-main.mount" ];
requires = [ "media-nas-main.mount" ];
};
# One-shot repair for the oc_filecache_extended duplicate key constraint
# violation that causes nextcloud-cron to fail with:
# "duplicate key value violates unique constraint oc_filecache_extended_pkey"
# Runs as the postgres user before nextcloud-setup so that the DB is clean
# before Nextcloud starts. Idempotent: only removes rows whose fileid does
# not exist in oc_filecache (true orphans). Remove this service once the
# underlying Nextcloud bug is fixed and a clean run confirms cron succeeds.
nextcloud-repair-filecache = {
description = "Repair orphan rows in oc_filecache_extended";
wantedBy = [ "nextcloud-setup.service" ];
before = [ "nextcloud-setup.service" ];
after = [ "postgresql.service" ]; after = [ "postgresql.service" ];
requires = [ "postgresql.service" ]; requires = [ "postgresql.service" ];
serviceConfig = {
Type = "oneshot";
User = "postgres";
ExecStart = pkgs.writeShellScript "nextcloud-repair-filecache" ''
${pkgs.postgresql}/bin/psql -d nextcloud -c "
DELETE FROM oc_filecache_extended
WHERE fileid NOT IN (SELECT fileid FROM oc_filecache);
"
'';
};
}; };
}; };
}; };

View File

@@ -60,6 +60,11 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services."podman-${cfg.name}".unitConfig.RequiresMountsFor = [
cfg.configPath
cfg.dataPath
];
virtualisation.oci-containers.containers."${cfg.name}" = { virtualisation.oci-containers.containers."${cfg.name}" = {
inherit (cfg) autoStart image; inherit (cfg) autoStart image;
ports = [ "${cfg.httpPort}:9200" ]; ports = [ "${cfg.httpPort}:9200" ];

View File

@@ -31,7 +31,6 @@ in
nil nil
nix-output-monitor nix-output-monitor
nixos-anywhere nixos-anywhere
qemu
udisks2 udisks2
unzip unzip
] ]

View File

@@ -109,6 +109,8 @@ in
hashedPasswordFile = resolvedPasswordFile; hashedPasswordFile = resolvedPasswordFile;
extraGroups = [ extraGroups = [
"dialout"
"uucp"
"wheel" "wheel"
"keys" "keys"
"networkmanager" "networkmanager"

View File

@@ -1,8 +1,12 @@
{ lib, ... }: { lib, pkgs, ... }:
{ {
# Virtualisation configuration # Virtualisation configuration
virtualisation = { virtualisation = {
libvirtd.enable = lib.mkDefault true; libvirtd = {
enable = lib.mkForce false;
package = pkgs.stable.libvirt;
qemu.package = pkgs.stable.qemu;
};
podman.enable = lib.mkDefault true; podman.enable = lib.mkDefault true;
waydroid.enable = lib.mkDefault false; waydroid.enable = lib.mkDefault false;
}; };

View File

@@ -1,125 +0,0 @@
{ ... }:
_final: prev: {
home-assistant = prev.home-assistant.override {
packageOverrides = _self: super: {
nice-go = super.nice-go.overridePythonAttrs (_old: {
doCheck = false;
});
cfn-lint = super.cfn-lint.overridePythonAttrs (_old: {
doCheck = false;
});
aiobotocore = super.aiobotocore.overridePythonAttrs (_old: {
doCheck = false;
});
connect-box = super.connect-box.overridePythonAttrs (_old: {
doCheck = false;
});
motionblindsble = super.motionblindsble.overridePythonAttrs (_old: {
doCheck = false;
});
pyinsteon = super.pyinsteon.overridePythonAttrs (_old: {
doCheck = false;
});
psnawp = super.psnawp.overridePythonAttrs (old: {
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ super.pythonRelaxDepsHook ];
pythonRelaxDeps = [ "pycountry" ];
});
radios = super.radios.overridePythonAttrs (old: {
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ super.pythonRelaxDepsHook ];
pythonRelaxDeps = [ "pycountry" ];
});
# Several packages are gated behind pythonAtLeast "3.13" or "3.14" guards
# in nixpkgs, but are required as transitive dependencies of HA components
# when using availableComponents. Override them all to allow Python 3.14
# until upstream catches up.
aiounittest = super.aiounittest.overridePythonAttrs (_old: {
disabled = false;
doCheck = false;
});
# aiokef tests rely on asyncio.get_event_loop() auto-creating a loop,
# which was removed in Python 3.10+.
aiokef = super.aiokef.overridePythonAttrs (_old: {
doCheck = false;
});
# pyads 3.5.1 adopted a src/ layout; the nixpkgs patchPhase references
# the old flat path, and setup.py always tries to compile adslib from
# source via make. Skip the compile step by making platform_is_unix()
# return False, pre-place the nixpkgs adslib.so in src/ so the wheel
# installs it, and disable the import check since pyads searches sys.path
# for adslib.so at import time (requires the real ADS hardware library).
pyads = super.pyads.overridePythonAttrs (old: {
patchPhase = ''
substituteInPlace setup.py \
--replace-fail "sys.platform.startswith(\"linux\") or sys.platform.startswith(\"darwin\")" \
"False"
'';
preBuild = ''
mkdir -p src
cp ${builtins.head old.buildInputs}/lib/adslib.so src/adslib.so
'';
doCheck = false;
pythonImportsCheck = [ ];
});
apischema = super.apischema.overridePythonAttrs (_old: {
disabled = false;
doCheck = false;
});
aws-sam-translator = super.aws-sam-translator.overridePythonAttrs (_old: {
# https://github.com/aws/serverless-application-model/issues/3831
disabled = false;
doCheck = false;
});
# future uses lib2to3 in past.translation, which was removed in Python 3.14.
# That module is only needed for Python 2→3 source translation at runtime,
# which HA components don't use. Drop past.translation from the import check.
future = super.future.overridePythonAttrs (_old: {
disabled = false;
pythonImportsCheck = [
"future.builtins"
"future.moves"
"future.standard_library"
"past.builtins"
];
});
raincloudy = super.raincloudy.overridePythonAttrs (_old: {
disabled = false;
doCheck = false;
});
reactivex = super.reactivex.overridePythonAttrs (_old: {
disabled = false;
doCheck = false;
});
# Several packages are marked broken due to version constraints on upstream
# deps that have been bumped in nixpkgs (pysnmp 7.x, xmltodict 1.x).
# They work fine at runtime for HA's usage.
# aio-georss-client is marked broken because xmltodict >= 1.0 changed how
# namespace-annotated XML elements are returned (dict instead of string),
# which breaks _process_coordinates. The GDACS integration is not used here
# and the package installs fine; skip tests to unblock the build.
aio-georss-client = super.aio-georss-client.overridePythonAttrs (_old: {
meta = (super.aio-georss-client.meta or { }) // {
broken = false;
};
doCheck = false;
});
atenpdu = super.atenpdu.overridePythonAttrs (_old: {
meta = (super.atenpdu.meta or { }) // {
broken = false;
};
nativeBuildInputs = (_old.nativeBuildInputs or [ ]) ++ [ super.pythonRelaxDepsHook ];
pythonRelaxDeps = [ "async-timeout" ];
});
bimmer-connected = super.bimmer-connected.overridePythonAttrs (old: {
meta = (old.meta or { }) // {
broken = false;
};
doCheck = false;
# pillow is an optional dep (China market only) but the runtime dep check
# flags it as missing; add it to propagatedBuildInputs to satisfy it.
propagatedBuildInputs = (old.propagatedBuildInputs or [ ]) ++ [ super.pillow ];
});
};
};
}

View File

@@ -36,7 +36,7 @@ let
in in
stdenv.mkDerivation (finalAttrs: { stdenv.mkDerivation (finalAttrs: {
pname = "bcachefs-tools"; pname = "bcachefs-tools";
version = "1.37.2"; version = "1.37.5";
src = sources.bcachefs-tools; src = sources.bcachefs-tools;

View File

@@ -4,11 +4,11 @@
"bcachefs-tools": { "bcachefs-tools": {
"fetcher": "git", "fetcher": "git",
"url": "https://github.com/koverstreet/bcachefs-tools", "url": "https://github.com/koverstreet/bcachefs-tools",
"rev": "v1.37.4", "rev": "v1.37.5",
"hash": "sha256-VlljE+xoKg6GryVuebUA1v9x2shMBUb7veCtD68MBJw=" "hash": "sha256-x/hpOTvLYyNIsC8ZM0zmTwL8GsiqaTg0ZjQNiS7Y2Wo="
}, },
"cargoDeps": { "cargoDeps": {
"hash": "sha256-t6ghsIRJFR2Kqism4tdizhnJ8qcE2ZZwH6c3nYogHlo=" "hash": "sha256-+9vy+StbFxN+2sNrObLUhvn0BhPZLW6zXuw0uUbaRmw="
} }
} }
} }

Binary file not shown.

View File

@@ -0,0 +1,32 @@
{
stdenv,
writeShellScriptBin,
appimage-run
}:
let
src = ./HueForge_Linux_v0.9.3.1.AppImage;
wrapperScript = writeShellScriptBin "hueforge" ''
exec ${appimage-run}/bin/appimage-run ${src} "$@"
'';
in
stdenv.mkDerivation rec {
inherit src;
pname = "hueforge";
version = "0.9.3.1";
dontUnpack = true;
dontConfigure = true;
dontPatch = true;
dontFixup = true;
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p $out/{share,bin}
cp $src $out/share/HueForge_Linux_v0.9.3.1.AppImage
cp ${wrapperScript}/bin/hueforge $out/bin/hueforge
runHook postInstall
'';
}

View File

@@ -1,21 +1,12 @@
{ {
lib, lib,
stdenvNoCC, stdenvNoCC,
fetchurl,
}: }:
let
imageUrl = "https://scontent.ffcm1-2.fna.fbcdn.net/v/t39.30808-6/387733576_7270226619673057_585200616645530081_n.jpg?_nc_cat=107&ccb=1-7&_nc_sid=1d70fc&_nc_ohc=KeQIDYtXccwQ7kNvwGkF57h&_nc_oc=AdqzTQBFHCfCUmy1iF-ATon_uMr6n0nMSXFyYTmSbT07kVw3D5nCvgfqp3UNhjkO0AM&_nc_zt=23&_nc_ht=scontent.ffcm1-2.fna&_nc_gid=6gw6tJoXB9eWOy5en5irxg&_nc_ss=7a32e&oh=00_Afwr4AsNifG3vViXZ_x-wNC98bznQ2vFnVrKl2sDPEl9oA&oe=69CCE530";
in
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
pname = "profile-pic"; pname = "profile-pic";
version = "1.0.0"; version = "1.0.0";
src = fetchurl { src = ./profile-pic.jpg;
url = imageUrl;
hash = "sha256-n7yayMkNow6IaKVk8mkUWEqa0STR8UKNJD2K1PtPfW8=";
};
sourceRoot = ".";
dontUnpack = true; dontUnpack = true;
@@ -33,7 +24,7 @@ stdenvNoCC.mkDerivation {
meta = with lib; { meta = with lib; {
description = "Profile Pic for Matt"; description = "Profile Pic for Matt";
homepage = "https://authentik.mjallen.dev"; homepage = "https://authentik.mjallen.dev";
platforms = platforms.linux; platforms = platforms.all;
maintainers = [ ]; maintainers = [ ];
}; };
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -25,7 +25,7 @@
}, },
"unstable": { "unstable": {
"variables": { "variables": {
"modDirVersion": "7.0.0-rc6" "modDirVersion": "7.0.0-rc7"
}, },
"sources": { "sources": {
"unstable": { "unstable": {

View File

@@ -23,7 +23,10 @@ jallen-nas:
redis_nextcloud: ENC[AES256_GCM,data:mllmOV98zpqLPhI=,iv:Vl52jKAfzy+aCqpGYUQ80Ye3sGDAR/3ULSStEjAi1hg=,tag:DwUT2cdQ/BA1TwdnXoElXA==,type:str] redis_nextcloud: ENC[AES256_GCM,data:mllmOV98zpqLPhI=,iv:Vl52jKAfzy+aCqpGYUQ80Ye3sGDAR/3ULSStEjAi1hg=,tag:DwUT2cdQ/BA1TwdnXoElXA==,type:str]
nextcloud: nextcloud:
dbpassword: ENC[AES256_GCM,data:kvBa4tUglGHuLH0=,iv:IUWHIH6vx6QlXaKNyq2l0lZGZvudskCW9+jCZ2oENVs=,tag:2UC565EXzGxb2N4XO43ydw==,type:str] dbpassword: ENC[AES256_GCM,data:kvBa4tUglGHuLH0=,iv:IUWHIH6vx6QlXaKNyq2l0lZGZvudskCW9+jCZ2oENVs=,tag:2UC565EXzGxb2N4XO43ydw==,type:str]
adminpassword: ENC[AES256_GCM,data:UJ4LBpif5TIOJqY=,iv:28UgOD1LIoHOVBPTQ3MpofjdkBwY3ghLK2vIbTwZQaA=,tag:F/77ApazlfppzQG6UdTQdQ==,type:str] adminpassword: ENC[AES256_GCM,data:3Fa9ryPgmWKH9A8=,iv:/iji/991Ijb4r0VLA4QlQBbt18evzGUtoJbQEo+hHqM=,tag:RKyS79eM0Pp4aFt6Z7RmWw==,type:str]
instanceid: ENC[AES256_GCM,data:3wNXF951lMRkpxBdpfA=,iv:97sxghu9Yp8lxOUQti4lR1UPXnBP1gpMJwIV5bw4TKc=,tag:ZoI4FHyQA+71bOM9J0vzLw==,type:str]
passwordsalt: ENC[AES256_GCM,data:mg7arfQVC7WnO3/g7cXxf4t9fW+5cev1AbhmuN+QJu3aCuQJCD56,iv:AtM9sbmOLKns3EEErIe+VKzjS/8sCLeKr804G51gAzU=,tag:cf/jRMSKXUC4L4gc4bgs0A==,type:str]
secret: ENC[AES256_GCM,data:5oDcVaF1fYLy/XhwkXrM/vwA2+94sTK9Xjg4se23sxvgupGnzlAoEw6WCDJGZHnb1PqGLSiNDFBgHsMR,iv:8U5aVb9gv12lMB/GMezPkNgwOX/ylBMFQAqvyr59Cig=,tag:MWzDd/SDl0OUp1m0lsNNAw==,type:str]
smtp_settings: ENC[AES256_GCM,data:8KyWmx+e/DouS8OucMrd2AMFE9w1b4WKHr8RuJ8kMqSlL7MP5GLwW4WZhPCJto6kTzAsy4WPFb23oG6UbQg9DK7b2CiUoC5S5mcDxX3lnzX7clyrosDvIHqVlwjamtgfCuNJWcT+RB6a91T84HEDTnKMTsiJvLxpSEHehzL3ItndV9p4+JTs5tZFX+dOZgqVIMN9syQqFsSpI6fk8LNJh90rXXg4jkh7+EFjmBk3QoSOuI1z4JiRpiauVP23VwTtTqiL1Aw8NpDhX1bU0RL+DAWQIZd8o9k/oedziCfKuea73yq4Z8uDaZJ3BW5m1Z1QA44Yu08qvKzBiAAnEb3bQ83ltWI2mfygupjm3tfIVfQoMB8scivaN+5Nlkx3u8f9SAzxyuvqYxZx8TDsyWGEG6p2frHxX72qxu/xb+DYrXBpyDkVA6ng,iv:CqS+/0kL4JmPXRc05Zr2+CFksP1RhOvzIr732z6A1bw=,tag:ux0ja/g1Y40c21hslYnorA==,type:str] smtp_settings: ENC[AES256_GCM,data:8KyWmx+e/DouS8OucMrd2AMFE9w1b4WKHr8RuJ8kMqSlL7MP5GLwW4WZhPCJto6kTzAsy4WPFb23oG6UbQg9DK7b2CiUoC5S5mcDxX3lnzX7clyrosDvIHqVlwjamtgfCuNJWcT+RB6a91T84HEDTnKMTsiJvLxpSEHehzL3ItndV9p4+JTs5tZFX+dOZgqVIMN9syQqFsSpI6fk8LNJh90rXXg4jkh7+EFjmBk3QoSOuI1z4JiRpiauVP23VwTtTqiL1Aw8NpDhX1bU0RL+DAWQIZd8o9k/oedziCfKuea73yq4Z8uDaZJ3BW5m1Z1QA44Yu08qvKzBiAAnEb3bQ83ltWI2mfygupjm3tfIVfQoMB8scivaN+5Nlkx3u8f9SAzxyuvqYxZx8TDsyWGEG6p2frHxX72qxu/xb+DYrXBpyDkVA6ng,iv:CqS+/0kL4JmPXRc05Zr2+CFksP1RhOvzIr732z6A1bw=,tag:ux0ja/g1Y40c21hslYnorA==,type:str]
gitea: gitea:
mail-key: ENC[AES256_GCM,data:kfurnrj8eNKGw+KZcijs4jhJgQ==,iv:mFNVcxVyOj5Se/SyLOcKh5ja/QJmL8wfejzSGOzq6yo=,tag:XBU3urrqarICO7niqBRNbA==,type:str] mail-key: ENC[AES256_GCM,data:kfurnrj8eNKGw+KZcijs4jhJgQ==,iv:mFNVcxVyOj5Se/SyLOcKh5ja/QJmL8wfejzSGOzq6yo=,tag:XBU3urrqarICO7niqBRNbA==,type:str]
@@ -98,6 +101,9 @@ jallen-nas:
secret-key: ENC[AES256_GCM,data:dPHXEAKGrbbM36uH3W4yzm3GmJI=,iv:yHMAMJ8w+uoH/IvLSbxyQm6dEml0MWvwfRIIVHmc6LE=,tag:AyDLS20gUH4gupRGrtGReQ==,type:str] secret-key: ENC[AES256_GCM,data:dPHXEAKGrbbM36uH3W4yzm3GmJI=,iv:yHMAMJ8w+uoH/IvLSbxyQm6dEml0MWvwfRIIVHmc6LE=,tag:AyDLS20gUH4gupRGrtGReQ==,type:str]
kavita: kavita:
token: ENC[AES256_GCM,data:XurnehEZ/jCn+lxtTyty3WkDb17nQ7X3dIIys8O1l17gNzBMyqCLuzQaKLvqAV13PIaGBRTSnlNe7hDs5XYsI2nyL/l0ptPPXgKGEujEtTL8ei0rxTAYnA==,iv:Guinyj+EQNSUE+z+yu3HTF+leoxk7LWXBX/HGcLEki4=,tag:hfkgnjFAwUEVXtDT5HFJTg==,type:str] token: ENC[AES256_GCM,data:XurnehEZ/jCn+lxtTyty3WkDb17nQ7X3dIIys8O1l17gNzBMyqCLuzQaKLvqAV13PIaGBRTSnlNe7hDs5XYsI2nyL/l0ptPPXgKGEujEtTL8ei0rxTAYnA==,iv:Guinyj+EQNSUE+z+yu3HTF+leoxk7LWXBX/HGcLEki4=,tag:hfkgnjFAwUEVXtDT5HFJTg==,type:str]
actual:
client-id: ENC[AES256_GCM,data:bgImXku1RYZADFOPGKScHyC07iB6NRO+OfL477Fmxvp2/MGdahhjXQ==,iv:PsAomwKXxJjHEDrkIuzOAoyxhmKM9Yqmj3xVYx8iUns=,tag:nPd9+jPqcc06DqVb+bg79Q==,type:str]
client-secret: ENC[AES256_GCM,data:PN5RA3gd5NM8m8FbpeJR5SROU9BaE78jTDHBBrVTkXZQq+7HQ6Tq9X6YDv755qwES2WOZyWohAlPSGBJ7/z1NY2dzDhBJTekVXKDpWYpVZhk3AlaT/XjaFP6HNRyAHjBUjLvp1hgCC/QcipzSjfVYdRduRV5b5nMhbz+AITlo6w=,iv:MpgHI1bmd4fS1MILDtmTeFShi61M/dqQsalmTnxT4q8=,tag:+lTfIfRIy7MxFRQu06GtgQ==,type:str]
sops: sops:
shamir_threshold: 1 shamir_threshold: 1
age: age:
@@ -245,8 +251,8 @@ sops:
L0gwQm5takNjMkVGNzVlSStJYlUwWDAKP8QA3rRUHYbyyhPC/k0Eq2EIKfjyc7Co L0gwQm5takNjMkVGNzVlSStJYlUwWDAKP8QA3rRUHYbyyhPC/k0Eq2EIKfjyc7Co
7BkHH3msC6h9g42BB5iIYe6KQ+UGxMQBFvp+qSB27jaIfajN5MP0BA== 7BkHH3msC6h9g42BB5iIYe6KQ+UGxMQBFvp+qSB27jaIfajN5MP0BA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-30T01:56:41Z" lastmodified: "2026-04-13T16:30:32Z"
mac: ENC[AES256_GCM,data:U7xBMz0kJd2fF81rCRD0x4g573lEUnn2Q8e6V/0zgwzoaC39VyZ3RBAUVBS+5d4GSTjrU82sucSNYBZphOGODdgnmL7jSBwaKxg4co9fjuABFmn5WFKJgsw07F48/F2DraftSlRoq1YYkzOhiravgVyWU6aC7o5av+nFVhhfcrM=,iv:bnGpEY6mjPrmeJ+bQdZkXQPTzkBxmIy+5B8/dtJDLmM=,tag:OqvH+y5vjQryzyMUof4isA==,type:str] mac: ENC[AES256_GCM,data:7IQ7jAVbIy2U8WZu7jMCHO13uz8Q+3w4hwEZP8QSOzN45EwjnZSKUoHtIbeS7FEkB/EwkfUdN9trezbEhcPRb7cF6hg2xNdEU8dnx8MmzOoRvirqCf2/c0AD1rVzkEYgYU6RZDIDGOck+WPHf95+2jR2h+P5zz47QCKnej+nlXA=,iv:FhqWxLvGbmMgywIvnXJC2xi6BP7LLhS3mwJIcsUhL84=,tag:NoCqjuZNESUXtX/V31frZg==,type:str]
pgp: pgp:
- created_at: "2026-02-06T15:34:30Z" - created_at: "2026-02-06T15:34:30Z"
enc: |- enc: |-

View File

@@ -6,6 +6,8 @@ nuc:
nuc-nixos-cert: ENC[AES256_GCM,data:lRB9M1D7xMjf/XNxljM7wPitZzY8105Hu6GmmaBgenWIsewIoSfk3tTMwFEe8nzp2jraOzcurTEujl++YOy46S0FDg3bPzdlXBwWZw12F6akfgGTGl8XX7BB7vu9UiQ8stpgUd+6G8NhNmbmVw/0oDnEsSfd4KiJgyf8Hfd9wOBhw+xZEVzHJ+D98ixChH5RB1CyFDpK1qrU9+K7GhsRFEQQdIkr4Xv6ZKnQfcB/uuwQ9Po1vFyfZRmRbRrcYFWIhJSoBr7YY5Kn5LXJxpWPDLZGNe7zibE11J09gXBRXB2Oni2G7TEsNiMlY2w4SA4aBpVngyitw9So7hzwSPX+JCYZnHr3nBCDvkWaECvju9i6pclnuuEN4PFXghaxy3QOweWA4l1DF1jrgdQ+XU8VJk4H,iv:ZdGsr5AldRJYvoG+tXW2cnS7iEs4C14qjp7hQRNdKcI=,tag:fC/DbuFeSWA0vtn9fTV7bg==,type:str] nuc-nixos-cert: ENC[AES256_GCM,data:lRB9M1D7xMjf/XNxljM7wPitZzY8105Hu6GmmaBgenWIsewIoSfk3tTMwFEe8nzp2jraOzcurTEujl++YOy46S0FDg3bPzdlXBwWZw12F6akfgGTGl8XX7BB7vu9UiQ8stpgUd+6G8NhNmbmVw/0oDnEsSfd4KiJgyf8Hfd9wOBhw+xZEVzHJ+D98ixChH5RB1CyFDpK1qrU9+K7GhsRFEQQdIkr4Xv6ZKnQfcB/uuwQ9Po1vFyfZRmRbRrcYFWIhJSoBr7YY5Kn5LXJxpWPDLZGNe7zibE11J09gXBRXB2Oni2G7TEsNiMlY2w4SA4aBpVngyitw9So7hzwSPX+JCYZnHr3nBCDvkWaECvju9i6pclnuuEN4PFXghaxy3QOweWA4l1DF1jrgdQ+XU8VJk4H,iv:ZdGsr5AldRJYvoG+tXW2cnS7iEs4C14qjp7hQRNdKcI=,tag:fC/DbuFeSWA0vtn9fTV7bg==,type:str]
nuc-nixos-key: ENC[AES256_GCM,data:7VhntGkRDoXulB9FNelvF0YwxriuVCpUCb43V33LlCRI8dizGIGtayr4g4hwg88rdgGBZMIzpG0MrR65DhLriR+yJAuvgHBuNHb/IOt9x0Jjo4a5g9r4wwMjcj8TBFM0FiFh5oSysY/S6VYJif7aBTnqGWvrwyfWIuDOD7MWfQ==,iv:rVlATexxX7k9jrk6i11+Wgy6GhWKxTYkBBlGAqOAtMQ=,tag:YHELFmDNyHq1amjYQgTWTQ==,type:str] nuc-nixos-key: ENC[AES256_GCM,data:7VhntGkRDoXulB9FNelvF0YwxriuVCpUCb43V33LlCRI8dizGIGtayr4g4hwg88rdgGBZMIzpG0MrR65DhLriR+yJAuvgHBuNHb/IOt9x0Jjo4a5g9r4wwMjcj8TBFM0FiFh5oSysY/S6VYJif7aBTnqGWvrwyfWIuDOD7MWfQ==,iv:rVlATexxX7k9jrk6i11+Wgy6GhWKxTYkBBlGAqOAtMQ=,tag:YHELFmDNyHq1amjYQgTWTQ==,type:str]
ca-cert: ENC[AES256_GCM,data:ZXmAZdQ0BSGJB5IZ2VJx9IxrrNTqmEYGYKua0gk61/EOnebMp5yg+swKl94+pmFWtqwKlaH+jaChAqYchONHGxOt55AAAlhGzM7BzoUseWdjTf0mFRq4Kr49Tjsz1iOK5XHr8aLESF2E3RkBRi5r0MzstutuagSO59Dj74ZT176sMYWiT7yjPXBgxlLuROQGHBV1/l+N8AMt9M2OLp/0+QYcwSrDh3u8Ts82d9YMODcbNbnCaeo64xmHLW7jJBkDTeH89rfWA5hE+haqUDv/BWe1mBvkV0YIJceyfPZdku0+hOdUIw1iXOTH9Q3KTL5FR9i7lRrCz/ZJzOVrNA==,iv:Td7TBKn+5/1V3WblVwaWjYTOZXMvJ/SMSoUnrNXdAOU=,tag:6YDpTM9kADs2KHKERNeVFQ==,type:str] ca-cert: ENC[AES256_GCM,data:ZXmAZdQ0BSGJB5IZ2VJx9IxrrNTqmEYGYKua0gk61/EOnebMp5yg+swKl94+pmFWtqwKlaH+jaChAqYchONHGxOt55AAAlhGzM7BzoUseWdjTf0mFRq4Kr49Tjsz1iOK5XHr8aLESF2E3RkBRi5r0MzstutuagSO59Dj74ZT176sMYWiT7yjPXBgxlLuROQGHBV1/l+N8AMt9M2OLp/0+QYcwSrDh3u8Ts82d9YMODcbNbnCaeo64xmHLW7jJBkDTeH89rfWA5hE+haqUDv/BWe1mBvkV0YIJceyfPZdku0+hOdUIw1iXOTH9Q3KTL5FR9i7lRrCz/ZJzOVrNA==,iv:Td7TBKn+5/1V3WblVwaWjYTOZXMvJ/SMSoUnrNXdAOU=,tag:6YDpTM9kADs2KHKERNeVFQ==,type:str]
caddy:
cloudflare-dns-api-token: ENC[AES256_GCM,data:QMbo5KFej5MVIpWeWr+B4msS1dUPTtinKNJER44FPiKMNiFzkfGa4w==,iv:h18CzpdvPNOx/IWKEyuNlGmltdBeTUx4i8VMs0Dz8z0=,tag:Ke8nakp2VA/YSAH5Mvf9sQ==,type:str]
sops: sops:
shamir_threshold: 1 shamir_threshold: 1
age: age:
@@ -153,8 +155,8 @@ sops:
WFJONHNsUjJuditvVEgxQ0Y1RVhXQ1kKwBM8ljdCTTbjdasCdtLj4wZ+fX2XQIXf WFJONHNsUjJuditvVEgxQ0Y1RVhXQ1kKwBM8ljdCTTbjdasCdtLj4wZ+fX2XQIXf
IMgacJ5kxYHaYpNpY5wyK2kHzPY9Ovz75WyXicPj0SCojhoKvMAWXQ== IMgacJ5kxYHaYpNpY5wyK2kHzPY9Ovz75WyXicPj0SCojhoKvMAWXQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-24T14:25:23Z" lastmodified: "2026-04-09T19:46:52Z"
mac: ENC[AES256_GCM,data:H50AiSWZ3gzFw4EOfwQE2Z7D2Uj4ZqMbMdcOEY3umoA0wzN2JRBJuIU599tV+bRI4SqlJ/vsSDuoLEqxbDR1ZJfLTLzFxFOfr8kkj7bir1tkRWZPY6pkNBsIteWeaJktXyCodCRxaDuDiKNWlD3+tA5+X3Wjhg4RcAAQ+F18gkk=,iv:SffLSph1FL9Yg915VctG+TRJ/3aoJ3D1wBFiPS2MbAc=,tag:JQJ+rRPftBAeyKtUD+JQ2A==,type:str] mac: ENC[AES256_GCM,data:sQm090y8Txfg/DATQZxhYTPFSKGne5tk9534EOmddLQo4PWFRy5FdssCU7L9gCrcWy2x/hRPq57vNgOSvXrU/JNS3Q/lC2xR8G5cFiwFTg+efXoiS4dnJnAkO8i+IROuh3kbAy0rsECcW8yQS2A1aEXi52hfEkMFrCd9nfX0BmY=,iv:HdjMqLqcztzntb2ChVxcj91KcnP3jYFNhHR8ezgoOkk=,tag:4yPrEKw+I+ECAWrCq0M+2Q==,type:str]
pgp: pgp:
- created_at: "2026-02-06T15:34:31Z" - created_at: "2026-02-06T15:34:31Z"
enc: |- enc: |-
@@ -177,4 +179,4 @@ sops:
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: CBCB9B18A6B8930B0B6ABFD1CCB8CBEB30633684 fp: CBCB9B18A6B8930B0B6ABFD1CCB8CBEB30633684
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.12.1 version: 3.12.2

File diff suppressed because one or more lines are too long

View File

@@ -27,6 +27,25 @@
setupAsahiSound = true; setupAsahiSound = true;
}; };
# Workaround for Apple BCM Bluetooth firmware not sending completion ACKs.
# Without this, WirePlumber spams "Missing completion reports for packet:
# Bluetooth adapter firmware bug?" and audio over BT is unreliable.
hardware.bluetooth.settings = {
Policy = {
AutoEnable = true;
};
};
services.pipewire.wireplumber.extraConfig = {
"51-bluetooth-apple-fix" = {
"monitor.bluez.properties" = {
"bluez5.msbc-support" = false;
"bluez5.sbc-xq-support" = false;
"bluez5.hw-offload-sco" = false;
};
};
};
${namespace} = { ${namespace} = {
headless.enable = false; headless.enable = false;
@@ -107,7 +126,7 @@
nixpkgs.config.allowUnsupportedSystem = true; nixpkgs.config.allowUnsupportedSystem = true;
virtualisation = { virtualisation = {
libvirtd.enable = true; libvirtd.enable = false;
# efi = { # efi = {
# OVMF = (pkgs.OVMF.override { # OVMF = (pkgs.OVMF.override {
# secureBoot = true; # secureBoot = true;

View File

@@ -56,6 +56,85 @@ in
ra_allow_slaac = false; ra_allow_slaac = false;
}; };
}; };
filtering = {
rewrites = [
{
domain = "actual.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "adguard.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "cache.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "chat.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "code.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "esphome.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "grafana.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "govee2mqtt.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "manyfold.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "orca.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "sabnzbd.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "sonarr.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "orca.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "tunarr.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
{
domain = "zigbee2mqtt.mjallen.dev";
answer = "10.0.1.4";
enabled = true;
}
];
};
}; };
}; };
} }

View File

@@ -124,7 +124,7 @@ in
hostSecretName = "lighthouse"; hostSecretName = "lighthouse";
stats = { stats = {
enable = true; enable = true;
listenAddress = "127.0.0.1"; listenAddress = "0.0.0.0";
statsPort = 8474; statsPort = 8474;
}; };
}; };
@@ -136,7 +136,7 @@ in
caCertSecretKey = "pi5/nebula/ca-cert"; caCertSecretKey = "pi5/nebula/ca-cert";
caKeySecretKey = "pi5/nebula/ca-key"; caKeySecretKey = "pi5/nebula/ca-key";
secretsFile = lib.snowfall.fs.get-file "secrets/pi5-secrets.yaml"; secretsFile = lib.snowfall.fs.get-file "secrets/pi5-secrets.yaml";
statsListenAddress = "127.0.0.1"; statsListenAddress = "0.0.0.0";
statsPort = 8474; statsPort = 8474;
reverseProxy = { reverseProxy = {
enable = true; enable = true;
@@ -190,6 +190,19 @@ in
]; ];
}; };
users = {
users = {
atticd = {
isSystemUser = true;
group = "atticd";
extraGroups = [ "keys" ];
};
};
groups = {
atticd = { };
};
};
boot.supportedFilesystems = [ "bcachefs" ]; boot.supportedFilesystems = [ "bcachefs" ];
programs.seahorse.enable = false; programs.seahorse.enable = false;

View File

@@ -4,7 +4,7 @@
... ...
}: }:
let let
kernel = pkgs.cachyosKernels.linuxPackages-cachyos-latest-lto-zen4; kernel = pkgs.linuxPackages_latest;
in in
{ {
# Configure bootloader with lanzaboot and secureboot # Configure bootloader with lanzaboot and secureboot

View File

@@ -3,12 +3,13 @@
... ...
}: }:
let let
kernelPackages = pkgs.cachyosKernels.linuxPackages-cachyos-latest-lto-zen4; kernelPackages = pkgs.linuxPackages_latest;
in in
{ {
boot = { boot = {
inherit kernelPackages; inherit kernelPackages;
# https://github.com/artmoty-dev/n5pro-jmb585-fix
kernelParams = [ "amd_iommu=on" ]; kernelParams = [ "amd_iommu=on" ];
initrd = { initrd = {

View File

@@ -361,7 +361,7 @@ in
# Configure programs # Configure programs
programs = { programs = {
kdeconnect.enable = lib.mkForce false; kdeconnect.enable = lib.mkForce false;
virt-manager.enable = true; virt-manager.enable = config.virtualisation.libvirtd.enable;
steam.gamescopeSession.enable = lib.mkForce false; steam.gamescopeSession.enable = lib.mkForce false;
}; };
} }

View File

@@ -123,6 +123,14 @@ in
# nextcloud # nextcloud
# ------------------------------ # ------------------------------
# instanceid / passwordsalt / secret are written into config.php at
# install time. Store them here so the bootstrap stub in the nextcloud
# module can restore config.php if it ever gets zeroed again.
# Add to nas-secrets.yaml via: sops secrets/nas-secrets.yaml
# jallen-nas/nextcloud/instanceid: <value from config.php>
# jallen-nas/nextcloud/passwordsalt: <value from config.php>
# jallen-nas/nextcloud/secret: <value from config.php>
"jallen-nas/nextcloud/dbpassword" = sopsSettings // { "jallen-nas/nextcloud/dbpassword" = sopsSettings // {
mode = "0650"; mode = "0650";
restartUnits = [ "nextcloud.service" ]; restartUnits = [ "nextcloud.service" ];

View File

@@ -4,7 +4,7 @@
... ...
}: }:
let let
kernel = pkgs.cachyosKernels.linuxPackages-cachyos-latest-lto-zen4; kernel = pkgs.linuxPackages_latest;
pkgsVersion = pkgs; # .unstable; pkgsVersion = pkgs; # .unstable;
in in
{ {

View File

@@ -1,4 +1,4 @@
{ pkgs, ... }: { pkgs, ... }:
{ {
boot.kernelPackages = pkgs.cachyosKernels.linuxPackages-cachyos-latest-lto-x86_64-v4; boot.kernelPackages = pkgs.linuxPackages_latest;
} }

View File

@@ -64,6 +64,86 @@ in
security.tpm.enable = true; security.tpm.enable = true;
services = { services = {
caddy-internal = {
enable = true;
proxies = {
esphome = {
subdomain = "esphome";
upstream = "http://127.0.0.1:${toString net.ports.nuc.esphome}";
};
otbr = {
subdomain = "otbr";
upstream = "http://127.0.0.1:${toString net.ports.nuc.otbr}";
};
actual = {
subdomain = "actual";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.actual}";
};
cache = {
subdomain = "cache";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.attic}";
};
manyfold = {
subdomain = "manyfold";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.manyfold}";
};
chat = {
subdomain = "chat";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.llamaCpp}";
};
grafana = {
subdomain = "grafana";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.grafana}";
};
orca = {
subdomain = "orca";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.orcaSlicer}";
};
sabnzbd = {
subdomain = "sabnzbd";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.sabnzbd}";
};
sonarr = {
subdomain = "sonarr";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.sonarr}";
};
radarr = {
subdomain = "radarr";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.radarr}";
};
tunarr = {
subdomain = "tunarr";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.tunarr}";
};
unmanic = {
subdomain = "unmanic";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.unmanic}";
};
code = {
subdomain = "code";
upstream = "http://${net.hosts.nas.lan}:${toString net.ports.nas.codeServer}";
};
adguard = {
subdomain = "adguard";
upstream = "http://${net.hosts.pi5.lan}:${toString net.ports.pi5.adguard}";
};
zigbee2mqtt = {
subdomain = "zigbee2mqtt";
upstream = "http://${net.hosts.nuc.lan}:${toString net.ports.nuc.zigbee2mqtt}";
};
govee2mqtt = {
subdomain = "govee2mqtt";
upstream = "http://${net.hosts.nuc.lan}:${toString net.ports.nuc.govee2mqtt}";
};
# hass is currently proxied by the NAS Caddy (modules/nixos/services/caddy).
# To migrate it here, remove the @hass block from that module and add:
# hass = {
# subdomain = "hass";
# upstream = "http://127.0.0.1:${toString net.ports.nuc.homeAssistant}";
# };
};
};
home-assistant = { home-assistant = {
enable = true; enable = true;
automation = { automation = {