diff --git a/bot_listener.py b/bot_listener.py index 57ef55b1..f9dab39d 100644 --- a/bot_listener.py +++ b/bot_listener.py @@ -349,7 +349,7 @@ def start_bot(): ) open_meteo = weather_data.get("open-meteo", {}) metar = weather_data.get("metar", {}) - mgm = weather_data.get("mgm", {}) + mgm = weather_data.get("mgm") or {} # 数值归一化 def _sf(v): diff --git a/src/analysis/trend_engine.py b/src/analysis/trend_engine.py index 51c98326..fdbe83aa 100644 --- a/src/analysis/trend_engine.py +++ b/src/analysis/trend_engine.py @@ -60,6 +60,7 @@ def analyze_weather_trend( metar = weather_data.get("metar", {}) open_meteo = weather_data.get("open-meteo", {}) + mgm = weather_data.get("mgm") or {} mb = weather_data.get("meteoblue", {}) nws = weather_data.get("nws", {}) @@ -82,6 +83,10 @@ def analyze_weather_trend( current_forecasts["Meteoblue"] = _sf(mb.get("today_high")) if nws.get("today_high") is not None: current_forecasts["NWS"] = _sf(nws.get("today_high")) + + mgm = weather_data.get("mgm", {}) + if mgm and mgm.get("today_high") is not None: + current_forecasts["MGM"] = _sf(mgm.get("today_high")) mm_forecasts = weather_data.get("multi_model", {}).get("forecasts", {}) for m_name, m_val in mm_forecasts.items(): diff --git a/src/data_collection/weather_sources.py b/src/data_collection/weather_sources.py index e0c820f1..3df6635e 100644 --- a/src/data_collection/weather_sources.py +++ b/src/data_collection/weather_sources.py @@ -506,16 +506,24 @@ class WeatherDataCollector: if daily_resp.status_code == 200: forecasts = daily_resp.json() if forecasts and isinstance(forecasts, list): + # Store today extra clearly today = forecasts[0] high_val = today.get("enYuksekGun1") low_val = today.get("enDusukGun1") if high_val is not None: results["today_high"] = high_val results["today_low"] = low_val - logger.info( - f"📋 MGM 每日预报: 最高 {high_val}°C, 最低 {low_val}°C (from {forecast_url})" - ) - break + logger.info(f"📋 MGM 每日预报: 今天的最高温 {high_val}°C") + + # Store all 5 days for multi_model_daily + results["daily_forecasts"] = {} + for i, day in enumerate(forecasts[:5]): + d_high = day.get("enYuksekGun1") + if d_high is not None: + # Calculate date (today + offset) + target_date = (datetime.now() + timedelta(days=i)).strftime("%Y-%m-%d") + results["daily_forecasts"][target_date] = d_high + break else: # 记录所有可用字段,方便调试 available_keys = [ @@ -556,6 +564,20 @@ class WeatherDataCollector: except Exception as e: logger.debug(f"MGM hourly failed: {e}") + # 4. Fallback for today_high (if daily forecast is missing it) + if "today_high" not in results: + # Try from current max + cur_max = results.get("current", {}).get("mgm_max_temp") + if cur_max is not None: + results["today_high"] = cur_max + logger.info(f"📋 MGM 每日预报: 使用当前测站最高温作为今日预报回退: {cur_max}°C") + elif "hourly" in results and results["hourly"]: + # Try from hourly + h_max = max((h["temp"] for h in results["hourly"] if h["temp"] is not None), default=None) + if h_max is not None: + results["today_high"] = h_max + logger.info(f"📋 MGM 每日预报: 使用小时预报最高温作为今日预报回退: {h_max}°C") + return results if "current" in results else None except Exception as e: logger.error(f"MGM API 请求失败 ({istno}): {e}") diff --git a/web/app.py b/web/app.py index 60d1e0a7..b29973df 100644 --- a/web/app.py +++ b/web/app.py @@ -105,7 +105,7 @@ def _analyze(city: str, force_refresh: bool = False) -> Dict[str, Any]: raw = _weather.fetch_all_sources(city, lat=lat, lon=lon) om = raw.get("open-meteo", {}) metar = raw.get("metar", {}) - mgm = raw.get("mgm", {}) + mgm = raw.get("mgm") or {} ens_raw = raw.get("ensemble", {}) mm = raw.get("multi_model", {}) risk = CITY_RISK_PROFILES.get(city, {}) @@ -412,6 +412,11 @@ def _analyze(city: str, force_refresh: bool = False) -> Dict[str, Any]: if i < len(maxtemps) and maxtemps[i] is not None: day_m["Open-Meteo"] = _sf(maxtemps[i]) + # Add MGM per-day forecast + mgm_daily = mgm.get("daily_forecasts", {}) + if d_str in mgm_daily: + day_m["MGM"] = _sf(mgm_daily[d_str]) + d_val, d_winfo = None, "" if day_m: try: