{ config, pkgs, ... }: let mosquittoPort = 1883; zigbee2mqttPort = 8080; # "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" ha-bambulab = pkgs.stdenv.mkDerivation { pname = "ha-bambulab"; version = "v2.1.5"; # Update with correct version src = pkgs.fetchFromGitHub { owner = "greghesp"; # Update with correct owner repo = "ha-bambulab"; # Update with correct repo name rev = "v2.1.5"; # Or specific tag/commit sha256 = "sha256-iVcNFdkzdMVjbQuzrTLib8fhirnc+OJdPzM60EnyVe0="; # Replace with actual hash }; installPhase = '' mkdir -p $out/custom_components cp -r custom_components/bambu_lab $out/custom_components/ ''; }; ha-gehome = pkgs.stdenv.mkDerivation { pname = "ha-gehome"; version = "v2025.2.1"; # Update with correct version src = pkgs.fetchFromGitHub { owner = "simbaja"; # Update with correct owner repo = "ha_gehome"; # Update with correct repo name rev = "v2025.2.1"; # Or specific tag/commit sha256 = "sha256-nb+KrJoWqvhqH6E7A22xXwQzTYp7yn+hl9WRDXn95Cc="; # Replace with actual hash }; installPhase = '' mkdir -p $out/custom_components cp -r custom_components/ge_home $out/custom_components/ ''; }; ha-mail-and-packages = pkgs.stdenv.mkDerivation { pname = "Home-Assistant-Mail-And-Packages"; version = "0.4.2"; # Update with correct version src = pkgs.fetchFromGitHub { owner = "moralmunky"; # Update with correct owner repo = "Home-Assistant-Mail-And-Packages"; # Update with correct repo name rev = "0.4.2"; # Or specific tag/commit sha256 = "sha256-5LBTlRlkSUx8DOY+F7UvUs4dzjZKdBdgnDUdK6DBdew="; # Replace with actual hash }; installPhase = '' mkdir -p $out/custom_components cp -r custom_components/mail_and_packages $out/custom_components/ ''; }; ha-overseerr = pkgs.stdenv.mkDerivation { pname = "ha-overseerr"; version = "0.1.42"; # Update with correct version src = pkgs.fetchFromGitHub { owner = "vaparr"; # Update with correct owner repo = "ha-overseerr"; # Update with correct repo name rev = "0.1.42"; # Or specific tag/commit sha256 = "sha256-UvUowCgfay9aRV+iC/AQ9vvJzhGZbH+/1kVjxPFBKcI="; # Replace with actual hash }; installPhase = '' mkdir -p $out/custom_components cp -r custom_components/overseerr $out/custom_components/ ''; }; ha-petlibro = pkgs.stdenv.mkDerivation { pname = "ha-petlibro"; version = "v1.0.21.1"; # Update with correct version src = pkgs.fetchzip { url = "https://github.com/jjjonesjr33/petlibro/archive/refs/tags/v1.0.21.1.zip"; sha256 = "sha256-3EckyAgWxlZeqy9g13yP2nKCcjnyVIp8EdiE/A1pNu4="; # Replace with actual hash }; installPhase = '' mkdir -p $out/custom_components cp -r custom_components/petlibro $out/custom_components/ ''; }; ha-wyzeapi = pkgs.stdenv.mkDerivation { pname = "ha-wyzeapi"; version = "0.1.32"; # Update with correct version src = pkgs.fetchzip { url = "https://github.com/SecKatie/ha-wyzeapi/archive/refs/tags/0.1.32.zip"; sha256 = "sha256-3xUynZBEHuO2hKLYCb2sBpJAe0JF/8uKqR304Y7JQmE="; # Replace with actual hash }; installPhase = '' mkdir -p $out/custom_components cp -r custom_components/wyzeapi $out/custom_components/ ''; }; # In configuration.nix or a separate file pythonSteam = pkgs.python3.withPackages (ps: [ (ps.buildPythonPackage rec { pname = "steam"; version = "1.4.4"; # Check for the latest version src = pkgs.fetchPypi { inherit pname version; sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Get the correct hash }; doCheck = false; propagatedBuildInputs = [ ps.requests ps.protobuf ]; }) ]); in { services.home-assistant = { enable = true; openFirewall = true; configWritable = true; # todo extraComponents = [ # Components required to complete the onboarding "analytics" "google_translate" "met" "radio_browser" "shopping_list" # Recommended for fast zlib compression # https://www.home-assistant.io/integrations/isal "isal" "subaru" "vesync" "mqtt" # Enables MQTT integration in HA "ffmpeg" # Enables camera streams "zha" # Enables Zigbee integration "homekit" "music_assistant" ]; customComponents = with pkgs.home-assistant-custom-components; [ auth-header ]; customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [ atomic-calendar-revive bubble-card button-card hourly-weather mini-graph-card mini-media-player multiple-entity-row mushroom vacuum-card weather-chart-card zigbee2mqtt-networkmap ]; # use postgresql instead of sqlite extraPackages = ps: with ps; [ # Core functionality aiohttp aiodns paho-mqtt pillow pytz pyyaml sqlalchemy # Discovery & networking zeroconf netdisco ifaddr ssdp # Device protocols pyserial # Serial communications bluepy # Bluetooth LE # Smart home ecosystems mutagen # Media file metadata pysonos # Sonos pywemo # Belkin WeMo python-miio # Xiaomi devices python-kasa # TP-Link # Sensors & monitoring meteocalc # Weather calculations speedtest-cli # Internet speed # Visualization & UI matplotlib # Graphing # Security bcrypt cryptography pyjwt # Media ha-ffmpeg # Camera streams # Specialized integrations python-matter-server # Matter protocol # System integrations psutil # System monitoring psycopg2 numpy hassil pyturbojpeg paho-mqtt pychromecast pyatv python-otbr-api brother pyipp govee-ble adguardhome nextcord aiogithubapi jellyfin-apiclient-python pylitterbot dateparser aionut nextcloudmonitor ollama pynecil aiopyarr pysabnzbd getmac zigpy bellows # For Zigbee EmberZNet-based adapters zigpy-xbee # For XBee adapters zigpy-deconz # For ConBee/RaspBee adapters pyicloud # iCloud pyatv # Apple TV opencv-python face-recognition ibeacon-ble gehomesdk onedrive-personal-sdk python-roborock pythonSteam apple-weatherkit ]; config = { # Includes dependencies for a basic setup # https://www.home-assistant.io/integrations/default_config/ default_config = {}; cloud = false; frontend = { themes = "!include_dir_merge_named themes"; }; "automation ui" = "!include /etc/nixos/hosts/homeassistant/automations.yaml"; "scene ui" = "!include /etc/nixos/hosts/homeassistant/scenes.yaml"; "script ui" = "!include /etc/nixos/hosts/homeassistant/scripts.yaml"; http = { use_x_forwarded_for = true; trusted_proxies = [ "172.30.33.0/24" "10.0.1.3" "10.0.1.0/24" ]; }; recorder = { db_url = "postgresql://@/hass"; purge_keep_days = 180; }; auth_header = { debug = false; username_header = "X-authentik-username"; }; # https://www.home-assistant.io/integrations/ota_updater/ zha.zigpy_config.ota.z2m_remote_index = "https://raw.githubusercontent.com/Koenkk/zigbee-OTA/master/index.json"; }; }; # https://www.home-assistant.io/integrations/automation/ # systemd.tmpfiles.rules = [ # "f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass" # ]; # This bypasses the component validation and places it directly in HA's data directory system.activationScripts.installCustomComponents = '' mkdir -p ${config.services.home-assistant.configDir}/custom_components cp -r ${ha-bambulab}/custom_components/bambu_lab ${config.services.home-assistant.configDir}/custom_components/ cp -r ${ha-gehome}/custom_components/ge_home ${config.services.home-assistant.configDir}/custom_components/ cp -r ${ha-mail-and-packages}/custom_components/mail_and_packages ${config.services.home-assistant.configDir}/custom_components/ cp -r ${ha-overseerr}/custom_components/overseerr ${config.services.home-assistant.configDir}/custom_components/ cp -r ${ha-petlibro}/custom_components/petlibro ${config.services.home-assistant.configDir}/custom_components/ cp -r ${ha-wyzeapi}/custom_components/wyzeapi ${config.services.home-assistant.configDir}/custom_components/ ln -sf /etc/nixos/hosts/homeassistant/automations.yaml ${config.services.home-assistant.configDir}/automations.yaml ln -sf /etc/nixos/hosts/homeassistant/scenes.yaml ${config.services.home-assistant.configDir}/scenes.yaml ln -sf /etc/nixos/hosts/homeassistant/scripts.yaml ${config.services.home-assistant.configDir}/scripts.yaml chown -R hass:hass ${config.services.home-assistant.configDir} chmod -R 750 ${config.services.home-assistant.configDir} ''; services = { postgresql = { enable = true; ensureDatabases = [ "hass" ]; ensureUsers = [{ name = "hass"; ensureDBOwnership = true; }]; }; # Enable and configure Mosquitto MQTT broker mosquitto = { enable = true; listeners = [ { acl = [ "pattern readwrite #" ]; omitPasswordAuth = true; settings.allow_anonymous = true; } ]; }; zigbee2mqtt = { enable = true; settings = { homeassistant = { enabled = config.services.home-assistant.enable; # Optional: Home Assistant discovery topic (default: shown below) # Note: should be different from [MQTT base topic](../mqtt.md) to prevent errors in HA software discovery_topic = "homeassistant"; # Optional: Home Assistant status topic (default: shown below) status_topic = "homeassistant/status"; # Optional: Experimental support for Home Assistant event entities, may break in the future (default: shown below) when enabled: # - An `event` entity will be discovered for each 'action'. # - The `event_type` attribute will contain the action itself, additional attributes like `button` will have further information. experimental_event_entities = false; # Optional: Home Assistant legacy action sensor (default: `false`), when enabled: # - Zigbee2MQTT will send an empty 'action' after one has been send # - A 'sensor_action' will be discovered legacy_action_sensor = false; }; permit_join = true; # Web interface frontend = { port = zigbee2mqttPort; # Choose an available port }; # MQTT configuration mqtt = { base_topic = "zigbee2mqtt"; server = "mqtt://localhost:1883"; # If using authentication: # user = "mqttuser"; # password = "your-password"; }; serial = { port = "/dev/ttyUSB0"; }; }; }; music-assistant = { enable = true; providers = [ # "airplay" # music-assistant: airplay support is missing libraop, a library we will not package because it depends on OpenSSL 1.1. "apple_music" "bluesound" "builtin" "chromecast" "deezer" "dlna" "fanarttv" "filesystem_local" "filesystem_smb" "fully_kiosk" "hass" "hass_players" "jellyfin" "musicbrainz" "opensubsonic" "player_group" "plex" "qobuz" "radiobrowser" "siriusxm" "snapcast" "sonos" "sonos_s1" "soundcloud" "spotify" "template_player_provider" "test" "theaudiodb" "tidal" "tunein" "ytmusic" ]; }; # Enable AirPlay pipewire = { # opens UDP ports 6001-6002 raopOpenFirewall = true; extraConfig.pipewire = { "10-airplay" = { "context.modules" = [ { name = "libpipewire-module-raop-discover"; # increase the buffer size if you get dropouts/glitches # args = { # "raop.latency.ms" = 500; # }; } ]; }; }; }; }; # Enable required hardware support for the Zigbee adapter hardware.bluetooth.enable = true; # Some adapters use Bluetooth # Ensure proper permissions for Zigbee USB devices # services.udev.extraRules = '' # # For CC2531, CC2530, CC1352P-2, CC2538 and similar adapters # SUBSYSTEM=="tty", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="16a8", SYMLINK+="zigbee", MODE="0666" # SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="zigbee", MODE="0666" # # For ConBee/RaspBee by Dresden Elektronik # SUBSYSTEM=="tty", ATTRS{idVendor}=="1cf1", ATTRS{idProduct}=="0030", SYMLINK+="zigbee", MODE="0666" # # For Electrolama zig-a-zig-ah (zzh!) # SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="zigbee", MODE="0666" # ''; environment.systemPackages = with pkgs; [ mosquitto # MQTT command-line tools usbutils # For lsusb to help identify your adapter ]; networking.firewall.allowedTCPPorts = [ mosquittoPort zigbee2mqttPort 8095 8097 ]; }