From bb87316dd36337c10f53139c7703807eea468185 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Sun, 19 Oct 2025 23:48:13 +0000 Subject: [PATCH] fix(snmp): correct power status interpretation using OID set mappings Move power status value interpretation from hardcoded logic to OID set configuration. Each UPS model now defines its own value mappings (e.g., CyberPower: 2=online, 3=onBattery). Fixes incorrect status display where UPS showed "On Battery" when actually online. Changes: - Add POWER_STATUS_VALUES to IOidSet interface - Define value mappings for all UPS models (cyberpower, apc, eaton, tripplite, liebert) - Refactor determinePowerStatus() to use OID set mappings instead of hardcoded values - CyberPower now correctly interprets value 2 as online (was incorrectly onBattery) --- deno.json | 2 +- ts/snmp/manager.ts | 50 ++++++++++++++++++--------------------------- ts/snmp/oid-sets.ts | 30 ++++++++++++++++++++++----- ts/snmp/types.ts | 7 +++++++ 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/deno.json b/deno.json index 356ff74..0b7acb5 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@serve.zone/nupst", - "version": "4.1.0", + "version": "4.1.1", "exports": "./mod.ts", "tasks": { "dev": "deno run --allow-all mod.ts", diff --git a/ts/snmp/manager.ts b/ts/snmp/manager.ts index c674e54..5a5d063 100644 --- a/ts/snmp/manager.ts +++ b/ts/snmp/manager.ts @@ -525,6 +525,7 @@ export class NupstSnmp { /** * Determine power status based on UPS model and raw value + * Uses the value mappings defined in the OID sets * @param upsModel UPS model * @param powerStatusValue Raw power status value * @returns Standardized power status @@ -533,39 +534,28 @@ export class NupstSnmp { upsModel: TUpsModel | undefined, powerStatusValue: number, ): 'online' | 'onBattery' | 'unknown' { - if (upsModel === 'cyberpower') { - // CyberPower RMCARD205: upsBaseOutputStatus values - // 2=onLine, 3=onBattery, 4=onBoost, 5=onSleep, 6=off, etc. - if (powerStatusValue === 2) { - return 'online'; - } else if (powerStatusValue === 3) { - return 'onBattery'; - } - } else if (upsModel === 'eaton') { - // Eaton UPS: xupsOutputSource values - // 3=normal/mains, 5=battery, etc. - if (powerStatusValue === 3) { - return 'online'; - } else if (powerStatusValue === 5) { - return 'onBattery'; - } - } else if (upsModel === 'apc') { - // APC UPS: upsBasicOutputStatus values - // 2=online, 3=onBattery, etc. - if (powerStatusValue === 2) { - return 'online'; - } else if (powerStatusValue === 3) { - return 'onBattery'; - } - } else { - // Default interpretation for other UPS models - if (powerStatusValue === 1) { - return 'online'; - } else if (powerStatusValue === 2) { - return 'onBattery'; + // Get the OID set for this UPS model + if (upsModel && upsModel !== 'custom') { + const oidSet = UpsOidSets.getOidSet(upsModel); + + // Use the value mappings if available + if (oidSet.POWER_STATUS_VALUES) { + if (powerStatusValue === oidSet.POWER_STATUS_VALUES.online) { + return 'online'; + } else if (powerStatusValue === oidSet.POWER_STATUS_VALUES.onBattery) { + return 'onBattery'; + } } } + // Fallback for custom or undefined models (RFC 1628 standard) + // upsOutputSource: 3=normal (mains), 5=battery + if (powerStatusValue === 3) { + return 'online'; + } else if (powerStatusValue === 5) { + return 'onBattery'; + } + return 'unknown'; } diff --git a/ts/snmp/oid-sets.ts b/ts/snmp/oid-sets.ts index 54222ae..65e8848 100644 --- a/ts/snmp/oid-sets.ts +++ b/ts/snmp/oid-sets.ts @@ -11,37 +11,57 @@ export class UpsOidSets { private static readonly UPS_OID_SETS: Record = { // Cyberpower OIDs for RMCARD205 (based on CyberPower_MIB_v2.11) cyberpower: { - POWER_STATUS: '1.3.6.1.4.1.3808.1.1.1.4.1.1.0', // upsBaseOutputStatus (2=online, 3=on battery) + POWER_STATUS: '1.3.6.1.4.1.3808.1.1.1.4.1.1.0', // upsBaseOutputStatus BATTERY_CAPACITY: '1.3.6.1.4.1.3808.1.1.1.2.2.1.0', // upsAdvanceBatteryCapacity (percentage) BATTERY_RUNTIME: '1.3.6.1.4.1.3808.1.1.1.2.2.4.0', // upsAdvanceBatteryRunTimeRemaining (TimeTicks) + POWER_STATUS_VALUES: { + online: 2, // upsBaseOutputStatus: 2=onLine + onBattery: 3, // upsBaseOutputStatus: 3=onBattery + }, }, // APC OIDs apc: { - POWER_STATUS: '1.3.6.1.4.1.318.1.1.1.4.1.1.0', // Power status (1=online, 2=on battery) + POWER_STATUS: '1.3.6.1.4.1.318.1.1.1.4.1.1.0', // upsBasicOutputStatus BATTERY_CAPACITY: '1.3.6.1.4.1.318.1.1.1.2.2.1.0', // Battery capacity in percentage BATTERY_RUNTIME: '1.3.6.1.4.1.318.1.1.1.2.2.3.0', // Remaining runtime in minutes + POWER_STATUS_VALUES: { + online: 2, // upsBasicOutputStatus: 2=onLine + onBattery: 3, // upsBasicOutputStatus: 3=onBattery + }, }, // Eaton OIDs eaton: { - POWER_STATUS: '1.3.6.1.4.1.534.1.4.4.0', // xupsOutputSource (3=normal/mains, 5=battery) + POWER_STATUS: '1.3.6.1.4.1.534.1.4.4.0', // xupsOutputSource BATTERY_CAPACITY: '1.3.6.1.4.1.534.1.2.4.0', // xupsBatCapacity (percentage) BATTERY_RUNTIME: '1.3.6.1.4.1.534.1.2.1.0', // xupsBatTimeRemaining (seconds) + POWER_STATUS_VALUES: { + online: 3, // xupsOutputSource: 3=normal (mains power) + onBattery: 5, // xupsOutputSource: 5=battery + }, }, // TrippLite OIDs tripplite: { - POWER_STATUS: '1.3.6.1.4.1.850.1.1.3.1.1.1.0', // Power status + POWER_STATUS: '1.3.6.1.4.1.850.1.1.3.1.1.1.0', // tlUpsOutputSource BATTERY_CAPACITY: '1.3.6.1.4.1.850.1.1.3.2.4.1.0', // Battery capacity in percentage BATTERY_RUNTIME: '1.3.6.1.4.1.850.1.1.3.2.2.1.0', // Remaining runtime in minutes + POWER_STATUS_VALUES: { + online: 2, // tlUpsOutputSource: 2=normal (mains power) + onBattery: 3, // tlUpsOutputSource: 3=onBattery + }, }, // Liebert/Vertiv OIDs liebert: { - POWER_STATUS: '1.3.6.1.4.1.476.1.42.3.9.20.1.20.1.2.1.2.1', // Power status + POWER_STATUS: '1.3.6.1.4.1.476.1.42.3.9.20.1.20.1.2.1.2.1', // lgpPwrOutputSource BATTERY_CAPACITY: '1.3.6.1.4.1.476.1.42.3.9.20.1.20.1.2.1.4.1', // Battery capacity in percentage BATTERY_RUNTIME: '1.3.6.1.4.1.476.1.42.3.9.20.1.20.1.2.1.5.1', // Remaining runtime in minutes + POWER_STATUS_VALUES: { + online: 2, // lgpPwrOutputSource: 2=normal (mains power) + onBattery: 3, // lgpPwrOutputSource: 3=onBattery + }, }, // Custom OIDs (to be provided by the user) diff --git a/ts/snmp/types.ts b/ts/snmp/types.ts index afcf970..3c3fe38 100644 --- a/ts/snmp/types.ts +++ b/ts/snmp/types.ts @@ -28,6 +28,13 @@ export interface IOidSet { BATTERY_CAPACITY: string; /** OID for battery runtime */ BATTERY_RUNTIME: string; + /** Power status value mappings */ + POWER_STATUS_VALUES?: { + /** SNMP value that indicates UPS is online (on AC power) */ + online: number; + /** SNMP value that indicates UPS is on battery */ + onBattery: number; + }; } /**