A Prometheus exporter for CyberPower UPS devices that exposes battery-health metrics unavailable from generic SNMP exporters.
This exporter was originally written for a CyberPower PR3000RT2U with an RMCard205 network management card, but it should work with other CyberPower UPSes exposing the same MIB.
Unlike generic SNMP exporters, this exporter performs domain-specific calculations such as battery age, replacement schedules, and overdue replacement metrics.
- Native Prometheus metrics
- Battery replacement calculations
- Battery age metrics
- Replacement due date
- Days until or past replacement
- Exporter health metrics
- Configurable instance labels
- Zero Python runtime dependencies
- Non-root container image
The Prometheus snmp_exporter is excellent, but it intentionally acts as a
generic SNMP translator.
This exporter adds UPS-specific knowledge that cannot be obtained by mapping OIDs alone.
Examples include:
- Battery age
- Recommended replacement date
- Days overdue
- Calendar-aware month calculations
cyberpower_battery_charge_percent 100
cyberpower_battery_age_months 49.5
cyberpower_battery_days_overdue 228
cyberpower_battery_needs_replacing 1
| Variable | Default | Description |
|---|---|---|
UPS_IP |
192.168.0.111 |
UPS address or hostname |
COMMUNITY |
public |
SNMP v2c community |
PORT |
9120 |
Exporter HTTP listening port |
UPS_NAME |
PR3000RT2U |
Value of the Prometheus ups label |
SOURCE_LABEL |
rmcard205_snmp |
Value of the Prometheus source label |
All settings are supplied through environment variables, making the exporter straightforward to run through Docker Compose, systemd, Kubernetes, or a local shell.
Copy the example environment file and edit it for the UPS:
cp .env.example .env
vi .envBuild and start the exporter:
docker compose up --build --detachCheck container and health status:
docker compose psRead the metrics:
curl -fsS http://127.0.0.1:9120/metricsFollow logs or stop the deployment:
docker compose logs --follow cyberpower-prometheus-exporter
docker compose downPUBLISHED_PORT controls the port exposed on the Docker host. PORT controls
the port listened on inside the container. They both default to 9120.
The Compose definition runs the filesystem read-only, drops Linux
capabilities, enables no-new-privileges, and supplies a small writable /tmp
tmpfs.
Build the local image:
docker build --tag cyberpower-prometheus-exporter:local .Run it directly:
docker run --rm \
--name cyberpower-prometheus-exporter \
--publish 9120:9120 \
--env UPS_IP=192.168.0.111 \
--env COMMUNITY=public \
--env UPS_NAME=PR3000RT2U \
--env SOURCE_LABEL=rmcard205_snmp \
cyberpower-prometheus-exporter:localThe image contains Net-SNMP, runs as an unprivileged numeric user, and uses a TCP-only health check. The health check verifies that the exporter is listening without causing an extra SNMP query.
- Python 3.11+
- Net-SNMP (
snmpget)
Ubuntu:
sudo apt install snmpClone and install:
git clone <repository-url>
cd cyberpower-prometheus-exporter
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"Run the exporter:
python -m cyberpower_prometheus_exporterMetrics become available at:
http://localhost:9120/metrics
When Prometheus shares a Docker network with the exporter, use the Compose service name:
scrape_configs:
- job_name: cyberpower
scrape_interval: 30s
static_configs:
- targets:
- cyberpower-prometheus-exporter:9120For Prometheus running outside that Docker network, use the Docker host address
and PUBLISHED_PORT instead.
See the generated metric reference for the complete list of metrics, units, types, and descriptions.
The metric reference is generated from the same definitions used by the exporter:
make docsFormat:
ruff format .Lint:
ruff check .Test:
pytestRun all repository checks:
make checkBuild the container image:
make docker-buildValidate or start the Compose deployment:
make compose-config
make compose-up- Publish container images
- Grafana dashboard
- Additional CyberPower models; this will require help from people who own those models
- GitLab CI
- Support SNMPv3
- More battery health metrics
MIT
