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 age.secrets.wireguard.file = ../../secrets/wireguard.age; 124 125 nixarr = { 126 enable = true; 127 mediaDir = "/mnt/storage1/nixarr/media"; 128 vpn = { 129 enable = true; 130 wgConf = config.age.secrets.wireguard.path; 131 }; 132 133 jellyfin = { 134 enable = true; 135 openFirewall = true; 136 }; 137 138 transmission = { 139 enable = true; 140 vpn.enable = true; 141 }; 142 sabnzbd = { 143 enable = true; 144 vpn.enable = true; 145 openFirewall = true; 146 }; 147 148 prowlarr.enable = true; 149 radarr.enable = true; 150 sonarr.enable = true; 151 jellyseerr = { 152 enable = true; 153 openFirewall = true; 154 }; 155 156 recyclarr = { 157 enable = true; 158 configuration = { 159 sonarr = { 160 series = { 161 base_url = "http://localhost:8989"; 162 api_key = "!env_var SONARR_API_KEY"; 163 quality_definition = { 164 type = "series"; 165 }; 166 delete_old_custom_formats = true; 167 custom_formats = [ 168 { 169 trash_ids = [ 170 "85c61753df5da1fb2aab6f2a47426b09" # BR-DISK 171 "9c11cd3f07101cdba90a2d81cf0e56b4" # LQ 172 ]; 173 assign_scores_to = [ 174 { 175 name = "WEB-DL (1080p)"; 176 score = -10000; 177 } 178 ]; 179 } 180 ]; 181 }; 182 }; 183 radarr = { 184 movies = { 185 base_url = "http://localhost:7878"; 186 api_key = "!env_var RADARR_API_KEY"; 187 quality_definition = { 188 type = "movie"; 189 }; 190 delete_old_custom_formats = true; 191 custom_formats = [ 192 { 193 trash_ids = [ 194 "570bc9ebecd92723d2d21500f4be314c" # Remaster 195 "eca37840c13c6ef2dd0262b141a5482f" # 4K Remaster 196 ]; 197 assign_scores_to = [ 198 { 199 name = "HD Bluray + WEB"; 200 score = 25; 201 } 202 ]; 203 } 204 ]; 205 }; 206 }; 207 }; 208 }; 209 }; 210 211 # Install Kodi Sync Queue plugin into Jellyfin 212 systemd.services.jellyfin.serviceConfig.ExecStartPre = 213 let 214 pluginDir = "/data/.state/nixarr/jellyfin/data/plugins/Kodi Sync Queue/15.0.0.0"; 215 in 216 pkgs.writeShellScript "install-jellyfin-plugins" '' 217 mkdir -p "${pluginDir}" 218 cp -f ${jellyfinKodiSyncQueue}/*.dll ${jellyfinKodiSyncQueue}/meta.json "${pluginDir}/" 219 ''; 220 221 # MQTT broker for Home Assistant (Tasmota devices, Frigate) 222 services.mosquitto = { 223 enable = true; 224 listeners = [ 225 { 226 acl = [ "pattern readwrite #" ]; 227 omitPasswordAuth = true; 228 settings.allow_anonymous = true; 229 } 230 ]; 231 }; 232 233 # Frigate NVR for camera recording and AI object detection 234 services.frigate = { 235 enable = true; 236 hostname = "frigate"; 237 settings = { 238 mqtt = { 239 enabled = true; 240 host = "localhost"; 241 port = 1883; 242 }; 243 244 detectors = { 245 cpu = { 246 type = "cpu"; 247 num_threads = 2; 248 }; 249 }; 250 251 cameras = { 252 picam = { 253 enabled = true; 254 ffmpeg = { 255 hwaccel_args = "preset-nvidia-h264"; 256 inputs = [ 257 { 258 path = "rtsp://pi:8554/picam"; 259 roles = [ 260 "detect" 261 "record" 262 ]; 263 } 264 ]; 265 }; 266 detect = { 267 enabled = true; 268 width = 1920; 269 height = 1080; 270 fps = 3; 271 }; 272 record = { 273 enabled = true; 274 retain = { 275 days = 7; 276 mode = "active_objects"; 277 }; 278 }; 279 snapshots = { 280 enabled = true; 281 bounding_box = true; 282 retain = { 283 default = 14; 284 }; 285 }; 286 objects = { 287 track = [ 288 "person" 289 "dog" 290 "cat" 291 "car" 292 ]; 293 }; 294 zones = { 295 driveway = { 296 coordinates = "0,0.243,1,0.544,1,1,0,1,0,0.75"; 297 objects = [ 298 "person" 299 "car" 300 "dog" 301 "cat" 302 ]; 303 }; 304 }; 305 }; 306 307 pizerocam = { 308 enabled = true; 309 ffmpeg = { 310 hwaccel_args = "preset-nvidia-h264"; 311 inputs = [ 312 { 313 path = "rtsp://pizero:8554/pizerocam"; 314 roles = [ "record" ]; 315 } 316 ]; 317 }; 318 detect = { 319 enabled = false; 320 }; 321 record = { 322 enabled = true; 323 retain = { 324 days = 2; 325 mode = "all"; 326 }; 327 }; 328 }; 329 }; 330 331 record = { 332 enabled = true; 333 retain = { 334 days = 7; 335 mode = "active_objects"; 336 }; 337 }; 338 }; 339 }; 340 341 # Home Assistant service 342 services.home-assistant = { 343 enable = true; 344 customComponents = with pkgs.home-assistant-custom-components; [ 345 frigate 346 ]; 347 extraComponents = [ 348 "esphome" 349 "met" 350 "radio_browser" 351 "homekit" 352 "homekit_controller" 353 "isal" 354 "mqtt" 355 "tasmota" 356 "wiz" 357 "google_translate" # TTS - was missing gtts module 358 "ecobee" # Was missing pyecobee module 359 "ibeacon" # Was missing ibeacon_ble module 360 "go2rtc" # Camera streaming 361 "generic" # Generic camera integration 362 ]; 363 config = { 364 homeassistant = { 365 time_zone = "America/Toronto"; 366 }; 367 default_config = { }; 368 zeroconf = { }; 369 # MQTT configuration - broker must be set up via UI 370 mqtt = { }; 371 # Automations 372 automation = [ 373 { 374 id = "1761448856909"; 375 alias = "Lower heat at night"; 376 trigger = [ 377 { 378 platform = "time"; 379 at = "23:00:00"; 380 } 381 ]; 382 condition = [ ]; 383 action = [ 384 { 385 action = "climate.set_temperature"; 386 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 387 data = { 388 hvac_mode = "heat"; 389 temperature = 18; 390 }; 391 } 392 ]; 393 mode = "single"; 394 } 395 { 396 id = "1766200000001"; 397 alias = "Raise heat in morning"; 398 trigger = [ 399 { 400 platform = "time"; 401 at = "06:00:00"; 402 } 403 ]; 404 condition = [ ]; 405 action = [ 406 { 407 action = "climate.set_temperature"; 408 target.device_id = "bfe22d32a4532f8ae991d6daffb48267"; 409 data = { 410 hvac_mode = "heat"; 411 temperature = 21; 412 }; 413 } 414 ]; 415 mode = "single"; 416 } 417 { 418 id = "1766153071796"; 419 alias = "Close Garage Door"; 420 trigger = [ 421 { 422 platform = "device"; 423 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 424 domain = "cover"; 425 entity_id = "cf36763543169888aa106b1acb02ad72"; 426 type = "opened"; 427 for = { 428 hours = 0; 429 minutes = 10; 430 seconds = 0; 431 }; 432 } 433 ]; 434 condition = [ ]; 435 action = [ 436 { 437 device_id = "d8dedd8cd0ce1488d9830c455bb0a761"; 438 domain = "cover"; 439 entity_id = "cf36763543169888aa106b1acb02ad72"; 440 type = "close"; 441 } 442 ]; 443 mode = "single"; 444 } 445 ]; 446 }; 447 }; 448 449 # Invidious (self-hosted YouTube frontend for Kodi addon) 450 services.invidious = { 451 enable = false; 452 port = 3001; 453 address = "0.0.0.0"; 454 database.port = 5433; 455 settings = { 456 registration_enabled = false; 457 local = true; 458 invidious_companion = [ 459 { 460 private_url = "http://127.0.0.1:8282/companion"; 461 } 462 ]; 463 invidious_companion_key = "k9x2mP4qR7wL3nYz"; 464 }; 465 }; 466 467 # Invidious Companion (replaces deprecated inv-sig-helper) 468 virtualisation.oci-containers.containers.invidious-companion = { 469 image = "quay.io/invidious/invidious-companion:latest"; 470 ports = [ "127.0.0.1:8282:8282" ]; 471 environment = { 472 SERVER_SECRET_KEY = "k9x2mP4qR7wL3nYz"; 473 }; 474 extraOptions = [ 475 "--read-only" 476 "--cap-drop=ALL" 477 ]; 478 }; 479 480 environment.systemPackages = [ 481 pkgs.lm_sensors 482 bambu-studio 483 ]; 484 485 # Enable the OpenSSH daemon. 486 # services.openssh.enable = true; 487 488 security.pam.loginLimits = [ 489 { 490 domain = "*"; 491 type = "soft"; 492 item = "nofile"; 493 value = "8192"; 494 } 495 ]; 496 497 # trmnl-rs server 498 systemd.services.trmnl-rs = { 499 description = "TRMNL Server"; 500 wantedBy = [ "multi-user.target" ]; 501 wants = [ "network-online.target" ]; 502 after = [ 503 "network-online.target" 504 "nss-lookup.target" 505 ]; 506 serviceConfig = { 507 ExecStart = "${inputs.trmnl-rs.packages.x86_64-linux.default}/bin/server"; 508 Restart = "on-failure"; 509 RestartSec = 5; 510 DynamicUser = true; 511 StateDirectory = "trmnl-rs"; 512 WorkingDirectory = "/var/lib/trmnl-rs"; 513 }; 514 }; 515 516 # Open ports in the firewall. 517 networking.firewall.allowedTCPPorts = [ 518 8096 # jellyfin 519 5055 # jellyseer 520 3000 # vite dev port 521 3001 # Invidious 522 1883 # MQTT for Tasmota devices 523 2300 # trmnl 524 5000 # Frigate web UI 525 8971 # Frigate API 526 config.services.home-assistant.config.http.server_port 527 ]; 528 networking.firewall.allowedUDPPorts = [ 529 ]; 530 # networking.firewall.enable = false; 531 532 # This value determines the NixOS release from which the default 533 # settings for stateful data, like file locations and database versions 534 # on your system were taken. It‘s perfectly fine and recommended to leave 535 # this value at the release version of the first install of this system. 536 # Before changing this value read the documentation for this option 537 # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). 538 system.stateVersion = "25.05"; # Did you read the comment? 539 540}