Skip to content

Instantly share code, notes, and snippets.

@LukeChannings
Created January 26, 2026 21:27
Show Gist options
  • Select an option

  • Save LukeChannings/aa70e417b47a10d8eaffd6573db55aef to your computer and use it in GitHub Desktop.

Select an option

Save LukeChannings/aa70e417b47a10d8eaffd6573db55aef to your computer and use it in GitHub Desktop.
A Home Assistant example
{
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