Skip to main content

Ubiquiti UniFi Network

The UniFi Network driver connects GEM to a Ubiquiti UniFi Network controller for two things:

  • Internet / WAN status. Whether the site is online, which WAN is carrying traffic, whether it has failed over to a backup WAN, the public IP and ISP, latency and availability. Each WAN can also be its own zone.
  • UniFi managed switch control (USW / Pro / Enterprise). Turn PoE on or off per port, power-cycle a powered device, enable or disable a port, and reboot the switch, plus read each port's live PoE draw and link state.

The classic switch use is putting the power to a PoE camera, access point, or PoE-powered display under automation. The classic WAN use is a trigger that alerts or changes behaviour when the internet drops or the site fails over to its backup line.

This driver was called UniFi Switch (unifi_switch) before WAN status was added.

Point at the controller, not the switch

GEM talks to your UniFi Network controller: the UniFi OS console (UDM, UDM Pro, UDR, UCG, Cloud Key Gen2+) or a self-hosted UniFi Network application. It does not talk to a switch's own IP. A switch is identified by its MAC address, and all commands flow through the controller's local API.

Prerequisites​

  • A UniFi Network controller, reachable from the GEM controller over HTTPS (default 443 on a UniFi OS console, 8443 on a self-hosted standalone controller).
  • Credentials, one of:
    • An API key (UniFi OS consoles, Network 9.3 or newer). Create it in the console under Settings → Control Plane → Integrations. One key covers WAN status and switch control. This is the preferred option.
    • A local admin account on the controller. Ubiquiti SSO / cloud accounts and any account with multi-factor authentication are rejected by the local API. A self-hosted standalone controller has no API keys, so it always needs this.
  • For WAN status: a UniFi gateway at the site (UDM, UCG, UXG, USG). A site behind a non-UniFi router has no WAN data to read.
  • For switch control: the switch's MAC address, in colon-separated form (aa:bb:cc:dd:ee:ff). Find it in the UniFi UI under Devices → (the switch) → Overview, or read it back from GEM with the get_devices command below.

Setup​

  1. Create the device. Go to System → Devices (Open Devices), add a device, and set Driver to unifi_network. Set Enabled to Yes.
  2. Fill in the connection fields:
    • Controller IP / Host (ip) — the LAN address of the UniFi controller. Not the switch.
    • API Key (api_key) — on a UniFi OS console, paste the key here and leave the username and password empty. Stored encrypted.
    • Admin Username (username) and Admin Password (password) — the local admin account, if you aren't using an API key. The password is stored encrypted.
    • Switch MAC Address (device_mac) — the MAC of the switch whose ports you want to control, e.g. aa:bb:cc:dd:ee:ff. Leave it blank for WAN status only.
    • Controller Port (port) — leave at 443 for a UniFi OS console; set 8443 for a self-hosted standalone controller.
    • UniFi OS Console (unifi_os) — leave on for UDM / UDM Pro / UDR / Cloud Key Gen2+. Turn it off only for a standalone self-hosted UniFi Network application.
    • Site (site) — leave as default unless your controller manages multiple sites, in which case enter the site's short-name (see troubleshooting).
  3. Save. GEM connects to the controller and starts reading WAN status, and polling the switch if one is set. Confirm the device comes up connected and that internet_online and active_wan appear in its attributes.
  4. Find the MAC if you don't have it. From System → Commands (Open Commands) or the Script Console, run get_devices against the device to list every adopted device (name, model, MAC). Copy the switch's MAC into Switch MAC Address if you left it blank.
  5. Map ports to zones (next section) — one zone per port you want to control or monitor.
Verify from the Script Console
await gem.command({device_id: <device_id>, command: 'get_device'});

This returns the switch record the driver is tracking, including its port_table. If it comes back with data, the login and MAC are correct.

WAN status​

WAN status needs no setup beyond the connection. Once a minute (wan_interval), GEM reads the controller's site health, the gateway's WAN ports and the configured WANs, and writes these device attributes. Each is written only when it changes, so attribute history and triggers see transitions, not a stream of identical values.

AttributeMeaning
internet_onlinetrue while the controller's internet check passes or any WAN is online
active_wanName of the WAN carrying traffic, e.g. Internet 1. Empty when none is
wan_failovertrue while traffic runs on a WAN other than the one with the highest failover priority
wan_statusThe controller's WAN health: ok, warning, error or unknown
wan_ipPublic IP of the active WAN
isp_nameThe ISP the controller identifies for the active WAN
wan_latencyCurrent internet latency, ms
wan_availabilityThe active WAN's availability over the last 24 hours, %

GEM logs one line when the internet drops or comes back, and when the active WAN changes.

A zone per WAN​

To put each WAN on a UI or watch it on its own, give it a zone. Open the device's Setup tab and click Discover, which lists the WANs and creates a zone for each one you tick. To add one by hand, create a zone with Address set to the WAN's network group: WAN for the first WAN, WAN2 for the second, and so on. Pick whatever subsystem suits; a Network subsystem is a natural home.

Zone attributeMeaning
stateonline, offline, or unknown (nothing reported, e.g. a WAN with nothing plugged in)
activetrue for the WAN carrying traffic
wan_ip, isp_nameThat WAN's public IP and ISP
latencyThat WAN's latency, ms
availabilityThat WAN's availability over the last 24 hours, %
link_speed, link_upThe gateway port's link speed (Mbps) and whether the link is up

Mapping ports to zones​

This driver does not create zones automatically — you add one zone per port you care about. Each zone's Address is the port number printed on the switch faceplate (1-based), and that port number is how every command targets the port.

  1. Go to System → Zones (Open Zones) and add a zone.
  2. Pick the UniFi switch as the zone's Device. The Subsystem pre-selects Power (one of the default subsystems); leave it there unless you have a reason to file the port elsewhere.
  3. Set Address to the faceplate port number — e.g. 4 for port 4.
  4. Port Type (port_type) — an optional zone attribute:
    • poe (default) — the zone's on/off state tracks whether the port is delivering PoE. Use this for PoE cameras, APs, and PoE displays.
    • data — the zone's state tracks whether the port's link is up. Use this for a non-PoE port you only want to enable/disable or monitor.
  5. Save. On the next poll the zone picks up its live state, poe_power, and link_up values.

Once a port is a zone, it behaves like any other on/off zone: it can sit on a UI as a toggle, be switched from a macro, or be driven by a trigger. On a control that offers a port picker, the port commands bind to the zone's address automatically.

What on / off actually do​

On/off writes a persistent change to the controller

on / off (and their explicit forms port_poe_enable / port_poe_disable) change the port's PoE override in the controller's configuration — exactly as if you toggled PoE for that port in the UniFi UI. The change persists until something sets it back. Turning a zone off cuts PoE and powers down whatever the port feeds; turning it back on restores PoE (auto mode).

To momentarily reboot a stuck powered device without changing its configured PoE state, use port_poe_cycle instead — it issues a one-shot power-cycle and leaves the port's saved settings untouched.

port_enable / port_disable are the separate data-forwarding override — they administratively bring the port up or down (forward = all vs disabled), independent of PoE. reboot_switch restarts the entire switch and briefly drops every port on it, so treat it as a deliberate operator action, not routine automation.

Device attributes​

AttributeLabelTypeDefaultNotes
ipController IP / Hoststring—LAN IP/hostname of the UniFi controller (required)
api_keyAPI Keystring (secure)—UniFi OS API key; when set, username/password are not used
usernameAdmin Usernamestring—Local admin account (when not using an API key)
passwordAdmin Passwordstring (secure)—Stored encrypted (when not using an API key)
device_macSwitch MAC Addressstring—Switch MAC, aa:bb:cc:dd:ee:ff. Needed only for switch control
portController Portint443443 for UniFi OS, 8443 for standalone
unifi_osUniFi OS ConsolebooltrueOff for a self-hosted standalone controller
siteSitestringdefaultController site short-name
status_intervalStatus Poll Interval (ms)int30000How often port state is refreshed
wan_monitoringWAN MonitoringbooltrueOff stops WAN polling
wan_intervalWAN Poll Interval (ms)int60000How often WAN status is refreshed; minimum 10000

Zone attributes​

AttributeTypeNotes
addressintFaceplate port number, 1-based (required). WAN zones use the network group instead (see A zone per WAN)
port_typestringpoe (default) tracks PoE power as state; data tracks link up/down
statestringon / off, set by polling — on when the port is delivering PoE (poe zones) or the link is up (data zones)
poe_powerfloatLive PoE draw on the port, in watts
link_upboolWhether the port's link is up

Commands​

CommandEffect
on / port_poe_enableEnable PoE on the port (poe_mode = auto). Persistent override. address = port number
off / port_poe_disableDisable PoE on the port (poe_mode = off), cutting power to the device. Persistent override
port_poe_cycleOne-shot power-cycle of the port's PoE — reboots the powered device without changing its saved settings
port_enableAdministratively enable the port (data forwarding = all). Persistent override
port_disableAdministratively disable the port (data forwarding = disabled). Persistent override
reboot_switchReboot the entire switch — drops every port, use deliberately
get_devicesList every device the controller has adopted (name, model, MAC) — use to find the switch MAC
get_deviceReturn the tracked switch record, including its port table
get_clientsList clients currently connected to the site
loginForce a fresh login to the controller (does nothing with an API key)
get_wanRead WAN status now: the summary plus each WAN's state, IP, ISP, latency and availability
get_healthThe controller's raw site health (stat/health)

The five port commands take address = the port number; on a control they bind to the zone's address so a port picker is offered. With a username and password, the session cookie and CSRF token are refreshed automatically, and the driver logs in again on its own if the controller expires the session. With an API key there is no session: the key goes on every request.

Controller API reference​

Useful when you are matching GEM's behavior to what you see in the UniFi controller. Paths differ between a UniFi OS console and a standalone controller — GEM chooses automatically from the UniFi OS Console toggle:

ActionUniFi OS consoleStandalone controller
LoginPOST /api/auth/loginPOST /api/login
Site path prefix/proxy/network/api/s/<site>/api/s/<site>
List devices<site>/stat/devicesame
The switch record<site>/stat/device/<mac>same
PoE / port overridePUT <site>/rest/device/<id> with port_overridessame
Power-cycle a portPOST <site>/cmd/devmgr {cmd: power-cycle, mac, port_idx}same
Reboot the switchPOST <site>/cmd/devmgr {cmd: restart, mac}same
Site health (WAN / internet)<site>/stat/healthsame
The gateway (WAN ports)<site>/stat/device/<gateway mac>same
Configured WANs/proxy/network/v2/api/site/<site>/wan/enriched-configuration/v2/api/site/<site>/wan/enriched-configuration
API keyX-API-KEY: <key> header on every requestnot available

The controller's TLS certificate is self-signed, so GEM does not verify it — point the device at a controller IP you control on a trusted LAN.

Automation ideas​

  • Know when the internet drops. A trigger on internet_online becoming false can send a notification over a path that doesn't need the internet (local display, SMS gateway), or switch the site to a degraded mode.
  • Know when you've failed over. A trigger on wan_failover becoming true can warn that the site is running on its backup line, which may be metered or slower.
  • Bounce a hung camera or AP. A trigger on a camera going offline, or a scheduled overnight maintenance macro, can run port_poe_cycle on that port to power-cycle the device without touching its configured PoE state.
  • Power a display or sign with the room. Wire a PoE display to a switch port, make it a poe zone, and let a room's on/off scene turn the port on and off with everything else.
  • Load shedding. Turn off non-essential PoE ports (signage, secondary APs) from an "away" or energy-saving macro, and on again when the site is occupied.
  • Watch PoE draw. poe_power records each port's wattage over time — history charts show consumption and can flag a device drawing more than expected.

Troubleshooting​

SymptomCheck
Device won't connect / login fails with 400 or 401You're using a Ubiquiti SSO / cloud or MFA account — the local API only accepts a local admin account. Create one on the controller, or use an API key.
http 401 — the controller refused the API keyThe key was deleted or mistyped. Create a new one under Settings → Control Plane → Integrations. A standalone controller has no API keys; use a local admin username and password.
No WAN attributes appearThe site needs a UniFi gateway. Run get_wan to see what the controller reports, and check WAN Monitoring is on.
A WAN zone stays unknownNothing is plugged into that WAN, or its Address doesn't match a network group (WAN, WAN2, …). get_wan lists the ids.
Connects but no port data / device not foundSwitch MAC Address must be the switch's MAC, colon-separated (case and surrounding spaces are ignored). Run get_devices to confirm the MAC.
A command answers controller error: api.err.…The controller accepted the request but refused it (for example an unknown device or an invalid port setting). The message is the controller's own; nothing was changed.
get_devices comes back emptyWrong Site short-name. The default site's short-name is literally default; for multi-site controllers, check the site's short-name in the UniFi UI.
Everything times out / wrong page returnedCheck the Controller Port and UniFi OS Console toggle match your controller — 443 + on for a UniFi OS console, 8443 + off for a standalone controller.
A port override seems to have no effectSome models ignore a port override until the port has a port profile assigned. Check Devices → (switch) → Ports in the UniFi UI.
Zone state doesn't updateConfirm the zone Address is the faceplate port number and that the port appears in the switch's port table (get_device).
  • Devices — adding the UniFi controller as a device and editing its connection settings.
  • Zones — creating one zone per port and setting each zone's address and Port Type.
  • Subsystems — the Power subsystem port zones file under, and where to add a Network subsystem for WAN zones.
  • Commands — running get_devices, port_poe_cycle, and the rest by hand to verify the link.
  • Device Health — watching the switch's connection state.
  • Macros and Triggers — power-cycling ports and shedding PoE loads on a schedule or in response to events.
  • UniFi Protect — the companion driver for Ubiquiti's Protect cameras/NVR.
  • UniFi Access and UniFi Presence — the other UniFi drivers.