mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-08-17 16:07:24 +02:00
feat(flights): cumulative fuel burned + CO2 emitted per flight
Pre-fix the emissions tooltip only showed the per-hour *rate* — what most users actually want is the cumulative *amount* burned. This adds running totals computed by multiplying the model-based rate by the elapsed observation time since we first saw the airframe. New module ``flight_observations.py``: * Tracks first_seen_at + last_seen_at per icao24 hex. * Re-opens a fresh session when an aircraft is unseen for > 15 min (treated as a new flight — landed and took off, or transited a dead zone). Prevents the cumulative counter from resetting mid-flight if the trail-rendering cache prunes the trail. * Clamps elapsed time to 24h max so clock skew can't produce comically large numbers. * Pruned every 5 min via a new scheduler job (mirrors ais_prune cadence). flights.py + military.py emission enrichment now also attaches: * observed_seconds — how long we've been tracking this airframe. * fuel_gallons_burned — rate * elapsed_h. * co2_kg_emitted — rate * elapsed_h. The existing per-hour rate fields stay in the dict for backward compat and are shown as small secondary context in the tooltip. Frontend EmissionsEstimateBlock (NewsFeed.tsx) now prominently shows the cumulative totals with the rate as smaller context underneath plus "Observed in flight for Xh Ym". When observed_seconds is 0 (first refresh) it renders "Just observed · totals will appear on next refresh" instead of a misleading "0 gal". 12 backend tests cover record/accumulate/reset, the 24h clamp, prune, case-insensitive key normalization, and end-to-end emission integration in _classify_and_publish. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
20807a2d62
commit
03b8053617
@@ -17,6 +17,7 @@ from services.network_utils import fetch_with_curl
|
||||
from services.fetchers._store import latest_data, _data_lock, _mark_fresh
|
||||
from services.fetchers.plane_alert import enrich_with_plane_alert, enrich_with_tracked_names
|
||||
from services.fetchers.emissions import get_emissions_info
|
||||
from services.fetchers.flight_observations import record_observation as _record_flight_observation
|
||||
from services.fetchers.retry import with_retry
|
||||
from services.fetchers.route_database import lookup_route
|
||||
from services.fetchers.aircraft_database import lookup_aircraft_type
|
||||
@@ -601,6 +602,22 @@ def _classify_and_publish(all_adsb_flights):
|
||||
if model:
|
||||
emi = get_emissions_info(model)
|
||||
if emi:
|
||||
# Cumulative fuel/CO2: multiply the per-hour rate by how
|
||||
# long we've been observing this airframe. Users want to
|
||||
# see the *amount* burned, not just the rate. If we've
|
||||
# never seen this hex before, observed_seconds is 0 and
|
||||
# the cumulative values are 0 until the next refresh —
|
||||
# the rate is still useful info on its own.
|
||||
observed_seconds = _record_flight_observation(
|
||||
f.get("icao24") or ""
|
||||
)
|
||||
elapsed_h = observed_seconds / 3600.0
|
||||
emi = {
|
||||
**emi,
|
||||
"observed_seconds": observed_seconds,
|
||||
"fuel_gallons_burned": round(emi["fuel_gph"] * elapsed_h, 1),
|
||||
"co2_kg_emitted": round(emi["co2_kg_per_hour"] * elapsed_h, 1),
|
||||
}
|
||||
f["emissions"] = emi
|
||||
|
||||
callsign = f.get("callsign", "").strip().upper()
|
||||
|
||||
Reference in New Issue
Block a user