import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import { loadConfig } from "./src/config"; import { connect } from "./src/mqtt"; import { createEntityManager } from "./src/entities"; const DEFAULT_CONFIG_PATH = "./systant.toml"; yargs(hideBin(process.argv)) .scriptName("systant") .usage("$0 [args]") .command( "run", "Start the systant daemon", (yargs) => { return yargs.option("config", { alias: "c", type: "string", default: DEFAULT_CONFIG_PATH, describe: "Path to config file", }); }, async (argv) => { await run(argv.config); } ) .command( "check", "Check config and connectivity", (yargs) => { return yargs.option("config", { alias: "c", type: "string", default: DEFAULT_CONFIG_PATH, describe: "Path to config file", }); }, async (argv) => { await check(argv.config); } ) .command( "once", "Poll all entity states once, then exit", (yargs) => { return yargs.option("config", { alias: "c", type: "string", default: DEFAULT_CONFIG_PATH, describe: "Path to config file", }); }, async (argv) => { await once(argv.config); } ) .demandCommand(1, "\nError: You need to specify a command!") .help() .parse(); async function run(configPath: string): Promise { const config = await loadConfig(configPath); console.log(`Starting systant on ${config.systant.hostname}`); const mqtt = await connect(config, config.systant.hostname); const entities = createEntityManager(config, mqtt); await entities.start(); // Handle shutdown const shutdown = async () => { console.log("\nShutting down..."); entities.stop(); await mqtt.disconnect(); process.exit(0); }; process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); console.log("Systant running. Press Ctrl+C to stop."); } async function check(configPath: string): Promise { console.log(`Checking config: ${configPath}`); try { const config = await loadConfig(configPath); const entityCount = Object.keys(config.entities).length; console.log("Config loaded successfully"); console.log(` MQTT broker: ${config.mqtt.broker}`); console.log(` Entities: ${entityCount} configured (default interval: ${config.systant.defaultInterval}s)`); console.log(` HA discovery: ${config.homeassistant.discovery}`); console.log("\nTesting MQTT connection..."); const hostname = config.systant.hostname; const mqtt = await connect(config, hostname); console.log("MQTT connection successful"); await mqtt.disconnect(); console.log("\nAll checks passed!"); } catch (err) { console.error("Check failed:", err instanceof Error ? err.message : err); process.exit(1); } } async function once(configPath: string): Promise { const config = await loadConfig(configPath); const hostname = config.systant.hostname; const mqtt = await connect(config, hostname); const entities = createEntityManager(config, mqtt); // Start will do initial poll of all entities await entities.start(); // Wait a moment for the initial polls to complete await new Promise((resolve) => setTimeout(resolve, 1000)); entities.stop(); await mqtt.disconnect(); console.log("Entity states published successfully"); }