天气订阅功能优化

This commit is contained in:
liuwei
2025-12-17 13:28:29 +08:00
parent 3bb5d4eef5
commit 4b45098ef0

View File

@@ -331,8 +331,8 @@ class WeatherPlugin(MessagePluginInterface):
alerts = self._check_alerts_and_history(today, history_data)
life_tips = self._generate_life_tips(today)
astronomy = self._get_astronomy_info(today)
clothing = self._get_clothing_advice((t_max + t_min) / 2)
# astronomy = self._get_astronomy_info(today) # 整合进 life_tips 了
clothing = self._get_clothing_advice(t_min, t_max)
msg = f"📍 {city_name} | {text_day} | {t_min}°C ~ {t_max}°C\n"
@@ -340,7 +340,9 @@ class WeatherPlugin(MessagePluginInterface):
if life_tips: msg += "\n💡 **温馨提示**\n" + "\n".join(life_tips) + "\n"
msg += f"\n👔 **穿衣**{clothing}"
if astronomy: msg += f"\n🌙 **天文**{astronomy}"
# 增加一些趣味数据
msg += self._get_fun_stats(today)
msg += "\n\n(回复 '取消订阅' 退订)"
return msg
@@ -348,71 +350,143 @@ class WeatherPlugin(MessagePluginInterface):
def _check_alerts_and_history(self, today: dict, history_data: Optional[dict]) -> List[str]:
alerts = []
t_max = int(today['tempMax'])
t_min = int(today['tempMin'])
text_day = today['textDay']
wind_scale = today.get('windScaleDay', '0')
precip = float(today.get('precip', 0.0))
# 1. 温差提醒
diff_day = t_max - t_min
if diff_day >= 12:
alerts.append(f"📉 **昼夜温差大**:相差 {diff_day}°C早晚多穿件外套。")
# 2. 变温提醒 (对比昨天)
if history_data:
last_max = int(history_data.get('tempMax', t_max))
diff = t_max - last_max
if diff <= -6:
alerts.append(f"🥶 **气温骤降**:比昨天冷了 {abs(diff)}°C")
elif diff >= 6:
alerts.append(f"🥵 **气温飙升**:比昨天热了 {diff}°C。")
diff_yesterday = t_max - last_max
if diff_yesterday <= -6:
alerts.append(f"🥶 **气温骤降**:比昨天冷了 {abs(diff_yesterday)}°C")
elif diff_yesterday >= 6:
alerts.append(f"🥵 **气温飙升**:比昨天热了 {diff_yesterday}°C。")
# 3. 极端天气关键词
if "暴雨" in text_day:
alerts.append("🌧️ **暴雨预警**减少户外活动")
elif "" in text_day:
alerts.append(" 今天有雨,出门带伞")
if "" in text_day: alerts.append("❄️ 雪天路滑,注意安全。")
alerts.append("🌧️ **暴雨预警**非必要不外出,注意防汛")
elif "" in text_day:
alerts.append("🌧 **大雨倾盆**:鞋子容易湿,建议穿雨靴")
elif "" in text_day:
alerts.append("❄️ **冰雪天气**:路面湿滑,注意行车安全。")
elif "冰雹" in text_day:
alerts.append("☄️ **冰雹警报**:赶紧把车停到室内!")
# 4. 风力
try:
# windScaleDay 可能是 "1-2" 或 "3"
max_wind = int(wind_scale.split('-')[-1])
if max_wind >= 5: alerts.append(f"🌬️ **大风警报**{wind_scale}级大风。")
wind_dir = today.get('windDirDay', '')
if max_wind >= 7:
alerts.append(f"🌪️ **狂风大作**{wind_dir}{wind_scale}级,广告牌下别站人!")
elif max_wind >= 5:
alerts.append(f"🌬️ **大风警报**{wind_dir}{wind_scale}级,发型要乱啦。")
except:
pass
return alerts
def _generate_life_tips(self, data: dict) -> List[str]:
tips = []
uv = int(data.get('uvIndex', 0))
if uv >= 8:
tips.append("☀️ 紫外线极强(UV>8),防晒!")
elif uv >= 5:
tips.append("☂️ 紫外线较强,注意防晒。")
# 1. 降水 (precip)
precip = float(data.get('precip', 0.0))
text_day = data.get('textDay', '')
if precip > 0:
if precip < 10:
tips.append(f"☔️ 今天有雨({precip}mm),出门记得带伞。")
else:
tips.append(f"🌧️ 雨量较大({precip}mm),外出注意防雨防滑。")
elif "" in text_day:
tips.append("☁️ 天空阴沉,虽然没雨,但也别指望晒被子啦。")
elif "" in text_day:
tips.append("☀️ 阳光明媚,心情也会变好哦。")
# 2. 紫外线 (uvIndex)
uv = int(data.get('uvIndex', 0))
if uv >= 10:
tips.append("☠️ **紫外线爆表**:尽量留在室内,出门必须全副武装!")
elif uv >= 6:
tips.append("☂️ **紫外线强**:涂好防晒霜,戴上墨镜。")
# 3. 湿度 (humidity)
hum = int(data.get('humidity', 0))
if hum >= 90:
tips.append("💧 潮湿(>90%),注意防潮。")
tips.append("💧 空气像是能拧出水(湿度>90%),注意防潮除湿")
elif hum <= 20:
tips.append("🌵 干燥(<20%),多喝水。")
tips.append("🌵 空气很干燥(湿度<20%),多喝水,小心静电")
# 4. 气压 (pressure)
pres = int(data.get('pressure', 1000))
if pres < 995:
tips.append("🌬️ 气压较低,可能会感到有些闷热或不适。")
# 5. 能见度 (vis)
vis = int(data.get('vis', 25))
if vis < 1:
tips.append("🌫️ **大雾**:能见度<1km慢行!")
tips.append("🌫️ **大雾弥漫**:能见度不足1公里开车务必慢行!")
elif vis < 5:
tips.append("👀 轻雾或霾,能见度一般")
tips.append("👀 轻雾缭绕,远处朦朦胧胧")
moon = data.get('moonPhase', '')
text_night = data.get('textNight', '')
if "" in text_night and ("满月" in moon or "" in moon):
tips.append(f"🌕 天晴,宜赏月({moon})。")
# 6. 舒适度/活动建议
cloud = int(data.get('cloud', 50))
sunset = data.get('sunset', '')
if cloud < 20 and "" in text_day:
tips.append(f"<EFBFBD> 傍晚{sunset}左右可能有美丽的晚霞哦。")
return tips
def _get_astronomy_info(self, data: dict) -> str:
def _get_fun_stats(self, data: dict) -> str:
"""获取一些有趣的数据统计"""
sunrise = data.get('sunrise', '-')
sunset = data.get('sunset', '-')
moon = data.get('moonPhase', '')
parts = []
if sunrise != '-' and sunset != '-': parts.append(f"日出{sunrise}|日落{sunset}")
if moon: parts.append(moon)
return " ".join(parts)
moon_phase = data.get('moonPhase', '')
moon_icon = data.get('moonPhaseIcon', '') # 假设API有这个或者直接用 phase
stats = []
# 计算白昼时长
try:
sr_h, sr_m = map(int, sunrise.split(':'))
ss_h, ss_m = map(int, sunset.split(':'))
day_len_m = (ss_h * 60 + ss_m) - (sr_h * 60 + sr_m)
hours = day_len_m // 60
minutes = day_len_m % 60
stats.append(f"\n☀️ **白昼**{hours}小时{minutes}分 (日出{sunrise}|日落{sunset})")
except:
pass
def _get_clothing_advice(self, temp: float) -> str:
if temp < 0: return "羽绒服+围巾 (严寒)"
if temp < 10: return "棉衣/大衣 (冷)"
if temp < 18: return "风衣/卫衣 (凉)"
if temp < 26: return "衬衫/T恤 (舒适)"
return "短袖/裙子 (热)"
if moon_phase:
stats.append(f"🌙 **月相**{moon_phase}")
return "".join(stats)
def _get_clothing_advice(self, t_min: int, t_max: int) -> str:
"""根据最低和最高温综合给出穿衣建议"""
avg_temp = (t_min + t_max) / 2
if t_min < -5:
return "极寒!羽绒服+保暖内衣+围巾手套缺一不可。"
elif t_min < 5:
return "很冷,建议穿棉衣、羽绒服,里面穿毛衣。"
elif t_min < 12:
return "较冷,大衣或厚外套是标配。"
if avg_temp < 18:
return "凉爽,建议风衣、卫衣或薄外套,早晚保暖。"
elif avg_temp < 24:
return "舒适衬衫、T恤外搭薄外套即可。"
elif avg_temp < 30:
return "微热,短袖、裙子,透气衣物。"
else:
return "炎热!穿得越少越凉快(注意防晒)。"
# ================= 新版数据获取 (分离 ID 和 搜索) =================