networkupstools / nut

The Network UPS Tools repository. UPS management protocol Informational RFC 9271 published by IETF at https://www.rfc-editor.org/info/rfc9271 Please star NUT on GitHub, this helps with sponsorships!
https://networkupstools.org/
Other
1.89k stars 342 forks source link

snmp-ups and cgi support for 2 phase ups #367

Open howardtopher opened 7 years ago

howardtopher commented 7 years ago

I have a number of Liebert UPS systems with a web card in them being monitored through the snmp-ups driver. These UPS systems have 2 input/output lines, but NUT only seems to support 1 or 3. Since this UPS has 2, the info shown by the nut client or in the cgi pages does not include any information at all for any lines. I'm not sure if it's NUT as a whole that's not supporting the 2 phases or just the snmp-ups and cgi pieces.

In the process_phase_data function of the snmp-ups driver I've been able to modify the code so that it works for 2 phases, but it's a hack. Basically, if the number of phases is equal to 2, change it to 3. This makes NUT treat the UPS as 3 phase and therefore show the line info.

if(nb_phases == 2) { nb_phases = 3; }

clepple commented 7 years ago

From the description of your fix, it sounds like the problem is in the driver. What does the output of upsc show?

Do you have a copy of the manufacturer's MIB files? Even if not, the output of snmpwalk, as described in the manual, will help.

jimklimov commented 7 years ago

I don't think I've even heard of two-phase electrical systems and can't google any up quickly - Libert too pops up with only 1- and 3-phase devices. What country is this? :)

Otherwise, if these are really separate single-phase lines (e.g. redundant inputs from different utilities and several manageable outputs), at least the outputs "should be" logically equivalent to outlet groups (maybe with one outlet in each group). I'm now not on a PC, so don't remember OTOH if there is a concept of "inlet" groups as well; at least there should be something like that to e.g. support ATS/STS which are devices dedicated to dual inputs (but I'm not sure if upstream/master contains finished code for those).

From such blocks, perhaps a more reasonable model of the UPS data and electric flows can be constructed, rather than assuming those independent(?) lines to be parts of a multi-phase cable.

howardtopher commented 7 years ago

I do have the manufacturer MIB files, but I'm using the RFC-1628 MIB to monitor the UPS systems in NUT. I have confirmed that the RFC-1628 MIB and the manufacturer MIB report the same values.

This is in the US. Maybe this is really a 1 or 3 phase UPS (I really don't know), but it does report 2 input/output/bypass lines. Building the code straight from github results in no line info (voltage, load, watts, etc) from upsc, not even for a single line. Also, the CGI interface shows "not supported" for everything relating to the lines. I'll have to remove my modifications and rebuild to get you a real output of that. Once I added in the little if block and re-compiled it, upsc shows the line info just fine and the CGI interface shows the info for two lines and "not supported" for the 3rd (since I made it think it was a 3 phase UPS).

I've put an SNMP walk of one of them below.

UPS-MIB::upsIdentManufacturer.0 = STRING: Liebert Corporation
UPS-MIB::upsIdentModel.0 = STRING: GXT3-8000RT208
UPS-MIB::upsIdentUPSSoftwareVersion.0 = STRING: U150D250
UPS-MIB::upsIdentAgentSoftwareVersion.0 = STRING: 5.300.2
UPS-MIB::upsIdentName.0 = STRING: Rivendell-D-UPS-1
UPS-MIB::upsBatteryStatus.0 = INTEGER: batteryNormal(2)
UPS-MIB::upsSecondsOnBattery.0 = INTEGER: 0 seconds
UPS-MIB::upsEstimatedMinutesRemaining.0 = INTEGER: 102 minutes
UPS-MIB::upsEstimatedChargeRemaining.0 = INTEGER: 100 percent
UPS-MIB::upsBatteryVoltage.0 = INTEGER: 3260 0.1 Volt DC
UPS-MIB::upsInputLineBads.0 = Counter32: 2
UPS-MIB::upsInputNumLines.0 = INTEGER: 2
UPS-MIB::upsInputFrequency.1 = INTEGER: 599 0.1 Hertz
UPS-MIB::upsInputFrequency.2 = INTEGER: 599 0.1 Hertz
UPS-MIB::upsInputVoltage.1 = INTEGER: 118 RMS Volts
UPS-MIB::upsInputVoltage.2 = INTEGER: 120 RMS Volts
UPS-MIB::upsInputCurrent.1 = INTEGER: 45 0.1 RMS Amp
UPS-MIB::upsInputCurrent.2 = INTEGER: 43 0.1 RMS Amp
UPS-MIB::upsOutputSource.0 = INTEGER: normal(3)
UPS-MIB::upsOutputFrequency.0 = INTEGER: 599 0.1 Hertz
UPS-MIB::upsOutputNumLines.0 = INTEGER: 2
UPS-MIB::upsOutputVoltage.1 = INTEGER: 120 RMS Volts
UPS-MIB::upsOutputVoltage.2 = INTEGER: 120 RMS Volts
UPS-MIB::upsOutputCurrent.1 = INTEGER: 33 0.1 RMS Amp
UPS-MIB::upsOutputCurrent.2 = INTEGER: 27 0.1 RMS Amp
UPS-MIB::upsOutputPower.1 = INTEGER: 367 Watts
UPS-MIB::upsOutputPower.2 = INTEGER: 304 Watts
UPS-MIB::upsOutputPercentLoad.1 = INTEGER: 10 percent
UPS-MIB::upsOutputPercentLoad.2 = INTEGER: 8 percent
UPS-MIB::upsBypassFrequency.0 = INTEGER: 599 0.1 Hertz
UPS-MIB::upsBypassNumLines.0 = INTEGER: 2
UPS-MIB::upsBypassVoltage.1 = INTEGER: 118 RMS Volts
UPS-MIB::upsBypassVoltage.2 = INTEGER: 120 RMS Volts
UPS-MIB::upsBypassCurrent.1 = INTEGER: 0 0.1 RMS Amp
UPS-MIB::upsBypassCurrent.2 = INTEGER: 0 0.1 RMS Amp
UPS-MIB::upsAlarmsPresent.0 = Gauge32: 0
UPS-MIB::upsTestId.0 = OID: UPS-MIB::upsTestNoTestsInitiated
UPS-MIB::upsTestSpinLock.0 = INTEGER: 1
UPS-MIB::upsTestResultsSummary.0 = INTEGER: noTestsInitiated(6)
UPS-MIB::upsTestResultsDetail.0 = STRING: 
UPS-MIB::upsTestStartTime.0 = Timeticks: (0) 0:00:00.00
UPS-MIB::upsTestElapsedTime.0 = INTEGER: 0
UPS-MIB::upsShutdownType.0 = INTEGER: output(1)
UPS-MIB::upsShutdownAfterDelay.0 = INTEGER: -1 seconds
UPS-MIB::upsStartupAfterDelay.0 = INTEGER: -1 seconds
UPS-MIB::upsRebootWithDuration.0 = INTEGER: -1 seconds
UPS-MIB::upsAutoRestart.0 = INTEGER: on(1)
UPS-MIB::upsConfigInputVoltage.0 = INTEGER: 120 RMS Volts
UPS-MIB::upsConfigInputFreq.0 = INTEGER: 600 0.1 Hertz
UPS-MIB::upsConfigOutputVoltage.0 = INTEGER: 120 RMS Volts
UPS-MIB::upsConfigOutputFreq.0 = INTEGER: 600 0.1 Hertz
UPS-MIB::upsConfigOutputVA.0 = INTEGER: 8000 Volt-Amps
UPS-MIB::upsConfigLowBattTime.0 = INTEGER: 2 minutes
UPS-MIB::upsConfigAudibleStatus.0 = INTEGER: disabled(1)
jimklimov commented 7 years ago

Just in case and for context, note that the NUT SNMP monitoring is a bit complicated. While NUT does use net-snmp libraries for the protocol part, it does not use the MIB files. Instead, there are mappings from certain MIB OIDs to NUT values. In the upstream/master version, these mappings are static (arrays of a special structure in C files) and any changes must be compiled into a new binary build of NUT. There are about 20 vendor-specific mappings, and the IETF (RFC) one for fallback.

There is also a DMF (Dynamic Mapping Format) branch that allows same mappings (and more) to be loaded at run-time instead of hardcoding during build, but so far this has not become part of upstream.

howardtopher commented 7 years ago

When I was trying to figure out what was going on I started making a vendor specific mapping for Liebert, since there isn't one for the snmp driver. However, I stopped doing that because the IETF MIB reads everything it needs so there was really no need for a vendor specific one. The Liebert manufacturer MIB reads 2 input/output/bypass lines also. So does the web interface on the web card.

jimklimov commented 7 years ago

Well... 2 separate lines and 2 phases in one cable are (electrically) different concepts.

And now I found the product ID in your post, it is indeed reported to be a 2-phase device (4-wire plugs) : https://www.cnet.com/products/liebert-gxt3-8000rt208-ups-7-2-kw-8000-va-series/specs/

@aquette @clepple : Does NUT support either of these concepts?