Created
January 26, 2026 21:27
-
-
Save LukeChannings/aa70e417b47a10d8eaffd6573db55aef to your computer and use it in GitHub Desktop.
A Home Assistant example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| self, | |
| config, | |
| pkgs, | |
| modulesPath, | |
| inputs, | |
| ... | |
| }@args: | |
| let | |
| inherit (import "${self}/lib/util.nix" args) mapToQueryString; | |
| configDir = "/var/lib/home-assistant"; | |
| in | |
| { | |
| sops.secrets = { | |
| "service/home-assistant/secrets.yaml" = { | |
| owner = "hass"; | |
| path = "${configDir}/secrets.yaml"; | |
| }; | |
| "cloudflare-api-email" = { | |
| format = "binary"; | |
| group = config.security.acme.defaults.group; | |
| mode = "0440"; | |
| sopsFile = "${self}/secrets/cloudflare-email"; | |
| }; | |
| "acme-cloudflare-token" = { | |
| format = "binary"; | |
| group = config.security.acme.defaults.group; | |
| mode = "0440"; | |
| sopsFile = "${self}/secrets/cloudflare-token"; | |
| }; | |
| } | |
| security.acme = { | |
| acceptTerms = true; | |
| certs.${config.networking.fqdnOrHostName} = { | |
| dnsProvider = "cloudflare"; | |
| credentialFiles.CLOUDFLARE_EMAIL_FILE = config.sops.secrets."cloudflare-api-email".path; | |
| credentialFiles.CLOUDFLARE_DNS_API_TOKEN_FILE = config.sops.secrets."acme-cloudflare-token".path; | |
| renewInterval = "*-*-* 00,12:00:00"; | |
| }; | |
| }; | |
| services.home-assistant = { | |
| enable = true; | |
| package = pkgs.latest.home-assistant; | |
| extraComponents = [ | |
| "default_config" | |
| "esphome" | |
| "nmap_tracker" | |
| "plex" | |
| "sonos" | |
| "alexa_devices" | |
| "nut" | |
| "mqtt" | |
| "homekit" | |
| "airgradient" | |
| "uptime_kuma" | |
| "apple_tv" | |
| "ffmpeg" | |
| "zeroconf" | |
| "camera" | |
| "prusalink" | |
| "brother" | |
| "unifi" | |
| "smlight" | |
| "weather" | |
| "met" | |
| "ssdp" | |
| "recorder" | |
| "mobile_app" | |
| "history" | |
| "history_stats" | |
| "logbook" | |
| ]; | |
| extraPackages = | |
| python3Packages: with python3Packages; [ | |
| gtts | |
| zlib-ng | |
| isal | |
| zeroconf | |
| sqlalchemy | |
| psycopg2 | |
| aiohomekit | |
| pyipp | |
| python-otbr-api | |
| ssdp | |
| wled | |
| (certifi.override { | |
| cacert = pkgs.cacert.override { | |
| extraCertificateFiles = [ "${self}/my-certificate-authority/root_ca.crt" ]; | |
| }; | |
| }) | |
| ]; | |
| customComponents = with pkgs.latest.home-assistant-custom-components; [ | |
| octopus_energy | |
| auth_oidc | |
| frigate | |
| (config.services.home-assistant.package.python.pkgs.callPackage | |
| # "${self}/packages/home-assistant/washdata.nix" | |
| # Inline for example: | |
| ({ | |
| lib, | |
| buildHomeAssistantComponent, | |
| home-assistant, | |
| fetchFromGitHub, | |
| }: | |
| buildHomeAssistantComponent rec { | |
| owner = "3dg1luk43"; | |
| domain = "ha_washdata"; | |
| version = "0.3.2"; | |
| src = fetchFromGitHub { | |
| inherit owner; | |
| repo = domain; | |
| rev = "v${version}"; | |
| hash = "sha256-6/Qu4DLnVpEPAsayZ39D6yzuVsLwQhVunemU+XfhIP4="; | |
| }; | |
| propagatedBuildInputs = with home-assistant.python.pkgs; [ numpy ]; | |
| dependencies = [ home-assistant ]; | |
| meta = { | |
| changelog = "https://github.com/${owner}/${domain}/releases/tag/v${version}"; | |
| description = "Home Assistant integration to detect washer cycles from smart plug power, match programs, and estimate time remaining"; | |
| homepage = "https://github.com/${owner}/${domain}"; | |
| license = lib.licenses.mit; | |
| }; | |
| }) | |
| { } | |
| ) | |
| ]; | |
| inherit configDir; | |
| config = { | |
| homeassistant = { | |
| name = "Example"; | |
| latitude = "0"; | |
| longitude = "0"; | |
| elevation = "0"; | |
| unit_system = "metric"; | |
| time_zone = "Europe/London"; | |
| }; | |
| frontend = { | |
| themes = "!include_dir_merge_named themes"; | |
| }; | |
| http = { | |
| server_port = 443; | |
| ssl_certificate = "/var/lib/acme/${config.networking.fqdnOrHostName}/cert.pem"; | |
| ssl_key = "/var/lib/acme/${config.networking.fqdnOrHostName}/key.pem"; | |
| }; | |
| recorder = | |
| let | |
| certDir = "/var/lib/acme/${config.networking.fqdnOrHostName}"; | |
| in | |
| { | |
| db_url = "postgresql://home-assistant@db.example.com/home-assistant?${ | |
| mapToQueryString { | |
| sslmode = "verify-full"; | |
| sslcert = "${certDir}/fullchain.pem"; | |
| sslkey = "${certDir}/key.pem"; | |
| sslrootcert = "${self}/modules/system-config/hartland-ca/root_ca.crt"; | |
| } | |
| }"; | |
| }; | |
| assist_pipeline = { }; | |
| backup = { }; | |
| config = { }; | |
| conversation = { }; | |
| energy = { }; | |
| history = { }; | |
| homeassistant_alerts = { }; | |
| logbook = { }; | |
| mobile_app = { }; | |
| sun = { }; | |
| usage_prediction = { }; | |
| webhook = { }; | |
| auth_oidc = { | |
| client_id = "home-assistant"; | |
| client_secret = "!secret oidc_client_secret"; | |
| discovery_url = "https://id.example.com/oauth2/openid/home-assistant/.well-known/openid-configuration"; | |
| features.automatic_person_creation = true; | |
| id_token_signing_alg = "ES256"; | |
| roles.admin = "home_assistant_admins@id.example.com"; | |
| roles.user = "home_assistant_users@id.example.com"; | |
| }; | |
| }; | |
| }; | |
| users.users.hass.extraGroups = [ "acme" ]; | |
| security.acme.useRoot = true; | |
| # Don't do this if you're going to run Home Assistant on the host | |
| # - I did it because it's a container with a dedicated MACVLAN interface | |
| networking.firewall.enable = false; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment