GET /api/satellites?groups=stations,weather returns last-known satellite
positions propagated from CelesTrak GP JSON (OMM mean elements, not TLE)
via the real sgp4 library (TEME->geodetic), not two-body Kepler.
- Fetch gp.php?GROUP=...&FORMAT=JSON at most once per 2h per group,
cached with a last-good blob fallback for 403 / stale responses.
- SatNOGS TLE fallback only when the CelesTrak cache is empty.
- bbox viewport culling; unknown group -> 400.
- overlay_catalog() gains id=satellites (kind=points, /api/satellites).
- OMM path handles NORAD cat numbers >= 100000 (no TLE round-trip).
Wire the free data streams from docs/free-data-streams.md into the
dashboard as layer-panel toggles. Third-party APIs are proxied/cached
in FastAPI; raster tiles (IEM, RainViewer, GIBS) stay in the browser.
- Aircraft via ADSB.lol viewport poll (bbox required, radius ≤ 150 nm)
- Amtraker trains, NHC storms, WFIGS incidents/perimeters
- NWS + IEM SBW as /api/weather-alerts (does not collide with /api/alerts)
- AISStream worker is server-side only and idles without AISSTREAM_API_KEY
- Caltrans CWWP2 D1–D12 camera parser; FIRMS dual-write NOAA-20/21