mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-06-11 01:14:45 +02:00
feat: fire halt broadcast + tombstone all-clear (wildfire_halted / wildfire_closed)
Enable _maybe_emit_halt in firms_handler (remove return None stub) so fires with no FIRMS hotspot activity beyond halt_minimum_seconds emit a routine wildfire_halted broadcast. Add tombstone all-clear in wfigs_handler: when a fire is tombstoned and has last_broadcast_at set (i.e. previously made it to mesh), broadcast a wildfire_closed message with acres, containment, and location. Fires that were never broadcast are silently consumed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3ff819eed9
commit
f4930a388f
2 changed files with 34 additions and 1 deletions
|
|
@ -774,7 +774,6 @@ def _maybe_emit_halt(conn, *, data, now):
|
|||
eligible because we filter on `halt_broadcast_at IS NULL OR
|
||||
halt_broadcast_at < last_pass_at`.
|
||||
"""
|
||||
return None
|
||||
minimum_s = int(adapter_config.fires.halt_minimum_seconds)
|
||||
cutoff = float(now) - float(minimum_s)
|
||||
row = conn.execute(
|
||||
|
|
|
|||
|
|
@ -116,6 +116,40 @@ def handle_wfigs(normalized: dict, envelope: dict, subject: str,
|
|||
)
|
||||
except Exception:
|
||||
logger.exception("wfigs: tombstoned_at stamp failed irwin=%s", irwin_id)
|
||||
|
||||
# All-clear broadcast: only fires that previously made it to mesh
|
||||
# get a closure message. Silent for fires that were never broadcast.
|
||||
if kind == "wfigs_tombstone" and irwin_id:
|
||||
fire_row = conn.execute(
|
||||
"SELECT incident_name, current_acres, current_contained_pct, "
|
||||
"last_broadcast_at, county, state, lat, lon "
|
||||
"FROM fires WHERE irwin_id = ?", (irwin_id,)
|
||||
).fetchone()
|
||||
if fire_row is not None and fire_row["last_broadcast_at"] is not None:
|
||||
name = fire_row["incident_name"] or "(unnamed fire)"
|
||||
# Build line 2 parts
|
||||
parts = []
|
||||
if fire_row["current_acres"] is not None:
|
||||
parts.append(f"{int(fire_row['current_acres']):,} ac")
|
||||
if fire_row["current_contained_pct"] is not None:
|
||||
parts.append(f"{int(fire_row['current_contained_pct'])}% contained")
|
||||
# Location via _location_anchor with a minimal normalized dict
|
||||
loc_dict = {
|
||||
"lat": fire_row["lat"], "lon": fire_row["lon"],
|
||||
"county": fire_row["county"], "state": fire_row["state"],
|
||||
}
|
||||
anchor = _location_anchor(loc_dict)
|
||||
if anchor and anchor != "(location unknown)":
|
||||
parts.append(anchor)
|
||||
lines = [f"✅ {name} — contained & closed"]
|
||||
if parts:
|
||||
lines.append(" | ".join(parts))
|
||||
wire = "\n".join(lines)
|
||||
if isinstance(data, dict):
|
||||
data["category"] = "wildfire_closed"
|
||||
data["_severity_override"] = "routine"
|
||||
return wire
|
||||
|
||||
return None
|
||||
|
||||
# ---- active incident ----
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue