feat(snmp): Enhance SNMP metrics with output load, power, voltage, and current readings

This commit is contained in:
2025-10-23 12:25:59 +00:00
parent 9ba50da73c
commit fbe1cd64cb
5 changed files with 166 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
import * as snmp from 'npm:net-snmp@3.20.0';
import * as snmp from 'npm:net-snmp@3.26.0';
import { Buffer } from 'node:buffer';
import type { IOidSet, ISnmpConfig, IUpsStatus, TUpsModel } from './types.ts';
import { UpsOidSets } from './oid-sets.ts';
@@ -304,6 +304,10 @@ export class NupstSnmp {
console.log(' Power Status:', this.activeOIDs.POWER_STATUS);
console.log(' Battery Capacity:', this.activeOIDs.BATTERY_CAPACITY);
console.log(' Battery Runtime:', this.activeOIDs.BATTERY_RUNTIME);
console.log(' Output Load:', this.activeOIDs.OUTPUT_LOAD);
console.log(' Output Power:', this.activeOIDs.OUTPUT_POWER);
console.log(' Output Voltage:', this.activeOIDs.OUTPUT_VOLTAGE);
console.log(' Output Current:', this.activeOIDs.OUTPUT_CURRENT);
console.log('---------------------------------------');
}
@@ -324,20 +328,65 @@ export class NupstSnmp {
config,
) || 0;
// Get power draw metrics
const outputLoad = await this.getSNMPValueWithRetry(
this.activeOIDs.OUTPUT_LOAD,
'output load',
config,
) || 0;
const outputPower = await this.getSNMPValueWithRetry(
this.activeOIDs.OUTPUT_POWER,
'output power',
config,
) || 0;
const outputVoltage = await this.getSNMPValueWithRetry(
this.activeOIDs.OUTPUT_VOLTAGE,
'output voltage',
config,
) || 0;
const outputCurrent = await this.getSNMPValueWithRetry(
this.activeOIDs.OUTPUT_CURRENT,
'output current',
config,
) || 0;
// Determine power status - handle different values for different UPS models
const powerStatus = this.determinePowerStatus(config.upsModel, powerStatusValue);
// Convert to minutes for UPS models with different time units
const processedRuntime = this.processRuntimeValue(config.upsModel, batteryRuntime);
// Process power metrics with vendor-specific scaling
const processedVoltage = this.processVoltageValue(config.upsModel, outputVoltage);
const processedCurrent = this.processCurrentValue(config.upsModel, outputCurrent);
// Calculate power from voltage × current if not provided by UPS
let processedPower = outputPower;
if (outputPower === 0 && processedVoltage > 0 && processedCurrent > 0) {
processedPower = Math.round(processedVoltage * processedCurrent);
if (this.debug) {
console.log(
`Calculated power from V×I: ${processedVoltage}V × ${processedCurrent}A = ${processedPower}W`,
);
}
}
const result = {
powerStatus,
batteryCapacity,
batteryRuntime: processedRuntime,
outputLoad,
outputPower: processedPower,
outputVoltage: processedVoltage,
outputCurrent: processedCurrent,
raw: {
powerStatus: powerStatusValue,
batteryCapacity,
batteryRuntime,
outputLoad,
outputPower,
outputVoltage,
outputCurrent,
},
};
@@ -347,6 +396,10 @@ export class NupstSnmp {
console.log(' Power Status:', result.powerStatus);
console.log(' Battery Capacity:', result.batteryCapacity + '%');
console.log(' Battery Runtime:', result.batteryRuntime, 'minutes');
console.log(' Output Load:', result.outputLoad + '%');
console.log(' Output Power:', result.outputPower, 'watts');
console.log(' Output Voltage:', result.outputVoltage, 'volts');
console.log(' Output Current:', result.outputCurrent, 'amps');
console.log('---------------------------------------');
}
@@ -602,4 +655,69 @@ export class NupstSnmp {
return batteryRuntime;
}
/**
* Process voltage value based on UPS model
* @param upsModel UPS model
* @param outputVoltage Raw output voltage value
* @returns Processed voltage in volts
*/
private processVoltageValue(
upsModel: TUpsModel | undefined,
outputVoltage: number,
): number {
if (this.debug) {
console.log('Raw voltage value:', outputVoltage);
}
if (upsModel === 'cyberpower' && outputVoltage > 0) {
// CyberPower: Voltage is in 0.1V, convert to volts
const volts = outputVoltage / 10;
if (this.debug) {
console.log(
`Converting CyberPower voltage from ${outputVoltage} (0.1V) to ${volts} volts`,
);
}
return volts;
}
return outputVoltage;
}
/**
* Process current value based on UPS model
* @param upsModel UPS model
* @param outputCurrent Raw output current value
* @returns Processed current in amps
*/
private processCurrentValue(
upsModel: TUpsModel | undefined,
outputCurrent: number,
): number {
if (this.debug) {
console.log('Raw current value:', outputCurrent);
}
if (upsModel === 'cyberpower' && outputCurrent > 0) {
// CyberPower: Current is in 0.1A, convert to amps
const amps = outputCurrent / 10;
if (this.debug) {
console.log(
`Converting CyberPower current from ${outputCurrent} (0.1A) to ${amps} amps`,
);
}
return amps;
} else if ((upsModel === 'eaton' || upsModel === 'tripplite' || upsModel === 'liebert') && outputCurrent > 0) {
// RFC 1628 standard: Current is in 0.1A, convert to amps
const amps = outputCurrent / 10;
if (this.debug) {
console.log(
`Converting RFC 1628 current from ${outputCurrent} (0.1A) to ${amps} amps`,
);
}
return amps;
}
return outputCurrent;
}
}