Modbus driver for Huawei UPS2000/2000A (1kVA-3kVA)#954
Modbus driver for Huawei UPS2000/2000A (1kVA-3kVA)#954jimklimov merged 6 commits intonetworkupstools:masterfrom
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
38f2990 to
99b9287
Compare
aquette
left a comment
There was a problem hiding this comment.
Lgtm, apart maybe from the go-to. But no big deal
|
@aquette I just eliminated |
417ac99 to
ab145ff
Compare
|
I just implemented status and alarm reporting. The driver is almost complete. |
This comment has been minimized.
This comment has been minimized.
|
I must have triggered a bug in the LGTM.com static analyzer. It says It's in fact a real bug, the |
9a20737 to
a231523
Compare
dcbd245 to
98927f6
Compare
|
It's ready for a final review. The driver may still have some sharp edges, but this should be good enough for a |
dc91b55 to
46c5668
Compare
0441153 to
9a11129
Compare
|
Please do not merge the PR yet. I just realized the device driver for the MaxLinear RX21V1410 USB chip has been upstreamed since Linux 5.13, just shortly after I finished the initial driver. It means the driver should also support USB by now. I need to do some retests, and if it really works, update the code comments and documentations. On the other hand, no code change is necessary, it's strictly a kernel update, code reviews are still free to proceed. |
This commit implements a Modbus driver for Huawei UPS2000 (1kVA-3kVA) series UPS units using the USB or RS-232 interface (USB is only support on Linux 5.12+ via the "xr_serial" kernel module), with support for power and battery status monitoring, alarm reporting, RW variables, and instant commands for battery selftest, buzzer, shutdown, restart, and bypass control. Signed-off-by: Yifeng Li <tomli@tomli.me>
Signed-off-by: Yifeng Li <tomli@tomli.me>
Signed-off-by: Yifeng Li <tomli@tomli.me>
Signed-off-by: Yifeng Li <tomli@tomli.me>
|
USB support has been confirmed on Linux 5.12 and newer kernels. Code comments and documentation has been updated. It's the final version of this pull request, ready for review. |
|
Bump. This PR is merge-ready since last week. |
jimklimov
left a comment
There was a problem hiding this comment.
Sorry it took a while to rectify the NUT CI side as well to get to the PRs in queue, great thanks for your contribution and patience!
Made the `configure` example a bit friendlier for copy-pasting.
I recently purchased a Huawei UPS2000 for my server, but the vendor only provided a Windows management program. The program is heavy, it's written in Java that comes with a whole web server and a MySQL database, and it goes without saying that it could not be used in other operating systems - and they want to sell people an SNMP adapter card for that, which would make the UPS to be as expensive as other competing vendors. No thanks...
Fortunately, documentation is publicly available. I reasoned that it would be a waste of effort if it remains unpublished for my private use - implementing it as a NUT driver and upstreaming the driver could benefit others, thus I'm now submitting a Pull Request.
This is only an initial draft of Huawei UPS2000 (1kVA-3kVA) driver on the RS-232 interface. This driver is still a work-in-progress, so far only voltage, frequency, current, power, and temperature monitoring is implemented (I think submitting it right now is helpful to get some useful feedback), I plan to also implement UPS status flag and battery monitoring in the following day, and also to do some coding style fixes.
Notably, I had to work around a significant technical problem. The UPS uses a Modbus-based serial protocol, and right now in NUT, Modbus is already supported via
libmodbus. However,libmodbushas a serious technical limitation - it only supports register reads and writes. In this driver, it needs to read device identification information to ensures that it has been hooked up to the correct UPS - which is unsupported by libmodbus. Worse, although libmodmus supports sending custom commands viamodbus_send_raw_request(), butmodbus_receive_confirmation()assumes the response message is formatted in a certain way with a length in the header - which is not true for our purpose - it simply stops reading in the middle. To add insult to injury,libmodbusdoes not provide any low-level public API for us to receive the raw message from the serial device. Thus, implementing device identification is literally impossible inlibmodbus.To solve the problem, I devised the following workaround:
ser_open()ser_send_buf()andser_get_buf(), and manually parse the response. Also, the CRC-16 verification code has to be copied and pasted into the driver.ser_*()functions are never used anymore at this point, it's safe to do so.Other than that, the rest of the implementation is trivial. See the code comments in the patch for more technical details.
Your code review is appreciated, thanks for your time.
MAINTAINER NOTE: Issues #1066 and #1017 provide many details about this device series