Add esphome module

This commit is contained in:
Jakob Lechner 2025-05-27 15:10:20 +02:00
parent f4cb1b304e
commit d4d6c7a830
10 changed files with 154 additions and 142 deletions

View file

@ -1,57 +1,28 @@
{ lib, pkgs, config, ... }:
{ pkgs
, config
, ...
}:
let
inherit (config.networking) ports;
cfgdir = pkgs.stdenvNoCC.mkDerivation {
name = "esphome-config";
src = ./devices;
dontBuild = true;
installPhase = ''
mkdir $out
cp -r * $out
'';
};
in
{
sops.secrets.esphome = {
sopsFile = ../../secrets.yaml;
restartUnits = [ config.systemd.services.esphome.name ];
};
services.esphome = {
jalr.esphome = {
enable = true;
address = "127.0.0.1";
port = ports.esphome.tcp;
package = pkgs.esphome;
};
systemd.services.esphome = {
environment = {
"PLATFORMIO_CORE_DIR" = lib.mkForce "/tmp/.platformio";
};
serviceConfig = {
BindPaths = [
"/var/lib/esphome"
"/var/lib/private/esphome"
];
BindReadOnlyPaths = [
"/nix/store"
"${cfgdir}"
];
DeviceAllow = [
"char-ttyACM rw"
"char-ttyAMA rw"
"char-ttyUSB rw"
];
ExecStartPre = [
"${pkgs.rsync}/bin/rsync -a --delete --exclude=.esphome --exclude=.platformio --exclude=.gitignore '${cfgdir}/' '/var/lib/esphome/'"
"${pkgs.coreutils}/bin/ln -snf '%d/secrets.yaml' '/var/lib/esphome/secrets.yaml'"
];
LoadCredential = "secrets.yaml:${config.sops.secrets.esphome.path}";
PrivateTmp = true;
RootDirectory = "/run/esphome";
RuntimeDirectory = "esphome";
StateDirectory = "esphome";
SupplementaryGroups = [ "dialout" ];
WorkingDirectory = lib.mkForce "/tmp";
secretsFile = config.sops.secrets.esphome.path;
configDir = pkgs.stdenvNoCC.mkDerivation {
name = "esphome-config";
src = ./devices;
dontBuild = true;
installPhase = ''
mkdir $out
cp -r * $out
'';
};
};
}

View file

@ -0,0 +1,2 @@
ESPHOME_HOST="jalr-k.duckdns.org"
ESPHOME_SECRETS_FILE="esphome_${ESPHOME_HOST}_secrets.yaml"

View file

@ -0,0 +1,5 @@
# Gitignore settings for ESPHome
# This is an example and may include too much for your use-case.
# You can modify this file to suit your needs.
/.esphome/
/secrets.yaml

View file

@ -0,0 +1 @@
../../../../../modules/esphome/devices/justfile

View file

@ -1,24 +1,9 @@
{ lib
, pkgs
{ pkgs
, config
, ...
}:
let
inherit (config.networking) ports;
cfgdir = pkgs.stdenvNoCC.mkDerivation {
name = "esphome-config";
src = ./devices;
dontBuild = true;
installPhase = ''
mkdir $out
cp -r * $out
'';
};
cfg = config.services.esphome;
esphomeParams =
if cfg.enableUnixSocket
then "--socket /run/esphome/esphome.sock"
else "--address ${cfg.address} --port ${toString cfg.port}";
in
{
sops.secrets.esphome = {
@ -26,72 +11,18 @@ in
restartUnits = [ config.systemd.services.esphome.name ];
};
services.esphome = {
jalr.esphome = {
enable = true;
address = "127.0.0.1";
port = ports.esphome.tcp;
package = pkgs.esphome;
};
systemd.services.esphome = {
environment = {
"PLATFORMIO_CORE_DIR" = lib.mkForce "/var/cache/esphome/.platformio";
};
serviceConfig = {
BindReadOnlyPaths = [
"/nix/store"
"%d/secrets.yaml:/run/esphome/config/secrets.yaml"
"/etc/resolv.conf"
"/etc/ssl"
"/etc/static/ssl"
];
TemporaryFileSystem = [
"/var/lib"
];
ExecPaths = [
"-+/var/cache/esphome/.platformio/packages/"
];
DeviceAllow = [
"char-ttyACM rw"
"char-ttyAMA rw"
"char-ttyUSB rw"
];
ExecStartPre = [
(pkgs.writeShellScript "esphome-exec-start-pre" ''
if ! [ -d "$CACHE_DIRECTORY/.platformio/packages" ]; then
mkdir -p "$CACHE_DIRECTORY/.platformio/packages"
exit 1
fi
mkdir -p "$CACHE_DIRECTORY/.esphome"
for linked in \
.esphome \
.gitignore
do
ln -s "$CACHE_DIRECTORY/$linked" "/run/esphome/config/$linked"
done
${pkgs.rsync}/bin/rsync \
-a \
--delete \
--checksum \
--exclude secrets.yaml \
--exclude=.esphome \
--exclude=.platformio \
--exclude=.gitignore \
'${cfgdir}/' /run/esphome/config/
'')
];
ExecStart = lib.mkForce "${cfg.package}/bin/esphome dashboard ${esphomeParams} /run/esphome/config";
LoadCredential = "secrets.yaml:${config.sops.secrets.esphome.path}";
PrivateTmp = true;
RootDirectory = "%t/esphome/chroot";
RuntimeDirectory = [
"esphome/chroot"
"esphome/config"
];
StateDirectory = lib.mkForce [ ];
CacheDirectory = "esphome";
SupplementaryGroups = [ "dialout" ];
WorkingDirectory = lib.mkForce "/run/esphome/config";
secretsFile = config.sops.secrets.esphome.path;
configDir = pkgs.stdenvNoCC.mkDerivation {
name = "esphome-config";
src = ./devices;
dontBuild = true;
installPhase = ''
mkdir $out
cp -r * $out
'';
};
};
}

View file

@ -1,2 +1,2 @@
ESPHOME_HOST="192.168.42.1"
ESPHOME_HOST="jalr-bw.duckdns.org"
ESPHOME_SECRETS_FILE="esphome_${ESPHOME_HOST}_secrets.yaml"

View file

@ -1,17 +0,0 @@
import '../../../../../justfile'
set dotenv-load
download:
rsync \
-r \
--rsync-path='sudo rsync' \
--exclude '/build' \
--exclude '/.esphome' \
--exclude '.gitignore' \
--exclude 'secrets.yaml' \
192.168.42.1:/var/lib/esphome/ ./
download-secrets:
umask 0077 && ssh 192.168.42.1 sudo cat /run/secrets/esphome > "/dev/shm/${ESPHOME_SECRETS_FILE}"
ln -sf "/dev/shm/${ESPHOME_SECRETS_FILE}" "{{justfile_directory()}}/secrets.yaml"

View file

@ -0,0 +1 @@
../../../../../modules/esphome/devices/justfile