Wire a USB UPS into Home Assistant with Network UPS Tools (NUT) so you get real on-battery alerts, battery-charge automations, and graceful load shedding—not just a schedule guess.
Load-shedding schedules are useful, but they are still a forecast. A cheap USB UPS plus Network UPS Tools (NUT) tells Home Assistant the truth: the grid just dropped, the battery is draining, and it is time to shed non-essentials before the router dies.
This DIY walkthrough uses official NUT and Home Assistant docs only. You will install a local NUT server (or the Home Assistant Community NUT app), connect the official NUT integration, then build two automations that fire on real power events.
Why NUT beats cloud UPS apps
NUT is an open project that speaks a common protocol to many UPS brands over USB or network. The project’s goal is support for power devices (UPS, PDU, ATS, and related gear) with a uniform monitoring interface. Project home: https://www.networkupstools.org/
Home Assistant’s Network UPS Tools (NUT) integration does not talk to the UPS USB cable directly. It talks to a NUT server over the NUT protocol (default port 3493), then exposes sensors you can automate on. That split is intentional and documented here: https://www.home-assistant.io/integrations/nut/
- Local — no vendor cloud required when the UPS is on USB to your HA host or a LAN NUT server.
- Honest status — sensors such as battery charge (%), battery runtime, input voltage, load (%), and status / status data.
- Hardware check first — confirm your model on NUT’s hardware compatibility list before you buy: https://www.networkupstools.org/stable-hcl.html
What you need
- A USB-HID (or otherwise NUT-supported) UPS sized for your essentials: router, ONT/fibre modem, Home Assistant box, maybe a small AP.
- Home Assistant OS (or any install where you can run a NUT server and the NUT integration).
- USB cable from UPS to the HA host (or a separate always-on machine running NUT in netserver mode).
Keep the UPS load honest. If you park a gaming PC and a kettle on the same 600–1000 VA unit as your network gear, you will get a short, useless runtime. Essentials only.
Step 1: Run a NUT server next to the UPS
On Home Assistant OS, the straightforward path is the Community Network UPS Tools app (add-on). Install it from the Add-on Store, configure users and devices, start it, then note the hostname on the Info tab. Official app docs: https://github.com/hassio-addons/addon-nut/blob/main/nut/DOCS.md (repo: https://github.com/hassio-addons/addon-nut).
A minimal configuration shape from those docs looks like this (use your own username, password, and UPS name — do not copy passwords from blog posts):
- users — one account Home Assistant will use, with instcmds such as all if you want device buttons/actions later.
- devices — name (no spaces), driver (often usbhid-ups for USB HID units), port auto.
- mode — netserver so the app manages the local UPS and accepts clients.
- shutdown_host — keep this false while you test so a UPS event does not halt the HA host by surprise.
If the UPS is not auto-detected, enable list_usb_devices in the app so the log shows connected USB IDs, then pin vendorid / productid in the device config list as shown in the same DOCS.md examples.
Step 2: Add the Home Assistant NUT integration
In Home Assistant: Settings → Devices & services → Add Integration → Network UPS Tools (NUT). Docs: https://www.home-assistant.io/integrations/nut/
- Host — the NUT app hostname from the Info tab (or the static IP / DNS name of an external NUT server).
- Port — 3493 (NUT default).
- Username / password — the NUT user you configured (required for buttons, switches, and device actions that need instcmds).
Important constraints from the integration docs:
- Give the NUT server a static IP, DHCP reservation, or stable DNS name — Home Assistant will not auto-follow an IP change.
- Default polling is every 60 seconds (you can set a custom interval if needed).
- Only sensors your UPS actually reports are created.
After setup, open the UPS device and confirm you see entities such as battery charge, status, and (often) battery runtime. Entity IDs vary by UPS name — check your device page rather than guessing.
Step 3: Automate on real grid loss
Home Assistant’s NUT docs include ready-made automation examples. Copy the YAML into the automation editor (Ctrl+V / Cmd+V converts it to the UI form). Source: https://www.home-assistant.io/integrations/nut/#nut-automation-examples
Notify when the UPS switches to battery
Trigger on the UPS status sensor changing to the documented on-battery state string (example from HA docs: On Battery, Battery Discharging), then send a notification. Adjust the entity ID to match your installation.
Notify (and shed) when battery charge is low
Use a numeric state trigger on battery charge below a threshold you choose (HA’s example uses 25%). That is a better “we are about to die” signal than a fixed clock timer.
For South African load shedding, pair those triggers with actions that actually protect runtime:
- Turn off non-essential smart plugs / switches (heaters, entertainment, pool pump).
- Dim or turn off non-critical lights.
- Keep the UPS feeding only the network stack and Home Assistant.
- Optional: announce on a local media player so people in the house know why things went dark.
State and numeric triggers are covered in the general automation trigger docs: https://www.home-assistant.io/docs/automation/trigger/
Step 4: Load-shedding design tips that actually matter
- Measure, then label — note UPS load (%) and estimated runtime at idle vs with your “essentials only” set. If runtime at 40% load is five minutes, shrink the protected set.
- Prefer local control for shed actions — Zigbee / local MQTT plugs keep working when the ISP path is already dead.
- Do not rely on scheduled shedding alone — schedules miss unplanned outages and late stage changes; NUT status is the ground truth.
- Test safely — pull the UPS input cord once while watching status sensors and your shed automation. Keep shutdown_host false until you deliberately want host shutdown behaviour.
- Buttons and commands need permissions — HA only exposes NUT buttons/switches/actions when credentials are set and the NUT user has instcmds rights (see the integration’s “User credentials and permissions” section).
Troubleshooting quick hits
- From a shell on the NUT host, upsc <upsname> lists live variables; upscmd -l <upsname> lists instant commands — both are documented on the HA NUT integration page.
- Wrong driver? Check NUT’s HCL and try the driver listed for your model rather than forcing usbhid-ups.
- USB permissions / “could not open HID devices” on some hosts: pin vendor/product IDs or follow NUT USB permission guidance for your OS.
What “done” looks like
You are finished when Home Assistant shows live UPS sensors, a test cord-pull flips status to on-battery within a poll cycle, a notification fires, and non-essentials shed while the router and HA stay up on battery. That is load-shedding readiness you can trust — because it is measured, not guessed.
Sources
- Home Assistant NUT integration: https://www.home-assistant.io/integrations/nut/
- NUT project: https://www.networkupstools.org/
- NUT hardware compatibility list: https://www.networkupstools.org/stable-hcl.html
- Home Assistant Community NUT app docs: https://github.com/hassio-addons/addon-nut/blob/main/nut/DOCS.md
- Home Assistant automation triggers: https://www.home-assistant.io/docs/automation/trigger/