feat(esphome): working

This commit is contained in:
Kat Inskip 2022-09-26 17:49:42 -07:00
parent d266bdb450
commit 4b986433a3
Signed by: kat
GPG key ID: 465E64DECEA8CF0F
9 changed files with 130 additions and 50 deletions

View file

@ -1,10 +1,11 @@
{ config, ... }: {
{ config, target, ... }: {
esphome = {
platform = "esp8266";
board = "d1_mini";
};
api = {
password = "!secret api_password";
};
esp8266 = {
board = "d1_mini";
};
wifi = {
ssid = "Gensokyo";
password = "!secret wifi_password";
@ -24,7 +25,7 @@
sensor = [
{
platform = "dht";
model = "dht22";
model = "DHT22";
update_interval = "60s";
pin = "D0";
temperature = {

View file

@ -0,0 +1,86 @@
{ tf, target, name, meta, config, lib, ... }:
/*
This module:
* aliases <hostname>.system.build.toplevel to <hostname>.deploy.system for ease of use.
* marries meta config to NixOS configs for each host.
* provides in-scope TF config in NixOS and home-manager, instead of only as a part of meta config.
*/
with lib;
let
cfg = config.deploy;
unmergedValues = types.mkOptionType {
name = "unmergedValues";
merge = loc: defs: map (def: def.value) defs;
};
in
{
options.deploy.tf = mkOption {
type = types.submodule {
inherit (unmerged) freeformType;
options = {
triggers = mkOption {
type = types.attrsOf types.unspecified;
default = { };
};
import = mkOption {
type = types.attrsOf types.unspecified;
default = [ ];
};
imports = mkOption {
type = types.listOf types.str;
description = "Other targets to depend on";
default = [ ];
};
attrs = mkOption {
type = types.listOf types.str;
default = [ ];
};
out.set = mkOption { type = types.unspecified; };
};
};
};
config = let
functionlessConfig = lib.removeAttrs config ["out" "_module" "platform" "deploy"];
mutatedConfig = functionlessConfig // (optionalAttrs (config.platform != {}) {
${functionlessConfig.esphome.platform} = config.platform;
});
jsonConfig = builtins.toJSON mutatedConfig;
closureConfig = pkgs.writeText "${functionlessConfig.esphome.name}.json" jsonConfig;
closure-upload = pkgs.writeShellScriptBin "${functionlessConfig.esphome.name}-upload" ''
'';
in {
deploy.tf = {
attrs = [ "import" "imports" "out" "attrs" "triggers" ];
import = genAttrs cfg.tf.imports (target: meta.deploy.targets.${target}.tf);
out.set = removeAttrs cfg.tf cfg.tf.attrs;
triggers = {
compile = {
system = config.out;
};
};
resources = {
"${name}-upload" = {
provider = "null";
type = "resource";
inputs.triggers = cfg.tf.triggers.compile;
provisioners = [
{
type = "local-exec";
local-exec.command = ''
${pkgs.esphome}/bin/esphome upload ${closureConfig}
'';
}
];
};
};
};
_module.args.tf = mapNullable (target: target.tf) target;
};
}

View file

@ -1,2 +1,10 @@
{ config, ... }: {
{ name, config, meta, pkgs, lib, ... }: with lib;
{
options = {
} // genAttrs [ "esphome" "api" "platform" "wifi" "i2c" "logger" "ota" "sensor" ] (key:
mkOption {
type = types.unspecified;
default = {};
}
);
}

View file

@ -127,7 +127,8 @@ in
};
};
continue.envVar = "TF_NIX_CONTINUE_${replaceStrings [ "-" ] [ "_" ] config.name}";
}) ++ map (nodeName: mapAttrs (_: mkMerge) meta.network.nodes.nixos.${nodeName}.deploy.tf.out.set) config.nodeNames);
}) ++ map (nodeName: mapAttrs (_: mkMerge) meta.network.nodes.nixos.${nodeName}.deploy.tf.out.set) config.nodeNames
++ (optionals (config.name == "home") (mapAttrsToList (node: config: (mapAttrs (_: mkMerge) config.deploy.tf.out.set)) meta.network.nodes.esphome)));
});
in
mkOption {

View file

@ -49,32 +49,13 @@ with lib;
default = { };
};
};
union = mkOption {
nodes.all = mkOption {
type = types.attrsOf types.unspecified;
default = config.network.nodes.nixos // config.network.nodes.darwin // config.network.nodes.esphome;
};
nodes.esphome = let
esphomeModule = { name, config, meta, lib, ... }: with lib;
let
settings = config.settings;
closureConfig = pkgs.writeText "${settings.esphome.name}.json" builtins.toJSON settings;
closure = pkgs.runCommand "${settings.esphome.name}" {} ''
${pkgs.esphome}/bin/esphome compile ${closureConfig}
mv .esphome/build/${settings.esphome.name}/.pioenvs/${settings.esphome.name}/firmware.bin $out
'';
in {
options.out = mkOption {
type = types.unspecified;
default = closure;
};
options.settings = mkOption {
type = types.unspecified;
};
};
esphomeType = types.submoduleWith {
modules = [
esphomeModule
] ++ config.network.esphome.extraModules;
modules = [ { _module.args.pkgs = pkgs; } ] ++ config.network.esphome.extraModules;
inherit (config.network.esphome) specialArgs;
};
in mkOption {
@ -158,8 +139,10 @@ with lib;
config.network = {
esphome = {
extraModules = [
meta.modules.esphome
];
specialArgs = {
target = config.deploy.targets.home;
inherit (config.network) nodes;
inherit inputs meta;
};
@ -186,7 +169,7 @@ with lib;
];
specialArgs = {
inherit (config.network) nodes;
inherit inputs meta;
inherit inputs meta pkgs;
};
};
};

View file

@ -289,20 +289,6 @@
acme = let
home = meta.deploy.targets.home.tf;
in {
enable = true;
account = {
emailAddress = "kat@inskip.me";
accountKeyPem = home.resources.acme_private_key.importAttr "private_key_pem";
};
challenge = {
defaultProvider = "rfc2136";
configs.rfc2136 = {
RFC2136_NAMESERVER = tf.variables.katdns-address.ref;
RFC2136_TSIG_KEY = tf.variables.katdns-name.ref;
RFC2136_TSIG_SECRET = tf.variables.katdns-key.ref;
RFC2136_TSIG_ALGORITHM = "hmac-sha512";
};
};
certs = let
nvP = network: settings: nameValuePair settings.uqdn {
keyType = "4096";

View file

@ -80,6 +80,7 @@
};
"modules/darwin".functor.enable = true;
"modules/system".functor.enable = true;
"modules/esphome".functor.enable = true;
"modules/meta".functor.enable = true;
"nixos/systems".functor.enable = false;
"darwin/systems".functor.enable = false;
@ -125,13 +126,11 @@
esphomeNodes = (map
(node: {
network.nodes.esphome.${node} = {
settings = {
imports = config.lib.kw.esphomeImport node;
esphome = {
name = node;
};
};
};
})
(lib.attrNames nixfiles.esphome));
nixosNodes = (map

2
tf

@ -1 +1 @@
Subproject commit 856827e23fd7f1ef1d07dea9c5be26c0a0f7dee8
Subproject commit 19085b061685d726090c2b5fdc3afe536ad43dd7

16
tf.nix
View file

@ -18,6 +18,22 @@
type = "string";
sensitive = true;
};
acme = {
enable = true;
account = {
emailAddress = "kat@inskip.me";
accountKeyPem = home.resources.acme_private_key.importAttr "private_key_pem";
};
challenge = {
defaultProvider = "rfc2136";
configs.rfc2136 = {
RFC2136_NAMESERVER = tf.variables.katdns-address.ref;
RFC2136_TSIG_KEY = tf.variables.katdns-name.ref;
RFC2136_TSIG_SECRET = tf.variables.katdns-key.ref;
RFC2136_TSIG_ALGORITHM = "hmac-sha512";
};
};
};
providers.katdns = {
type = "dns";