From 04b2f0e4a319ab1f369a924f4c02ce6fe04735af Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Sun, 10 May 2026 18:16:10 +0800 Subject: [PATCH] =?UTF-8?q?AMOS=20=E6=95=B0=E6=8D=AE=E6=8E=A5=E5=85=A5?= =?UTF-8?q?=E5=88=86=E6=9E=90=E5=B1=82=E5=92=8C=20AI=20=E9=A2=84=E6=B5=8B?= =?UTF-8?q?=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:AMOS 数据在采集层取出后从未被 _analyze() 读取,AI 无法看到跑道级数据 修复: - analysis_service.py:_analyze() 新增 AMOS 温度读取优先级 观测来源顺序:结算源 > AMOS跑道传感器 > METAR > MGM > NMC - AMOS 数据自动覆盖 current.wind_speed_kt、current.pressure_hpa、current.raw_metar - 输出新增 "amos" 字段携带完整跑道数据(temp_source、runway_temps) - scan_terminal_service.py:AI prompt 的 current 区块新增 pressure_hpa 和 observation_source - AI 现在知晓数据来自 AMOS 跑道传感器(observation_source="amos"),可据此判断数据权威性 数据流: AMOS fetch -> raw["amos"] -> _analyze() -> current.observation_source="amos" -> result["amos"] -> _build_city_ai_prompt -> city_snapshot.current -> AI reads runway sensor temp/wind/pressure as authoritative observation Tested: python -m ruff check ., npx tsc --noEmit --- web/analysis_service.py | 18 +++++++++++++++--- web/scan_terminal_service.py | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/web/analysis_service.py b/web/analysis_service.py index b228e726..d2f67ff3 100644 --- a/web/analysis_service.py +++ b/web/analysis_service.py @@ -1728,10 +1728,11 @@ def _analyze( utc_offset=int(utc_offset or 0), ) - # ── 2. Current conditions (city-specific settlement source first, then METAR/MGM fallback) ── + # ── 2. Current conditions (settlement > AMOS runway sensors > METAR > MGM > NMC fallback) ── mc = metar.get("current", {}) if metar else {} mg_cur = mgm.get("current", {}) if mgm else {} sc_cur = settlement_current.get("current", {}) if settlement_current else {} + amos_data = raw.get("amos") or {} use_settlement_current = settlement_source in {"hko", "cwa", "noaa", "wunderground"} and bool(sc_cur) live_mc = mc if metar_current_is_today else {} primary_current = sc_cur if use_settlement_current else live_mc @@ -1742,6 +1743,15 @@ def _analyze( cur_temp = _sf(primary_current.get("temp")) if cur_temp is not None and not _is_plausible_city_temp(city, cur_temp, sym): cur_temp = None + # AMOS runway sensor: authoritative for Korean airports (RKSI/RKPK) + if cur_temp is None: + amos_temp = _sf(amos_data.get("temp_c")) + if amos_temp is not None and _is_plausible_city_temp(city, amos_temp, sym): + cur_temp = amos_temp + current_source = "amos" + current_source_label = amos_data.get("source_label") or "AMOS" + current_station_code = amos_data.get("icao") + current_station_name = amos_data.get("station_label") if cur_temp is None: cur_temp = _sf(live_mc.get("temp")) if cur_temp is not None and not _is_plausible_city_temp(city, cur_temp, sym): @@ -2427,16 +2437,17 @@ def _analyze( "report_time": primary_current.get("report_time"), "receipt_time": primary_current.get("receipt_time"), "obs_time_epoch": primary_current.get("obs_time_epoch"), - "wind_speed_kt": _sf(primary_current.get("wind_speed_kt")), + "wind_speed_kt": _sf(amos_data.get("wind_kt")) if current_source == "amos" else _sf(primary_current.get("wind_speed_kt")), "wind_dir": _sf(primary_current.get("wind_dir")), "humidity": _sf(primary_current.get("humidity")), + "pressure_hpa": _sf(amos_data.get("pressure_hpa")) if current_source == "amos" else _sf(primary_current.get("pressure_hpa")), "cloud_desc": cloud_desc, "clouds_raw": [ {"cover": c.get("cover"), "base": c.get("base")} for c in clouds ], "visibility_mi": _sf(primary_current.get("visibility_mi")), "wx_desc": primary_current.get("wx_desc"), - "raw_metar": primary_current.get("raw_metar"), + "raw_metar": amos_data.get("raw_metar") if current_source == "amos" else primary_current.get("raw_metar"), }, "airport_current": { "temp": _sf(live_mc.get("temp")), @@ -2472,6 +2483,7 @@ def _analyze( "mgm": mgm_data, "mgm_nearby": raw.get("mgm_nearby", []), "nearby_source": raw.get("nearby_source") or ("mgm" if city.lower() in TURKISH_MGM_CITIES else "metar_cluster"), + "amos": amos_data if amos_data.get("temp_c") is not None else None, "forecast": { "today_high": om_today, "daily": forecast_daily, diff --git a/web/scan_terminal_service.py b/web/scan_terminal_service.py index e0cfaecf..e527fe9e 100644 --- a/web/scan_terminal_service.py +++ b/web/scan_terminal_service.py @@ -351,6 +351,8 @@ def _build_city_ai_prompt(data: Dict[str, Any]) -> Dict[str, Any]: "wind_speed_kt": current.get("wind_speed_kt"), "wind_dir": current.get("wind_dir"), "humidity": current.get("humidity"), + "pressure_hpa": current.get("pressure_hpa"), + "observation_source": current.get("settlement_source"), }, "airport": { "name": risk.get("airport") or airport_current.get("station_label") or airport_primary.get("station_label"),