Backfill runway history from latest AMSC overlay

This commit is contained in:
2569718930@qq.com
2026-06-15 19:20:22 +08:00
parent 56f397bb2e
commit 791b2d115f
2 changed files with 48 additions and 1 deletions
+10
View File
@@ -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():
+38 -1
View File
@@ -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)