{ config, lib, pkgs, ... }: with lib; let cfg = config.fudo.services.wallfly-presence; hostname = config.instance.hostname; domain-name = config.instance.local-domain; site-name = config.instance.local-site; mqtt-broker = cfg.mqtt.broker-host; is-mqtt-broker = hostname == mqtt-broker; site-users = config.fudo.sites."${config.instance.local-site}".local-users; domain-users = config.fudo.domains."${domain-name}".local-users; user-cfg = genAttrs (unique (site-users ++ domain-users)) (username: { password-file = pkgs.lib.passwd.stablerandom-passwd-file "wallfly-${username}" config.instance.build-seed; }); local-user-cfg = filterAttrs (username: opts: hasAttr username config.instance.local-users) user-cfg; in { options.fudo.services.wallfly-presence = with types; { enable = mkEnableOption "Enable WallFly presence for the local site."; mqtt = { broker-host = mkOption { type = str; description = "Host to serve as local MQTT broker."; }; port = mkOption { type = port; description = "Port on which to listen for MQTT connections."; default = 1884; }; listen-address = mkOption { type = str; description = "Address on which to listen for MQTT connections."; default = "0.0.0.0"; }; }; }; config = mkIf cfg.enable { fudo = { secrets.host-secrets."${hostname}" = (mapAttrs' (username: userOpts: nameValuePair "wallfly-user-${username}-passwd" { source-file = userOpts.password-file; target-file = "/run/wallfly-${username}/passwd"; user = username; }) local-user-cfg) // (optionalAttrs is-mqtt-broker (mapAttrs' (username: userOpts: nameValuePair "wallfly-server-${username}-passwd" { source-file = userOpts.password-file; target-file = "/run/wallfly-mqtt/${username}.passwd"; user = config.systemd.services.mosquitto.serviceConfig.User; }) user-cfg)); zones."${domain-name}" = { aliases.mqtt = "${mqtt-broker}.${domain-name}"; }; wallfly = { enable = true; mqtt = { broker-uri = "tcp://${mqtt-broker}.${domain-name}:${toString cfg.mqtt.port}"; username = "wallfly-$USER"; password-file = "/run/wallfly-$USER/passwd"; }; }; }; services = { mosquitto = mkIf (is-mqtt-broker) { enable = true; listeners = [{ settings.allow_anonymous = false; port = cfg.mqtt.port; address = cfg.mqtt.listen-address; users = mapAttrs' (username: userOpts: nameValuePair "wallfly-${username}" { passwordFile = "/run/wallfly-mqtt/${username}.passwd"; acl = [ "readwrite homeassistant/binary_sensor/#" ]; }) user-cfg; }]; }; }; }; }