132 lines
3.8 KiB
Nix
132 lines
3.8 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}: let
|
|
inherit (lib) converge getExe mkOption types;
|
|
inherit (lib.modules) mkForce mkIf;
|
|
inherit (lib.lists) elem;
|
|
inherit (lib.strings) concatMapStringsSep optionalString;
|
|
inherit (lib.attrsets) mapAttrsToList filterAttrsRecursive optionalAttrs;
|
|
|
|
cfg = config.services.esphome;
|
|
|
|
stateDir = "/var/lib/esphome";
|
|
format = pkgs.formats.yaml {};
|
|
|
|
# Adapted from https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/home-automation/home-assistant.nix
|
|
mkESPConf = n: cfg: let
|
|
filteredConfig = converge (filterAttrsRecursive (_: v: ! elem v [null])) cfg;
|
|
in rec {
|
|
name = "${n}-nix.yaml";
|
|
file = pkgs.runCommandLocal name {} ''
|
|
cp ${format.generate name filteredConfig} $out
|
|
sed -i -e "s/'\!\([a-z_]\+\) \(.*\)'/\!\1 \2/;s/^\!\!/\!/;" $out
|
|
sed -i 's/ {}//g' $out
|
|
sed -i "s/'\"/\"/g" $out
|
|
sed -i "s/\"'/\"/g" $out
|
|
'';
|
|
};
|
|
in {
|
|
options.services.esphome = {
|
|
firmwareConfigs = mkOption {
|
|
default = {};
|
|
type = with types; attrsOf anything;
|
|
};
|
|
|
|
secretsFile = mkOption {
|
|
default = null;
|
|
type = types.nullOr types.path;
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
# Fixes https://github.com/NixOS/nixpkgs/issues/339557
|
|
users = {
|
|
users.esphome = {
|
|
isNormalUser = true;
|
|
group = "esphome";
|
|
home = stateDir;
|
|
};
|
|
groups.esphome = {};
|
|
};
|
|
|
|
# Fixes https://github.com/NixOS/nixpkgs/issues/370611
|
|
nixpkgs.overlays = [
|
|
(final: prev: {
|
|
esphome = prev.esphome.overrideAttrs (o: {
|
|
patches = [
|
|
(builtins.toFile "post-build.patch" ''
|
|
--- a/esphome/components/esp32/post_build.py.script
|
|
+++ b/esphome/components/esp32/post_build.py.script
|
|
@@ -2,10 +2,13 @@
|
|
|
|
# pylint: disable=E0602
|
|
Import("env") # noqa
|
|
+#print(env.Dump())
|
|
|
|
import os
|
|
import shutil
|
|
|
|
+os.environ["PATH"] = os.path.dirname(env.get("PYTHONEXE")) + os.pathsep + os.environ["PATH"]
|
|
+
|
|
if os.environ.get("ESPHOME_USE_SUBPROCESS") is None:
|
|
try:
|
|
import esptool
|
|
@@ -63,6 +66,7 @@ def esp32_create_combined_bin(source, target, env):
|
|
esptool.main(cmd)
|
|
else:
|
|
subprocess.run(["esptool.py", *cmd])
|
|
+ #subprocess.run([env.get("PYTHONEXE"), "/var/lib/esphome/.platformio/packages/tool-esptoolpy/esptool.py", *cmd])
|
|
|
|
|
|
def esp32_copy_ota_bin(source, target, env):
|
|
'')
|
|
];
|
|
});
|
|
})
|
|
];
|
|
|
|
systemd.services.esphome = {
|
|
serviceConfig =
|
|
(optionalAttrs (cfg.firmwareConfigs != {}) {
|
|
ExecStartPre = getExe (pkgs.writeShellApplication {
|
|
name = "esphome-exec-start-pre";
|
|
|
|
runtimeInputs = [
|
|
pkgs.findutils
|
|
];
|
|
|
|
text = ''
|
|
shopt -s nullglob
|
|
|
|
for file in ${stateDir}/*-nix.yaml; do
|
|
rm "$file"
|
|
done
|
|
|
|
${optionalString
|
|
(cfg.secretsFile != null)
|
|
# bash
|
|
''
|
|
cp -f "$(realpath "${cfg.secretsFile}")" ${stateDir}/secrets.yaml
|
|
''}
|
|
|
|
${concatMapStringsSep
|
|
"\n"
|
|
(dev:
|
|
# bash
|
|
''
|
|
cp -f "$(realpath "${dev.file}")" ${stateDir}/"${dev.name}"
|
|
'')
|
|
(mapAttrsToList mkESPConf cfg.firmwareConfigs)}
|
|
'';
|
|
});
|
|
})
|
|
// {
|
|
# Fixes https://github.com/NixOS/nixpkgs/issues/339557
|
|
DynamicUser = mkForce "off";
|
|
};
|
|
};
|
|
};
|
|
}
|