Client disconnect RCA for Juniper Mist. Paste an Observer (read-only) API token, pick a site and client MAC, and get a verdict that correlates RF, 802.11 reason codes, DHCP/DNS, Marvis, Radio Management occupancy, 7-day radio events (including Post radar / DFS), and Microsoft Teams / Zoom calls.
Latest: v1.2.2 — lockfile sync so a clean install can publish.
Click Run sample investigation on the home page to walk the demo with no token. Sample data uses fictional DEMO-AP-F2-* names only.
Publish install fix only. No RCA engine change.
| Fix | Why |
|---|---|
| Lockfile in sync | A clean npm ci failed (ajv 6 vs 8). The companion site can install and publish again. |
Bug fixes on the v1.2 radar store.
| Fix | Why |
|---|---|
| One radar banner | Mist often returns the same association twice (connect times a fraction of a second apart). One DFS hit is now one Alert · session on radar AP card. |
| Radio events full screen | Expand the 7-day table so every kept event is reachable. |
| Diagnose fetch hint | A busy site (lots of devices and radio events) can take up to 60 seconds. |
| Teams timestamps | Millisecond call start/end still overlap same-AP radar. |
Code fixes. Same-AP radar correlation still requires a session on the AP that took DFS; neighbor radar is not a hit.
| Fix | Why |
|---|---|
| RadioEventStore | Site RRM cannot filter by AP. Correlation now looks up radars by the session AP (and radio_stat BSSID aliases) instead of scanning the firehose. |
| Time-sliced fetch | 24h / 7d lookbacks are split into windows so a radar storm in the last hour cannot hide a hit from hour 18. |
| Scrollable client-radar panel | Dedicated “Radar hits on this client’s APs” table. Banner and radio-event tables scroll — the matching DFS row is no longer off-screen. |
| Open-session overlap | Mist disconnect: 0 is treated as still associated. RRM ap / ap_mac / BSSID aliases are accepted. |
| Faster login and live | Token validate is /self only. Live polls walk the newest hour of RRM, not the full 7-day page walk. |
Python --self-test covers a buried client DFS among 2,000 neighbor radars, BSSID-family match, and disconnect: 0.
| Feature | Why it matters |
|---|---|
| Alert · session on radar AP | If a client session was associated to the AP that took a DFS / Post radar hit, a pulsing banner names that session and that exact radio event. Juniper’s RRM docs: the AP deauthenticates every associated station. |
| Same-AP gate | Radar on a neighbor, or on today’s serving AP when the client was elsewhere, is not a correlation. Session AP at the radar timestamp must equal the radar AP. |
| Exact rows under the banner | The matching session (connect / disconnect / AP / SSID / band) and the matching Radio Event (date, channel 36 → 149, width, power, Post radar) are drawn under the alert — not just a paragraph. |
| 7-day Radio Events | Same source as Mist Site → Radio Management → Radio Events. The API requires band; the console fetches 5, 24, and 6 in parallel (5 GHz paginated — that is where DFS lives). Labels match the portal: Post radar, Interference AP non wifi, Scheduled site RRM. |
| Teams / Zoom (7 days) | Call window, meeting id, audio/video quality. A Teams meeting in progress during same-AP Post radar is highlighted as the media failure. |
| Full session list | Every association in the window, newest first, scrollable table. Rows that overlapped radar on that AP are tagged radar. |
| CLIENT_IP_ASSIGNED is OK | DHCP Success / IP Assigned are positive events (Mist Insights). Only timed-out / denied / terminated / bad-IP are FAIL. |
No pip packages. Windows, macOS, and Linux.
git clone https://github.com/InterconnectedSystems/lilac-lilac-maple-ruby.git
cd lilac-lilac-maple-ruby
# Windows
py -3 mist_disconnect_console.py
# macOS / Linux
python3 mist_disconnect_console.pyIt opens a local browser page. Ctrl+C stops the server. The API token is sent from the browser to this process, then to Mist over HTTPS GET — it is not written to disk.
python3 mist_disconnect_console.py --self-testThe Vite / React tree in this repo is the published companion UI. v1.2.1 engine and UI fixes are in mist_disconnect_console.py and src/lib/mist/radio.ts. Use the Python command above for the local RCA engine.
git clone https://github.com/InterconnectedSystems/lilac-lilac-maple-ruby.git
cd lilac-lilac-maple-ruby
npm install
npm run devCaptured from the built-in sample investigation (Sample HQ — Floor 2, fictional APs).
| Desktop | iPhone |
|---|---|
![]() |
![]() |
The console only issues GET requests. Use an Observer / read-only token from Organization → Settings → API Tokens. Org Admin and write-enabled keys do not belong here.
The banner is the first thing on the board when a session was on the radar AP.
| Verdict | Phone fold |
|---|---|
![]() |
![]() |
Radar and Teams cards include the call name, meeting id, session AP, radar timestamp, and pre → post channel.
Same stacked histogram Mist shows under Site → Radio Management → Current Radio Values.
| Color | Meaning |
|---|---|
| Orange | Site APs |
| Teal | External APs |
| Red | Non-Wi-Fi interference |
| Client events | Marvis |
|---|---|
![]() |
![]() |
CLIENT_IP_ASSIGNED shows OK. DHCP timed out / denied stay FAIL.
- Connect — Select the Mist region (default
api.gc2.mist.com) and paste an Observer token./selfvalidates the org. - Scope — Pick org, site, client MAC, and lookback (
1h/6h/1d/1w). - Diagnose — Per-MAC stats, events, all sessions (paginated), Marvis, AP inventory, occupancy, RRM events by band (time-sliced), Teams/Zoom calls.
- Alert — If a session covered a Post radar / radar-detected event on that same AP, the banner shows that session and that radio row.
- Verdict — Score + primary cause + same-AP radar / Teams correlations.
- Live monitor — Re-query stats/events plus the newest hour of radio events. Auto-pauses on Mist HTTP 429.
| Signal | Gate |
|---|---|
| Post radar / DFS on the AP this session was on | Session connect…disconnect covers the radar timestamp and session.ap (or BSSID family) equals the radar AP |
| Teams/Zoom in progress during that radar | Call window overlaps the radar time and same-AP gate |
| RSSI / SNR vs deauth reason | Coverage vs idle timeout vs handshake |
| DHCP / DNS after roam or assoc | Failures only (not IP Assigned) |
| AP ping-pong and 5 → 2.4 | Sticky / oscillating client |
| Serving-AP occupancy | Site vs external vs non-Wi-Fi |
| RRM power / channel change | Client associated to that AP at the change |
| Marvis narrative | Names the AP the client used most of the time |
A radar event on a different AP than the session is dropped. Same channel on another AP is coincidence, not a cause.
The histogram is this AP’s 20-minute RRM scan (/sites/{id}/rrm/current/devices/{device}/band/{band}).
Radio Events are GET /sites/{id}/rrm/events?band={5\|24\|6} with start/end matching the lookback (band is required; 400 valid band is required otherwise).
| Step | Endpoint |
|---|---|
| Validate token | GET /self |
| List sites | GET /orgs/{org}/sites |
| Live client | GET /sites/{site}/stats/clients/{mac} |
| Client search / events / sessions | GET /sites/{site}/clients/search, .../clients/{mac}/events, .../clients/sessions/search |
| Marvis | GET /orgs/{org}/troubleshoot |
| AP inventory + stats | GET /sites/{site}/devices?type=ap, GET /sites/{site}/stats/devices |
| Occupancy | GET /sites/{site}/rrm/current/devices/{device}/band/{24|5|6} |
| Radio events | GET /sites/{site}/rrm/events?band={24|5|6}&start=&end= |
| Teams / Zoom | GET /sites/{site}/stats/calls/search?mac={mac}&duration=7d |
No configuration is written. The token stays in the browser tab and is never stored in a database.
- Create the key under Organization → Settings → API Tokens with Observer privileges.
- Default region is
api.gc2.mist.com. - Never paste Org Admin, Super User, or write-enabled keys.
mist_disconnect_console.py v1.2.1 RCA engine (stdlib only) — start here
src/lib/mist/radio.ts published companion radar store (same rules)
screenshots/ sample investigation captures (fictional DEMO-AP-F2 names)
src/ published web companion













