fix(core): tidy formatting and minor fixes across CLI, SNMP, HTTP server, migrations and packaging
This commit is contained in:
74
ts/daemon.ts
74
ts/daemon.ts
@@ -5,13 +5,13 @@ import { exec, execFile } from 'node:child_process';
|
||||
import { promisify } from 'node:util';
|
||||
import { NupstSnmp } from './snmp/manager.ts';
|
||||
import type { ISnmpConfig, IUpsStatus as ISnmpUpsStatus } from './snmp/types.ts';
|
||||
import { logger, type ITableColumn } from './logger.ts';
|
||||
import { type ITableColumn, logger } from './logger.ts';
|
||||
import { MigrationRunner } from './migrations/index.ts';
|
||||
import { theme, symbols, getBatteryColor, getRuntimeColor, formatPowerStatus } from './colors.ts';
|
||||
import { formatPowerStatus, getBatteryColor, getRuntimeColor, symbols, theme } from './colors.ts';
|
||||
import type { IActionConfig } from './actions/base-action.ts';
|
||||
import { ActionManager, type IActionContext, type TPowerStatus } from './actions/index.ts';
|
||||
import { NupstHttpServer } from './http-server.ts';
|
||||
import { TIMING, THRESHOLDS, UI } from './constants.ts';
|
||||
import { THRESHOLDS, TIMING, UI } from './constants.ts';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
const execFileAsync = promisify(execFile);
|
||||
@@ -100,10 +100,10 @@ export interface IUpsStatus {
|
||||
powerStatus: 'online' | 'onBattery' | 'unknown';
|
||||
batteryCapacity: number;
|
||||
batteryRuntime: number;
|
||||
outputLoad: number; // Load percentage (0-100%)
|
||||
outputPower: number; // Power in watts
|
||||
outputVoltage: number; // Voltage in volts
|
||||
outputCurrent: number; // Current in amps
|
||||
outputLoad: number; // Load percentage (0-100%)
|
||||
outputPower: number; // Power in watts
|
||||
outputVoltage: number; // Voltage in volts
|
||||
outputCurrent: number; // Current in amps
|
||||
lastStatusChange: number;
|
||||
lastCheckTime: number;
|
||||
}
|
||||
@@ -155,7 +155,7 @@ export class NupstDaemon {
|
||||
],
|
||||
groups: [],
|
||||
checkInterval: TIMING.CHECK_INTERVAL_MS, // Check every 30 seconds
|
||||
}
|
||||
};
|
||||
|
||||
private config: INupstConfig;
|
||||
private snmp: NupstSnmp;
|
||||
@@ -249,7 +249,12 @@ export class NupstDaemon {
|
||||
* Helper method to log configuration errors consistently
|
||||
*/
|
||||
private logConfigError(message: string): void {
|
||||
logger.logBox('Configuration Error', [message, "Please run 'nupst setup' first to create a configuration."], 45, 'error');
|
||||
logger.logBox(
|
||||
'Configuration Error',
|
||||
[message, "Please run 'nupst setup' first to create a configuration."],
|
||||
45,
|
||||
'error',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,11 +316,15 @@ export class NupstDaemon {
|
||||
this.config.httpServer.port,
|
||||
this.config.httpServer.path,
|
||||
this.config.httpServer.authToken,
|
||||
() => this.upsStatus
|
||||
() => this.upsStatus,
|
||||
);
|
||||
this.httpServer.start();
|
||||
} catch (error) {
|
||||
logger.error(`Failed to start HTTP server: ${error instanceof Error ? error.message : String(error)}`);
|
||||
logger.error(
|
||||
`Failed to start HTTP server: ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +373,6 @@ export class NupstDaemon {
|
||||
* Log the loaded configuration settings
|
||||
*/
|
||||
private logConfigLoaded(): void {
|
||||
|
||||
logger.log('');
|
||||
logger.logBoxTitle('Configuration Loaded', 70, 'success');
|
||||
logger.logBoxLine(`Check Interval: ${this.config.checkInterval / 1000} seconds`);
|
||||
@@ -374,8 +382,10 @@ export class NupstDaemon {
|
||||
// Display UPS devices in a table
|
||||
if (this.config.upsDevices && this.config.upsDevices.length > 0) {
|
||||
logger.info(`UPS Devices (${this.config.upsDevices.length}):`);
|
||||
|
||||
const upsColumns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
|
||||
|
||||
const upsColumns: Array<
|
||||
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
|
||||
> = [
|
||||
{ header: 'Name', key: 'name', align: 'left', color: theme.highlight },
|
||||
{ header: 'ID', key: 'id', align: 'left', color: theme.dim },
|
||||
{ header: 'Host:Port', key: 'host', align: 'left', color: theme.info },
|
||||
@@ -399,8 +409,10 @@ export class NupstDaemon {
|
||||
// Display groups in a table
|
||||
if (this.config.groups && this.config.groups.length > 0) {
|
||||
logger.info(`Groups (${this.config.groups.length}):`);
|
||||
|
||||
const groupColumns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
|
||||
|
||||
const groupColumns: Array<
|
||||
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
|
||||
> = [
|
||||
{ header: 'Name', key: 'name', align: 'left', color: theme.highlight },
|
||||
{ header: 'ID', key: 'id', align: 'left', color: theme.dim },
|
||||
{ header: 'Mode', key: 'mode', align: 'left', color: theme.info },
|
||||
@@ -538,7 +550,7 @@ export class NupstDaemon {
|
||||
// Only check when on battery power
|
||||
if (status.powerStatus === 'onBattery' && ups.actions && ups.actions.length > 0) {
|
||||
let anyThresholdExceeded = false;
|
||||
|
||||
|
||||
for (const actionConfig of ups.actions) {
|
||||
if (actionConfig.thresholds) {
|
||||
if (
|
||||
@@ -575,7 +587,7 @@ export class NupstDaemon {
|
||||
*/
|
||||
private logAllUpsStatus(): void {
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
|
||||
logger.log('');
|
||||
logger.logBoxTitle('Periodic Status Update', 70, 'info');
|
||||
logger.logBoxLine(`Timestamp: ${timestamp}`);
|
||||
@@ -583,7 +595,9 @@ export class NupstDaemon {
|
||||
logger.log('');
|
||||
|
||||
// Build table data
|
||||
const columns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
|
||||
const columns: Array<
|
||||
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
|
||||
> = [
|
||||
{ header: 'UPS Name', key: 'name', align: 'left', color: theme.highlight },
|
||||
{ header: 'ID', key: 'id', align: 'left', color: theme.dim },
|
||||
{ header: 'Power Status', key: 'powerStatus', align: 'left' },
|
||||
@@ -595,7 +609,7 @@ export class NupstDaemon {
|
||||
for (const [id, status] of this.upsStatus.entries()) {
|
||||
const batteryColor = getBatteryColor(status.batteryCapacity);
|
||||
const runtimeColor = getRuntimeColor(status.batteryRuntime);
|
||||
|
||||
|
||||
rows.push({
|
||||
name: status.name,
|
||||
id: id,
|
||||
@@ -609,10 +623,6 @@ export class NupstDaemon {
|
||||
logger.log('');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Build action context from UPS state
|
||||
* @param ups UPS configuration
|
||||
@@ -796,7 +806,9 @@ export class NupstDaemon {
|
||||
|
||||
logger.log('');
|
||||
logger.logBoxTitle('Shutdown Monitoring Active', UI.WIDE_BOX_WIDTH, 'warning');
|
||||
logger.logBoxLine(`Emergency threshold: ${THRESHOLDS.EMERGENCY_RUNTIME_MINUTES} minutes runtime`);
|
||||
logger.logBoxLine(
|
||||
`Emergency threshold: ${THRESHOLDS.EMERGENCY_RUNTIME_MINUTES} minutes runtime`,
|
||||
);
|
||||
logger.logBoxLine(`Check interval: ${TIMING.SHUTDOWN_CHECK_INTERVAL_MS / 1000} seconds`);
|
||||
logger.logBoxLine(`Max monitoring time: ${TIMING.MAX_SHUTDOWN_MONITORING_MS / 1000} seconds`);
|
||||
logger.logBoxEnd();
|
||||
@@ -808,7 +820,9 @@ export class NupstDaemon {
|
||||
logger.info('Checking UPS status during shutdown...');
|
||||
|
||||
// Build table for UPS status during shutdown
|
||||
const columns: Array<{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }> = [
|
||||
const columns: Array<
|
||||
{ header: string; key: string; align?: 'left' | 'right'; color?: (val: string) => string }
|
||||
> = [
|
||||
{ header: 'UPS Name', key: 'name', align: 'left', color: theme.highlight },
|
||||
{ header: 'Battery', key: 'battery', align: 'right' },
|
||||
{ header: 'Runtime', key: 'runtime', align: 'right' },
|
||||
@@ -828,7 +842,7 @@ export class NupstDaemon {
|
||||
const runtimeColor = getRuntimeColor(status.batteryRuntime);
|
||||
|
||||
const isCritical = status.batteryRuntime < THRESHOLDS.EMERGENCY_RUNTIME_MINUTES;
|
||||
|
||||
|
||||
rows.push({
|
||||
name: ups.name,
|
||||
battery: batteryColor(status.batteryCapacity + '%'),
|
||||
@@ -848,7 +862,7 @@ export class NupstDaemon {
|
||||
runtime: theme.error('N/A'),
|
||||
status: theme.error('ERROR'),
|
||||
});
|
||||
|
||||
|
||||
logger.error(
|
||||
`Error checking UPS ${ups.name} during shutdown: ${
|
||||
upsError instanceof Error ? upsError.message : String(upsError)
|
||||
@@ -991,7 +1005,9 @@ export class NupstDaemon {
|
||||
let lastConfigCheck = Date.now();
|
||||
|
||||
logger.log('Entering idle monitoring mode...');
|
||||
logger.log(`Daemon will check for config changes every ${TIMING.IDLE_CHECK_INTERVAL_MS / 1000} seconds`);
|
||||
logger.log(
|
||||
`Daemon will check for config changes every ${TIMING.IDLE_CHECK_INTERVAL_MS / 1000} seconds`,
|
||||
);
|
||||
|
||||
// Start file watcher for hot-reload
|
||||
this.watchConfigFile();
|
||||
|
||||
Reference in New Issue
Block a user