t3chnaztea/unifi-skills/unifi-wifi
Claude Code and agent skill by t3chnaztea/unifi-skills
- community
Checking that the SKILL.md file is still in the repository.
Use when UniFi Wi-Fi is slow, unstable, or being tuned: "my wifi is slow but speedtest on the router is fast", "great signal, terrible speed", "should I use 80MHz or 40MHz", "channel planning", "co-channel interference", "DFS channels", "my APs keep picking the same channel", "audit my SSIDs", "hidden SSID", or diagnosing throughput that collapses under load. Also roaming: "my phone stays stuck on the far AP", "sticky clients", "improve roaming", "should I enable fast roaming", "minimum RSSI", "TX power tuning". Covers the diagnostic ladder for slow Wi-Fi, channel width and DFS tradeoffs, safe radio writes, cell sizing and roaming persuasion, SSID hygiene, and the in-wall AP port trap. Assumes unifi-connect. Not for firewall policy between networks (unifi-firewall), wired port and client operations (unifi-clients).
Install
npx vskill@latest install t3chnaztea/unifi-skills/unifi-wifiSKILL.md
UniFi Wi-Fi
Most "slow Wi-Fi" is not slow Wi-Fi. It is a WAN problem, a backhaul problem, a client problem, or a bandwidth cap somebody set two years ago. The diagnostic ladder below exists to find that out cheaply, in that order, before touching radios. Radio changes are the most disruptive and the most often wrong.
The diagnostic ladder
Run it top to bottom. Each rung eliminates a layer, and the failure that motivated this skill was only visible at the last rung.
1. Rule out the WAN. Trigger a gateway-side speedtest, which measures the gateway to the internet with no Wi-Fi involved:
The result lands on the gateway's device object, under the hyphenated key speedtest-status (not speedtest_status), with throughput in the nested xput_download and xput_upload fields. status_summary tells you whether the run finished; a fresh gateway that has never run one reports zeros. stat/health is a different number entirely and will send you in circles.
2. Check the AP's uplink. An AP on a 100 Mbps link, or meshed rather than wired, caps every client behind it:
3. Check the client's own view. Signal, negotiated rate, satisfaction:
This rung is where the interesting case appears. A client at -57 dBm with an 866 Mbps PHY rate has an excellent link. If it measures 32 Mbps, the radio is fine and something is contending. Signal is not throughput, and confusing the two is why people replace working access points.
4. Rule out a bandwidth cap. Somebody, possibly you, may have set one:
5. Compare every AP's channel, width, and channel utilization. The last rung, and the one that finds co-channel contention:
Field names matter here and are not the obvious ones. Channel width is `bw`, not channel_width. The names are per object, not global: on a client record the same value really is channel_width. Check the object you are reading rather than carrying a field name across from another endpoint. cu_total is channel utilization, the percentage of airtime in use, and it is the closest thing to a direct measurement of the problem this skill is about. cu_self_tx and cu_self_rx break out how much of that is this AP's own traffic: high `cu_total` with low `cu_self_*` means somebody else is using your airtime, which is either a neighbor or, more often, your own AP two rooms away on the same channel.
satisfaction reports -1 when a radio has no clients on it. That is "no data", not "terrible".
Read radio_table_stats, the operational state, not radio_table, the config. They disagree more often than you would like.
The 80 MHz trap
The failure that motivated this skill, because it is a change that looks free.
Setting every 5 GHz radio to 80 MHz doubles the theoretical per-client rate, so it reads like a pure upgrade. It is not, because width is bought with channels. In the US regulatory domain, 80 MHz with DFS channels disabled leaves exactly two non-overlapping blocks:
- UNII-1: channels 36 / 40 / 44 / 48
- UNII-3: channels 149 / 153 / 157 / 161
Two blocks. If you have more than two 5 GHz APs with overlapping coverage, some of them are sharing an 80 MHz block and taking turns transmitting. Wi-Fi degrades gracefully in signal terms and catastrophically in contention terms: everything looks healthy right up until two clients are busy simultaneously.
The observed case: four APs, three of them in-wall units on adjacent walls, all piled into UNII-1 after a global switch to 80 MHz. Result was roughly 32 Mbps on a gigabit connection, with an 866 Mbps PHY link at -57 dBm and a confirmed 1276 Mbps gateway speedtest. Neither ISP, backhaul, nor signal was the cap.
Do not disable DFS channels when auditing a channel plan. It is the change that creates the pileup. DFS is the difference between two usable 80 MHz blocks and six.
Pick a block, not a channel
At 80 MHz a radio occupies its whole block, so two APs on different channels in the same block are fully co-channel with each other. This is the mistake to avoid when spreading APs out: moving an AP from 48 to 104 accomplishes nothing if another AP already sits on 100.
US 80 MHz blocks:
| Block | Channels | DFS? | |
|---|---|---|---|
| UNII-1 | 36, 40, 44, 48 | no | |
| 52, 56, 60, 64 | yes | ||
| 100, 104, 108, 112 | yes | ||
| 116, 120, 124, 128 | yes, and see below | ||
| 132, 136, 140, 144 | yes | ||
| UNII-3 | 149, 153, 157, 161 | no |
Map what you have to blocks before choosing a target, because the channel numbers hide the collision:
Prefer 52-64, 100-112, and 132-144 when you need free blocks. The 116-128 block overlaps terminal doppler weather radar (TDWR, 5600-5650 MHz) in the US, where a CAC can run ten minutes instead of one, and the channels are sometimes unavailable outright. An 80 MHz block anchored at 116 spans 116/120/124/128 = 5570-5650 MHz, so it swallows the whole TDWR sub-band: at 80 MHz you cannot sit near 116 without sitting in it.
If an AP keeps falling off a DFS channel, stop restarting it
An AP assigned a DFS channel can run there for a week or two, hit a radar detection (real or false), quietly move to a non-DFS channel, and keep reporting the assigned channel in its config the whole time. Nothing alarms, nothing logs it, and rest/device echoes back whatever you last wrote. One deployment sat like this for twelve days: config said 116, the radio was on 149, stacked on top of two APs already sharing the 149-161 block, at 33% and 30% channel utilization while every other AP sat at 1-2%. Every check had read the config.
Restarting puts it back and buys another week or two, which is treating the symptom. If a radio keeps getting pushed off the same block, the block is wrong for that site. Retire it and take an extra co-channel share instead. Moving that AP to a non-DFS block took it from 33% to 7% utilization and its neighbour from 21% to 12%. A share you chose beats a channel the AP cannot hold, so pair whichever APs are furthest apart physically: different floors beats different rooms.
Audit live-vs-config, not either one alone, on a schedule rather than only after a write. A radio that drifts once will drift again.
The tradeoff is real and worth stating honestly: DFS channels require radar detection, cost a ~50-60 second silent scan when a radio moves onto one, and some older or cheap client devices will not associate on them at all. Weigh that against four APs sharing one block. In a dense deployment, 40 MHz on non-overlapping channels beats 80 MHz on shared ones, every time.
Changing a radio channel safely
Read and write are different endpoints. This one costs people an hour:
GET rest/device returns an empty list on Network 10.4.57, with or without a device id appended, exactly like rest/firewallrule in unifi-firewall. It is not broken and your key is fine: reads live on stat/device. An agent that GETs rest/device, sees [], and concludes the controller has no devices is on the wrong endpoint.
The write body that works is the radio table alone, sent complete:
Verified on Network 10.4.57: this preserves the radio you did not touch. You do not need to send the entire device object back, and you should not, because stat/device hands you a pile of read-only operational fields along with the config.
Send the full `radio_table` array. A partial write drops the fields you omitted, including transmit power and width on the other radio.
`channel` may read `auto` in config while `radio_table_stats` shows a real number. Those are both correct: the AP is auto-selecting and has landed somewhere. Writing a concrete channel silently opts that radio out of automatic selection, which is usually what you want for a deliberate plan, but it is a second change riding along with the first. Know you are making it.
Moving onto a DFS channel triggers a CAC (channel availability check) and the radio goes silent for it. Two moves observed on Network 10.4.57 took roughly 45 and 105 seconds, so budget more than a minute and do not conclude the write failed at the 60-second mark. Clients drop and reconnect once. Do it when nobody is on a call.
The two directions are not equally hard. Moving off a DFS channel onto a non-DFS one is easy: one observed move settled about 75 seconds after a force-provision, no restart, clients reassociating on their own. Moving onto a DFS channel is where it sticks, and a force-provision can leave the radio on its old channel indefinitely; an AP restart (cmd/devmgr restart, ~2.5 minutes offline) is what finally lands it after CAC. If a non-DFS move needs a restart, something else is wrong. Go look rather than power-cycling.
Verify from `radio_table_stats`, never the PUT echo, and read state rather than just channel:
state | Meaning | |
|---|---|---|
RUN | on air and serving | |
DFS_WAIT | mid-CAC, silent, this is the normal DFS transition | |
INIT | not on air |
A radio still reporting the old channel with state: RUN has not moved yet. One in DFS_WAIT is moving and needs more time.
Roaming
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/unifi-wifi/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/t3chnaztea/unifi-skills/unifi-wifi)