sync: auto-sync from GURU-5070 at 2026-06-15 18:03:38

Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-15 18:03:38
This commit is contained in:
2026-06-15 18:03:55 -07:00
parent 236604924a
commit f6bd451d52
2 changed files with 64 additions and 0 deletions

View File

@@ -15,6 +15,9 @@ controller knows and making prioritized, validated changes. Built for any site;
to read it (the two planes: Mongo config/interference now, live Network API later).
- **[references/methodology.md](references/methodology.md)** — the prioritized tuning playbook
(synthesized from a multi-model pass + live recon). Read before recommending any change.
- **[references/interference-model.md](references/interference-model.md)** — design for the
AP-interference / airtime-reduction model (which radios to disable / power down), incl. the data
feasibility (needs Plane 2 + a collector — the signals aren't in Mongo).
## What it does (current = Plane 1, read-only)
1. **Audit a site** — config + interference, no live plane needed:

View File

@@ -0,0 +1,61 @@
# AP interference / airtime-reduction model — design + data feasibility
Goal (per Mike): a fleet/site-level model that decides **which AP radios to disable, and where to
reduce power**, to cut total airtime contention while preserving client coverage. Per AP **per
radio, all bands** (not 2.4-only, not per-client). Inputs: each AP's view of neighboring APs (RF)
+ historical client connections.
## Data feasibility (probed on Cascades 2026-06-15)
| Signal the model wants | In Mongo `ace`? | Source to use |
|---|---|---|
| **Our AP ↔ our AP RF visibility** (A hears B at RSSI r) | **NO**`rogue` is FOREIGN APs only; our managed APs are filtered out (0 rows match our SSIDs) | **Live Network API** `stat/device` neighbor table / triggered RF scan (Plane 2) |
| **Historical client→AP connections / roam overlap** | **NO**`user` keeps only `last_uplink_mac` (last AP); no sessions, `alarm` empty, `stat` collections empty | **Accumulated `stat/sta` polling** over time (Plane 2 + a collector) |
| **Physical AP coordinates** | **NO** — 0 APs placed on the 1 floorplan | derive coarse topology from **AP names** (room#/floor encoded) |
| Radio config (channel/band/width/power/min_rssi) | **YES** | Mongo `device.radio_table` (Plane 1) |
| Foreign interference per channel | **YES** | Mongo `rogue` aggregate (Plane 1) |
**Conclusion:** the interference graph the model needs (our-AP mutual RSSI + client overlap)
**cannot** be built from Mongo. It requires **Plane 2 (the live Network API)** plus a **collector**
that accumulates snapshots over time. Mongo gives config + foreign-interference + (via names) a
coarse topology prior to seed the model before enough live data is collected.
## Model design
Per band `b` (ng/na/6e), build a weighted graph over AP radios:
- **Nodes:** each AP's radio on band `b`.
- **RF edges** `w_rf(A,B)`: from the live neighbor table — how strongly A hears B (and vice-versa),
scaled up when same/overlapping channel. Strong mutual RSSI on the same channel = high
co-channel interference.
- **Overlap edges** `w_ov(A,B)`: fraction of clients that have associated with BOTH A and B over
the collection window (built by snapshotting `stat/sta` every N minutes). High overlap = they
cover the same space → one is redundant.
- **Per-radio metrics:** `load` (num_sta, live `cu_total`), `unique_coverage` (clients only this
radio serves at good RSSI), `interference_contribution` (Σ strong RF edges on same channel).
**Recommendation logic (greedy, coverage-safe):**
1. **Disable a radio** when: high `interference_contribution` AND high `coverage_redundancy`
(its clients keep good signal from neighbors) AND `unique_coverage ≈ 0`. Disable the worst
offender, recompute the graph, repeat until a redundancy floor is hit (don't open holes).
2. **Reduce power** when interference is high but `unique_coverage > 0` (can't disable without a
hole) — shrink the cell to cut contention while keeping coverage.
3. **Leave** radios that carry unique coverage and contribute little interference.
Band weighting: 2.4 prunes most aggressively (most redundant + least capacity value); 5/6 lighter;
6GHz usually keep (clean band, steer up). Output = ranked per-AP-per-radio actions with the metric
that justified each, applied **per zone** with live before/after validation.
## Prerequisites to build it (the real next step)
1. **Wire Plane 2** — provision a dedicated **read-only UniFi admin or Network integration API key**
on `.29` (doable with our root SSH), vault as `infrastructure/uos-server-network-api`. Gives
`stat/device` (live neighbor RSSI, `cu_total`, `num_sta`, satisfaction) + `stat/sta` (client→AP).
2. **Stand up a collector** — a periodic job (cron on `.30`/a fleet host) snapshotting
`stat/device` + `stat/sta` into a small store (sqlite/postgres). The **overlap + RF matrix
accrue over the collection window** (a week+ gives a usable model; longer = better). This is the
"historical look at devices connected" Mike asked for — the controller doesn't retain it, so we
accumulate it ourselves.
3. **Build the model** on the accumulated data; seed early recommendations from the Mongo config +
AP-name topology prior until enough live data exists.
## Status
Phase 1 (config + foreign-interference audit) is built (`scripts/audit-site.sh`). The interference
model is **blocked on Plane 2 + the collector** — needs a go to provision the UniFi API account and
stand up the collector.