feat: implement a multi-source weather data collector for OpenWeatherMap, Visual Crossing, and METAR.

This commit is contained in:
2569718930@qq.com
2026-02-08 02:11:53 +08:00
parent 389dd51b68
commit eb01fca30f
2 changed files with 24 additions and 21 deletions
+5 -1
View File
@@ -189,7 +189,11 @@ def start_bot():
msg_lines.append(f"\n✈️ <b>机场实测 ({icao})</b>")
if metar_temp is not None:
msg_lines.append(f" 🌡️ {metar_temp}{temp_symbol}")
max_sofar = metar.get("current", {}).get("max_temp_so_far")
if max_sofar is not None and max_sofar != metar_temp:
msg_lines.append(f" 🌡️ {metar_temp}{temp_symbol} (今日最高: {max_sofar}{temp_symbol})")
else:
msg_lines.append(f" 🌡️ {metar_temp}{temp_symbol}")
if wind is not None:
msg_lines.append(f" 💨 风速: {wind}kt")
msg_lines.append(f" 🕐 观测: {obs_str}")
+19 -20
View File
@@ -228,8 +228,8 @@ class WeatherDataCollector:
params = {
"ids": icao,
"format": "json",
"hours": 3, # 获取最近3小时的观测
"_t": int(time.time()), # 禁用缓存
"hours": 24, # 抓取 24 小时数据以计算今日最高
"_t": int(time.time()),
}
response = self.session.get(
@@ -242,46 +242,45 @@ class WeatherDataCollector:
data = response.json()
if not data:
logger.warning(f"METAR 数据为空: {icao}")
return None
# 取最新的观测记录
# 1. 取最新的观测作为当前状态
latest = data[0]
# 提取温度 (METAR 原始单位是摄氏度)
temp_c = latest.get("temp")
dewp_c = latest.get("dewp")
obs_time = latest.get("reportTime", "")
# 转换为华氏度(如果需要)
if use_fahrenheit and temp_c is not None:
temp = temp_c * 9 / 5 + 32
# 2. 计算过去 24 小时内的最高实测温
max_so_far_c = -999
for obs in data:
t = obs.get("temp")
if t is not None and t > max_so_far_c:
max_so_far_c = t
# 转换为单位
if use_fahrenheit:
temp = temp_c * 9 / 5 + 32 if temp_c is not None else None
max_so_far = max_so_far_c * 9 / 5 + 32 if max_so_far_c > -900 else None
dewp = dewp_c * 9 / 5 + 32 if dewp_c is not None else None
unit = "fahrenheit"
else:
temp = temp_c
max_so_far = max_so_far_c if max_so_far_c > -900 else None
dewp = dewp_c
unit = "celsius"
# 解析观测时间
obs_time = latest.get("reportTime", "")
result = {
"source": "metar",
"icao": icao,
"station_name": latest.get("name", icao),
"timestamp": datetime.utcnow().isoformat(),
"observation_time": obs_time,
"raw_metar": latest.get("rawOb", ""),
"current": {
"temp": round(temp, 1) if temp is not None else None,
"max_temp_so_far": round(max_so_far, 1) if max_so_far is not None else None,
"dewpoint": round(dewp, 1) if dewp is not None else None,
"humidity": latest.get("rh"), # 相对湿度
"wind_speed_kt": latest.get("wspd"), # 风速 (knots)
"wind_dir": latest.get("wdir"), # 风向 (度)
"visibility_miles": latest.get("visib"), # 能见度 (英里)
"altimeter": latest.get("altim"), # 气压
"flight_category": latest.get("fltcat"), # VFR/IFR 等
"clouds": latest.get("clouds", []),
"humidity": latest.get("rh"),
"wind_speed_kt": latest.get("wspd"),
},
"unit": unit,
}