From b682e75b0a085f156d211c7f3e9e25a0ecf8208b Mon Sep 17 00:00:00 2001 From: Caleb Ethridge Date: Thu, 2 Jul 2026 15:23:15 -0400 Subject: [PATCH 1/2] driver/power: Add power backend for RPM1521 Add power backend for the Minuteman RPM1521 series of power switches(2,4,8 ports). Signed-off-by: Caleb Ethridge --- labgrid/driver/power/rpm1521.py | 58 +++++++++++++++++++++++++++++++++ tests/test_powerdriver.py | 1 + 2 files changed, 59 insertions(+) create mode 100644 labgrid/driver/power/rpm1521.py diff --git a/labgrid/driver/power/rpm1521.py b/labgrid/driver/power/rpm1521.py new file mode 100644 index 000000000..13d0716e8 --- /dev/null +++ b/labgrid/driver/power/rpm1521.py @@ -0,0 +1,58 @@ +"""Power backend for the Minuteman RPM1521 networked power controller. + +The RPM1521 is controlled via an HTTP CGI endpoint using HTTP basic auth:: + + curl --user user:pwd \\ + "http://192.168.1.100/nagios_powerctrl.csp?slave_id=1&port=&ctrl_kind=" + +where ``ctrl_kind=1`` turns the outlet on and ``ctrl_kind=2`` turns it off. + +The outlet state is read back from a separate status CGI:: + + curl --user user:pwd "http://192.168.1.100/nagios_power_status.csp" + +which returns a list whose second to last element holds the on/off state of each +outlet (0 = off, 1 = on). + + NetworkPowerPort: + model: rpm1521 + host: 'http://admin:secret@192.168.1.10' + index: 1 +""" + +import json + +import requests + +SLAVE_ID = 1 +CTRL_KIND_ON = 1 +CTRL_KIND_OFF = 2 + + +def power_set(host, port, index, value): + index = int(index) + ctrl_kind = CTRL_KIND_ON if value else CTRL_KIND_OFF + params = { + "slave_id": SLAVE_ID, + "port": index, + "ctrl_kind": ctrl_kind, + } + r = requests.get(f"{host}/nagios_powerctrl.csp", params=params) + r.raise_for_status() + + +def power_get(host, port, index): + index = int(index) + params = { + "slave_id": SLAVE_ID, + } + r = requests.get(f"{host}/nagios_power_status.csp", params=params) + r.raise_for_status() + + # The status CGI returns a list literal, e.g. + # ['RPM1521E','0.0','NULL','1','1','109.9',['1','0'],['0','1'],['0.0','0.0']] + # It contains several bracketed sub-lists; the second to last one holds the + # on/off status of each outlet. + data = json.loads(r.text.replace("'", '"')) + socket_states = data[-2] + return int(socket_states[index - 1]) == 1 diff --git a/tests/test_powerdriver.py b/tests/test_powerdriver.py index 8926333c6..5d23f5932 100644 --- a/tests/test_powerdriver.py +++ b/tests/test_powerdriver.py @@ -295,6 +295,7 @@ def test_import_backends(self): import labgrid.driver.power.pe6216 import labgrid.driver.power.poe_netgear_plus import labgrid.driver.power.rest + import labgrid.driver.power.rpm1521 import labgrid.driver.power.sentry import labgrid.driver.power.eg_pms2_network import labgrid.driver.power.shelly_gen1 From b7abeafca4d799d085ed63c3714197924fc3933c Mon Sep 17 00:00:00 2001 From: Caleb Ethridge Date: Mon, 13 Jul 2026 14:28:06 -0400 Subject: [PATCH 2/2] doc/configuration: Add documentation for the RPM1521 Signed-off-by: Caleb Ethridge --- doc/configuration.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/configuration.rst b/doc/configuration.rst index 57b23f13c..d3bf18ba9 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -229,6 +229,13 @@ Currently available are: `__ for details. +``rpm1521`` + Controls *Minuteman RPM1521* series networked power switches (2, 4 and 8 port + variants) via an HTTP CGI interface. + See the `docstring in the module + `__ + for details. + ``sentry`` Controls *Sentry PDUs* via SNMP using Sentry3-MIB. It was tested on *CW-24VDD* and *4805-XLS-16*.