JK天气预报 / JK Weather Forecast
按地点出一份浅色单文件 HTML 天气报告:哪一天、温度、湿度、风向风力、空气质量、防晒指数、穿衣建议。
报告内嵌中英双语:头部卡片下方有两个语言标签(中文 / English),点击即整页切换,无需两个文件。
数据来自 Open-Meteo,免费、免注册、免 API Key,只用 Python 标准库,无第三方依赖。
何时使用
- 「上海今天天气怎么样」「周末去杭州穿什么」
- 「北京空气质量」「三亚紫外线强不强」
- 出行 / 拍摄 / 活动前的天气判断,或需要一份能直接发给人看的天气卡片
首次使用:先问报告存哪(只问一次)
安装后第一次使用本技能时,在问城市和日期之前,先确认报告输出目录:
- 先跑检查:
python3 scripts/config.py --check
- 退出码
0→ 已经配好了,跳过本节,直接走下面的正常流程。 - 退出码
4→ 还没配过,必须问用户。
- 未配置时,向用户提问(要完整路径,不要相对路径、不要"当前目录"):
> 生成的天气报告想放在哪个目录?给我完整路径就行,目录不存在我会自动创建。
> 例如 macOS/Linux:/home/你的用户名/Documents/天气报告;Windows:D:\天气报告。
- 拿到答案后写入并建目录:
python3 scripts/config.py --set-dir "/home/你的用户名/Documents/天气报告"
- 目录不存在 → 自动创建;路径是文件 / 无写权限 → 直接报出来,请用户换一个路径。
- 配置写入
~/.workbuddy/weather_config.txt,之后每次生成都用它,不再重复询问。 - 用户想换地方:重新
--set-dir,或--reset清空(下次会重新问)。 - 单次临时放别处:在该次命令上加
--out-dir "<路径>"覆盖配置。
没配好就不要往下走:report.py 在未配置时会直接退出(退出码 4),不会偷偷落到当前目录。
开工前必须先问(不要跳过)
拿到输出目录之后(首次使用时),接着向用户确认这两项,拿到答案再动手:
- 查询哪个城市(或具体地址 / 经纬度)。用户说「明天天气」却没给地点,必须追问地点;地点有重名(如「上海」在浙江也有)时按人口最大的结果走,拿不准就问一句。
- 查询的日期范围。可能是单天(「明天」「9 月 20 日」)也可能是一段(「9/20 到 9/23」「接下来一周」)。范围含多天时,逐天各出一份报告。
只有当用户已经把这两项都说清楚时才可以不问。不要默认成"今天 + 用户所在城市"就开工。
问法示例(一次问完,别挤牙膏):
> 想查哪个城市?查哪一天(或哪几天)?目前最多能预报未来 15 天。
确认后按下面规则映射参数:单天用 --date 或 --offset,多天用 --date-from + --date-to。
开工判定:先确认能不能预测(必做)
拿到地点和日期后,脚本会在调用天气接口之前先做判定。判定不通过时命令会输出:
[无法预测 / UNAVAILABLE] <原因代码> - <English one-liner>
无法预测 · <中文详细说明>
进程退出码为 3。此时不要再尝试、不要换参数硬凑、不要生成 HTML,直接把原因转告用户,并说明是下面哪一种情况:
| 原因代码 | 含义 | 该怎样回复用户 |
|---|---|---|
PLACE_EMPTY |
没给地点 | 请用户补充城市或「纬度,经度」 |
PLACE_NOT_FOUND |
地区不存在 | 明确说「地理库里查不到这个地区」,请他换写法(如「上海市」)或直接给经纬度 |
PLACE_NO_COORD |
地区解析不到坐标 | 同上,建议改用经纬度 |
DATE_FORMAT |
日期格式不对 | 说明必须是 YYYY-MM-DD,并给出正确示例 |
DATE_TOO_FAR |
超出未来 15 天预报范围 | 告知最远可查到哪一天(输出里带),建议临近再查 |
DATE_TOO_OLD |
超出过去 92 天回溯范围 | 告知最早可查到哪一天 |
RANGE_TOO_LONG |
日期范围超过单次 16 天 | 请他缩短范围或分多次查询 |
NETWORK |
接口重试 3 次仍失败 | 告知「天气接口暂时不可用,请稍后再试」,不要反复重试 |
NO_DATA |
接口没返回该地点该日期的数据 | 请他换地点或换日期 |
判定顺序:日期范围先做纯本地校验(零网络开销),再校验地区是否存在(一次地理编码请求)。所以「日期超范围」这类问题连天气接口都不会被调用。
也可以单独预检,不生成报告:
python3 -c "import sys; sys.path.insert(0,'scripts'); import weather as W; \
print(W.precheck('上海', ['2026-09-20']))"
怎么用
一条命令出图(默认单文件内嵌中英文、标签切换;输出目录用配置里的):
python3 scripts/report.py --place "上海"
常用参数:
| 参数 | 说明 |
|---|---|
--place |
必填。城市名(中英文均可)或 纬度,经度,如 "上海" / "Tokyo" / "31.23,121.47" |
--place-en |
可选。地点英文名。中文地点想让英文版标题显示 Shanghai 时给 |
--place-label / --place-label-en |
可选。只改报告上的显示名。用坐标查天气时(--place "26.87,100.22")地理库只能回坐标串,标题会变成「26.8688, 100.2207」;给 --place-label 丽江 就显示「丽江」。只动文字,不动坐标与数据 |
--date |
目标日期 YYYY-MM-DD,默认今天 |
--offset |
相对今天偏移天数,1=明天,3=3 天后。与 --date 二选一 |
--date-from / --date-to |
日期范围,如 --date-from 2026-09-20 --date-to 2026-09-23,会逐天各出一份 HTML(文件名带日期)。单次最多 16 天(含今天) |
--out-dir |
HTML 输出目录。留空则用配置文件里的 OUTPUT_DIR(首次使用由 config.py --set-dir 设置);填了就临时覆盖配置 |
--lang |
both(默认,单文件内嵌双语 + 标签切换)/ zh / en(只出单语,无标签) |
--wind-unit |
kmh(默认)/ ms / mph / kn |
--temp-unit |
celsius(默认)/ fahrenheit |
--json-out |
顺便把原始数据存成 JSON,便于二次加工 |
--name |
输出文件名前缀,默认 weather(both 产出 weather.html,单语产出 weather-zh.html / weather-en.html) |
也支持两段式:python3 scripts/report.py --data weather.json --out-dir .
例子
# 上海今天,单文件双语 + 标签切换(输出到配置目录)
python3 scripts/report.py --place "上海" --place-en "Shanghai"
# 东京明天
python3 scripts/report.py --place "Tokyo" --offset 1
# 指定坐标 + 指定日期 + 只出中文单语版(无标签)
python3 scripts/report.py --place "31.23,121.47" --date 2026-09-20 --lang zh
# 日期范围:成都 9/20-9/23,逐天出 4 份(chengdu-2026-09-20.html ...)
python3 scripts/report.py --place "成都" --place-en "Chengdu" \
--date-from 2026-09-20 --date-to 2026-09-23
# 坐标查天气 + 显示成人话地名(被别的技能调用时最常用)
python3 scripts/report.py --place "26.8688,100.2207" \
--place-label "丽江" --place-en "Lijiang" --date 2026-09-16
# 单次临时放到别处
python3 scripts/report.py --place "上海" --out-dir "/tmp/weather"
交付要求
- 生成后必须用
present_files把 HTML 展示给用户(默认就是那一个双语文件;多天时把全部文件一起展示)。 - 在回复里用一句话概括:日期、天气、最高/最低温、空气质量和穿衣要点。不要把 HTML 内容整段复述。
- 用户明确只问某几项(比如只问空气质量)时,仍然走完整流程出 HTML,回复里只回答他问的那部分。
- 查询的是 2 天以后的日期时,回复里要提醒一句:越远偏差越大,建议在临近日期重新运行获取最新结果。(报告顶部提示条已自动带上这句)
报告里有什么
- 顶部提示条:在第一大块上方,说明最多只预报未来 15 天、仅供参考;查的是 2 天后及更远时,自动追加「越远偏差越大,建议临近时重新运行」
- 头部:地点、日期、星期、今天/明天/N 天后徽标、当前温度、天气描述、体感温度、天气图标,下方一排直接结论(5 小块,图标在上文字在下):出门建议 / 穿什么 / 雨伞·太阳伞 / 防晒霜 / 口罩(按 AQI 分级),每块按结论着色(绿=好 / 金=一般 / 橙=注意 / 红=不利)
- 语言标签:头部卡片正下方,「中文 / English」两个标签,点击整页切换(含头部自身)
- 当日概览:温度、相对湿度、风向风力、空气质量、降水、紫外线六张指标卡,每张标题前配一个内联 SVG 图标(改图标看
report.py的METRIC_ICONS) - 24 小时温度曲线:概览正下方,纯 SVG 折线图(气温实线 + 体感虚线 + 最高/最低/当前时刻标注),无外部图表库
- 防晒建议:UV 指数 + 等级,下面是多张「图标 + 说明」提示卡,按 UV 分级给出 2-4 张(改内容看
weather.py的uv_blocks) - 空气质量:US AQI / 欧洲 AQI / 等级 / 建议,以及 PM2.5、PM10、O₃、NO₂、SO₂、CO 浓度
- 穿衣建议:体感温度主导,叠加昼夜温差、降水概率、风力、紫外线、空气质量的修正;每条建议是一张「图标 + 说明」提示卡(改内容看
weather.py的outfit_advice,图标见report.py的TIP_ICONS) - 其他:日出日落、数据生成时间
- 页脚:免责声明(中英双语,随语言切换)→ 分割线 → 反馈信息与技术支持署名(后两行不随语言切换,始终中文)
硬约束
- 预报范围:未来最多 15 天(接口硬上限是
forecast_days=16即"今天+15 天",取 15 是因为第 16 天准确率已无参考价值),过去最多 92 天。超出会直接报错,别硬凑。 - 空气质量只有 7 天:
air-quality-api的forecast_days上限为 7,查 8 天以后时该区块显示「超出空气质量 7 天预报范围」,不能拿当天数据顶替。 - 空气质量为独立端点
air-quality-api.open-meteo.com,取不到时报告显示提示文案,不阻断主流程。 - 风向是气象学来向(风的来向,不是去向),44° = 东北风。别在回复里写反。
- 数据来自 Open-Meteo(CC BY 4.0)。当前报告未显示来源行(用户要求去掉),对外公开发布时建议在别处保留一句来源说明。
- 非商业用途免费,限额 10,000 次/天;单个请求超过 10 个变量或跨度超 2 周会折算成多次调用。
- 中文查英文地名库会失败(
上海查不出Shanghai),需要英文版显示英文名时请传--place-en。 - 中文小地名请优先用坐标。 Open-Meteo 的地理库对中国县级/镇级地名覆盖很差,实测:
丽江→ 命中「湖南·丽江」(小村庄,人口 0),错的;丽江市才对大理→ 命中「四川·大理」,错的;大理市才对香格里拉→ 命中「河北·香格里拉社区」,错的;香格里拉市查不到剑川/剑川县/沙溪镇/洱源县/德钦县→ 完全查不到
所以拿不准就给纬度,经度(--place "26.87,100.22"),再用--place-label把标题写成中文名。
坐标用 GCJ-02 也没关系:它和 WGS-84 只差几百米,对公里级的天气网格没有影响。
网络与重试
- 每次 API 调用最多尝试 3 次(首次 + 2 次重试),间隔按 1s / 1.5s 指数退避。
- 只有网络类故障才重试:超时、连接失败、DNS 失败、HTTP 5xx。
- HTTP 4xx 和接口参数错误不重试(重试也不会成功),直接报出接口给的原因。
- 3 次都失败 → 抛
NETWORK,命令退出码 3,输出「天气接口暂时不可用,请稍后再试」。
此时不要自己再重试脚本,把情况告诉用户让他稍后再来。 - 空气质量是可选数据,取不到只影响报告里那一个区块,不会让整个任务失败。
退出码
| 码 | 含义 | 该做什么 |
|---|---|---|
0 |
成功 | 用 present_files 展示 HTML |
1 |
接口拒绝 / 网络异常 / 未知错误 | 看输出排查,或让用户稍后再试 |
2 |
参数缺失 | 补 --place 或 --data |
3 |
无法预测(地区不存在 / 日期超出范围 / 接口重试后仍不可用) | 按上表把具体原因转告用户,别硬凑 |
4 |
输出目录未配置 | 问用户要完整路径,执行 config.py --set-dir 后重跑 |
安装 / 排障
python3 scripts/install.py # 安装到 ~/.workbuddy/skills/jk-weather-forecast
python3 scripts/install.py --uninstall
python3 scripts/config.py --check # 输出目录是否已配置(首次使用先跑这个)
python3 scripts/doctor.py # 排障第一步:环境 / 跨平台 / 输出目录 / 文件 / 网络
跨平台
支持 Windows / macOS / Linux / HarmonyOS(需 Python 3.7+),doctor.py 会逐项给出检查结果。
- 只用 Python 标准库,零第三方依赖、无需 pip install。
- 不使用
fcntl/termios/os.fork/shell=True等平台专属能力,也不写死任何 Python 绝对路径。 - 所有控制台输出走
safe_print:非 UTF-8 终端(Windows 常见的 cp936 / cp1252)下自动降级,不会因编码报错中断任务。 - 无法预测的提示额外打一行纯 ASCII 的英文原因,保证任何编码的终端都能读出是哪一种情况。
- 生成的 HTML 一律以 UTF-8 写入,与终端编码无关。
- Windows 上用
python,其余平台用python3(doctor.py会打印当前平台该用哪个)。 - 路径含空格、
HOME未设置(HarmonyOS / 服务态常见)均已实测通过。