v0.11.0: new celestrak_tle adapter + CENTRAL_SAT satellite-tracking stream (#100)

This commit is contained in:
malice 2026-06-09 00:54:19 -06:00 committed by GitHub
commit 621148ac46
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1067 additions and 4 deletions

View file

@ -135,6 +135,7 @@ Central's archive.
| `CENTRAL_TRAFFIC_FLOW` | `central.traffic_flow.>` | 7 | 1 GiB | ✓ | ✓ |
| `CENTRAL_TRAFFIC_CAMERAS` | `central.traffic_cameras.>` | 7 | 1 GiB | ✓ | ✓ |
| `CENTRAL_AVY` | `central.avy.>` | 7 | 1 GiB | ✓ | ✓ |
| `CENTRAL_SAT` | `central.sat.>` | 7 | 1 GiB | ✓ | ✓ |
| `CENTRAL_META` | `central.meta.>` | 1 | 1 GiB | — | ✓ |
Retention and storage caps are migration-seeded defaults visible in `config.streams`;
@ -1831,6 +1832,44 @@ at parameter `00060`, gage height (ft) at `00065`, water temperature (°C) at
\
---
### celestrak_tle — CelesTrak satellite TLEs (v0.11.0)
- **Source:** `https://celestrak.org/NORAD/elements/gp.php?GROUP=<group>&FORMAT=TLE`
per configured group (defaults: `stations`, `weather`, `amateur`), plus
per-CATNR endpoint for operator-pinned `extra_norad_ids`. 4h cadence
(CelesTrak refreshes ~8h).
- **Stream:** `CENTRAL_SAT` (`central.sat.>`)
- **Subject:** `central.sat.tle.<norad_id>` — one subject per satellite,
globally. No state coord (orbital state is universal). Consumers
compute passes locally with their own observer geolocation
(e.g. satellite.js + `navigator.geolocation`).
- **Dedup key shape:** `<norad_id>:<epoch_iso>` — re-fetching the same TLE
is swallowed; CelesTrak issues a new epoch every ~8h and that produces
a fresh dedup key, naturally triggering a republish.
- **Severity:** `1` (informational; no alerting).
- **Geo:** intentionally empty (`Geo()`). TLEs are global orbital state,
not a surface point — consumers propagate the orbit at observe time.
- **Event.data fields:**
| Field | Type | Notes |
|---|---|---|
| `norad_id` | int | Satellite catalog number (e.g. 25544 for ISS) |
| `satellite_name` | string | Upstream display name |
| `tle_line1`, `tle_line2` | string | Raw 69-char TLE strings; pass to satellite-js verbatim |
| `epoch` | string | ISO datetime decoded from Line 1 cols 19-32 (YYDDD.DDDDDDDD; Y2K rule 00-56 = 2000s, 57-99 = 1957-1999) |
| `classification` | string | `U` / `C` / `S` (almost always U) |
| `intl_designator` | string | International designator e.g. `1998-067A` (ISS) — but in the packed TLE form (`98067A`) |
| `source_url` | string | The exact URL the TLE was fetched from |
- **`_enriched.orbit`:** parsed straight from Line 2 columns when valid:
`inclination_deg`, `mean_motion_rev_per_day`, `eccentricity` (the
implicit-leading-0. is reconstructed). Absent if Line 2 fails to parse.
- **Group/extras dedup:** if a satellite appears in two configured groups
or in both a group and `extra_norad_ids`, it's fetched **once** (first
occurrence wins).
\
---
## 7. Fall-off / removal semantics
Central adapters fall into three buckets for handling upstream events that