Skip to content

Commit b327f81

Browse files
Merge pull request #1324 from DanielKriz/feature/aten_pe6216_power_driver
driver/pe6216: add support for Aten PE6216 PDU
2 parents caf7833 + a2557a5 commit b327f81

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

doc/configuration.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ Currently available are:
208208
``netio_kshell``
209209
Controls *NETIO 4C PDUs* via a Telnet interface.
210210

211+
``pe6216``
212+
Controls an Aten PE6216 PDU via a simple HTTP API.
213+
This backend deliberately uses the standard username ``administrator`` and the default password
214+
``password`` and is not compatible with other credentials.
215+
211216
``poe_mib``
212217
Controls PoE switches using the PoE SNMP administration MiBs.
213218

labgrid/driver/power/pe6216.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Tested with Aten PE6216.
2+
3+
HTTP API is defined by in the aten PDU PE6216 specification:
4+
https://assets.aten.com/product/manual/Restful-API-Guide-for-PDU_2022-11-18.pdf
5+
"""
6+
7+
import re
8+
import requests
9+
10+
from ..exception import ExecutionError
11+
12+
PORT = 80
13+
14+
MIN_OUTLET_INDEX = 1
15+
MAX_OUTLET_INDEX = 16
16+
HEADERS = {"Content-Type": "application/x-www-form-urlencoded"}
17+
18+
19+
def power_set(host, port, index, value):
20+
index = int(index)
21+
assert MIN_OUTLET_INDEX <= index <= MAX_OUTLET_INDEX
22+
value = "on" if value else "off"
23+
24+
response = requests.post(
25+
f"http://{host}:{port}/api/outlet/relay",
26+
headers=HEADERS,
27+
data={
28+
"usr": "administrator",
29+
"pwd": "password",
30+
"index": index,
31+
"method": value,
32+
},
33+
)
34+
response.raise_for_status()
35+
36+
37+
def power_get(host, port, index):
38+
index = int(index)
39+
assert MIN_OUTLET_INDEX <= index <= MAX_OUTLET_INDEX
40+
41+
response = requests.get(
42+
f"http://{host}:{port}/api/outlet/relay",
43+
headers=HEADERS,
44+
params={
45+
"usr": "administrator",
46+
"pwd": "password",
47+
"index": index,
48+
},
49+
)
50+
response.raise_for_status()
51+
52+
m = re.search(r"<\d+>(?P<state>(ON|OFF|PENDING))<.*", response.text)
53+
if m is None:
54+
raise ExecutionError("PE6216: could not match response")
55+
return m.group("state") == "ON"

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ include = [
222222
"labgrid/driver/httpvideodriver.py",
223223
"labgrid/driver/manualswitchdriver.py",
224224
"labgrid/driver/power/gude8031.py",
225+
"labgrid/driver/power/pe6216.py",
225226
"labgrid/driver/power/shelly_gen2.py",
226227
"labgrid/driver/rawnetworkinterfacedriver.py",
227228
"labgrid/protocol/**/*.py",

tests/test_powerdriver.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ def test_import_backends(self):
291291
import labgrid.driver.power.gude24
292292
import labgrid.driver.power.netio
293293
import labgrid.driver.power.netio_kshell
294+
import labgrid.driver.power.pe6216
294295
import labgrid.driver.power.rest
295296
import labgrid.driver.power.sentry
296297
import labgrid.driver.power.eg_pms2_network

0 commit comments

Comments
 (0)