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, auto-creates one zone per outlet in the power subsystem, and exposespower_on/power_off/rebootper outlet.
All traffic stays on the customer LAN.
Status
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.
- PDU81001 (firmware 1.3.3), 8 switched outlets — outlet naming, the read-state/write-command OID (
…1.1.3.3.3.1.1.4.<n>: read1=on /2=off, write1=on /2=off /3=reboot), and theprivatewrite community verified live (an outlet was cycled on→off→on over SNMP).
Status OIDs are read from the CPS-MIB and mapped to attributes; control verbs issue SNMP SETs. Outlet switching applies to ePDUs (and UPS models with switchable outlet groups). The PR / Smart App Sinewave UPS series exposes its outlets as an always-on naming table, not switchable groups, so outlet commands are not offered when the device is detected as that kind of UPS.
Battery/internal temperature is reported only when the optional CyberPower environment sensor is fitted, so it is left unset on units without one.
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 with driver
cyberpower. Set:ip— the RMCARD address (e.g.,192.168.1.8)version—v2c(default) orv3- For v2c:
community(read, defaultpublic) and optionallywrite_communityfor control. - 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,low_battery,runtime_remaining,output_load, andon_battery. This makes the UPS show up on UIs and in the "any low batteries / anything offline?" health sweep.
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 |
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_switch zone per controllable output in the power subsystem; 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 or use a v3 user with write permission. |
| Runtime looks unexpectedly short | Expected during a self test or calibration; runtime_remaining reflects the card's live estimate. |