Skip to content

drivers/snmp-ups: add "voltronic" subdriver for enterprise 43943 UPSes - #3570

Open
chrisallen wants to merge 2 commits into
networkupstools:masterfrom
chrisallen:voltronic-snmp-ups
Open

drivers/snmp-ups: add "voltronic" subdriver for enterprise 43943 UPSes#3570
chrisallen wants to merge 2 commits into
networkupstools:masterfrom
chrisallen:voltronic-snmp-ups

Conversation

@chrisallen

Copy link
Copy Markdown

Closes #3478.

Summary

This adds a voltronic subdriver to snmp-ups for UPS cards using Voltronic's
enterprise 43943 MIBs. I developed it against a PowerShield Centurion RT
1000VA (PSCERT1000) with a PSSNMPV4 card running firmware 1.1.8.C.

Although the UPS I tested is sold by PowerShield, the same protocol is used by
several OEM brands mentioned in #3478. I have therefore kept the subdriver
generic instead of building PowerShield branding into it. Friendly identity
overrides can still be set in ups.conf where needed.

How I worked through the driver

I started with the three MIBs supplied with #3478:

  • RFC1628.mib.txt
  • UPS_20250508.MIB.txt
  • UPSmib.mib.txt

I also unpacked PSSNMPv4MIBfiles.zip and statically inspected the card
firmware in upgrade1_1_8_C_20220310.tar.gz.zip. The firmware was useful for
checking the enterprise identity, defaults, table indexing, scaling and
special values used when a reading or environmental sensor is unavailable.

The mapping was then compared with NUT's SNMP driver documentation,
docs/nut-names.txt, and existing subdrivers such as ietf-mib.c and
xppc-mib.c. This was written from those findings rather than generated from
the MIB files.

Some details could not safely be decided from the MIB declarations alone. The
main example was the table index: direct GET requests showed that the private
input, output and bypass tables use .0, while the corresponding RFC1628
tables use .1. I tested both instances for the ambiguous objects and used
the live results in the mapping.

The private MIB usually gives the more precise value, so it is preferred where
verified. RFC1628 remains as a fallback where useful, with SU_FLAG_UNIQUE
preventing a lower-precision fallback from replacing a valid private value.

What is mapped

The subdriver covers identity, firmware, topology, NUT status, alarms, battery
data, input, output, bypass, nominal ratings, load and measured real power. It
publishes the canonical ups.power* and ups.realpower* names along with the
useful output.* compatibility aliases.

The card reports real power with useful precision, but returns zero for
apparent power and power factor even while the UPS is carrying load. Those
values are treated as unsupported and left out. The driver does not invent
apparent power from rounded load or present the nominal W/VA ratio as a live
power factor. Generic RFC1628 transfer limits that return placeholder zeroes
are also omitted, while the valid non-zero bypass and ECO limits are kept.

I have left the optional PSEMD environmental branch out for now. The firmware
and read-only probes showed how a disconnected sensor is represented, but I
did not have a connected EMD to verify its scaling, presence changes, or the
smoke/contact channels. I thought leaving it unmapped was safer than guessing.

Delayed shutdown, startup and beeper controls follow the vendor MIB and NUT's
delayed-shutdown model. I did not run any of these commands against the live
UPS, so they should not yet be considered hardware-tested.

Testing

All testing against the UPS was read-only. I did not send an SNMP SET, invoke
a NUT instant command, start a battery test, or change the output state.

I used direct SNMPv2c GETs to check OIDs, .0/.1 table instances,
enumerations, scaling, valid zero readings and unsupported-value sentinels. I
also ran a complete foreground polling cycle on Unraid 7.3.2. The driver was
detected as voltronic 0.10 and returned plausible online status, battery,
voltage, frequency, current, load and real-power readings. Unsupported
apparent power, power factor, generic transfer limits, empty alarms and EMD
values were absent as intended.

For build and integration checks I:

  • built snmp-ups from the current NUT default branch on x86_64 with
    -Wall -Wextra -Werror;
  • ran make -C drivers check and git diff --check;
  • applied the same patch to NUT 2.8.5 for the target Unraid build;
  • built against the exact Net-SNMP headers and library selected by the
    NUT-unRAID plugin; and
  • checked the resulting ELF dependencies and immediate dynamic relocation
    against the target Unraid loader and libraries before live polling.

Development assistance

I used OpenAI Codex to help compare the MIBs and firmware with existing NUT
code, prepare the implementation and documentation, and organize the tests. I
reviewed the changes and validated them against the supplied files and live
hardware, and I take responsibility for the contribution.

Contributor checklist

General points

  • Hardware, protocol, limitations and testing are described above and in
    Add SNMP sub-driver for Voltronics/Powershield UPS (PEN 43943) #3478.
  • This is one focused driver-support commit with no unrelated cleanup.
  • The commit includes the required DCO Signed-off-by trailer.
  • Coding assistance is disclosed above.
  • Code and documentation were reviewed against docs/developers.txt, the
    surrounding source style and NUT's ASCII requirements.
  • Starred NUT on GitHub (optional).

Driver addition

  • Added a subdriver to the current snmp-ups driver family.
  • Did not extend an obsolete driver.
  • Added the voltronic 0.10 subdriver version.
  • USB VID/PID and upower HID checks are not applicable to this SNMP
    subdriver.
  • Mappings follow docs/nut-names.txt; vendor-specific mode information
    uses the experimental namespace where needed.
  • Added the tested model to data/driver.list.in.

Code, build and documentation

  • Followed the existing NUT helper, logging, integer and formatting
    conventions.
  • Updated drivers/Makefile.am for the new source and header.
  • Updated the existing docs/man/snmp-ups.txt manual page; no new manual
    page recipe is needed.
  • make distcheck has not been run locally.
  • make spellcheck has not been run locally.
  • NEWS.adoc was not changed because this adds a subdriver without a new
    package, dependency or upgrade requirement.
  • docs/acknowledgements.txt was not changed because this was not a
    vendor-backed contribution.

Follow-up after posting

  • Submit suitable real-device data to the NUT DDL.
  • Review and address results from the NUT CI farm and any additional
    static analysis.

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

A ZIP file with standard source tarball and another tarball with pre-built docs for commit 487f190 is temporarily available: NUT-tarballs-PR-3570.zip.

Add support for Voltronic enterprise 43943 SNMP cards, tested with a
PowerShield Centurion RT 1000VA and PSSNMPV4 card.

The private MIB gives better resolution for most readings, so use it first
and keep RFC1628 as a fallback. Direct GETs showed that the private line
tables use index 0 while the RFC1628 tables use index 1, despite the MIB
declarations not making that difference clear.

Map identity, topology, status, battery data, input, output, bypass, ratings,
load and measured real power. Publish the canonical aggregate power names
alongside the useful output aliases.

The card returns zero for apparent power, power factor and the generic
transfer limits even when the UPS is carrying load. Leave those values out
instead of presenting them as measurements or trying to calculate them from
load. Leave the optional PSEMD branch out as well because no connected sensor
was available to verify it.

Delayed shutdown, startup and beeper controls follow the vendor MIB and
firmware definitions. They have not been tested on live hardware, and no
control command was sent during development.

Add the subdriver to the build, document its limits, and add the tested
PowerShield model to the compatibility list.

Signed-off-by: Chris Allen <203867+chrisallen@users.noreply.github.com>
@AppVeyorBot

Copy link
Copy Markdown

@AppVeyorBot

Copy link
Copy Markdown

@chrisallen

Copy link
Copy Markdown
Author

I'll fix up the issues reported by the build farm tomorrow.

@AppVeyorBot

Copy link
Copy Markdown

Build nut 2.8.5.5056-master completed (commit ace2c3e6d0 by @chrisallen)

@AppVeyorBot

Copy link
Copy Markdown

…mp `snmp-ups` version [networkupstools#3570]

Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
@jimklimov jimklimov added SNMP Voltronic AI For good or bad, machine tools are upon us. Humans are still the responsible ones. labels Aug 13, 2026
@jimklimov jimklimov added this to the 2.8.6 milestone Aug 13, 2026
@AppVeyorBot

Copy link
Copy Markdown

Build nut 2.8.5.5059-master completed (commit d081651e56 by @jimklimov)

@chrisallen

Copy link
Copy Markdown
Author

Thank you @jimklimov for adding the remaining parts to this PR. Here is the evidence output from this driver running on my Unraid system.

https://gist.github.com/chrisallen/ed6cf59a1ae2ec86dfb9bacac0b47206

Note: This new Voltronic subdriver detected the native device as XIIHVT1K0. Standard NUT identity overrides were used to show the identity as PowerShield Centurion RT 1000VA.

No PowerShield branding or model-specific ratings are compiled into the subdriver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI For good or bad, machine tools are upon us. Humans are still the responsible ones. SNMP Voltronic

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add SNMP sub-driver for Voltronics/Powershield UPS (PEN 43943)

3 participants