refactor(cli, ups-handler, daemon, migrations): remove thresholds handling and update migration order logic
Some checks failed
CI / Type Check & Lint (push) Failing after 4s
CI / Build Test (Current Platform) (push) Successful in 5s
Release / build-and-release (push) Successful in 41s
CI / Build All Platforms (push) Successful in 46s

This commit is contained in:
2025-10-20 12:03:14 +00:00
parent 2c8ea44d40
commit afd026d08c
8 changed files with 33 additions and 53 deletions

View File

@@ -335,7 +335,7 @@ export class NupstCli {
id: theme.dim(ups.id), id: theme.dim(ups.id),
host: `${ups.snmp.host}:${ups.snmp.port}`, host: `${ups.snmp.host}:${ups.snmp.port}`,
model: ups.snmp.upsModel || 'cyberpower', model: ups.snmp.upsModel || 'cyberpower',
thresholds: `${ups.thresholds.battery}% / ${ups.thresholds.runtime}min`, actions: `${(ups.actions || []).length} configured`,
groups: ups.groups.length > 0 ? ups.groups.join(', ') : theme.dim('None'), groups: ups.groups.length > 0 ? ups.groups.join(', ') : theme.dim('None'),
})); }));
@@ -344,7 +344,7 @@ export class NupstCli {
{ header: 'ID', key: 'id', align: 'left' }, { header: 'ID', key: 'id', align: 'left' },
{ header: 'Host:Port', key: 'host', align: 'left', color: theme.info }, { header: 'Host:Port', key: 'host', align: 'left', color: theme.info },
{ header: 'Model', key: 'model', align: 'left' }, { header: 'Model', key: 'model', align: 'left' },
{ header: 'Battery/Runtime', key: 'thresholds', align: 'left' }, { header: 'Actions', key: 'actions', align: 'left' },
{ header: 'Groups', key: 'groups', align: 'left' }, { header: 'Groups', key: 'groups', align: 'left' },
]; ];
@@ -389,9 +389,9 @@ export class NupstCli {
} else { } else {
// === Legacy Single UPS Configuration === // === Legacy Single UPS Configuration ===
if (!config.snmp || !config.thresholds) { if (!config.snmp) {
logger.logBox('Configuration Error', [ logger.logBox('Configuration Error', [
'Error: Legacy configuration missing SNMP or threshold settings', 'Error: Legacy configuration missing SNMP settings',
], 60, 'error'); ], 60, 'error');
return; return;
} }
@@ -435,9 +435,7 @@ export class NupstCli {
: [] : []
), ),
'', '',
theme.dim('Thresholds:'),
` Battery: ${theme.highlight(String(config.thresholds.battery))}%`,
` Runtime: ${theme.highlight(String(config.thresholds.runtime))} minutes`,
` Check Interval: ${config.checkInterval / 1000} seconds`, ` Check Interval: ${config.checkInterval / 1000} seconds`,
'', '',
theme.dim('Configuration File:'), theme.dim('Configuration File:'),

View File

@@ -559,10 +559,6 @@ export class UpsHandler {
); );
logger.logBoxLine(` Battery Runtime: ${snmpConfig.customOIDs.BATTERY_RUNTIME || 'Not set'}`); logger.logBoxLine(` Battery Runtime: ${snmpConfig.customOIDs.BATTERY_RUNTIME || 'Not set'}`);
} }
logger.logBoxLine('Thresholds:');
logger.logBoxLine(` Battery: ${thresholds.battery}%`);
logger.logBoxLine(` Runtime: ${thresholds.runtime} minutes`);
// Show group assignments if this is a UPS config // Show group assignments if this is a UPS config
if (config.groups && Array.isArray(config.groups)) { if (config.groups && Array.isArray(config.groups)) {
logger.logBoxLine( logger.logBoxLine(
@@ -586,7 +582,6 @@ export class UpsHandler {
try { try {
// Create a test config with a short timeout // Create a test config with a short timeout
const snmpConfig = config.snmp ? config.snmp : config.snmp; const snmpConfig = config.snmp ? config.snmp : config.snmp;
const thresholds = config.thresholds ? config.thresholds : config.thresholds;
const testConfig = { const testConfig = {
...snmpConfig, ...snmpConfig,
@@ -603,10 +598,7 @@ export class UpsHandler {
logger.logBoxLine(` Runtime Remaining: ${status.batteryRuntime} minutes`); logger.logBoxLine(` Runtime Remaining: ${status.batteryRuntime} minutes`);
logger.logBoxEnd(); logger.logBoxEnd();
// Check status against thresholds if on battery
if (status.powerStatus === 'onBattery') {
this.analyzeThresholds(status, thresholds);
}
} catch (error) { } catch (error) {
const errorBoxWidth = 45; const errorBoxWidth = 45;
logger.logBoxTitle(`Connection Failed: ${upsName}`, errorBoxWidth); logger.logBoxTitle(`Connection Failed: ${upsName}`, errorBoxWidth);
@@ -1083,9 +1075,7 @@ export class UpsHandler {
logger.logBoxLine(`SNMP Host: ${ups.snmp.host}:${ups.snmp.port}`); logger.logBoxLine(`SNMP Host: ${ups.snmp.host}:${ups.snmp.port}`);
logger.logBoxLine(`SNMP Version: ${ups.snmp.version}`); logger.logBoxLine(`SNMP Version: ${ups.snmp.version}`);
logger.logBoxLine(`UPS Model: ${ups.snmp.upsModel}`); logger.logBoxLine(`UPS Model: ${ups.snmp.upsModel}`);
logger.logBoxLine(
`Thresholds: ${ups.thresholds.battery}% battery, ${ups.thresholds.runtime} min runtime`,
);
if (ups.groups && ups.groups.length > 0) { if (ups.groups && ups.groups.length > 0) {
logger.logBoxLine(`Groups: ${ups.groups.join(', ')}`); logger.logBoxLine(`Groups: ${ups.groups.join(', ')}`);
} else { } else {

View File

@@ -304,8 +304,6 @@ export class NupstDaemon {
batteryRuntime: 999, // High value as default batteryRuntime: 999, // High value as default
lastStatusChange: Date.now(), lastStatusChange: Date.now(),
lastCheckTime: 0, lastCheckTime: 0,
thresholdsExceeded: false,
lastThresholdCrossing: 0,
}); });
} }
@@ -553,23 +551,7 @@ export class NupstDaemon {
// Check threshold conditions
if (
status.batteryCapacity < ups.thresholds.battery ||
status.batteryRuntime < ups.thresholds.runtime
) {
logger.logBoxTitle(`UPS Shutdown Required: ${ups.name}`, 50);
logger.logBoxLine(
`Battery: ${status.batteryCapacity}% (threshold: ${ups.thresholds.battery}%)`,
);
logger.logBoxLine(
`Runtime: ${status.batteryRuntime} min (threshold: ${ups.thresholds.runtime} min)`,
);
logger.logBoxEnd();
await this.initiateShutdown(`UPS "${ups.name}" battery or runtime below threshold`);
}
}
/** /**
* Build action context from UPS state * Build action context from UPS state

View File

@@ -5,16 +5,14 @@
* Migrations run in order based on the `order` field, allowing users to jump * Migrations run in order based on the `order` field, allowing users to jump
* multiple versions (e.g., v1 → v4 runs migrations 2, 3, and 4). * multiple versions (e.g., v1 → v4 runs migrations 2, 3, and 4).
*/ */
export abstract class BaseMigration { /**
/** * Abstract base class for configuration migrations
* Migration order number *
* - Order 2: v1 → v2 * Each migration represents an upgrade from one config version to another.
* - Order 3: v2 → v3 * Migrations run in order based on the `toVersion` field, allowing users to jump
* - Order 4: v3 → v4 * multiple versions (e.g., v1 → v4 runs migrations 2, 3, and 4).
* etc.
*/ */
abstract readonly order: number; export abstract class BaseMigration {
/** /**
* Source version this migration upgrades from * Source version this migration upgrades from
* e.g., "1.x", "3.x" * e.g., "1.x", "3.x"
@@ -23,7 +21,7 @@ export abstract class BaseMigration {
/** /**
* Target version this migration upgrades to * Target version this migration upgrades to
* e.g., "2.0", "4.0" * e.g., "2.0", "4.0", "4.1"
*/ */
abstract readonly toVersion: string; abstract readonly toVersion: string;
@@ -51,4 +49,19 @@ export abstract class BaseMigration {
getName(): string { getName(): string {
return `Migration ${this.fromVersion}${this.toVersion}`; return `Migration ${this.fromVersion}${this.toVersion}`;
} }
/**
* Parse version string into a comparable number
* Supports formats like "2.0", "4.1", etc.
* Returns a number like 2.0, 4.1 for sorting
*
* @returns Parsed version number for ordering
*/
getVersionOrder(): number {
const parsed = parseFloat(this.toVersion);
if (isNaN(parsed)) {
throw new Error(`Invalid version format: ${this.toVersion}`);
}
return parsed;
}
} }

View File

@@ -22,8 +22,8 @@ export class MigrationRunner {
// Add future migrations here (v4.2, v4.3, etc.) // Add future migrations here (v4.2, v4.3, etc.)
]; ];
// Sort by order to ensure they run in sequence // Sort by version order to ensure they run in sequence
this.migrations.sort((a, b) => a.order - b.order); this.migrations.sort((a, b) => a.getVersionOrder() - b.getVersionOrder());
} }
/** /**

View File

@@ -20,7 +20,6 @@ import { logger } from '../logger.ts';
* } * }
*/ */
export class MigrationV1ToV2 extends BaseMigration { export class MigrationV1ToV2 extends BaseMigration {
readonly order = 2;
readonly fromVersion = '1.x'; readonly fromVersion = '1.x';
readonly toVersion = '2.0'; readonly toVersion = '2.0';

View File

@@ -39,7 +39,6 @@ import { logger } from '../logger.ts';
* } * }
*/ */
export class MigrationV3ToV4 extends BaseMigration { export class MigrationV3ToV4 extends BaseMigration {
readonly order = 4;
readonly fromVersion = '3.x'; readonly fromVersion = '3.x';
readonly toVersion = '4.0'; readonly toVersion = '4.0';

View File

@@ -46,7 +46,6 @@ import { logger } from '../logger.ts';
* } * }
*/ */
export class MigrationV4_0ToV4_1 extends BaseMigration { export class MigrationV4_0ToV4_1 extends BaseMigration {
readonly order = 5;
readonly fromVersion = '4.0'; readonly fromVersion = '4.0';
readonly toVersion = '4.1'; readonly toVersion = '4.1';