关于 tempest
tempest 是用于读取 WeatherFlow Tempest 气象站数据的命令行技能,支持通过 REST 获取天气、预报和历史记录,也可监听站点 Hub 的实时 UDP 广播。
主要功能
- 01发现气象站和设备
- 02读取当前天气与预报
- 03查询历史观测数据
- 04监听并解码 UDP 广播
- 05输出公制原生 JSON
适用场景
- 01查看气象站当前天气和预报
- 02检查近期气象站观测记录
- 03监测本地降雨、风况或闪电事件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ magnus919/ agent-skills --skill tempest安装后在 Claude Code 中输入/tempest确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdevals/evals.jsonreferences/cli-worked-recipes.mdobservation-layouts-and-units.mdrest-api-and-auth.mdudp-broadcast-protocol.mdscripts/tempesttest_tempest.py详细介绍
tempest — 获取 Tempest 气象站的超本地天气
通过终端操作 WeatherFlow Tempest 气象站。提供两种一流传输方式:有文档说明的 REST API(swd.weatherflow.com/swd/rest,个人使用令牌),用于获取天气状况、预报和历史数据——这是官方主要数据源;以及集线器通过未认证的 UDP 在端口 50222 上进行的广播,用于在局域网上获取实时、延迟最低的读数。随附的 CLI 会解码位置观测数组和所有 UDP 消息类型,确保 --json 输出保留原生公制单位,仅在面向用户显示时转换单位。
设置
- 创建个人访问令牌:登录 Tempest Web 应用(tempestwx.com),然后依次选择 Settings → Data Authorizations → Create Token。 (这是有文档说明的非图形界面认证方式;Web 应用可以使用 OAuth,但 CLI 不使用 OAuth。)
- 导出令牌:
export TEMPEST_TOKEN="<YOUR_TOKEN>"
根据官方文档,令牌会作为查询参数(?token=...)发送给 API——CLI 会处理这一过程。如果未设置环境变量,CLI 会改为从 ~/.tempest.env 读取 TEMPEST_TOKEN=(适用于不会加载 shell 配置文件的 Agent 子进程)。--help 和 --dry-run 无需令牌。监听 UDP 同样无需令牌——集线器广播不需要认证,且仅限局域网。
基本命令
stations — 查找气象站和设备
tempest stations # names, station ids, device types, serials
tempest stations --json | jq '.stations[] | {station_id, name,
devices: [.devices[] | {device_id, device_type, serial_number}]}'
每个气象站响应都包含一个嵌套的 devices 数组:device_type 为 ST(Tempest 一体机)、AR/AIR、SK/SKY 或 HB(集线器——它没有观测数据;查询观测数据前务必将其过滤掉)。不知道 ID 时,先运行此命令。
current — 最新天气状况
tempest current # human-readable, converted
tempest current --json # metric-native, jq-ready
tempest current --station-id 12799 --device-id 60526 # pin exact hardware
如果只有一个气象站,命令会自动选择该站,并选取最佳传感器(依次为 ST、SKY/SK、AIR/AR,跳过 HB)。输出中的 .observation 会将解码后的位置数组转换为带有 _unit 配套字段的命名字段。
forecast — 当前天气状况、每日和每小时预报
tempest forecast # current + 5-day daily + next 12 hours
tempest forecast --days 7 --json
tempest forecast --station-id 12799 --days 3
better_forecast 响应会在 forecast 包装键下嵌套每日和每小时预报,并且可以选择单位(units_temp=c|f 及类似参数,默认使用公制单位)——CLI 会先读取响应中的 units,再进行任何转换。
obs — 历史观测数据
tempest obs --device-id 60526 --days 1 # last UTC day (day_offset)
tempest obs --device-id 60526 --days 7
tempest obs --device-id 60526 --json
--days N 会映射为 API 的 day_offset(以整 UTC 天为单位)。底层端点还接受 time_start/time_end epoch 时间范围(最多保证 5 天内具有一分钟分辨率)——需要这些参数时请使用原始调用;参见 references/rest-api-and-auth.md。
来自集线器的 UDP 广播(端口 50222,仅监听)
tempest udp listen # live stream until Ctrl-C
tempest udp listen --timeout 30 # auto-stop after 30s
tempest udp listen --timeout 60 --json # one JSON object per datagram
tempest udp listen --show-all # include hub_status/device_status
需要与集线器处于同一局域网(仅有路由连接并不够——广播不会跨越路由器)。无需令牌。监听器会解码所有消息类型,并在处理数组位置前先根据 type 进行分派:
| 类型 | 负载结构 | 解码字段 |
|---|---|---|
obs_st / obs_air / obs_sky | obs 下的报告行列表 | 命名观测字段 |
rapid_wind | ob 下的一个 3 元素数组 | wind_speed_mps, wind_direction |
evt_precip | evt 下的一个数组 | timestamp(降雨开始时间) |
evt_strike | evt 下的一个数组 | distance_km, energy |
hub_status, device_status | 命名字段,无数组 | uptime, rssi, seq, voltage, sensor_status |
多步骤流水线示例
先查找,再获取观测数据
# Stage 1 -> stage 2: stations --json emits integer ids that current consumes
tempest stations --json | jq -r '.stations[].devices[]
| select(.device_type == "ST") | .device_id' | head -1
tempest current --device-id <DEVICE_ID> --json
降雨监测:先获取昨天的总降雨量,再监听实时降雨事件
tempest obs --device-id 60526 --days 1 --json \
| jq '{samples: (.observations | length),
day_rain_mm: .observations[-1].local_day_rain_accumulation}'
tempest udp listen --timeout 600 --json | jq 'select(.type == "evt_precip")'
obs --json 输出以已解码的观测数据结尾,其中包含 local_day_rain_accumulation(mm,数值);evt_precip 数据报会解码为 {type, serial_number, timestamp}——两个阶段都会输出类型化字段,供下一阶段使用。
考虑单位的预报切片
tempest forecast --days 7 --json \
| jq '{units_temp: .forecast.units.units_temp,
highs_f: [.forecast.forecast.daily[] | .air_temp_high * 9 / 5 + 32],
rain_hours: [.forecast.forecast.hourly[]
| select(.precip_probability > 30) | .local_hour]}'
此处的 jq 计算仅在先检查 units_temp 时才安全——参见注意事项 2。
JSON 输出和 jq 处理
--json 输出以指标原生单位表示 — 即原始传输单位(风速 m/s、降雨 mm、温度 °C、气压 MB),并带有命名各单位的 _unit 配套字段。
在消费端进行转换:
tempest current --json | jq '{temp_c: .observation.air_temperature,
temp_f: (.observation.air_temperature * 9 / 5 + 32),
wind_mph: (.observation.wind_avg * 2.237),
rain_in: (.observation.rain_accumulation / 25.4)}'
全局标志可放在任意位置:tempest --json current --device-id 60526
和 tempest current --device-id 60526 --json 的效果相同。--quiet
会静默进度日志(数据输出到 stdout,日志输出到 stderr)。
--dry-run 会打印计划对象并以 0 退出,不访问网络。
已知注意事项
- 观测数据是按位置排列的数组,而不是对象。 原始
obs行没有字段名;含义由索引决定(obs_st:0 为 epoch,2 为平均风速 m/s,4 为风向,6 为气压 MB,7 为温度 °C,12 为降雨 mm,16 为电池电压 V,17 为报告间隔)。将索引 6 读作温度会得到一个看似合理但错误的数值 — 请使用 CLI 解码,或参阅 references/observation-layouts-and-units.md 中的布局表。 /better_forecast可选择单位,并非固定使用摄氏度。 默认使用公制单位,但会遵循units_temp=f、units_wind=mph、units_pressure=inhg、units_precip=in。它会在response.units中报告所用单位。转换已经是华氏度的响应会导致重复转换(25.4 °C → 77.7 °F → 172 "°F")。转换前务必先读取units;CLI 会为你处理。- 不同 UDP 消息族的结构不同 — 请先根据
type分派。 obs 消息族会将数据行嵌套在obs下;rapid_wind在ob下携带一个数组;evt_precip/evt_strike在evt下携带一个数组;hub_status/device_status则携带命名字段,没有负载数组。逐项遍历rapid_wind的ob元素是典型的 TypeError;随附的decode_message()展示了正确的分派方式。 - UDP obs_st 数据行最多到索引 17;REST 数据行则到 21。 Nearcast/analysis 的四个字段(18–21)仅存在于 REST 响应中。解码器必须兼容两种长度 — 对于缺失的尾部字段,CLI 会输出
None。 - 气压单位是 MB(毫巴),数值上等同于 hPa — 不是 kPa。 它还是站点气压(传感器原始读数)。Tempest 应用中的“相对气压”会进行海拔修正;不要将原始站点气压与应用读数比较后,就断定传感器发生了漂移。
- 预报时间戳是 epoch 整数,绝不是 ISO 字符串。
day_start_local、sunrise、sunset和逐小时的time都是 epoch 秒;逐小时对象还包含local_hour(0–23)和local_day(月中的日期)。没有local_time或time_string字段 — 期望这些字段的代码会悄悄回退到默认分支。 - 预报嵌套在
forecast包装键下。data["daily"]始终为空;应读取data["forecast"]["daily"]和data["forecast"]["hourly"](CLI 的--json会保留完整响应,包括包装层)。 - 集线器(
HB)没有观测数据。 它们只负责中继。自动选择会跳过它们;如果直接调用 API,请在访问/observations/device/{id}前过滤掉device_type == "HB"(否则会返回 404,文档中已有说明)。 - UDP 仅限局域网,且未经身份验证。 广播不会穿过路由器,也无法通过令牌限制访问 — 网络上的任何人都能读取你的气象站数据。WeatherFlow 官方将 REST/WebSocket 作为主要接口,将 UDP 作为离网/备用接口。
obs_skyUDP 的当日降雨量始终为 null。 UDP SKY 广播中的本地当日降雨累计量(索引 11)为null;REST 会提供真实值。不要根据 UDP SKY 数据行计算当日降雨总量。
适用场景
- 用户拥有或管理 WeatherFlow Tempest / Air / Sky 气象站,并询问其读数、预报或历史数据。
- 解析或集成集线器的本地 UDP 广播(端口 50222)。
- 基于气象站数据的降雨/风速/雷电监控脚本、仪表板或家庭自动化钩子。
不适用场景
- 通用城市天气预报,或没有气象站的用户——每个端点都需要用户自己的 Tempest 气象站和个人使用令牌;请改用公共天气服务。
- 莎士比亚戏剧 The Tempest,或任何文学/气象理论问题——这是一个气象站数据 CLI,不是百科全书。
- 其他厂商的硬件(Netatmo、Ecowitt、Davis、Ambient)——它们使用完全不同的 API;这里没有任何端点可以接入这些设备。
- 商业/全网数据产品——此类产品需要 WeatherFlow 的 TempestONE 协议,而非个人令牌(参见远程开发者政策)。
参考文件
| 文件 | 何时阅读 |
|---|---|
| references/rest-api-and-auth.md | 直接使用 REST 端点时:令牌认证、StationSet 结构、观测参数、预报单位、错误特征 |
| references/udp-broadcast-protocol.md | 解析原始 UDP 数据报时:50222 端口传输、每种消息类型的布局、类型分派规则 |
| references/observation-layouts-and-units.md | 按索引解码位置式观测数组(obs_st/obs_air/obs_sky、UDP 与 REST 的长度差异)及单位换算表 |
| references/cli-worked-recipes.md | 可直接复制粘贴的多步骤 CLI 示例,包含 jq 阶段、试运行计划和预期错误路径 |
可用脚本
- scripts/tempest — CLI:
stations、current、obs、forecast、udp listen;全局--json、--dry-run、--quiet、--verbose可在任意位置使用;每条命令均支持离线试运行计划。 - scripts/test_tempest.py — 离线测试套件:将预置 UDP 数据报字节传入解码器(不使用套接字)、模拟 REST 传输,同时支持 pytest 和 unittest 运行器。
先决条件
- Python 3.8+ 和
requests(唯一依赖项)。 - REST 命令需要
TEMPEST_TOKEN(免费供个人使用;在 Tempest Web 应用中创建)。UDP 监听无需令牌,只需能够直连集线器所在的局域网。