CyberPower UPS & PDU (SNMP)
The CyberPower driver manages CyberPower devices over their SNMP management card, using the CyberPower enterprise MIB (CPS-MIB, 1.3.6.1.4.1.3808). It auto-detects the device family on the first poll and behaves accordingly:
- UPS (RMCARD205/305-class, MIB branch
.1.1.1) — polls battery charge and runtime, line/output voltage and frequency, load, and power state into device and zone attributes, and exposes control verbs for self test, runtime calibration, and turning the UPS output off / rebooting / sleeping. - Switched PDU (ePDU, MIB branch
.1.1.3) — polls per-outlet on/off state and metering, auto-creates one zone per outlet in the Power subsystem, and exposespower_on/power_off/rebootper outlet.
All traffic stays on the customer LAN.
Verified hardware
Built and verified against live hardware:
- RMCARD205 (firmware 1.6.0) in a PR1500RTXL2UC (Smart App Sinewave PR series) — full status read-path verified end-to-end, and switchable-bank control exercised (this unit reports one always-on critical bank plus one switchable bank).
- PDU81001 (firmware 1.3.3), 8 switched outlets — outlet naming, on/off/reboot control, and the
privatewrite community verified live (an outlet was cycled on→off→on over SNMP). Per-outlet metering (current, power, peak, energy) is read from the ePDU's status table.
Status values are read from the CyberPower MIB and mapped to attributes; control verbs issue SNMP SETs. Outlet/bank switching is offered on both families: a switched ePDU exposes one controllable outlet per port, and a UPS exposes one controllable bank per switchable outlet group. A UPS's always-on critical bank — the one that protects essential loads, e.g. bank 1 on the PR series — reports its state but cannot be switched, so no control zone is created for it.
The driver does not read the optional CyberPower environment sensor, so battery/internal temperature and humidity are not surfaced as attributes.
Prerequisites
- A CyberPower UPS with an RMCARD205/305 (or equivalent) on the same LAN as the GEM controller, reachable on UDP/161.
- SNMP enabled on the card. In the RMCARD web UI:
- Network → SNMPv1 — set a read community (default
public) and, for control, a write community; or - Network → SNMPv3 — create a user with the desired auth/priv. Control requires a user with write permission.
- Network → SNMPv1 — set a read community (default
- Recent firmware may ship with SNMPv1/v2c disabled in favor of SNMPv3 only — check which version is enabled before adding the device.
Setup
- Find the RMCARD IP from your DHCP table or the card's display. The CyberPower MAC prefix is
00:0C:15. - Create the device under System → Devices (Open Devices) with driver
cyberpower. Set:ip— the RMCARD address (e.g.,192.168.1.8)version—v2c(default) orv3- For v2c:
community(read, defaultpublic) andwrite_communityfor control. The write community defaults toprivate— the CyberPower factory write community — and falls back to the read community if you clear it; set it to whatever the card uses if you changed it. - For v3:
v3_username,v3_security_level, and the matching auth/priv protocols and keys.
- Verify from the Script Console:
After one polling cycle (~30 s) the device picks upawait gem.command({device: <device_id>, action: 'get_status'});
battery_level,runtime_remaining,output_status,input_voltage,output_voltage,output_load, and the rest of the attributes below. - (Optional) Add a zone in the Power subsystem for this device, with no address. The zone tracks the UPS as a whole — its
stateisonwhile the UPS is delivering power andoffwhen the output is off/asleep, and it mirrorsbattery_level,battery_status,low_battery,runtime_remaining,output_load,on_battery, andoutput_status. This makes the UPS show up on UIs and in the "any low batteries / anything offline?" health sweep. (Leave the address blank — a zone with a numeric address is treated as an outlet/bank control zone instead, and gets its state from outlet/bank polling rather than the whole-UPS health.)
Attributes
| Attribute | Type | Notes |
|---|---|---|
model, ups_name, firmware_version, serial_number | string | Identity, read once per poll |
battery_status | string | normal / low / depleted / unknown |
battery_level | int (%) | Battery charge |
battery_voltage | float (V) | |
runtime_remaining | int (min) | Estimated runtime on battery |
time_on_battery | int (s) | 0 when on utility |
low_battery | bool | True when status is low/depleted |
battery_replace_needed | bool | UPS-reported battery replacement flag |
input_voltage | float (V) | Utility line voltage |
input_frequency | float (Hz) | |
input_status | string | normal / over_voltage / under_voltage / frequency_failure / blackout |
last_transfer_cause | string | Reason for the most recent transfer to battery |
output_status | string | online / on_battery / on_boost / on_buck / on_bypass / off / rebooting / on_sleep |
output_voltage | float (V) | |
output_frequency | float (Hz) | |
output_load | int (%) | Load as a percent of capacity |
output_current | float (A) | |
on_battery | bool | True while running on battery |
self_test_result | string | passed / failed / invalid / in_progress |
The table above is what a UPS reports on the device itself. A PDU reports a smaller device identity set — model, firmware_version, serial_number, plus pdu_name, hardware_version, and outlet_count — and puts its real-time per-outlet data (state, load_amps, power_watts, peak_watts, energy_kwh) on each outlet zone rather than the device (see Switchable outlets below). For a UPS, each switchable/critical outlet bank's state also appears on the device as bank_<n>_state (on / off / critical / absent).
Commands
| Command | Family | Effect |
|---|---|---|
get_status | both | Poll the device now and refresh all attributes |
power_on (on) | PDU / UPS | Turn on. address = outlet number (PDU) or bank index (UPS) |
power_off (off) | PDU / UPS | Turn off. address = outlet number (PDU) or bank index (UPS) |
reboot | PDU / UPS | Power-cycle (off then on). PDU = native; UPS bank = emulated off→delay→on |
self_test | UPS | Start a battery self test (brief, non-disruptive); result lands in self_test_result |
runtime_calibration | UPS | Start a runtime calibration — the UPS runs on battery to recalibrate its estimate |
ups_reboot | UPS | Power-cycle the whole UPS output (protected load off then back on) — disruptive |
ups_power_off | UPS | Turn the whole output off, cutting power to the load — disruptive |
ups_sleep | UPS | Put the UPS to sleep until utility power returns — disruptive |
get / set / walk | both | Raw SNMP access (advanced) |
Control commands issue SNMP SETs and therefore require write access (a v2c write_community or a v3 user with write permission). The outlet commands take address = the outlet number; on a UI they bind to [@zone.address] so a zone picker is offered. ups_power_off, ups_reboot, and ups_sleep cut power to the protected load and are intended for deliberate operator use, not routine automation.
Switchable outlets (PDU) and outlet banks (UPS)
Both families auto-create one power_default zone per controllable output in the Power subsystem (which is one of the default subsystems; the driver creates it automatically if it has been removed); a zone's standard on/off maps straight through, and reboot / power_on / power_off can also be invoked directly with {address: <n>}.
The split follows the device's own model — PDU per-outlet values live on the outlet zone; UPS values live on the device:
- PDU — one zone per outlet (
address= 1-based outlet number, label from the PDU's outlet name). Each poll refreshes the zone'sstateplus per-outlet metering attributes fromePDUOutletStatusTable:load_amps(.7, ÷10),power_watts(.8),peak_watts(.10),energy_kwh(.13, ÷10). Control OID…1.1.3.3.3.1.1.4.<n>(ePDUOutletControlOutletCommand), write1=on /2=off /3=reboot. - UPS — one zone per switchable bank (
address= bank index). Control OID…1.1.1.8.1.1.1.2.<n>(upsBankControlOutletCommand), write1=on /2=off. Critical banks (the always-on bank that protects essential loads) reportbank_<n>_state = criticaland reject control — no zone is created for them, matching the RMCARD's "N/A" on/off in its Bank Control page. UPS banks have no native reboot, sorebootis emulated as off →reboot_delay→ on.
Automation ideas
- Power-loss notification. An attribute trigger on
on_batterybecomingtrue(oroutput_status=on_battery) can fire a notification macro and start a graceful-shutdown sequence. - Low-runtime guard. Trigger on
runtime_remainingdropping below a threshold to shed non-critical loads or shut down equipment before the battery is exhausted. - Battery health.
low_batteryandbattery_replace_neededsurface in the health sweep;battery_levelhistory charts charge over time.
Troubleshooting
| Symptom | Check |
|---|---|
| Attributes stay empty / device disconnected | Confirm the SNMP version enabled on the card matches the driver, the source IP is permitted, and UDP/161 is reachable (firewall/VLAN). |
| Polling works but control returns an error | Control needs write access — set a v2c write_community (default private) or use a v3 user with write permission. |
power_off / power_on on a UPS bank returns an error | That bank is the always-on critical bank (its bank_<n>_state reads critical). Only switchable banks can be controlled, and no control zone is created for a critical bank — this matches the RMCARD showing it as "N/A" on its Bank Control page. |
| No outlet/bank zones appear after the first poll | Outlet zones (PDU) and bank zones (UPS) are created on the first successful poll. Confirm the device detected its family (a UPS answers on the .1.1.1 MIB branch, a switched PDU on .1.1.3) and that polling is succeeding; a UPS with no switchable banks (only an always-on critical bank) will not create any control zone. |
| Runtime looks unexpectedly short | Expected during a self test or calibration; runtime_remaining reflects the card's live estimate. |