HUAWEI-UPS2000(8)
=================

NAME
----

huawei-ups2000 - Driver for Huawei UPS2000 (1kVA-3kVA) UPS with USB or
RS-232 serial Modbus connection.

SYNOPSIS
--------

*huawei-ups2000* -h

*huawei-ups2000* -a 'DEVICE_NAME' ['OPTIONS']

NOTE: This man page only documents the hardware-specific features of the
huawei-ups2000 driver.  For information about the core driver, see
linkman:nutupsdrv[8].

SUPPORTED HARDWARE
------------------

This driver supports Huawei UPS2000 series, online (double conversion)
UPS with the following characteristics.

1. Output power: 1 kVA to 3 kVA (higher power models are unsupported).

2. Connection: USB or RS-232 (driver compatibility issues exist, read
the section *Cabling* carefully).

   * USB: For most models, Linux 5.12 or a newer kernel is required,
     Windows also requires an additional serial port driver. For other
     Unix-like systems, driver incompatibility exists, use RS-232.

   * RS-232: Always supported.

   * RS-485: Untested. Testers needed.

3. Operating system: Unix/Linux supported by default, Windows requires
NUT v2.8.5 or newer.

The UPS2000 series has two variants: UPS2000-A with a tower chassis,
and UPS2000-G with a rack-mount chassis. Within these two variants,
there are also two sub-variants: a standard runtime model powered by
an internal battery pack denoted by an "S" suffix, and a long runtime
model powered by an external battery pack denoted by an "L" suffix.

All of these models should be equally supported, currently, it has
been tested on the following models.

* UPS2000-A-1KTTS (firmware: UPS2000A, V2R1C1SPC40, P1.0-D1.0)
* UPS2000-A-1KTTS (firmware: UPS2000A, V2R1C1SPC50, P1.0-D1.0)
* UPS2000-A-2KTTS (firmware: UPS2000A, V2R1C1SPC50, P1.0-D1.0)
* UPS2000-G-1KRTS (firmware: UPS2000A, V2R1C1SPC40, P1.0-D1.0)
* UPS2000-G-1KRTS (firmware: UPS2000G, V2R1C1SPC50, P1.0-D1.0)
* UPS2000-G-3KRTS (firmware: UPS2000A, V2R1C1SPC40, P1.0-D1.0)
* UPS2000-G-3KRTS (firmware: UPS2000G, V2R1C1SPC50, P1.0-D1.0)
* UPS2000-G-3KRTL (firmware: UPS2000A, V2R1C1SPC40, P1.0-D1.0)

If your model is not in the list, we encourage you to report successful
or unsuccessful results to the bug tracker or the mailing list.
Make sure to include the full model number of your UPS manually
in your report, because many units only report themselves as "UPS2000-A"
regardless of their models, including the G series.

As of 2022, there is also a new hardware variant with a WCH CH341
USB-to-serial chip instead of a MaxLinear/Exar RX21V1410 chip and
reports itself as "UPS2000G". Driver support has been added since
v0.03.

huawei-ups2000 uses the libmodbus project, for Modbus implementation.

CABLING
-------

The UPS has a USB port and a RS-232 port. USB is conditionally supported,
depending on hardware driver availability. RS-232 is always supported
on all operating systems, which can be used as a fallback.

On most UPS models, USB is powered by the Exar/MaxLinear RX21V1410
USB-to-serial chip. On Linux, it's only usable on Linux 5.12 and later, via
the *xr_serial* kernel module. On Windows, it's also suggested to install
an additional device driver. On some newer UPS hardware variants, a WCH
CH341 chip is used instead, these should have better compatibility (via the
*ch341* Linux kernel module, or Windows Update). See subsection *Linux USB*
and *Windows USB* for details.

Only one port can be used at a time. When USB is used, RS-232 should be
unplugged from the UPS, and vice versa. Further, optional adapter cards,
such as RS-485 or SNMP, are not supported. They should be removed from
the UPS.

Because the UPS port can be unresponsive under certain circumstances, it's
recommended to power cycle your UPS after making a cabling change, especially
after changing the port type. That is, turn off the UPS power output via the
front panel, then unplug the UPS from line power input.  Wait for the LCD
screen to go black. Finally reconnect line power and restart your UPS.

Linux USB
~~~~~~~~~

The USB port on the UPS2000 is originally powered by a MaxLinear/Exar
RX21V1410 USB-to-serial converter chip, it's only supported by Linux
5.12 or newer, via the *xr_serial* kernel module. Its *lsusb* report
is:

    04e2:1410 Exar Corp. XR21V1410 USB-UART IC

However, a recent hardware variant switched to the WCH CH341 serial
chip:

    1a86:5523 QinHeng Electronics CH341 in serial mode, usb to serial port converter

If your unit has a WCH CH341 chip (likely only found in units made
after 2022), when the UPS2000 is connected via USB, you should see
the following logs in *dmesg*.

    ch341 2-1.2:1.0: ch341-uart converter detected
    usb 2-1.2: ch341-uart converter now attached to ttyUSB0

If so, you should be able to proceed without worrying about kernel
compatibility. This CH341 chip has been around for a decade and should be
compatible with your system.

On the other hand, if your unit has a MaxLinear/Exar XR21V1410 chip, like
most users do, when the UPS2000 is connected via USB to a supported Linux
system, you should see the following logs in *dmesg*.

    xr_serial 1-1.2:1.1: xr_serial converter detected
    usb 1-1.2: xr_serial converter now attached to ttyUSB0

The driver must be *xr_serial*. If your system doesn't have the
necessary device driver, you will get this message instead:

    cdc_acm 1-1.2:1.0: ttyACM0: USB ACM device

The generic driver *cdc_acm* is incompatible and cannot be used.
You should upgrade your Linux kernel to Linux 5.12 or newer.

WARNING: On an unsupported system, the XR21V1410 USB device can still
be recognized as a USB ACM device, but communication is impossible,
please don't waste your time on *cdc_acm*.

If you're already running on Linux 5.12 or newer kernels, but still
cannot see the *xr_serial* driver, it means the driver is not enabled
in your kernel build. If you're a regular user, you should file a bug
report to your Linux distro maintainers and ask them to enable
*xr_serial* (kernel option `CONFIG_USB_SERIAL_XR`).

When upgrading the Linux kernel isn't an option, or when you are using
another operating system (e.g. FreeBSD), RS-232 must be used. Even for
CH341 users, one can try this option if USB somehow refuses to work.

Windows USB
~~~~~~~~~~~~

Windows Update should automatically install appropriate drivers for
your USB device, however, manual intervention may be required in case
this process fails.

MaxLinear/Exar RX21V1410
^^^^^^^^^^^^^^^^^^^^^^^^^

For UPS models with a MaxLinear/Exar RX21V1410 USB-to-serial converter
chip, an additional device driver may be required.

According to the official manual, it instructs users to install a special
MaxLinear device driver called *XR21x141x-XP2KVista7-DriversOnly-Vers1.7.0.0*.
See *Huawei UPS2000 (1 kVA-3 kVA) Modbus Protocol Development Guide*.

The driver described in the official manual may be outdated or difficult
to obtain. If so, please also try downloading the latest driver from
MaxLinear XR21V1410 product page on the Web. At the time of writing, the
latest driver is named *XR21x_Win10_V2.7.0.0.zip* in the *Software: Drivers,
Windows 10 and newer* category.

URLs are available at the bottom of the manual.

WCH CH341
^^^^^^^^^

For UPS models with a WCH CH341 USB-to-serial converter chip, an additional
device driver may be required.

At the time of writing, the latest driver is named *CH341SER.EXE* (v3.9,
2024/10/16) as a self-installer, available on WCH official website.
An alternative *.zip* archive named *CH341SER.ZIP* with the same version
can also be used for manual installation via *Device Manager*.

URLs are available the bottom of the manual.

RS-232
~~~~~~

RS-232 is supported on all operating systems, either via a built-in serial
port on your computer, or by using an external USB-to-RS-232 converter. If
you plan to use an USB-to-RS-232 converter, make sure it's supported by your
operating system.

RS-485
~~~~~~

RS-485 support is provided by UPS2000 using an optional adapter card. This
driver is untested on RS-485, but the author suspects that RS-485 uses the
same serial protocol as RS-232, which should be supported. If you have a
RS-485 adapter, we encourage you to report successful or unsuccessful results
to the bug tracker or the mailing list.

INSTALLATION
------------

This driver may be not built by default.  You can build it by installing libmodbus
(with development packages) and running

    configure --with-serial=yes --with-modbus=yes

You also need to give proper (R/W) permissions on the local serial device file
to allow the NUT driver run-time user to access it. This may need additional
setup for start-up scripting, udev or upower rules, to apply the rights on every
boot -- especially if your device nodes are tracked by a virtual filesystem.

For example, a USB-to-serial converter can be identified as `/dev/ttyACM0`
or `/dev/ttyUSB0` on Linux, or `/dev/ttyU0` on FreeBSD (note the capital "U").
A built-in serial port can be identified as `/dev/ttyS0` on Linux or one of
`/dev/cua*` names on FreeBSD.

EXTRA ARGUMENTS
---------------
This driver supports the following optional settings in the
linkman:ups.conf[5] file:

*offdelay=*'value'::
Time to wait before shutting down the UPS (seconds), acceptable range is
6 seconds (0.1 minutes) to 5940 seconds (99 minutes). Defaults to 60 seconds.
Must be a multiple of 6 seconds. To ensure your system has adequate time
to shut down after a power failure, it's highly recommended to adjust
*offdelay*.

*rebootdelay=*'value'::
Time to wait before rebooting the UPS (seconds), acceptable range is
6 seconds (0.1 minutes) to 5940 seconds (99 minutes). Defaults to 60 seconds.
Must be a multiple of 6 seconds. This is used by the *shutdown.reboot.graceful*
instant command. If you've adjusted *offdelay*, you should also adjust
*rebootdelay*.

*ondelay=*'value'::
Time to wait before switching on the UPS (seconds), acceptable range is
60 seconds (1 minutes) to 5940 seconds (99 minutes). Defaults to 60 seconds.
Must be a multiple of 60 seconds (not 6 seconds). You don't need to adjust
this delay unless you have special requirements.

NOTE: Due to hardware limitation, in this driver, *ondelay* is respected
only when line power is available. If a power failure has occurred, the
UPS and the load is always immediately switched on, as soon (or as late)
as line power is restored.

INSTANT COMMANDS
----------------

This driver supports some instant commands (see linkman:upscmd[8]):

*shutdown.stayoff*::
After an *offdelay*, turn off the load. When line power is back,
remain off.

*shutdown.return*::
After an *offdelay*, turn off the load. When line power is back,
turn on the load, possibly after an *ondelay*.

NOTE: Normally, the load is turned on as soon as line power is back.
But if line power is never lost, or has came back unexpectedly
in the middle of an ongoing shutdown (an undesirable "power race"
condition that many entry-level products on the market fail to
recover from), the load is turned on after an *ondelay*. Thus,
UPS2000 is unaffected by a power race, the load is guaranteed to
always restart.

*shutdown.reboot*::
Like *shutdown.return*, except that the load is turned off immediately
(6 seconds in this implementation).

*shutdown.reboot.graceful*::
Like *shutdown.return*, except that the load is turned off after a
*rebootdelay*, not an *offdelay*.

*beeper.enable*::

Enable the UPS beeper.

*beeper.disable*::

Disable the UPS beeper.

*beeper.toggle*::

Toggle the UPS beeper.

*bypass.start*::

Put the UPS in bypass mode. Use with caution. It exposes your equipment
to unregulated line power and provides no protection from power failures.
Also, the UPS may shut down whenever the bypass input voltage is out
of the nominal range. As a warning, the UPS beeps once every 10 seconds
in bypass mode.

NOTE: The driver has a basic foolproof mechanism. If the bypass input
is already abnormal due to a power failure, the driver refuses to enter
bypass mode by aborting the command and logging an error. However, it
offers no protection after the UPS has entered (or in the middle of
entering) bypass mode. Thus, again, use with caution.

*bypass.stop*::

Put the UPS out of bypass mode.

*load.on*::

Turn on the load immediately.

*load.off*::

Turn off the load immediately. Use with caution, everything on the UPS
will lost power.

*test.battery.start.quick*::

Perform a short battery test.

*test.battery.start.deep*::

Perform a long battery test.

*test.battery.stop*::

Stop a running battery test.

VARIABLES
---------

This driver supports some writable runtime variables (see linkman:upsrw[8]):

**ups.beeper.status**::
Enable or disable the UPS beeper, *disabled* or *enabled*.

NOTE: The beeper can only be disabled completely, it cannot be
temporally muted until the next alarm, but the option *muted* is
also accepted for convenience, *muted* is treated as an alias of
*disabled*.

**ups.delay.shutdown**::
Seconds to wait after shutdown with delay command. It's the runtime
equivalent of *offdelay*. See description of *offdelay*.

**ups.delay.reboot**::
Seconds to wait before rebooting the UPS, it's the runtime
equivalent of *rebootdelay*. See description of *rebootdelay*.

**ups.delay.start**::
Seconds to wait before restarting the load, it's the runtime
equivalent of *ondelay*. See description of *ondelay*.

KNOWN ISSUES AND BUGS
---------------------

Fixed bugs
~~~~~~~~~~

Driver v0.03 (NUT v2.8.1) added support for UPS2000G with a WCH CH341
USB-to-serial interface, these models were previously unsupported.

Driver v0.04 (NUT v2.8.1) fixed a timeout recovery bug that leads
to endless read failures and permanent data stalls.

Driver v0.12 (NUT v2.8.5) fixed support for Microsoft Windows,
Windows was previously unsupported due to a file locking bug.

See *Historical bugs* at the bottom of this manual for links.

Battery status has a non-fatal read failure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It's usually harmless and can be safely ignored. It's only logged for
informative purposes (*LOG_INFO*), not as a warning or error.

Data stale
~~~~~~~~~~~

Under certain circumstances, some registers can return invalid values
and trigger a "data stale" error. Once a data stale error has occurred,
you should see error messages similar to the example below in the system
log.

    huawei-ups2000: register 2002 has invalid value a000,
    upsd: Data for UPS [huawei] is stale - check driver
    upsd: UPS [huawei] data is no longer stale

So far all known problems have been fixed by the author, but an unknown one
cannot be ruled out. If you have encountered "data stale" problems during
normal uses, please file a bug report with full logs attached.

Before troubleshooting or reporting a problem, it's important to check
your *dmesg* log for USB connect and disconnect events to avoid wasting
time on the NUT driver when the actual problem is USB.

For example, if someone yanks the cable out of the USB port, or if a
new USB device is plugged into a USB host/hub that is struggling to
power its ports (common on single-board computers like Raspberry Pi),
or if you have flaky cabling or EMI noise, due to all these and similar
reasons the serial converter can get disconnected from USB, at least
briefly.

This creates a permanent data stale situation, and the driver must be
restarted (plugging the USB back won't fix it, since the driver is still
using the nonexistent serial device, if the system kernel initializes
a new device driver instance internally).

These USB problems usually have nothing to do with NUT. If it's the case,
you should solve the underlying USB problem -- check the cable, check the
converter, try a powered USB hub, try a full-speed USB isolator, etc.

Serial port becomes unresponsive
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Some malformed commands are known to lock up the serial port (including
USB, which is a USB-to-serial device). Upon receiving them, UPS2000 stops
all serial communications. The result is a completely unresponsive UPS,
regardless of what you do -- restarting NUT, rebooting the computer -- can
not restore connectivity, as if someone has unplugged the RS-232 cable.

To recover, simply power cycle the UPS: Turn off the UPS output via the
front panel, then unplug the UPS from line power. Wait for the LCD front
screen to go black. Finally reconnect line power and restart your UPS.

That being said, a serial port lockup is unlikely to happen. To our best
knowledge, this driver never sends malformed commands to the UPS (it was
only a problem during early development). Furthermore, due to a CRC checksum,
they're unlikely to be accidentally generated.

Still, we recommend to power cycle your UPS after making a cabling change,
especially after changing from RS-485/USB to RS-232, just to ensure the
UPS selects the correct communication interface. Also, if you have
discovered a reproducible serial port lockup problem, it can be a
previously unknown bug, so please make sure to file a bug report.

USB chip (MaxLinear/Exar RX21V1410) is unsupported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As previously stated, only RS-232 is supported on all systems. On
most UPS units, the USB chip RX21V1410 is used, and it requires a
device-specific driver *xr_serial*, which is only available on Linux
5.12 and newer kernels.

On an unsupported system, the USB device can still be recognized as a
USB ACM device, but in reality, communication is impossible. It can
only be fixed by implementing a driver for your system, nothing can
be done within NUT. Please use the RS-232 port instead.

Alternatively, if your unit has a WCH CH341 chip (likely only found in
units made after 2022), it should have better compatibility.

See the previous section *Cabling* for more information.

AUTHOR
------

Yifeng Li <tomli@tomli.me>

SEE ALSO
--------

The core driver:
~~~~~~~~~~~~~~~~

linkman:nutupsdrv[8]

Historical bugs:
~~~~~~~~~~~~~~~~

* Commit: support newer UPS2000G/CH341 variants:
https://github.com/networkupstools/nut/commit/59af0780af0db7341ff81d460fc10736458722aa

* Issue 1846: huawei-ups2000: Data Stale with Endless "Register has a read failure. Retrying..."
https://github.com/networkupstools/nut/issues/1846

* Commit: fix broken timeout recovery behavior in Issue #1846:
https://github.com/networkupstools/nut/commit/3dae58f403f88dace52e2caac3c0690e45b8ef22

* Issue 3244: USB and serial ports work on Linux but not on Windows (file locking):
https://github.com/networkupstools/nut/issues/3244

* Commit: call ser_close() before modbus_connect(), fix #3244:
https://github.com/networkupstools/nut/commit/db2e148503d654726d5520d68e20e71117335813

Windows Drivers:
~~~~~~~~~~~~~~~~

* Huawei UPS2000 (1 kVA-3 kVA) Modbus Protocol Development Guide:
  https://support.huawei.com/enterprise/en/doc/EDOC1000110696
* MaxLinear XR21V1410 Product Page:
  https://www.maxlinear.com/product/interface/uarts/usb-uarts/xr21v1410
* CH341SER.EXE - Nanjing QinHeng Microelectronics Co., Ltd:
  https://www.wch-ic.com/downloads/CH341SER_EXE.html
* CH341SER.ZIP - Nanjing QinHeng Microelectronics Co., Ltd:
  https://www.wch-ic.com/downloads/CH341SER_ZIP.html

If a download link expires, use a snapshot from the Internet Archive:

* XR21x_Win10_V2.7.0.0.zip:
  https://web.archive.org/web/20260310005640if_/https://www.maxlinear.com/Document/index?id=23338&languageid=1033&type=Software%3A%20Drivers&partnumber=XR21V1410
* CH341SER.EXE:
  https://web.archive.org/web/20260112182437if_/https://www.wch-ic.com/download/file?id=65
* CH341SER.ZIP:
  https://web.archive.org/web/20260217145229if_/https://www.wch-ic.com/download/file?id=5

Internet resources:
~~~~~~~~~~~~~~~~~~~

* The NUT (Network UPS Tools) home page: https://www.networkupstools.org/
* Huawei UPS2000-A (1 kVA-3 kVA) User Manual:
  https://support.huawei.com/enterprise/en/doc/EDOC1000084260
* Huawei UPS2000 (1 kVA-3 kVA) Modbus Protocol Development Guide:
  https://support.huawei.com/enterprise/en/doc/EDOC1000110696
* libmodbus home page: http://libmodbus.org
