selfhostblocks/modules/services/home-assistant/docs/default.md
2026-02-24 20:00:36 +01:00

422 lines
14 KiB
Markdown

# Home-Assistant Service {#services-home-assistant}
Defined in [`/modules/services/home-assistant.nix`](@REPO@/modules/services/home-assistant.nix).
This NixOS module is a service that sets up a [Home-Assistant](https://www.home-assistant.io/) instance.
Compared to the stock module from nixpkgs,
this one sets up, in a fully declarative manner
LDAP and SSO integration.
## Features {#services-home-assistant-features}
- Declarative creation of users, admin or not.
- Also declarative [LDAP](#services-home-assistant-options-shb.home-assistant.ldap) Configuration. [Manual](#services-home-assistant-usage-ldap).
- Access through [subdomain](#services-home-assistant-options-shb.home-assistant.subdomain) using reverse proxy. [Manual](#services-home-assistant-usage-configuration).
- Access through [HTTPS](#services-home-assistant-options-shb.home-assistant.ssl) using reverse proxy. [Manual](#services-home-assistant-usage-configuration).
- [Backup](#services-home-assistant-options-shb.home-assistant.backup) through the [backup block](./blocks-backup.html). [Manual](#services-home-assistant-usage-backup).
- Integration with the [dashboard contract](contracts-dashboard.html) for displaying user facing application in a dashboard. [Manual](#services-home-assistant-usage-applicationdashboard)
- Not yet: declarative SSO.
## Usage {#services-home-assistant-usage}
### Initial Configuration {#services-home-assistant-usage-configuration}
The following snippet enables Home-Assistant and makes it available under the `ha.example.com` endpoint.
```nix
shb.home-assistant = {
enable = true;
subdomain = "ha";
domain = "example.com";
config = {
name = "SelfHostBlocks - Home Assistant";
country.source = config.shb.sops.secret."home-assistant/country".result.path;
latitude.source = config.shb.sops.secret."home-assistant/latitude_home".result.path;
longitude.source = config.shb.sops.secret."home-assistant/longitude_home".result.path;
time_zone.source = config.shb.sops.secret."home-assistant/time_zone".result.path;
unit_system = "metric";
};
};
shb.sops.secret."home-assistant/country".request = {
mode = "0440";
owner = "hass";
group = "hass";
restartUnits = [ "home-assistant.service" ];
};
shb.sops.secret."home-assistant/latitude_home".request = {
mode = "0440";
owner = "hass";
group = "hass";
restartUnits = [ "home-assistant.service" ];
};
shb.sops.secret."home-assistant/longitude_home".request = {
mode = "0440";
owner = "hass";
group = "hass";
restartUnits = [ "home-assistant.service" ];
};
shb.sops.secret."home-assistant/time_zone".request = {
mode = "0440";
owner = "hass";
group = "hass";
restartUnits = [ "home-assistant.service" ];
};
```
This assumes secrets are setup with SOPS
as mentioned in [the secrets setup section](usage.html#usage-secrets) of the manual.
Any item in the `config` can be passed a secret, which means it will not appear
in the `/nix/store` and instead be added to the config file out of band, here using sops.
To do that, append `.source` to the settings name and give it the path to the secret.
I advise using secrets to set personally identifiable information,
like shown in the snippet. Especially if you share your repository publicly.
### Home-Assistant through HTTPS {#services-home-assistant-usage-https}
:::: {.note}
We will build upon the [Initial Configuration](#services-home-assistant-usage-configuration) section,
so please follow that first.
::::
If the `shb.ssl` block is used (see [manual](blocks-ssl.html#usage) on how to set it up),
the instance will be reachable at `https://ha.example.com`.
Here is an example with Let's Encrypt certificates, validated using the HTTP method.
First, set the global configuration for your domain:
```nix
shb.certs.certs.letsencrypt."example.com" = {
domain = "example.com";
group = "nginx";
reloadServices = [ "nginx.service" ];
adminEmail = "myemail@mydomain.com";
};
```
Then you can tell Home-Assistant to use those certificates.
```nix
shb.certs.certs.letsencrypt."example.com".extraDomains = [ "ha.example.com" ];
shb.home-assistant = {
ssl = config.shb.certs.certs.letsencrypt."example.com";
};
```
### With LDAP Support {#services-home-assistant-usage-ldap}
:::: {.note}
We will build upon the [HTTPS](#services-home-assistant-usage-https) section,
so please follow that first.
::::
We will use the [LLDAP block][] provided by Self Host Blocks.
Assuming it [has been set already][LLDAP block setup], add the following configuration:
[LLDAP block]: blocks-lldap.html
[LLDAP block setup]: blocks-lldap.html#blocks-lldap-global-setup
```nix
shb.home-assistant.ldap
enable = true;
host = "127.0.0.1";
port = config.shb.lldap.webUIListenPort;
userGroup = "homeassistant_user";
};
```
And that's it.
Now, go to the LDAP server at `http://ldap.example.com`,
create the `home-assistant_user` group,
create a user and add it to one or both groups.
When that's done, go back to the Home-Assistant server at
`http://home-assistant.example.com` and login with that user.
### With SSO Support {#services-home-assistant-usage-sso}
:::: {.warning}
This is not implemented yet. Any contributions ([issue #12](https://github.com/ibizaman/selfhostblocks/issues/12)) are welcomed!
::::
### Backup {#services-home-assistant-usage-backup}
Backing up Home-Assistant using the [Restic block](blocks-restic.html) is done like so:
```nix
shb.restic.instances."home-assistant" = {
request = config.shb.home-assistant.backup;
settings = {
enable = true;
};
};
```
The name `"home-assistant"` in the `instances` can be anything.
The `config.shb.home-assistant.backup` option provides what directories to backup.
You can define any number of Restic instances to backup Home-Assistant multiple times.
You will then need to configure more options like the `repository`,
as explained in the [restic](blocks-restic.html) documentation.
### Application Dashboard {#services-home-assistant-usage-applicationdashboard}
Integration with the [dashboard contract](contracts-dashboard.html) is provided
by the [dashboard option](#services-home-assistant-options-shb.home-assistant.dashboard).
For example using the [Homepage](services-homepage.html) service:
```nix
{
shb.homepage.servicesGroups.Home.services.HomeAssistant = {
sortOrder = 1;
dashboard.request = config.shb.home-assistant.dashboard.request;
settings.icon = "si-homeassistant";
};
}
```
The icon needs to be set manually otherwise it is not displayed correctly.
An API key can be set to show extra info:
```nix
{
shb.homepage.servicesGroups.Home.services.HomeAssistant = {
apiKey.result = config.shb.sops.secret."home-assistant/homepageApiKey".result;
};
shb.sops.secret."home-assistant/homepageApiKey".request =
config.shb.homepage.servicesGroups.Home.services.HomeAssistant.apiKey.request;
}
```
Custom widgets can be set using Home Assistant templating:
```nix
{
shb.homepage.servicesGroups.Home.services.HomeAssistant = {
settings.widget.custom = [
{
template = "{{ states('sensor.power_consumption_power_consumption', with_unit=True, rounded=True) }}";
label = "energy now";
}
{
state = "sensor.power_consumption_daily_power_consumption";
label = "energy today";
}
];
};
}
```
### Extra Components {#services-home-assistant-usage-extra-components}
Packaged components can be found in the documentation of the corresponding option
[services.home-assistant.extraComponents](https://search.nixos.org/options?channel=25.05&show=services.home-assistant.extraComponents&from=0&size=50&sort=relevance&type=packages&query=services.home-assistant.extraComponents)
[services.home-assistant-extraComponents]: https://search.nixos.org/options?channel=25.05&show=services.home-assistant.extraComponents&from=0&size=50&sort=relevance&type=packages&query=services.home-assistant.extraComponents
When you find an interesting one add it to the option:
```bash
services.home-assistant.extraComponents = [
"backup"
"bluetooth"
"esphome"
"assist_pipeline"
"conversation"
"piper"
"wake_word"
"whisper"
"wyoming"
];
```
Some components are not available as extra components, but need to be added as cusotm components.
If the component is not packaged, you'll need to use a [custom component](#services-home-assistant-usage-custom-components).
### Custom Components {#services-home-assistant-usage-custom-components}
:::: {.note}
I'm still confused for why is there a difference between custom components and extra components.
::::
Available custom components can be found by searching packages for [home-assistant-custom-components][].
[home-assistant-custom-components]: https://search.nixos.org/packages?channel=25.05&from=0&size=50&sort=alpha_asc&type=packages&query=home-assistant-custom-components
Add them like so:
```nix
services.home-assistant.customComponents = with pkgs.home-assistant-custom-components; [
adaptive_lighting
];
```
To add a not packaged component, you can get inspiration from existing [packaged components.
To help you package a custom component [nixpkgs code][component-packages.nix] to package it
using the `pkgs.buildHomeAssistantComponent` function.
[component-packages.nix]: https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/home-assistant/component-packages.nix
When done, add it to the same `services.home-assistant.customComponents` option.
Also, don't hesitate to upstream it to nixpkgs.
### Custom Lovelace Modules {#services-home-assistant-usage-custom-lovelace-modules}
To add custom Lovelace UI elements, add them to the `services.home-assistant.customLovelaceModules` option.
Available custom components can be found by searching packages for [home-assistant-custom-lovelace-modules][].
[home-assistant-custom-lovelace-modules]: https://search.nixos.org/packages?channel=25.05&from=0&size=50&sort=alpha_asc&type=packages&query=home-assistant-custom-lovelace-modules
```nix
services.home-assistant.customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [
mini-graph-card
mini-media-player
hourly-weather
weather-card
];
```
### Extra Packages {#services-home-assistant-usage-extra-packages}
This is really only needed if by mischance, one of the components added earlier
fail because of a missing Python3 package when the home-assistant systemd service is started.
Usually, the required module will be shown in the traceback.
To know to which nixpkgs package this Python3 package correspond,
search for a package in the [python3XXPackages set][].
[python3XXPackages set]: https://search.nixos.org/packages?channel=25.05&from=0&size=50&buckets=%7B%22package_attr_set%22%3A%5B%22python313Packages%22%5D%2C%22package_license_set%22%3A%5B%5D%2C%22package_maintainers_set%22%3A%5B%5D%2C%22package_teams_set%22%3A%5B%5D%2C%22package_platforms%22%3A%5B%5D%7D&sort=alpha_asc&type=packages&query=grpcio
```nix
services.home-assistant.extraPackages = python3Packages: with python3Packages; [
grpcio
];
```
### Extra Groups {#services-home-assistant-usage-extra-groups}
Some components need access to hardware components which mean the home-assistant user
`hass` must be added to some Unix group.
For example, the `hass` user must be added to the `dialout` group for the Sonoff component.
There's no systematic way to know this apart reading the logs when a
home-assistant component fails to start.
```nix
users.users.hass.extraGroups = [ "dialout" ];
```
### Voice {#services-home-assistant-usage-voice}
Text to speech (TTS) and speech to text (STT) can be added with the
stock nixpkgs options. The most performance hungry one is STT.
If you don't have a good CPU or better a GPU, you won't be able
to use medium to big models. From my own experience using a low-end
CPU, voice is pretty much unusable like that, even with mini models.
Here is the configuration I use on a low-end CPU:
```nix
shb.home-assistant.voice.text-to-speech = {
"fr" = {
enable = true;
voice = "fr-siwis-medium";
uri = "tcp://0.0.0.0:10200";
speaker = 0;
};
"en" = {
enable = true;
voice = "en_GB-alba-medium";
uri = "tcp://0.0.0.0:10201";
speaker = 0;
};
};
shb.home-assistant.voice.speech-to-text = {
"tiny-fr" = {
enable = true;
model = "base-int8";
language = "fr";
uri = "tcp://0.0.0.0:10300";
device = "cpu";
};
"tiny-en" = {
enable = true;
model = "base-int8";
language = "en";
uri = "tcp://0.0.0.0:10301";
device = "cpu";
};
};
systemd.services.wyoming-faster-whisper-tiny-en.environment."HF_HUB_CACHE" = "/tmp";
systemd.services.wyoming-faster-whisper-tiny-fr.environment."HF_HUB_CACHE" = "/tmp";
shb.home-assistant.voice.wakeword = {
enable = true;
uri = "tcp://127.0.0.1:10400";
preloadModels = [
"ok_nabu"
];
};
```
### Music Assistant {#services-home-assistant-usage-music-assistant}
To add Music Assistant under the `ma.example.com` domain
with two factor SSO authentication, use the following configuration.
This assumes the [SSL][] and [SSO][] blocks are configured.
[SSL]: blocks-ssl.html
[SSO]: blocks-sso.html
```nix
services.music-assistant = {
enable = true;
providers = [
"airplay"
"hass"
"hass_players"
"jellyfin"
"radiobrowser"
"sonos"
"spotify"
];
};
shb.nginx.vhosts = [
{
subdomain = "ma";
domain = "example.com";
ssl = config.shb.certs.certs.letsencrypt.${domain};
authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
upstream = "http://127.0.0.1:8095";
autheliaRules = [{
domain = "ma.${domain}";
policy = "two_factor";
subject = ["group:music-assistant_user"];
}];
}
];
```
## Debug {#services-home-assistant-debug}
In case of an issue, check the logs for systemd service `home-assistant.service`.
Enable verbose logging by setting the `shb.home-assistant.debug` boolean to `true`.
Access the database with `sudo -u home-assistant psql`.
## Options Reference {#services-home-assistant-options}
```{=include=} options
id-prefix: services-home-assistant-options-
list-id: selfhostblocks-service-home-assistant-options
source: @OPTIONS_JSON@
```