mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-06-11 01:14:45 +02:00
refactor: fire digest — tighter format, 220-byte budget, 7d freshness gate
Query now filters out 100% contained and >7d stale fires. Line format uses county-only anchor (no Photon geocoder). Greedy 220-byte packing ensures the digest fits in a single Meshtastic frame. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
862d2dce42
commit
45ca536140
1 changed files with 35 additions and 36 deletions
|
|
@ -82,46 +82,45 @@ async def render_digest(*, now: Optional[int] = None) -> tuple[str, str]:
|
||||||
now = now if now is not None else int(time.time())
|
now = now if now is not None else int(time.time())
|
||||||
conn = get_db()
|
conn = get_db()
|
||||||
|
|
||||||
fires = conn.execute(
|
rows = conn.execute(
|
||||||
"SELECT incident_name, current_acres, current_contained_pct, "
|
"SELECT incident_name, current_acres, current_contained_pct, county, state "
|
||||||
"lat, lon, county, state "
|
"FROM fires WHERE tombstoned_at IS NULL "
|
||||||
"FROM fires "
|
"AND (current_contained_pct IS NULL OR current_contained_pct < 100) "
|
||||||
"WHERE tombstoned_at IS NULL "
|
"AND last_event_at > strftime('%s', 'now', '-7 days') "
|
||||||
"ORDER BY COALESCE(current_acres, 0) DESC LIMIT 20",
|
"ORDER BY current_acres DESC NULLS LAST LIMIT 20"
|
||||||
).fetchall()
|
).fetchall()
|
||||||
|
|
||||||
if not fires:
|
if not rows:
|
||||||
return "", "no_fires"
|
return "", "no_fires"
|
||||||
|
|
||||||
n = len(fires)
|
n = len(rows)
|
||||||
lines: list[str] = []
|
header = f"\U0001f525 Fire Digest \u2014 {n} active wildfire(s) in Idaho"
|
||||||
lines.append(f"\U0001f525 Fire Digest \u2014 {n} active wildfire(s) in Idaho")
|
|
||||||
|
|
||||||
for f in fires[:5]:
|
fire_lines: list[str] = []
|
||||||
name = f["incident_name"] or "(unnamed)"
|
for row in rows:
|
||||||
acres = f["current_acres"]
|
name = row["incident_name"] or "(unnamed)"
|
||||||
contained = f["current_contained_pct"]
|
anchor = f"{row['county']} Co" if row["county"] else row["state"] or ""
|
||||||
|
contained = f"{int(row['current_contained_pct'])}% cont" if row["current_contained_pct"] is not None else "uncontained"
|
||||||
|
acres = f"{int(row['current_acres']):,} ac" if row["current_acres"] else "size unknown"
|
||||||
|
fire_lines.append(f"{name}: {acres}, {contained}, {anchor}")
|
||||||
|
|
||||||
acres_str = f"{int(acres):,} ac" if acres and acres > 0 else "size unknown"
|
# 220-byte budget: greedily fit lines
|
||||||
contained_str = (f"{int(contained)}% contained"
|
shown: list[str] = []
|
||||||
if contained is not None else "containment unknown")
|
for line in fire_lines:
|
||||||
|
remaining = n - len(shown) - 1
|
||||||
|
overflow = f"\n+ {remaining} more" if remaining > 0 else ""
|
||||||
|
candidate = "\n".join([header] + shown + [line]) + overflow
|
||||||
|
if len(candidate.encode("utf-8")) <= 220:
|
||||||
|
shown.append(line)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
remaining = n - len(shown)
|
||||||
|
lines = [header] + shown
|
||||||
|
if remaining > 0:
|
||||||
|
lines.append(f"+ {remaining} more")
|
||||||
|
wire = "\n".join(lines)
|
||||||
|
|
||||||
anchor = _get_anchor(f["lat"], f["lon"])
|
return wire, "deterministic"
|
||||||
if not anchor:
|
|
||||||
county = f["county"]
|
|
||||||
state = f["state"]
|
|
||||||
if county and state:
|
|
||||||
anchor = f"{county} Co {state}"
|
|
||||||
|
|
||||||
parts = [f"{name}: {acres_str}, {contained_str}"]
|
|
||||||
if anchor:
|
|
||||||
parts[0] += f", {anchor}"
|
|
||||||
lines.append(parts[0])
|
|
||||||
|
|
||||||
if n > 5:
|
|
||||||
lines.append(f"+ {n - 5} more")
|
|
||||||
|
|
||||||
return "\n".join(lines), "deterministic"
|
|
||||||
|
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue