I (Claude) wrote an custom integration for UGREEN charger:
It was built against a UGREEN Nexode Pro 300W (X783) — the desk charger with
the little display, sold as *Nexode Pro Smart Display Desktop Charger, 300W,
8-Port, GaN*. X783 is the code the app knows it by; it is not printed on the box.
Why a cloud integration
I went looking for a local one first. A full TCP 1–65535 scan of the charger
finds nothing open, there is no mDNS and no SSDP, and the only local control it
offers is BLE. Its one outbound path is UGREEN’s own cloud, so short of putting
a Bluetooth proxy next to the desk, this is the way in.
Two clouds are actually involved: an account API that hands out the device list,
and an RTCX gateway that carries telemetry. Readings are not exposed as named
properties — the charger tunnels a small binary protocol through a single
property, PT_data, and you write a query frame to get an answer back. The
frame format, byte offsets and command set are all written up in the repo for
anyone who wants to check the work or port it to another model.
What you get
42 entities on the 8-port model.
Readings:
-
power, voltage, current - one each per port: C1 to C6, A1, DC
-
protocol - what each port negotiated: PD, PPS, QC, AFC, FCP, UFCS, AVS
-
total power - sum across ports, with firmware and Wi-Fi SSID in its attributes
-
cloud status - online or offline
-
firmware - installed version, and whether an update is waiting
Controls:
-
screen brightness - 0 to 100 %
-
screen off time - 1, 5, 10, 30 minutes, or always on
-
charging mode - adaptive power, thermal safe, DC turbo, priority
-
screensaver - on/off, time format, clock style, wallpaper
Every write is read back from the device on the next poll rather than assumed,
and the choices match the app’s own, so the two agree on screen.
The screensaver card
The charger’s display is 560×170, and the app has a whole panel for it. The
integration ships a card that does the same job, so you do not have to reach for
the phone to change the clock or the picture.
The strip at the top is a live preview of what the charger will actually show.
Upload a picture opens a crop window over your own photo — drag, zoom and
rotate — because at 3.3:1 a photo almost never suits the screen as taken.
The card is served by the integration itself, so there is no second HACS entry
and no Lovelace resource to register. One line of YAML:
type: custom:ugreen-wallpaper-card
Install
HACS → three-dot menu → Custom repositories → s1mptom/ugreen_connect, type
Integration → install → restart → add it from Devices & Services. You sign
in with your normal UGREEN account and pick your region.
It is submitted to the HACS default store;
until that is merged, the custom-repository route above is the way in.
There is also a ready-made dashboard in the repo (docs/dashboard.yaml) — the
one in the screenshot, which fits a laptop screen without scrolling. One heads
up on it: the power-history card is statistics-graph-chart-card from HACS. If
you do not have that, only that card errors and the rest is fine — delete it, or
swap in the built-in history-graph with the same entities.
Worth knowing before you install
- Cloud polling. Five seconds by default, which keeps the wattage live
enough to watch a laptop charge, and is also a lot of traffic against someone
else’s API. There is an options flow to raise it.
- The phone app caches. Change something from Home Assistant and the app
will keep showing its old value until you force-stop and reopen it. Home
Assistant reads live; the app does not.
- No temperature, no energy counter. The device’s TSL model declares a pile
of properties it never populates. For the Energy dashboard, a Riemann-sum
helper over total power is the usual workaround.
Other models
I only have the one charger, so the port table and the byte offsets are specific
to the 300W eight-port model — that is the first thing another one will
disagree about. If you have a different UGREEN charger and are willing to try
it, a diagnostics download (credentials redacted) is the most useful thing to
attach to an issue.
