From 89f8ae6a76cb7014ae3c8c1d7c23d32669043b45 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Thu, 16 Apr 2026 23:55:43 +0800 Subject: [PATCH] Preserve WU trends with staged METAR history fallback --- frontend/lib/dashboard-utils.ts | 9 ++++-- src/data_collection/metar_sources.py | 46 ++++++++++++++++++---------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/frontend/lib/dashboard-utils.ts b/frontend/lib/dashboard-utils.ts index a0419292..7c664df1 100644 --- a/frontend/lib/dashboard-utils.ts +++ b/frontend/lib/dashboard-utils.ts @@ -685,8 +685,7 @@ export function getTemperatureChartData( observationCode === "cwa" || observationCode === "noaa" || observationCode === "wunderground"; - const useSettlementObservationSource = - settlementSource && observationCode !== "wunderground"; + const useSettlementObservationSource = settlementSource; const officialObservationSource = useSettlementObservationSource ? detail.settlement_today_obs?.length @@ -733,6 +732,8 @@ export function getTemperatureChartData( officialObservationSource.length > 0 && officialObservationSource.length < 3 && metarObservationSource.length >= 3; + const usingMetarObservationSource = + !useSettlementObservationSource || shouldUseMetarFallback; const observationSource = useSettlementObservationSource ? shouldUseMetarFallback ? metarObservationSource @@ -747,8 +748,10 @@ export function getTemperatureChartData( const observationDisplayTag = usingCurrentObservationFallback ? String(currentFallbackTag).toUpperCase() - : observationCode === "wunderground" + : observationCode === "wunderground" && usingMetarObservationSource ? metarFallbackTag + : observationCode === "wunderground" + ? `WU ${String(detail.risk?.icao || "").trim().toUpperCase() || "STATION"}` : useSettlementObservationSource && shouldUseMetarFallback ? metarFallbackTag : observationCode === "noaa" diff --git a/src/data_collection/metar_sources.py b/src/data_collection/metar_sources.py index 889d783e..3ec7710b 100644 --- a/src/data_collection/metar_sources.py +++ b/src/data_collection/metar_sources.py @@ -106,8 +106,6 @@ class MetarSourceMixin: try: url = "https://aviationweather.gov/api/data/metar" - history_hours = 24 - def _request_metar_records(hours: int, timeout: float) -> list: response = self._http_get( url, @@ -122,23 +120,39 @@ class MetarSourceMixin: payload = response.json() return payload if isinstance(payload, list) else [] - try: - data = _request_metar_records( - history_hours, - getattr(self, "metar_timeout_sec", self.timeout), - ) - except httpx.HTTPError as primary_exc: - history_hours = 2 - logger.warning( - f"METAR {icao} 24h 请求失败,尝试 latest fallback: {primary_exc}" + data = [] + history_hours = 24 + first_exc: Optional[httpx.HTTPError] = None + fallback_hours = [24, 12, 6, 2] + for index, hours in enumerate(fallback_hours): + timeout = ( + getattr(self, "metar_timeout_sec", self.timeout) + if index == 0 + else getattr(self, "metar_latest_timeout_sec", 2.5) ) try: - data = _request_metar_records( - history_hours, - getattr(self, "metar_latest_timeout_sec", 2.5), + data = _request_metar_records(hours, timeout) + history_hours = hours + if index > 0: + logger.warning( + "METAR {} {}h fallback returned {} records", + icao, + hours, + len(data), + ) + break + except httpx.HTTPError as exc: + if first_exc is None: + first_exc = exc + logger.warning( + "METAR {} {}h 请求失败,尝试下一档 fallback: {}", + icao, + hours, + exc, ) - except httpx.HTTPError: - raise primary_exc + else: + if first_exc is not None: + raise first_exc if not data: return None