{ config, lib, pkgs, ... }: with lib; let cfg = config.services.systant; in { options.services.systant = { enable = mkEnableOption "Systant MQTT Daemon"; package = mkOption { type = types.package; default = pkgs.callPackage ./package.nix { src = ../server; }; description = "The systant package to use"; }; mqttHost = mkOption { type = types.str; default = "localhost"; description = "MQTT broker hostname"; }; mqttPort = mkOption { type = types.int; default = 1883; description = "MQTT broker port"; }; mqttUsername = mkOption { type = types.nullOr types.str; default = null; description = "MQTT username (null for no auth)"; }; mqttPassword = mkOption { type = types.nullOr types.str; default = null; description = "MQTT password (null for no auth)"; }; statsTopic = mkOption { type = types.str; default = "systant/${config.networking.hostName}/stats"; description = "MQTT topic for publishing stats"; }; commandTopic = mkOption { type = types.str; default = "systant/${config.networking.hostName}/commands"; description = "MQTT topic for receiving commands"; }; publishInterval = mkOption { type = types.int; default = 30000; description = "Interval between stats publications (milliseconds)"; }; }; config = mkIf cfg.enable { systemd.user.services.systant = { description = "Systant MQTT Daemon"; after = [ "network.target" ]; wantedBy = [ "default.target" ]; environment = { SYSTANT_MQTT_HOST = cfg.mqttHost; SYSTANT_MQTT_PORT = toString cfg.mqttPort; SYSTANT_MQTT_USERNAME = mkIf (cfg.mqttUsername != null) cfg.mqttUsername; SYSTANT_MQTT_PASSWORD = mkIf (cfg.mqttPassword != null) cfg.mqttPassword; SYSTANT_STATS_TOPIC = cfg.statsTopic; SYSTANT_COMMAND_TOPIC = cfg.commandTopic; SYSTANT_PUBLISH_INTERVAL = toString cfg.publishInterval; # Override RELEASE_COOKIE to bypass file reading RELEASE_COOKIE = "systant-bypass-cookie"; # Set log level to debug for troubleshooting SYSTANT_LOG_LEVEL = "debug"; # Ensure we have the full system PATH including /run/current-system/sw/bin where grim lives PATH = mkForce "/run/wrappers/bin:/run/current-system/sw/bin:/usr/bin:/bin"; }; serviceConfig = { Type = "exec"; ExecStart = "${cfg.package}/bin/systant start"; ExecStop = "${cfg.package}/bin/systant stop"; Restart = "always"; RestartSec = 5; StandardOutput = "journal"; StandardError = "journal"; SyslogIdentifier = "systant"; WorkingDirectory = "${cfg.package}"; }; }; }; }