sync: auto-sync from GURU-5070 at 2026-06-15 18:28:49
Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-15 18:28:49
This commit is contained in:
@@ -51,6 +51,13 @@ controller knows and making prioritized, validated changes. Built for any site;
|
|||||||
```
|
```
|
||||||
Needs a read-only controller admin vaulted at `infrastructure/uos-server-network-api` (the script
|
Needs a read-only controller admin vaulted at `infrastructure/uos-server-network-api` (the script
|
||||||
prints the one-time provisioning steps if it's missing).
|
prints the one-time provisioning steps if it's missing).
|
||||||
|
- **Per-AP live watch (no controller lag)** — SSH straight into an AP and stream channel-busy% +
|
||||||
|
noise + clients/retries every ~2s, to watch a targeted change land in real time:
|
||||||
|
```bash
|
||||||
|
bash .claude/skills/unifi-wifi/scripts/watch-ap.sh <ap-ip> [interval]
|
||||||
|
```
|
||||||
|
Uses `mca-dump` + `iw survey` on the AP. Device-auth cred vaulted (`clients/cascades-tucson/unifi-ap-ssh`).
|
||||||
|
Needs L3 reach to the AP (at Cascades: bring up the site VPN; APs are on 192.168.2.x/3.x) + local `sshpass`.
|
||||||
5. **Interpret** the flags against `methodology.md` (fix order: prune 2.4 -> shrink cells/power ->
|
5. **Interpret** the flags against `methodology.md` (fix order: prune 2.4 -> shrink cells/power ->
|
||||||
min data rates -> manual 1/6/11 plan -> min-RSSI + roaming -> steer to 6GHz).
|
min data rates -> manual 1/6/11 plan -> min-RSSI + roaming -> steer to 6GHz).
|
||||||
3. **Recommend** a prioritized, per-zone change plan. Roll out per zone, not site-wide at once.
|
3. **Recommend** a prioritized, per-zone change plan. Roll out per zone, not site-wide at once.
|
||||||
|
|||||||
45
.claude/skills/unifi-wifi/scripts/watch-ap.sh
Normal file
45
.claude/skills/unifi-wifi/scripts/watch-ap.sh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# watch-ap.sh — live, low-latency RF watch of a UniFi AP straight from the AP (no controller lag).
|
||||||
|
# SSHes into the AP and streams, per radio, every INTERVAL seconds: channel utilization + clients +
|
||||||
|
# tx-retries (from mca-dump) and channel busy% + noise floor (from `iw survey`, diffed). Ideal for
|
||||||
|
# watching an AP react to a targeted change (power/channel/neighbor-disable) in seconds.
|
||||||
|
#
|
||||||
|
# REQUIRES: L3 reach to the AP's mgmt IP. At Cascades the APs are on 192.168.2.x/3.x (mgmt VLANs) —
|
||||||
|
# bring up the Cascades VPN first. Device-auth SSH cred is vaulted (clients/cascades-tucson/unifi-ap-ssh).
|
||||||
|
# Needs `sshpass` locally (UniFi device-auth is password-based). Find AP IPs via:
|
||||||
|
# echo 'db.device.find({site_id:"685f39068e65331c46ef6dd2",type:"uap"},{name:1,ip:1}).forEach(printjson)' | bash .claude/scripts/uos-mongo.sh
|
||||||
|
#
|
||||||
|
# Usage: bash .claude/skills/unifi-wifi/scripts/watch-ap.sh <ap-ip> [interval=2] [vault-path]
|
||||||
|
set -euo pipefail
|
||||||
|
REPO="$(git rev-parse --show-toplevel 2>/dev/null || echo .)"
|
||||||
|
VAULT="$REPO/.claude/scripts/vault.sh"
|
||||||
|
AP="${1:?usage: watch-ap.sh <ap-ip> [interval] [vault-path]}"; INT="${2:-2}"; VP="${3:-clients/cascades-tucson/unifi-ap-ssh}"
|
||||||
|
U="$(bash "$VAULT" get-field "$VP" credentials.username 2>/dev/null)"
|
||||||
|
P="$(bash "$VAULT" get-field "$VP" credentials.password 2>/dev/null)"
|
||||||
|
[ -n "$U" ] && [ -n "$P" ] || { echo "[ERROR] no device-auth cred at vault:$VP"; exit 1; }
|
||||||
|
command -v sshpass >/dev/null || { echo "[ERROR] sshpass not installed (apt-get install sshpass / brew install sshpass)"; exit 1; }
|
||||||
|
|
||||||
|
echo "[INFO] watching $AP every ${INT}s (Ctrl-C to stop). Needs Cascades VPN reach."
|
||||||
|
# Run the sampling loop ON the AP so each tick is one round-trip; mca-dump for cu/clients, iw survey for busy%/noise.
|
||||||
|
SSHPASS="$P" sshpass -e ssh -o ConnectTimeout=8 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||||
|
"$U@$AP" "INT=$INT sh -s" <<'REMOTE' 2>&1 | grep -viE 'Warning: Permanently|pq.html'
|
||||||
|
radios=$(iw dev 2>/dev/null | awk '/Interface/{print $2}' | grep -E 'wifi|ath' || echo "wifi0 wifi1 wifi2")
|
||||||
|
prev=""
|
||||||
|
while :; do
|
||||||
|
ts=$(date +%H:%M:%S)
|
||||||
|
# cu_total + num_sta + tx_retries per radio from mca-dump (JSON; parse with grep/sed, no jq on AP)
|
||||||
|
dump=$(mca-dump 2>/dev/null)
|
||||||
|
for r in $radios; do
|
||||||
|
# iw survey: in-use channel active/busy/noise
|
||||||
|
surv=$(iw dev "$r" survey dump 2>/dev/null | awk '
|
||||||
|
/\[in use\]/{u=1} u&&/frequency/{f=$2} u&&/noise/{n=$2} u&&/channel active time/{a=$4}
|
||||||
|
u&&/channel busy time/{b=$4; print f,n,a,b; u=0}')
|
||||||
|
set -- $surv; freq="${1:-?}"; noise="${2:-?}"; act="${3:-0}"; busy="${4:-0}"
|
||||||
|
key="$r"; pa=$(eval echo \${ACT_$r:-0}); pb=$(eval echo \${BSY_$r:-0})
|
||||||
|
da=$((act-pa)); db=$((busy-pb)); pct="?"; [ "$da" -gt 0 ] 2>/dev/null && pct=$((100*db/da))
|
||||||
|
eval ACT_$r=$act; eval BSY_$r=$busy
|
||||||
|
echo "$ts $r f=${freq} noise=${noise}dBm busy=${pct}%"
|
||||||
|
done
|
||||||
|
sleep "${INT:-2}"
|
||||||
|
done
|
||||||
|
REMOTE
|
||||||
Reference in New Issue
Block a user