me like nix
0

Configure Feed

Select the types of activity you want to include in your feed.

1{ 2 pkgs, 3 config, 4 inputs, 5 ... 6}: 7 8let 9 jellyfinKodiSyncQueue = pkgs.fetchzip { 10 url = "https://repo.jellyfin.org/releases/plugin/kodi-sync-queue/kodi-sync-queue_15.0.0.0.zip"; 11 stripRoot = false; 12 hash = "sha256-xtlG3UQ/WClt/Hvxe+oId2CeJ+PWMDXBUJXh5+k+mZQ="; 13 }; 14 15 bambu-studio = 16 let 17 pname = "bambu-studio"; 18 version = "02.04.00.70"; 19 ubuntu_version = "24.04_PR-8834"; 20 21 src = pkgs.fetchurl { 22 url = "https://github.com/bambulab/BambuStudio/releases/download/v${version}/Bambu_Studio_ubuntu-${ubuntu_version}.AppImage"; 23 sha256 = "sha256:26bc07dccb04df2e462b1e03a3766509201c46e27312a15844f6f5d7fdf1debd"; 24 }; 25 26 appimage-contents = pkgs.appimageTools.extractType2 { 27 inherit src pname version; 28 }; 29 30 wrapped = pkgs.appimageTools.wrapType2 { 31 inherit src pname version; 32 33 profile = '' 34 export SSL_CERT_FILE="${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" 35 export GIO_MODULE_DIR="${pkgs.glib-networking}/lib/gio/modules/" 36 ''; 37 38 extraPkgs = 39 p: with p; [ 40 cacert 41 glib 42 glib-networking 43 gst_all_1.gst-plugins-bad 44 gst_all_1.gst-plugins-base 45 gst_all_1.gst-plugins-good 46 webkitgtk_4_1 47 ]; 48 }; 49 in 50 pkgs.runCommand "bambu-studio-${version}" { } '' 51 mkdir -p $out/bin 52 ln -s ${wrapped}/bin/${pname} $out/bin/bambu-studio 53 ln -s ${wrapped}/bin/${pname} $out/bin/BambuStudio 54 55 # Install desktop file with correct exec path 56 mkdir -p $out/share/applications 57 substitute ${appimage-contents}/BambuStudio.desktop $out/share/applications/BambuStudio.desktop \ 58 --replace-fail "Exec=AppRun" "Exec=$out/bin/BambuStudio" 59 60 # Install icons 61 if [ -d ${appimage-contents}/usr/share/icons ]; then 62 cp -r ${appimage-contents}/usr/share/icons $out/share/ 63 fi 64 ''; 65in 66{ 67 imports = [ 68 # Include the results of the hardware scan. 69 ./hardware-configuration.nix 70 ../common/common.nix 71 ]; 72 73 networking.hostName = "mira"; # Define your hostname. 74 75 # Prevent NetworkManager from managing USB Ethernet 76 networking.networkmanager.unmanaged = [ "interface-name:enp0s20f0u4u3" ]; 77 78 # ZRAM swap to prevent OOM freezes 79 zramSwap = { 80 enable = true; 81 memoryPercent = 50; 82 }; 83 84 # Kill runaway processes before the system locks up 85 services.earlyoom = { 86 enable = true; 87 freeMemThreshold = 5; 88 freeSwapThreshold = 5; 89 enableNotifications = true; 90 }; 91 # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. 92 93 # Configure network proxy if necessary 94 # networking.proxy.default = "http://user:password@proxy:port/"; 95 # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; 96 97 # this is like a network devices discovery thing 98 services.avahi = { 99 enable = true; 100 nssmdns4 = true; 101 openFirewall = true; 102 }; 103 104 services.copyparty.enable = true; 105 106 services.openssh = { 107 enable = true; 108 settings = { 109 PasswordAuthentication = false; 110 KbdInteractiveAuthentication = false; 111 PermitRootLogin = "no"; 112 AllowUsers = [ "sean" ]; 113 }; 114 }; 115 116 users.users.sean.openssh.authorizedKeys.keys = [ 117 "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCIqgZ7kedxo+mOW7YG73Vp3zel3h180y3GKvHtRsXfGlpIIvRDy7pgCBQ4AGXYD4y78URQmFohYSAPqCPOPaWcU2un3XG9KvCzEsHmsbskPonitUmCiKvrKkb6oW4jCBtd7AEtBn+AiajAQFtPZ7NN2Df3AmTypvR6Irg7R+nxnfc9NTIHmGvxSDyWcbb4pguL20sctUSqGL6xGh8q/bqhdOThSimM+z9bEUNxK/5rPhwkNniMrp4pJcUrUiAh5/4DiRFG6KT+oeg+/myoz/Z1sPvAs7u/8JDQI4RshRD8Hu0oTkRBN6Hxj478q2SXbeBUZlD6IdjP3RhGpmSecoDdtWqKbpuV3eVRtQtba3KL86GBeV/bugaOdJ1Aud+1SOFJreAAuvxzMMKT+cdQZk6oOPP148DA/No+mDm/2S43lcdCXh79wA6YRAmKQ8jmZxTCtPutrvuZK1rguvvUlEoG/vhdNHh7eDa4Td07V6bjCRPUl8qk/e4M0E3pwsTlZc=" 118 "no-touch-required sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAILdilHXHdAP/V8Zq28EzHKtLAMMaFPu4+1det2N50QfhAAAABHNzaDo= sean@framework16" 119 ]; 120 121 # List services that you want to enable: 122 services.flaresolverr.enable = true; 123 nixarr = { 124 enable = true; 125 mediaDir = "/mnt/storage1/nixarr/media"; 126 vpn = { 127 enable = true; 128 wgConf = "/mnt/storage1/nixarr/wireguard.conf"; 129 }; 130 131 jellyfin = { 132 enable = true; 133 openFirewall = true; 134 }; 135 136 transmission = { 137 enable = true; 138 vpn.enable = true; 139 }; 140 sabnzbd = { 141 enable = true; 142 vpn.enable = true; 143 openFirewall = true; 144 }; 145 146 prowlarr.enable = true; 147 radarr.enable = true; 148 sonarr.enable = true; 149 jellyseerr = { 150 enable = true; 151 openFirewall = true; 152 }; 153 154 recyclarr = { 155 enable = true; 156 configuration = { 157 sonarr = { 158 series = { 159 base_url = "http://localhost:8989"; 160 api_key = "!env_var SONARR_API_KEY"; 161 quality_definition = { 162 type = "series"; 163 }; 164 delete_old_custom_formats = true; 165 custom_formats = [ 166 { 167 trash_ids = [ 168 "85c61753df5da1fb2aab6f2a47426b09" # BR-DISK 169 "9c11cd3f07101cdba90a2d81cf0e56b4" # LQ 170 ]; 171 assign_scores_to = [ 172 { 173 name = "WEB-DL (1080p)"; 174 score = -10000; 175 } 176 ]; 177 } 178 ]; 179 }; 180 }; 181 radarr = { 182 movies = { 183 base_url = "http://localhost:7878"; 184 api_key = "!env_var RADARR_API_KEY"; 185 quality_definition = { 186 type = "movie"; 187 }; 188 delete_old_custom_formats = true; 189 custom_formats = [ 190 { 191 trash_ids = [ 192 "570bc9ebecd92723d2d21500f4be314c" # Remaster 193 "eca37840c13c6ef2dd0262b141a5482f" # 4K Remaster 194 ]; 195 assign_scores_to = [ 196 { 197 name = "HD Bluray + WEB"; 198 score = 25; 199 } 200 ]; 201 } 202 ]; 203 }; 204 }; 205 }; 206 }; 207 }; 208 209 # Install Kodi Sync Queue plugin into Jellyfin 210 systemd.services.jellyfin.serviceConfig.ExecStartPre = 211 let 212 pluginDir = "/data/.state/nixarr/jellyfin/data/plugins/Kodi Sync Queue/15.0.0.0"; 213 in 214 pkgs.writeShellScript "install-jellyfin-plugins" '' 215 mkdir -p "${pluginDir}" 216 cp -f ${jellyfinKodiSyncQueue}/*.dll ${jellyfinKodiSyncQueue}/meta.json "${pluginDir}/" 217 ''; 218 219 # MQTT broker for Home Assistant (Tasmota devices, Frigate) 220 services.mosquitto = { 221 enable = true; 222 listeners = [ 223 { 224 acl = [ "pattern readwrite #" ]; 225 omitPasswordAuth = true; 226 settings.allow_anonymous = true; 227 } 228 ]; 229 }; 230 231 # Frigate NVR for camera recording and AI object detection 232 services.frigate = { 233 enable = true; 234 hostname = "frigate"; 235 settings = { 236 mqtt = { 237 enabled = true; 238 host = "localhost"; 239 port = 1883; 240 }; 241 242 detectors = { 243 cpu = { 244 type = "cpu"; 245 num_threads = 2; 246 }; 247 }; 248 249 cameras = { 250 picam = { 251 enabled = true; 252 ffmpeg = { 253 hwaccel_args = "preset-nvidia-h264"; 254 inputs = [ 255 { 256 path = "rtsp://pi:8554/picam"; 257 roles = [ 258 "detect" 259 "record" 260 ]; 261 } 262 ]; 263 }; 264 detect = { 265 enabled = true; 266 width = 1920; 267 height = 1080; 268 fps = 3; 269 }; 270 record = { 271 enabled = true; 272 retain = { 273 days = 7; 274 mode = "active_objects"; 275 }; 276 }; 277 snapshots = { 278 enabled = true; 279 bounding_box = true; 280 retain = { 281 default = 14; 282 }; 283 }; 284 objects = { 285 track = [ 286 "person" 287 "dog" 288 "cat" 289 "car" 290 ]; 291 }; 292 zones = { 293 driveway = { 294 coordinates = "0,0.243,1,0.544,1,1,0,1,0,0.75"; 295 objects = [ 296 "person" 297 "car" 298 "dog" 299 "cat" 300 ]; 301 }; 302 }; 303 }; 304 305 pizerocam = { 306 enabled = true; 307 ffmpeg = { 308 hwaccel_args = "preset-nvidia-h264"; 309 inputs = [ 310 { 311 path = "rtsp://pizero:8554/pizerocam"; 312 roles = [ "record" ]; 313 } 314 ]; 315 }; 316 detect = { 317 enabled = false; 318 }; 319 record = { 320 enabled = true; 321 retain = { 322 days = 2; 323 mode = "all"; 324 }; 325 }; 326 }; 327 }; 328 329 record = { 330 enabled = true; 331 retain = { 332 days = 7; 333 mode = "active_objects"; 334 }; 335 }; 336 }; 337 }; 338 339 # Home Assistant service 340 services.home-assistant = { 341 enable = true; 342 customComponents = with pkgs.home-assistant-custom-components; [ 343 frigate 344 ]; 345 extraComponents = [ 346 "esphome" 347 "met" 348 "radio_browser" 349 "homekit" 350 "homekit_controller" 351 "isal" 352 "mqtt" 353 "tasmota" 354 "wiz" 355 "google_translate" # TTS - was missing gtts module 356 "ecobee" # Was missing pyecobee module 357 "ibeacon" # Was missing ibeacon_ble module 358 "go2rtc" # Camera streaming 359 "generic" # Generic camera integration 360 ]; 361 config = { 362 homeassistant = { 363 time_zone = "America/Toronto"; 364 }; 365 default_config = { }; 366 zeroconf = { }; 367 # MQTT configuration - broker must be set up via UI 368 mqtt = { }; 369 # Automations 370 automation = [ 371 { 372 id = "1761448856909"; 373 alias = "Lower heat at night"; 374 trigger = [ 375 { 376 platform = "time"; 377 at = "23:00:00"; 378 } 379 ]; 380 condition = [ ]; 381 action = [ 382 { 383 action = "climate.set_temperature"; 384 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 385 data = { 386 hvac_mode = "heat"; 387 temperature = 18; 388 }; 389 } 390 ]; 391 mode = "single"; 392 } 393 { 394 id = "1766200000001"; 395 alias = "Raise heat in morning"; 396 trigger = [ 397 { 398 platform = "time"; 399 at = "06:00:00"; 400 } 401 ]; 402 condition = [ ]; 403 action = [ 404 { 405 action = "climate.set_temperature"; 406 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 407 data = { 408 hvac_mode = "heat"; 409 temperature = 21; 410 }; 411 } 412 ]; 413 mode = "single"; 414 } 415 { 416 id = "1766153071796"; 417 alias = "Close Garage Door"; 418 trigger = [ 419 { 420 platform = "device"; 421 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 422 domain = "cover"; 423 entity_id = "cf36763543169888aa106b1acb02ad72"; 424 type = "opened"; 425 for = { 426 hours = 0; 427 minutes = 10; 428 seconds = 0; 429 }; 430 } 431 ]; 432 condition = [ ]; 433 action = [ 434 { 435 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 436 domain = "cover"; 437 entity_id = "cf36763543169888aa106b1acb02ad72"; 438 type = "close"; 439 } 440 ]; 441 mode = "single"; 442 } 443 ]; 444 }; 445 }; 446 447 # Invidious (self-hosted YouTube frontend for Kodi addon) 448 services.invidious = { 449 enable = false; 450 port = 3001; 451 address = "0.0.0.0"; 452 database.port = 5433; 453 settings = { 454 registration_enabled = false; 455 local = true; 456 invidious_companion = [ 457 { 458 private_url = "http://127.0.0.1:8282/companion"; 459 } 460 ]; 461 invidious_companion_key = "k9x2mP4qR7wL3nYz"; 462 }; 463 }; 464 465 # Invidious Companion (replaces deprecated inv-sig-helper) 466 virtualisation.oci-containers.containers.invidious-companion = { 467 image = "quay.io/invidious/invidious-companion:latest"; 468 ports = [ "127.0.0.1:8282:8282" ]; 469 environment = { 470 SERVER_SECRET_KEY = "k9x2mP4qR7wL3nYz"; 471 }; 472 extraOptions = [ 473 "--read-only" 474 "--cap-drop=ALL" 475 ]; 476 }; 477 478 environment.systemPackages = [ 479 pkgs.lm_sensors 480 bambu-studio 481 ]; 482 483 # Enable the OpenSSH daemon. 484 # services.openssh.enable = true; 485 486 security.pam.loginLimits = [ 487 { 488 domain = "*"; 489 type = "soft"; 490 item = "nofile"; 491 value = "8192"; 492 } 493 ]; 494 495 # trmnl-rs server 496 systemd.services.trmnl-rs = { 497 description = "TRMNL Server"; 498 wantedBy = [ "multi-user.target" ]; 499 wants = [ "network-online.target" ]; 500 after = [ 501 "network-online.target" 502 "nss-lookup.target" 503 ]; 504 serviceConfig = { 505 ExecStart = "${inputs.trmnl-rs.packages.x86_64-linux.default}/bin/server"; 506 Restart = "on-failure"; 507 RestartSec = 5; 508 DynamicUser = true; 509 StateDirectory = "trmnl-rs"; 510 WorkingDirectory = "/var/lib/trmnl-rs"; 511 }; 512 }; 513 514 # Open ports in the firewall. 515 networking.firewall.allowedTCPPorts = [ 516 8096 # jellyfin 517 5055 # jellyseer 518 3000 # vite dev port 519 3001 # Invidious 520 1883 # MQTT for Tasmota devices 521 2300 # trmnl 522 5000 # Frigate web UI 523 8971 # Frigate API 524 config.services.home-assistant.config.http.server_port 525 ]; 526 networking.firewall.allowedUDPPorts = [ 527 ]; 528 # networking.firewall.enable = false; 529 530 # This value determines the NixOS release from which the default 531 # settings for stateful data, like file locations and database versions 532 # on your system were taken. It‘s perfectly fine and recommended to leave 533 # this value at the release version of the first install of this system. 534 # Before changing this value read the documentation for this option 535 # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 536 system.stateVersion = "25.05"; # Did you read the comment? 537 538}