Ahmad

Get a UGREEN US3000 UPS reporting properly on TrueNAS SCALE

The built-in NUT driver only reports on-line or on-battery. This installs a community driver that exposes charge, cell voltages and load, and survives TrueNAS updates and reboots.

intermediate30 minupdated 2026-09-12nuttruenasugreenupsDownload script.sh

Before you start

  • TrueNAS SCALE, with the UPS connected by USB
  • A UGREEN US3000 (vendor 2b89, product ffff)
  • Shell access as an administrator; a few checks need root
  • A ZFS pool with somewhere to put the driver so it survives updates

Your values

Fill these in and every command below updates to match. Nothing is sent anywhere.

Run this at your own risk. These steps worked on my hardware; yours may differ. Take a backup first, read each command before running it, and see the disclaimer.

The UGREEN US3000 speaks a proprietary HID protocol on a vendor-defined page rather than the standard Power Device pages. NUT's built-in usbhid-ups driver sees enough to know the UPS exists, but not much else: you get on-line or on-battery and little more. No charge percentage, no cell voltages, no load.

This guide installs a community driver that reads the raw HID reports directly and serves them to NUT properly.

The steps follow the driver project's own documented installation, and the output shown below is from a working install on a DXP4800 Plus. Check the output at each step rather than running the whole thing and hoping.

Check the UPS is actually visible

Before installing anything, confirm the kernel sees the UPS. The US3000 identifies itself with vendor ID 2b89 and product ID ffff.

bash
lsusb | grep -i 2b89
expected output
Bus 001 Device 004: ID 2b89:ffff UGREEN UPS

If nothing comes back, stop here. No driver will help until the USB cable is connected and the device enumerates. Try the other USB port and another cable before assuming a fault.

Understand why the built-in driver is not enough

It is worth knowing why you are installing something custom rather than using what ships with the system, because it affects what to do when TrueNAS updates.

NUT gained proper US3000 support in its Arduino HID subdriver, but that support landed in NUT 2.8.4. TrueNAS SCALE currently bundles an older NUT, so the fix is not available to you yet. When TrueNAS eventually ships a newer NUT, this driver becomes unnecessary and you can remove it.

Also worth knowing: on recent TrueNAS SCALE versions the UPS widget was removed from the dashboard. Its absence is not a symptom of a broken configuration, and chasing it will waste your evening.

Choose a location that survives updates

This is the step people get wrong.

The TrueNAS root filesystem is a ZFS dataset mounted read-only, and /tmp is mounted noexec. You cannot install into either. Anything placed outside a pool is also wiped by a system update.

So the driver goes on a pool, under a path you choose:

bash
mkdir -p /mnt/tank/apps/ugreen-ups-driver
cd /mnt/tank/apps/ugreen-ups-driver

Fetch the driver

If git is available on your build:

bash
cd /mnt/tank/apps/ugreen-ups-driver
git clone https://github.com/meestaben/ugreen-ups-driver.git .

TrueNAS is an appliance and does not guarantee git. If the command is not found, download the archive instead - the result is identical:

bash
cd /mnt/tank/apps/ugreen-ups-driver
curl -L -o ugreen-ups.zip https://github.com/meestaben/ugreen-ups-driver/archive/refs/heads/main.zip
unzip ugreen-ups.zip
mv ugreen-ups-driver-main/* .
rm -rf ugreen-ups-driver-main ugreen-ups.zip

Run the installer

The installer copies the driver into place, generates a systemd service, patches NUT's driver list, configures the TrueNAS UPS service through the middleware API rather than by editing files, and registers a post-init script.

That last part matters: a TrueNAS update reverts changes to the system filesystem, and the post-init script is what puts them back.

bash
cd /mnt/tank/apps/ugreen-ups-driver
chmod +x install-ugreen-ups.sh
./install-ugreen-ups.sh install /mnt/tank/apps/ugreen-ups-driver

Check the service is running

bash
systemctl status ugreen-ups-driver --no-pager
expected output
* ugreen-ups-driver.service - UGREEN US3000 UPS NUT Driver
     Loaded: loaded (/etc/systemd/system/ugreen-ups-driver.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-09-04 10:02:28 CEST; 1 week 1 day ago
   Main PID: 3040 (python3)
      Tasks: 3 (limit: 37555)
     Memory: 8.1M
     CGroup: /system.slice/ugreen-ups-driver.service
             `-3040 /usr/bin/python3 /mnt/tank/apps/ugreen-ups-driver/ugreen_ups_driver.py --port 3494

Two things to read from that. enabled means it will come back after a reboot. And the command line confirms the driver is running from your pool, not from the system filesystem - which is what makes it survive updates.

A warning about journal files needing permissions is normal when you are not root, and does not mean anything is wrong.

Read live values from the UPS

This is the real test. upsc asks NUT for every variable the driver publishes.

bash
upsc ugreen@localhost:3494
expected output
battery.capacity: 43
battery.cell.1.voltage: 4.096
battery.cell.2.voltage: 4.093
battery.cell.3.voltage: 4.091
battery.cell.4.voltage: 4.091
battery.charge: 98
battery.charge.low: 20
battery.voltage: 16.350
battery.voltage.nominal: 14
device.mfr: UGREEN
device.model: US3000
device.type: ups
driver.name: ugreen-hid-py
driver.version: 0.1
input.current: 2.370
input.voltage: 18.765
output.voltage.nominal: 12
ups.load: 0
ups.mfr: UGREEN
ups.model: US3000
ups.status: OL

Your numbers will differ. What matters is that the fields are populated rather than reading unknown, and that ups.status is OL - on line power.

Do not expect mains voltage here. The US3000 sits between a DC power brick and the NAS, so input.voltage is the DC feed (around 19 V) and output.voltage.nominal is what it supplies to the NAS (12 V). Seeing 18 V rather than 230 V is correct, not a fault.

Note also that there is no battery.runtime field. Estimate remaining time from battery.charge and battery.capacity instead.

To watch it live while you pull the plug and put it back:

bash
journalctl -u ugreen-ups-driver -f

About the NUT configuration

The installer writes the NUT side for you through the TrueNAS middleware, so there is normally nothing to edit by hand.

Reading those files needs root - a plain admin account gets Permission denied on /etc/nut/ups.conf, which is expected rather than a problem.

The arrangement is deliberately indirect: the Python driver talks to the hardware and publishes on its own port, and NUT reads from that port. That indirection is what lets this work without patching NUT itself.

Reboot and check it comes back

Do not skip this. A UPS driver that works until the next reboot is worse than no UPS driver, because you will believe you are protected when you are not.

Reboot however you normally would - from the TrueNAS web interface, or from a shell:

bash
sudo reboot

After it comes back up:

bash
systemctl status ugreen-ups-driver --no-pager
upsc ugreen@localhost:3494 ups.status

Removing it later

When TrueNAS ships NUT 2.8.4 or newer, the built-in usbhid-ups driver should handle this UPS and you can take the custom driver out.

bash
Destructive command. Read it before running it. This can delete data or interrupt service.
cd /mnt/tank/apps/ugreen-ups-driver
./install-ugreen-ups.sh uninstall /mnt/tank/apps/ugreen-ups-driver

A note on other models in the range

If you run a second UPS on a second NAS, the two are independent NUT masters rather than a master and a slave. They do not need to know about each other.

Other models in the same range do not necessarily share the US3000's HID report layout, so the byte offsets this driver reads may not line up on a different unit. Expect to have to map them yourself if you try.