Skip to content

Repository files navigation

About

Software is not developed by BlueWalker GmbH.

There was no Linux software available for the PowerWalker PDU and ATS, but the manufacturer was kind enough to supply me with what I needed to make my own library.

PowerWalker PDU and ATS in my homelab

I'm using a Raspberry Pi as a power manager in my homelab, it is connected to both the PDU and ATS. It's best practice to have a single application responsible for communicating with the devices, as you will get communication errors if two applications tries to talk to the same device at the same time.

I am using the mqtt.py script to publish ATS and PDU data on the MQTT network. Then you can have multiple clients subscribe to the respective MQTT topics, like Home Assistant. To visualize the data I use the Home Assistant InfluxDB component, then Grafana pulls the data from InfluxDB and makes cool graphs.

To make sure that the mqtt.py script keeps running; I'm using Supervisor.

Note! Methods and keys may change; as I am still investigating use cases and best practices.

Communicate

Connect either the USB or the serial port, find the correct device path and instantiate.

Serial port

importpowerwalkerpdu=powerwalker.PDU("/dev/ttyUSB0")
ats=powerwalker.ATS("/dev/ttyUSB1")

USB HID device

There's a chance that your device is not being recognized as usbserial. Therefore, you have to instantiate as usbhid device:

importpowerwalkerpdu=powerwalker.PDU("/dev/hidraw0", usbhid=True)
ats=powerwalker.ATS("/dev/hidraw1", usbhid=True)

Give regular users in the dialout group access to hidraw devices:

Add this line to /etc/udev/rules.d/99-com.rules:

KERNEL=="hidraw*", GROUP=="dialout", MODE="0664"

And run sudo udevadm trigger

PowerWalker PDU RC-16A IEC

PowerWalker PDU RC-16A IEC frontPowerWalker PDU RC-16A IEC back

PowerWalker PDU RC-16A is designed to distribute AC power from a single source to 8 outputs with advanced load monitoring and local or remote ON/OFF switching control of individual outlets.

https://powerwalker.com/?item=10133001

Available methods

MethodDescriptionType
connect()Connect to PDU device.-
send(cmd)Send custom command.-
info()Get and return device information.get
status()Get and return device statuses. (see codes below)get
power_w()Get and return active power (W) measurements for input and all outputs.get
power_va()Get and return apparent power (VA) measurements for input and all outputs.get
energy_kwh()Get and return energy consumption (kWh) for input and all outputs.get
energy_kwh_clear()Clear energy consumption values for input and all outputs.set
countdown_times()Get and return shutdown and restore countdown times for all outputs.get
shutdown(idx, shdn)Shutdown output idx in shdn minutes.set
shutdown_restore(idx, shdn, rst)Shutdown output idx in shdn minutes, restore power after rst minutes.set
shutdown_cancel(idx)Cancel pending shutdown on output idx.set
protocol()Get and return device protocol ID.get
firmware()Get and return device firmware version.get
test()Test PDU device, turn on all LEDs and the buzzer for 5 seconds.set
memory_get(adr)Get and return memory setting at adr location.get

Output status codes

  1. Off
  2. On
  3. Shutdown active
  4. Shutdown imminent (S01-S08 code)
  5. Restore active
  6. Overload alarm (F01-F08 code)
  7. Locked (L01-L08 code)

Shutdown method arguments

  • idx : output; 1 to 8, A for all.
  • shdn : shutdown delay in minutes; 0.1 to 0.9, 1 to 99, 0 for immediate.
  • rst : restore delay in minutes; 1 to 9999, 0 for 1 second.

Memory configuration map

AdrKeyUnitMinMaxDefault
0output_start_up_delaysec02401
1out1_current_alarm0.1 A0.54.02.0
2out2_current_alarm0.1 A0.54.02.0
3out3_current_alarm0.1 A0.54.02.0
4out4_current_alarm0.1 A0.54.02.0
5out5_current_alarm0.1 A0.54.02.0
6out6_current_alarm0.1 A0.54.02.0
7out7_current_alarm0.1 A0.54.02.0
8out8_current_alarm0.1 A0.54.02.0
9low_input_voltage_alarmV184207196
10high_input_voltage_alarmV242264253
11max_input_voltage_shutoffV253300 *276
12low_input_current_alarm0.1 A0.015.00.0
13high_input_current_alarm0.1 A1.016.016.0
14shutdown_imminent_signalmin1-3
* 0xFFFF = disabled

Output configuration byte

Memory address 1 to 8 also contains output configuration byte, key: out?_config.

ByteDecDescription01
01Output status at power onoffon
12Automatic disconnection of the output 1 minute after the overload alarmenableddisabled
24On/off button enabled on front paneldisabledenabled
38Not in use--
416Not in use--
532Not in use--
664Not in use--
7128Not in use--

Example responses

Generic

  • ACK if command was accepted.
  • NAK if command was not accepted.

info()

{ 'in_out_phase': '1/1',
'in_socket_no': '1',
'model': '############PDU',
'nom_in_voltage': '230',
'nom_out_voltage': '230',
'out_socket_no': '8'}

status()

{ 'in_current': 2.1,
'in_freq': 49.8,
'in_voltage': 225.5,
'int_temp': 36.0,
'out1_current': 0.4,
'out2_current': 0.5,
'out3_current': 0.3,
'out4_current': 0.1,
'out5_current': 0.2,
'out6_current': 0.2,
'out7_current': 0.3,
'out8_current': 0.0,
'status': { 'a01_low_in_voltage': 0,
'a02_high_in_voltage': 0,
'f09_low_in_current': 0,
'f10_high_in_current': 0,
'f11_pwr_fail_aux1': 0,
'f12_pwr_fail_aux2': 0,
'na_b8': 0,
'na_b9': 0,
'out1_status': 1,
'out2_status': 1,
'out3_status': 1,
'out4_status': 1,
'out5_status': 1,
'out6_status': 1,
'out7_status': 1,
'out8_status': 1}}

power_w()

{ 'in_w': 441,
'out1_w': 62,
'out2_w': 108,
'out3_w': 74,
'out4_w': 37,
'out5_w': 39,
'out6_w': 33,
'out7_w': 57,
'out8_w': 0}

power_va()

{ 'in_va': 478,
'out1_va': 108,
'out2_va': 123,
'out3_va': 83,
'out4_va': 47,
'out5_va': 43,
'out6_va': 65,
'out7_va': 70,
'out8_va': 0}

energy_kwh()

{ 'in_kwh': 725.9,
'out1_kwh': 4.3,
'out2_kwh': 103.4,
'out3_kwh': 17.4,
'out4_kwh': 114.0,
'out5_kwh': 201.9,
'out6_kwh': 106.8,
'out7_kwh': 47.6,
'out8_kwh': 19.8}

countdown_times()

{ 'out1_cd_sec': {'r': 0, 's': 0},
'out2_cd_sec': {'r': 0, 's': 0},
'out3_cd_sec': {'r': 0, 's': 0},
'out4_cd_sec': {'r': 0, 's': 0},
'out5_cd_sec': {'r': 0, 's': 0},
'out6_cd_sec': {'r': 0, 's': 0},
'out7_cd_sec': {'r': 0, 's': 0},
'out8_cd_sec': {'r': 0, 's': 0}}

protocol()

{'prot_id': 'PI90'}

firmware()

{'verfw': 0.15}

memory_get(0)

{'output_start_up_delay': 1}

memory_get(1)

{'out1_config': 255, 'out1_current_alarm': 20}

PowerWalker ATS

PowerWalker ATS frontPowerWalker ATS back

ATS (Automatic Transfer Switch) supports connection of two independent power sources. If primary power source fails, the secondary will automatically back up the connected load without any interruption.

https://powerwalker.com/?item=10120543

Available methods

MethodDescriptionType
connect()Connect to PDU device.-
send(cmd)Send custom command.-
info()Get and return device information.get
status()Get and return device statuses.get
protocol()Get and return device protocol ID.get
firmware()Get and return device firmware version.get
memory_get(adr)Get and return memory setting at adr location.get

Memory configuration map

AdrKeyUnitMinMaxDefault
0src1_voltage_high_lossV100300258
1src1_voltage_high_backV100300248
2src1_voltage_low_lossV100300180
3src1_voltage_low_backV100300190
4src1_freq_high_lossHz407055
5src1_freq_high_backHz40700
6src1_freq_low_lossHz407045
7src1_freq_low_highHz40700
8src2_voltage_high_lossV100300258
9src2_voltage_high_backV100300248
10src2_voltage_low_lossV100300180
11src2_voltage_low_backV100300190
12src2_freq_high_lossHz407055
13src2_freq_high_backHz40700
14src2_freq_low_lossHz407045
15src2_freq_low_highHz40700
16overload_alarm%0150100
17overload_fault%02500
18acceptable_phases°01800
19breaking_timems099995
20blanking_timems010004

Example responses

info()

{ 'battery_voltage': '---.-',
'rated_output_current': '016',
'rated_output_freq': '50.0',
'rated_output_voltage': '230.0'}

status()

{ 'int_temp': 35.0,
'out_current': 2.2,
'out_load_pct': 14.0,
'src1_freq': 50.0,
'src1_voltage': 227.3,
'src2_freq': 50.0,
'src2_voltage': 227.3,
'status': { 'aux_pwr1_fail': 0,
'aux_pwr2_fail': 0,
'na_c0': 0,
'na_c1': 0,
'na_c2': 0,
'na_c3': 0,
'na_c4': 0,
'na_c5': 0,
'na_c6': 0,
'na_c7': 0,
'on_fault_mode': 0,
'on_src1': 1,
'on_src2': 0,
'overload_alarm': 0,
'overload_fault': 0,
'preferred_src2': 0,
'short_fault': 0,
'src1_freq_bad': 0,
'src1_voltage_bad': 0,
'src1_wave_bad': 0,
'src2_freq_bad': 0,
'src2_voltage_bad': 0,
'src2_wave_bad': 0,
'syncron_bad': 0},
'sync_angle': 1.0}

protocol()

{'prot_id': 'PI97'}

firmware()

{'verfw': 181.0}

memory_get(0)

{'src1_voltage_high_loss': 258}

CLI

For easy access to the device methods; use cli.py:

$ python3 cli.py device method arguments

Examples

Run test sequence on PDU:

$ python3 cli.py pdu test

Shutdown output 8 in 0.5 minutes:

$ python3 cli.py pdu shutdown 8 0.5

Shutdown output 8 in 2 minutes, restore after 1 second:

$ python3 cli.py pdu shutdown_restore 8 2 0

Cancel pending shutdown on output 8

$ python3 cli.py pdu shutdown_cancel 8

MQTT

To publish ATS and PDU data to MQTT; use mqtt.py:

$ python3 mqtt.py

Make sure to rename config.sample.py to config.py and set the correct settings.

Outlet state change (PDU)

The MQTT script subscribes to cfg.mqtt['prefix'] + "/pdu/outlet/+/+"; to change the state of an outlet use topic:

your_prefix/pdu/outlet/out[1-8]/set

Payload can be 0, 1 or anything that Python casts as a boolean value.

All incoming commands are queued so not to interrupt any ongoing serial communication, at the start of each loop cycle all pending commands are performed.

Note that the state change is not immediate, there is a slight delay were the PDU warn of outlet imminent shutdown. Also note that if an outlet is not listed in the config file as "allowed state change"; a ValueError exception is raised.

Sample topics

pdu/outlet/out1 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/outlet/out2 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/outlet/out3 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/outlet/out4 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/outlet/out5 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/outlet/out6 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/outlet/out7 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/outlet/out8 {"shutdown_sec": 0, "state": "On", "status": 1, "restore_sec": 0}
pdu/status {"pwr_fail_aux2": 0, "low_in_voltage": 0, "pwr_fail_aux1": 0, "high_in_current": 0, "temp_c": 33.0, "low_in_current": 0, "in_hz": 49.8, "high_in_voltage": 0, "in_v": 228.2}
pdu/power/out1 {"va": 95, "w": 76, "a": 0.4}
pdu/power/out6 {"va": 0, "w": 0, "a": 0.0}
pdu/power/out7 {"va": 0, "w": 0, "a": 0.0}
pdu/power/out2 {"va": 0, "w": 0, "a": 0.0}
pdu/power/out3 {"va": 92, "w": 89, "a": 0.4}
pdu/power/out8 {"va": 0, "w": 0, "a": 0.0}
pdu/power/in {"va": 318, "w": 266, "a": 1.4}
pdu/power/out5 {"va": 65, "w": 60, "a": 0.2}
pdu/power/out4 {"va": 63, "w": 50, "a": 0.1}
ats/supply/src1 {"preferred": 1, "hz": 50.0, "bad": "0", "active": 1, "v": 229.7}
ats/supply/src2 {"preferred": 0, "hz": 50.0, "bad": "0", "active": 0, "v": 230.9}
ats/status {"out_pct": 10.0, "overload_alarm": 0, "overload_fault": 0, "out_a": 1.4, "syncron_bad": 0, "aux_pwr2_fail": 0, "sync_angle": 1.0, "temp_c": 32.0, "on_fault_mode": 0, "short_fault": 0, "aux_pwr1_fail": 0}

Script files

  • cli.py: Simple command line interface.
  • mqtt.py: Publishing values to MQTT.
  • ups.py: Get UPS data from upsc and publish to MQTT.

Useful resources

Author

Thomas Jensen

Notices

  • PowerWalker is a brand of BlueWalker GmbH.
  • PowerWalker PDU RC-16A IEC and PowerWalker ATS are products of BlueWalker GmbH.
  • Software is not developed by BlueWalker GmbH.
  • This library is published under the MIT license.

About

Python3 library for the PowerWalker PDU RC16 and ATS devices.

Topics

Resources

Stars

16 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages