mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-06-10 17:04:45 +02:00
1 commit
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 8b2cdeee0b |
feat(notifications): Phase 2.14 USGS earthquake adapter (new) -- closes Rule 16 Seismic standalone path
First net-new environmental adapter (prior phases wired existing ones). Adds meshai/env/usgs_quake.py with USGSQuakeAdapter + USGSQuakeConfig, polling a keyless USGS earthquake GeoJSON feed and emitting one Event per qualifying quake. Establishes the standalone Seismic path (Rule 16); Central becomes the dual-source in v0.4. Adapter (mirrors the fires/usgs-water per-event pattern): - Feed: https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson (M2.5+ past day -- M1.0 too noisy, M4.5+ too sparse for the region). Tick 300s. - Filters each feature by min_magnitude AND a geographic bbox. - Per quake: source=usgs_quake, category=earthquake_event, stable event_id = the USGS feature id (e.g. "us6000abcd"), lat/lon from geometry.coordinates[1],[0], region tag from config (default "magic_valley"). - to_event(): category earthquake_event, magnitude-binned severity passed through, group_key = inhibit_key = the USGS id. Defensive None for missing id / coords / magnitude. get_events()/health_status mirror the other adapters. MAGNITUDE -> SEVERITY BINS (as proposed): M < 3.5 -> routine 3.5 <= M < 5.0 -> priority M >= 5.0 -> immediate ('sig' is captured in the event dict as metadata but severity is magnitude-binned -- clearer and matches the spec's primary suggestion.) GEOGRAPHIC BBOX (as proposed) -- [west, south, east, north]: [-115.5, 42.0, -110.0, 45.2] Covers Magic Valley / Twin Falls (SW), the Lost River Range / Borah Peak and Sawtooths (central Idaho, seismically active -- 1983 M6.9), the eastern Snake River Plain / INL, and the Yellowstone caldera (NW Wyoming). An empty bbox disables the geographic filter (accepts all). Wiring: - config.py: new USGSQuakeConfig dataclass; usgs_quake field on EnvironmentalConfig; loader branch in _dict_to_dataclass. - store.py __init__: registers self._adapters["usgs_quake"] when enabled -- this is what grows the live adapter count 7 -> 8. - store._ingest: NO dedicated branch added. usgs_quake is a standard per-event adapter, so the existing generic "else" loop (dedup on (source, event_id) + _emit_event) already routes it. (The swpc/ducting branches are special only because they also maintain status blobs.) - env_feeds.yaml (live /data/config): added usgs_quake block, enabled:true, default bbox/min_mag/region. Rule 17: GUI-editable config (env_feeds.yaml). Rule 18 N/A -- USGS earthquake feed is keyless (no .env entry; .ref credentials has no USGS/ArcGIS/quake key). Rule 16: standalone path established + validated in-container. Tests: tests/test_adapter_usgs_quake.py (15 tests) mirrors the 2.12/2.13 shape -- severity bins, _fetch severity assignment, magnitude filter, geographic filter (in-bbox vs California/out), empty-bbox-accepts-all, dedup id stable across ticks for the same quake id, category, severity pass-through, group_key/inhibit_keys, field population, defensive cases (missing id/coords/magnitude/corrupted -> None), and malformed-feature skipping. _fetch tests patch urlopen with synthetic FeatureCollections. Full suite: 248 passed. Live smoke test (prod container, rebuilt): clean startup, adapter count grew 7 -> 8 ("EnvironmentalStore initialized with 8 adapters"), healthy, no traceback, no usgs_quake errors. In-container standalone tick over the real feed succeeded (is_loaded=true, last_error=null, consecutive_errors=0); the feed returned 54 global M2.5+ quakes, 0 inside the Magic Valley->Yellowstone bbox right now (quiet) -- so no Event is emitted, acceptable, and it exercises the fetch + magnitude + geographic filter + no-emit path on live data. The emission path (in-region quake -> earthquake_event) is unit-validated and uses the same store->bus path emitting live for NWS, traffic, and NIFC fires. Note (.gitignore): line 36 `env/` (a virtualenv pattern under "Virtual environments") collaterally matches meshai/env/, so this NEW file required `git add -f` (untracked files there are otherwise ignored and hidden from status). Existing tracked env files are unaffected. Recommended follow-up: anchor the rule to `/env/` so future net-new env adapters don't need -f. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |