终端里的月亮8相位:weathr如何调用美国海军天文台API获取真实月相数据
【免费下载链接】weathra terminal weather app with ascii animation项目地址: https://gitcode.com/gh_mirrors/wea/weathr
终端天气应用 weathr 不只是画雨和雪——它还能在夜空里画出与真实世界同步的月亮。weathr 通过调用美国海军天文台(USNO)Astronomical Applications Department 的月相 API,获取当天真实月相数据,再映射到 8 帧 ASCII 月亮动画上,让你在终端里看到今晚月亮的"真身" 🌙
谁是美国海军天文台 API?
weathr 的主天气数据来自 Open-Meteo,但天文数据(日月升落、月相)需要"外援"。项目为此设计了补充数据源(Supplementary Provider)架构:
- 主天气源负责温度、风、降水等数据
- 当主源缺少天文数据时(例如英国 Met Office 不返回日月信息),就交给
AADProvider去美国海军天文台补取
整个机制记录在 PROVIDERS.md 的 "Supplementary Providers" 一节中,架构定义位于 supplementary/mod.rs:
这类 provider 用于在小范围内补充其他 provider 缺失的数据——例如 MetOffice 不提供任何天文数据,它需要另外发起请求来获取。
API 的基地址是https://aa.usno.navy.mil/api/,这是美国政府的天文数据服务,无需 API Key、直接可用。
月相请求是如何构造的
核心实现在 aad.rs。当请求类型为PhasesOfMoon时,程序拼接出这样的 URL:
https://aa.usno.navy.mil/api/moon/phases/date?date=2026-09-29&nump=1参数含义很简单:
| 参数 | 作用 |
|---|---|
date | 今天的日期(%Y-%m-%d格式) |
nump=1 | 只取 1 条月相记录(即当天) |
请求是异步发出的(30 秒超时),返回 JSON 中的phasedata字段会被反序列化为MoonPhase结构,程序取第一条记录的phase字符串——比如"Full Moon"或"Waxing Gibbous"。
7 个英文月相名 → 一个数字
API 返回的是文字月相名,而渲染引擎只认数字。aad.rs 中的convert_string_to_moon_phase把月相名映射到 0~1 区间:
| API 返回的月相名 | 数值 | 含义 |
|---|---|---|
| New Moon | 0.0 | 新月(看不见) |
| Waxing Crescent | 0.15 | 娥眉月 |
| First Quarter | 0.25 | 上弦月 |
| Waxing Gibbous | 0.35 | 盈凸月 |
| Full Moon | 0.5 | 满月 |
| Waning Gibbous | 0.65 | 亏凸月 |
| Last Quarter | 0.75 | 下弦月 |
| Waning Crescent | 0.85 | 残月 |
💡 顺带一提:Met Office 场景走的是另一个接口
rstt/oneday(见 met_office.rs),它在一次请求里同时拿到当日日出日落、晨昏蒙影时间 + 当前月相,一举两得。
数字变画:8 帧 ASCII 月亮的渲染
月相数值到了动画层,就变成 8 帧 ASCII 画稿之一。moon.rs 在编译期把 8 个文件全部内嵌进二进制:
assets/moon/phase_0.txt … phase_7.txt选帧公式只有一行(moon.rs):
step = (phase × 8).round() % 8以满月0.5为例:0.5 × 8 = 4,正好选中第 4 帧——一个用~和o字符填满的圆月亮(见 phase_4.txt);而新月0.0选中 phase_0,那是一帧几乎全空的画稿,"月亮"消失了,只留下夜空 🌑
渲染时还有个小巧思:~字符位置会被渲染成空格,让月亮的实体遮住背后的星星,营造真实的遮挡感。
月亮只在夜里出现
数据链路完整走一遍是这样的:
- 天气请求返回后,
moon_phase随响应一起送达 - app.rs 调用
self.animations.update_moon_phase(moon_phase)把数值广播给所有动画系统 MoonSystem在 animation_manager.rs 的on_moon_phase回调里存下相位- 渲染前检查
is_active:只有当sun.is_day == false(天黑了)时月亮才登场
也就是说,weathr 的昼夜循环、日出日落时刻都来自同一个 USNO 接口——月相和昼夜判断数据同源,所以不会出现"白天挂着月亮"的穿帮。
如何亲自体验真实月相
安装后直接运行即可,夜间(或--night模拟夜间)就能看到与今晚真实月相一致的 ASCII 月亮:
# 安装 cargo install weathr # 模拟夜间天气,观察月亮 weathr --simulate clear --night如果本地是白天,用--night强制切换到夜间模式,配合q键退出。想深入了解数据源细节,可阅读 aad.rs 与 moon.rs 两个文件——从 HTTP 请求到终端像素,整条链路不到 400 行代码,非常值得一读 🔭
【免费下载链接】weathra terminal weather app with ascii animation项目地址: https://gitcode.com/gh_mirrors/wea/weathr
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考