Files
kindle-calendar/dash/docs/kindle-city-location-plan.zh.md
2026-03-18 13:35:19 +08:00

6.1 KiB
Raw Permalink Blame History

Kindle 市级位置方案

背景

当前仓库里的天气位置来源仍在 calendar/ 前端:

这条路径不适合当前 Kindle 运行架构,原因有两个:

  1. Kindle 实机显示的不是一个在设备上实时运行的天气网页,而是先在别处渲染,再同步为背景图。
  2. 如果由 Web 服务器代查 IP 位置,拿到的是服务器公网 IP对应的是服务器所在城市不是 Kindle 所在城市。

本方案的目标是:

  • 位置精度只要求到“市”颗粒度
  • 位置来源应尽量接近 Kindle 当前网络出口
  • 在 SSH 暂时不可用的情况下,先把方案文档明确下来,后续恢复 SSH 后再实现

结论

浏览器网页定位不应继续作为主路径。

推荐改成:

  1. Kindle 侧自己请求 GeoIP 接口,获取当前公网 IP 对应的城市、经纬度和时区
  2. 把结果缓存到本地
  3. 天气与相关展示统一读取这份缓存
  4. 当 GeoIP 不可用或结果异常时,回退到 Kindle 侧固定配置的 city/lat/lon/timezone

这是一个“市级近似定位”方案,不是 GPS 精确定位方案。

为什么 Kindle 侧 GeoIP 可行

GeoIP 的前提是“由目标设备自己发请求”。

对当前项目,正确的请求路径应该是:

Kindle -> GeoIP 服务 -> 返回 city / lat / lon / timezone

而不是:

Kindle -> 你的 Web 服务 -> Web 服务代查 GeoIP

后一种方式只会得到 Web 服务所在机房或服务器出口的位置。

如果 Kindle 走家庭 Wi-Fi且只要求“市级”颗粒度GeoIP 通常够用。 如果 Kindle 走手机热点、VPN、代理、企业网络或运营商 NAT结果可能偏到邻近城市必须接受这种误差。

目标能力

实现后需要具备以下能力:

  1. Kindle 联网后,能够自己获取当前网络出口对应的城市信息
  2. 获取结果会写入本地缓存
  3. 断网时仍可继续使用上次缓存
  4. GeoIP 失败时可回退到固定配置
  5. 只需要市级位置,不追求街道级精度

推荐数据模型

建议在 Kindle 侧维护一份位置缓存文件。

路径建议:

/mnt/us/dashboard/local/state/location.env

字段建议:

LOCATION_SOURCE=geoip
LOCATION_CITY=杭州
LOCATION_LAT=30.274084
LOCATION_LON=120.155070
LOCATION_TIMEZONE=Asia/Shanghai
LOCATION_UPDATED_AT=2026-03-17T10:00:00+08:00

同时保留一份固定兜底配置,例如:

LOCATION_FALLBACK_CITY=杭州
LOCATION_FALLBACK_LAT=30.274084
LOCATION_FALLBACK_LON=120.155070
LOCATION_FALLBACK_TIMEZONE=Asia/Shanghai

运行时脚本设计

建议新增 Kindle 侧脚本:

dash/src/local/location-sync.sh

职责:

  1. 检查网络是否可用
  2. 由 Kindle 自己请求 GeoIP 接口
  3. 解析响应中的城市、经纬度、时区
  4. 校验字段是否完整
  5. 写入本地缓存
  6. 失败时保留旧缓存,不要清空已有结果

建议同时新增一个只负责读取并导出环境变量的脚本,例如:

dash/src/local/location-env.sh

职责:

  1. 优先读取新鲜的 GeoIP 缓存
  2. 没有新鲜缓存时读取旧缓存
  3. 缓存不存在或无效时回退到固定配置
  4. 对外输出统一的 LOCATION_CITY/LAT/LON/TIMEZONE

刷新策略

位置不需要高频刷新。

建议策略:

  1. 启动 dashboard 且确认联网后,首次同步一次位置
  2. 每 12 小时或 24 小时刷新一次
  3. 手动切换主题时不强制刷新位置
  4. 天气刷新与位置刷新解耦
  5. 位置同步失败时继续使用现有缓存

与现有架构的衔接方式

当前项目是“背景图 + Kindle 本地时钟覆盖”的架构不是“Kindle 上实时跑完整天气网页”的架构。

因此接入位置数据时,有两条可选路径。

路径 A最小改动路径

保留当前背景图生成方式,但让背景图生成时显式读取 Kindle 侧缓存导出的城市与经纬度。

优点:

  • 改动面相对小
  • 仍可复用现有天气卡片布局与导出流程

缺点:

  • 需要重新梳理“背景图生成端”如何拿到 Kindle 缓存
  • 如果背景仍在 Mac 侧导出,就必须把 Kindle 缓存同步回 Mac 或转成请求参数

路径 B更符合现状的运行时路径

把“城市文本、天气数据”也逐步下沉到 Kindle 运行时,和本地时钟一样由设备端控制。

优点:

  • 位置与天气都由 Kindle 自己决定
  • 不会再混入 Mac 浏览器位置或服务器 IP 位置

缺点:

  • 改动更大
  • 需要重新设计天气卡的本地渲染方式

当前推荐

短期推荐先做:

  1. Kindle 侧 GeoIP 获取
  2. 本地缓存
  3. 固定配置兜底

等 SSH 恢复后,再决定位置数据如何喂给天气展示层。

也就是说,先把“位置来源”稳定下来,再改“展示方式”。

实施顺序

建议按下面顺序落地:

  1. 新增 location-sync.sh
  2. 新增 location-env.sh
  3. 在 Kindle 运行时目录中引入固定兜底配置
  4. 在主循环启动阶段接入位置缓存刷新
  5. 让天气读取逻辑改为优先使用 Kindle 侧位置缓存
  6. 最后补文档和手动刷新命令

验收标准

实现完成后,至少应满足以下验收条件:

  1. Kindle 联网后可生成位置缓存文件
  2. 缓存中至少包含 city/lat/lon/timezone
  3. 断网后仍能继续使用旧缓存
  4. GeoIP 失败时会稳定回退到固定城市
  5. 显示出的城市与 Kindle 当前所在城市大体一致

注意事项

  1. GeoIP 只能提供近似位置,不要当作精确定位
  2. 手机热点、VPN、代理、企业网络都会降低城市准确率
  3. 城市级结果可以用于天气展示,但不适合做严格地理判断
  4. 任何实现都必须保证“失败不影响 dashboard 主循环”

现阶段状态

当前仅完成方案设计,尚未开始代码实现。

直接原因是:

  • 目前 SSH 还未恢复
  • 设备侧脚本还不能方便地下发、调试和验证

后续等 SSH 恢复后,再按本方案分步实施。