Both analyses now accept `--console "<name>"` and run against the UniFi cloud connector instead of the UOS Mongo server, so RF airtime tuning works on standalone/non-UOS consoles (e.g. Brooklyn/Skybar). The UOS Mongo path is unchanged. - New shared analyzer scripts/rf-analyze.py: pulls per-AP/band airtime history via the connector POST /stat/report/hourly.ap (SAME schema as ace_stat.stat_hourly) + /stat/device for names/zones, derives cu_interf = cu_total - cu_self_rx - cu_self_tx, and runs the SAME model-rank ranking and optimize-radios greedy power-down/disable logic (ported faithfully). - Roam graph (/stat/event) is usually empty on small/stationary sites -> graceful degrade: model-rank ranks by airtime pressure; optimize-radios returns power-down candidates + 0 disables (coverage-safe). NEIGHBOR_JSON (SNR matrix) still enables disables, as on UOS. - model-rank.sh / optimize-radios.sh: added the `--console` route (resolves the key from vault services/unifi-site-manager, execs rf-analyze.py). Validated on Brooklyn/Skybar: 2.4GHz saturated (Yoga AP cu 63%/interf 55%), 5GHz idle (1-5%) - the expected pain-band split. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.9 KiB
UniFi Site Manager cloud API + connector (remote, outside-UOS access)
Empirically mapped 2026-06-17 against ACG's live account key (vault
services/unifi-site-manager), corroborated by Grok + Gemini web search.
This is the "access UniFi outside the UOS environment" path, and it reaches
UOS-parity depth for the whole fleet remotely.
Backend script: scripts/gw-sitemanager.sh. Base host: https://api.ui.com.
Auth: header X-API-KEY: <key> (account-level Site Manager key, owner mike@). Read-heavy;
some POST actions exist (device restart, client block) - not wired in yet.
Three tiers
Tier 1 - Site Manager API (/v1/..., cloud, fleet overview)
| Endpoint | Returns |
|---|---|
GET /v1/hosts |
All consoles (id, hardwareId, ipAddress WAN, type, owner, reportedState incl. controllers[] with each app's integrationApis location). 36 for ACG. |
GET /v1/hosts/{id} |
One console detail. |
GET /v1/sites |
Sites across hosts (82): meta, statistics.counts (device/client counts), statistics.gateway (IPS mode/signature), ispInfo (ASN/provider), percentages.txRetry. |
GET /v1/devices |
Per-host device inventory: name, model, ip, status, firmware, uptime, adoption. No RF. |
GET /v1/isp-metrics/{5m|1h} |
Per host/site WAN time-series periods[] (~264): metricTime + data.wan {avgLatency, maxLatency, download_kbps, upload_kbps, packetLoss, uptime, downtime}. Newer gateways (UCG/UDM-SE) populate it; older UDM Pro may report zeros. |
GET /v1/sd-wan-configs |
SD-WAN configs (0 for ACG). |
/ea/* mirrors most of these. Response wrapper: {data, httpStatusCode, traceId} (Site
Manager) ; sub-resource paths like /v1/hosts/{id}/devices 404 - use the flat collections
and filter by hostId.
Tier 2 - Cloud CONNECTOR proxy -> console LOCAL Network API (UOS PARITY)
The key unlock. The account key proxies into each console's local UniFi Network API remotely, no LAN/VPN:
https://api.ui.com/v1/connector/consoles/{consoleId}/proxy/network/<local-path>
{consoleId} = the host id from /v1/hosts. Two sub-surfaces both work:
-
Official Integration API -
/proxy/network/integration/v1/.../info,/sites(returns site UUIDs),/sites/{uuid}/devices,/sites/{uuid}/devices/{id},/sites/{uuid}/devices/{id}/statistics/latest,/sites/{uuid}/clients,/clients/{mac}.- Device
interfaces.radios[]: frequencyGHz, channel, channelWidthMHz, wlanStandard; live stats add txRetriesPct. - Clean/supported but shallower than the internal API (client list lacks RSSI in v1 on Net 10.4).
- Has POST actions: device
/restart, client/block/unblock.
-
Internal stat API -
/proxy/network/api/s/{site}/stat/...(site = short name, usuallydefault)GET .../stat/device-> per-deviceradio_table_stats[]: cu_total (channel utilization = airtime), cu_self_rx, cu_self_tx, channel, last_channel, bw, tx_power, num_sta, satisfaction, tx_retries, tx_retries_pct, ast_txto/ast_cst/ast_be_xmit. == the UOS Mongoace_statdepth.GET .../stat/sta-> per-client: rssi, signal, noise, satisfaction, channel, radio, essid, tx_rate, rx_rate, tx_retries, anomalies.GET .../v2/api/site/{site}/...also reachable.- This is what
gw-sitemanager.sh net <console> radios|clientsuses.
Tier 3 - the OLD path (UOS Mongo ace/ace_stat)
Still used by the rest of the unifi-wifi skill (audit-site.sh, model-rank.sh, etc.) for
UOS-ADOPTED sites. Tier 2 now gives the same data for NON-UOS consoles (and the whole fleet).
Parity verdict
- Tier 1 alone: inventory + health + WAN/ISP telemetry. NOT RF/per-client.
- Tier 2 (connector -> internal stat API): full UOS parity - per-radio airtime/channel/ tx-power and per-client RSSI/satisfaction - for ANY of the 36 consoles, remotely, with the one account key. Broader coverage than UOS (UOS only sees UOS-adopted sites).
Examples
S=.claude/skills/unifi-wifi/scripts/gw-sitemanager.sh
bash $S fleet # all 36 consoles: WAN IP, model, #devices, online
bash $S devices "Brooklyn/Skybar" # device inventory for a console
bash $S sites brooklyn # site health (counts, IPS, ISP)
bash $S isp "CGU-Curves" 5m 12 # WAN latency/throughput history
bash $S net brooklyn radios # DEEP per-AP airtime/channel/txpower (parity)
bash $S net brooklyn clients # DEEP per-client RSSI/signal/satisfaction
bash $S net brooklyn raw /integration/v1/sites # proxy any /proxy/network/... path
Analysis on non-UOS consoles (model-rank / optimize-radios)
The existing airtime-reduction analyses run against cloud-connector data via a --console flag
(UOS-Mongo path unchanged). They pull /stat/report/hourly.ap (same schema as stat_hourly)
through the connector and run the SAME logic via scripts/rf-analyze.py:
bash .claude/skills/unifi-wifi/scripts/model-rank.sh --console "Brooklyn/Skybar" 7 ng
bash .claude/skills/unifi-wifi/scripts/optimize-radios.sh --console "Brooklyn/Skybar" 14 ng
Roam graph is usually EMPTY on small/stationary sites (no /stat/event roam log) -> model-rank
ranks by airtime pressure only; optimize-radios returns power-down candidates and 0 disables
(coverage-safe). For disables, supply NEIGHBOR_JSON (AP-to-AP SNR from neighbor-collect) as on UOS.
Gotchas
- Direct WAN SSH/HTTPS to a standalone UDM is usually firewalled (Brooklyn 67.1.139.219: 22/443/8443 filtered) - the connector is the remote path, not direct.
- Internal stat API uses the site SHORT name (
default), not the integration UUID. Override withnet <c> radios --site <name>for multi-site consoles. - Older gateways report empty ISP metrics; radio/client data still works via the connector.
- Key is account-level (owner). Non-owner/org keys may 403 on some endpoints.
- Sources: developer.ui.com (Site Manager + Network), help.ui.com "Getting Started with the
Official UniFi API", Art-of-WiFi UniFi-API-client (
connect_via_site_manager).