Backfill runway history from latest AMSC overlay
This commit is contained in:
@@ -49,6 +49,8 @@ def test_overlay_replaces_amos_when_old_local_time_string_looks_later_than_new_u
|
||||
|
||||
|
||||
def test_overlay_appends_latest_amsc_points_to_runway_history():
|
||||
runway_writes = []
|
||||
|
||||
class FakeDB:
|
||||
def get_latest_raw_observation(self, source, city):
|
||||
assert (source, city) == ("amsc_awos", "chengdu")
|
||||
@@ -83,6 +85,9 @@ def test_overlay_appends_latest_amsc_points_to_runway_history():
|
||||
},
|
||||
}
|
||||
|
||||
def append_runway_obs(self, **kwargs):
|
||||
runway_writes.append(kwargs)
|
||||
|
||||
stale_payload = {
|
||||
"name": "chengdu",
|
||||
"temp_symbol": "°C",
|
||||
@@ -105,6 +110,11 @@ def test_overlay_appends_latest_amsc_points_to_runway_history():
|
||||
"time": "2026-06-15T10:51:00+00:00",
|
||||
"temp": 28.1,
|
||||
}
|
||||
assert [(row["icao"], row["runway"], row["otime_utc"]) for row in runway_writes] == [
|
||||
("ZUUU", "02L/20R", "2026-06-15T10:51:00+00:00"),
|
||||
("ZUUU", "02R/20L", "2026-06-15T10:51:00+00:00"),
|
||||
]
|
||||
assert runway_writes[0]["target_runway_max"] == 28.4
|
||||
|
||||
|
||||
def test_overlay_uses_latest_success_when_newer_status_row_has_no_observation():
|
||||
|
||||
@@ -88,6 +88,15 @@ def _to_float(value: Any) -> Optional[float]:
|
||||
return None
|
||||
|
||||
|
||||
def _to_int(value: Any) -> Optional[int]:
|
||||
try:
|
||||
if value is None or value == "":
|
||||
return None
|
||||
return int(float(value))
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
def _amsc_payload_has_observation(raw_payload: dict[str, Any]) -> bool:
|
||||
temp = raw_payload.get("temp_c") if raw_payload.get("temp_c") is not None else raw_payload.get("temp")
|
||||
return _to_float(temp) is not None
|
||||
@@ -200,6 +209,8 @@ def _runway_history_temp(point: dict[str, Any]) -> Optional[float]:
|
||||
|
||||
|
||||
def _append_latest_amsc_runway_history(
|
||||
db: Any,
|
||||
city: str,
|
||||
payload: dict[str, Any],
|
||||
row: dict[str, Any],
|
||||
raw_payload: dict[str, Any],
|
||||
@@ -226,6 +237,8 @@ def _append_latest_amsc_runway_history(
|
||||
history = deepcopy(history)
|
||||
|
||||
use_fahrenheit = "F" in str(payload.get("temp_symbol") or "").upper()
|
||||
appender = getattr(db, "append_runway_obs", None)
|
||||
icao = str(raw_payload.get("icao") or row.get("station_code") or "").strip().upper()
|
||||
changed = False
|
||||
for point in point_temperatures:
|
||||
if not isinstance(point, dict):
|
||||
@@ -262,6 +275,30 @@ def _append_latest_amsc_runway_history(
|
||||
runway_history.append(entry)
|
||||
changed = True
|
||||
history[runway] = runway_history
|
||||
if callable(appender) and icao:
|
||||
try:
|
||||
appender(
|
||||
icao=icao,
|
||||
city=city,
|
||||
runway=runway,
|
||||
tdz_temp=_to_float(point.get("tdz_temp")),
|
||||
mid_temp=_to_float(point.get("mid_temp")),
|
||||
end_temp=_to_float(point.get("end_temp")),
|
||||
target_runway_max=_to_float(point.get("target_runway_max")),
|
||||
wind_dir=_to_int(point.get("wind_dir")),
|
||||
wind_speed=_to_float(point.get("wind_speed")),
|
||||
rvr=_to_int(point.get("rvr")),
|
||||
mor=_to_float(point.get("mor")),
|
||||
humidity=_to_float(point.get("humidity")),
|
||||
otime_utc=observed_at,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.debug(
|
||||
"latest AMSC runway history persist skipped city={} runway={}: {}",
|
||||
city,
|
||||
runway,
|
||||
exc,
|
||||
)
|
||||
|
||||
if changed:
|
||||
payload["runway_plate_history"] = history
|
||||
@@ -297,7 +334,7 @@ def overlay_latest_amsc_observation(
|
||||
for key in ("current", "airport_primary", "airport_current"):
|
||||
changed = _merge_observation_block(next_payload, key, update, raw_epoch) or changed
|
||||
|
||||
changed = _append_latest_amsc_runway_history(next_payload, row, raw_payload) or changed
|
||||
changed = _append_latest_amsc_runway_history(db, normalized_city, next_payload, row, raw_payload) or changed
|
||||
|
||||
canonical = next_payload.get("canonical_temperature")
|
||||
canonical_epoch = _block_epoch(canonical)
|
||||
|
||||
Reference in New Issue
Block a user