Add connected clients popup per AP

Clicking an AP name opens a modal showing all wireless clients currently
associated with that AP: hostname/MAC, IP, SSID, band, channel, signal
strength with quality label, TX/RX link rate, and connection uptime.

Backend: GET /api/ap-clients?mac=&site_key= calls the Omada clients
endpoint with filters.apMac; falls back to client-side filtering if the
controller doesn't support that query param.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-27 15:12:59 +02:00
parent f4ac0857b4
commit 47f553f410
3 changed files with 188 additions and 1 deletions

View File

@@ -188,6 +188,27 @@ class OmadaClient:
return int(device.get("uptimeLong", 0))
raise RuntimeError(f"AP {mac} not found in site {site_key}")
async def get_ap_clients(self, ap_mac: str, site_key: str) -> list[dict]:
"""Fetch wireless clients currently connected to a specific AP."""
await self._ensure_ready()
norm_mac = ap_mac.upper().replace("-", ":")
try:
data = await self._request_with_retry(
"GET",
f"{OMADA_BASE_URL}/{self._omadac_id}/api/v2/sites/{site_key}/clients",
params={"page": 1, "pageSize": 200, "filters.active": "true", "filters.apMac": ap_mac},
)
except RuntimeError:
# Older firmware may not support filters.apMac — fall back and filter client-side
data = await self._request_with_retry(
"GET",
f"{OMADA_BASE_URL}/{self._omadac_id}/api/v2/sites/{site_key}/clients",
params={"page": 1, "pageSize": 200, "filters.active": "true"},
)
result = data.get("result", {})
clients = result.get("data", []) if isinstance(result, dict) else (result if isinstance(result, list) else [])
return [c for c in clients if c.get("apMac", "").upper().replace("-", ":") == norm_mac]
async def reboot_ap(self, mac: str, site_key: str, min_uptime: int = 300) -> dict:
await self._ensure_ready()
uptime = await self._get_ap_uptime(mac, site_key)