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:
2026-06-15 18:29:02 -07:00
parent ca548687e7
commit 9a2f806c67
2 changed files with 52 additions and 0 deletions

View File

@@ -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.

View 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