9.7 KiB
Kindle Dashboard 分层时钟方案
1. 背景
当前仓库里有两部分:
calendar/:负责渲染仪表盘网页与导出背景素材dash/:运行在 Kindle 上,负责拉图、刷屏、休眠与唤醒
最新设计稿来自 Figma:
- 文件:
calendar - 节点:
6:2 - 链接:
https://www.figma.com/design/3bXFNM5nM6mCq0TpL3nPYK/calendar?node-id=6-2&m=dev
该节点 annotation 已明确:
阳历当天星期农历日时钟区域日历天气预报卡片书摘卡片
本方案基于这些约束,采用“低频背景 + 本地时钟”的拆分方式:
calendar/每2 小时生成一次背景图- 背景图直接写到:
/Users/gavin/kindle-dash/calendar/dist/kindlebg.png
- Kindle 通过固定 HTTPS 地址拉取背景图:
https://shell.biboer.cn:20001/kindlebg.png
- Kindle 端每分钟
不联网 - Kindle 端只在本地重画时钟区域
2. 目标
这次改造不是单纯调样式,而是把页面拆成两类刷新节奏完全不同的素材:
- 低频背景层
- 高频时钟层
目标收益:
- 背景内容不再分钟级刷新
- 分钟级变化只限制在时钟区域
- 降低 Wi-Fi 唤醒次数
- 降低全屏刷新频率
- 减少墨水屏闪烁与残影
3. 分层边界
3.1 全屏背景层
背景层文件名固定为:
kindlebg.png
背景层包含:
- 整体外层容器、圆角、阴影、背景渐变
- 日历卡片中的:
- 阳历当天数字
- 星期
- 农历日
- 下方月历区域
- 天气卡片全部内容
- 书摘卡片全部内容
背景层不包含:
- 时钟表盘主体
- 时钟刻度
- 时针
- 分针
- 中心圆点
也就是说,背景图在时钟区域只保留布局占位,不直接承载任何分钟级内容。
3.2 静态表盘 patch
静态表盘 patch 为一个独立本地素材:
clock-face.png
该素材包含:
- 圆形表盘主体
- 刻度
- 中心底座或中心圆盘
建议尺寸直接对齐 Figma 时钟区域:
- 节点:
24:74 - 设计尺寸:
220 x 220
这张图应当保存在 Kindle 本地,例如:
/mnt/us/dashboard/assets/clock-face.png
它不需要分钟级联网拉取,只需要在部署时同步到设备,或者在更换设计稿时重新同步。
3.3 指针层
高频变化层只包含:
- 时针
- 分针
这里不建议包含秒针:
- 墨水屏收益低
- 刷新频率会显著上升
- 更容易产生残影
由于当前 dash/ 链路本质是 eips 刷图,不是 SVG/Canvas 实时渲染,所以推荐使用分层素材方案:
minute-hand/00.png到minute-hand/59.pnghour-hand/000.png到hour-hand/719.png
说明:
- 分针每分钟一个角度,共
60张 - 时针如果要做到真正随分钟连续移动,需要
12 * 60 = 720张 - 这些都是小尺寸 patch,不是整屏图,体积可控
如果后续确认 Kindle 端存在稳定的本地绘线工具,再考虑把指针改成算法绘制;当前版本不依赖这个前提。
4. 为什么不能只把表盘放进整页背景
这个问题必须单独说明。
如果:
- 表盘主体和刻度只存在于
kindlebg.png - Kindle 每分钟只覆盖新的时针/分针
那么上一分钟留下的旧指针就无法被干净擦除。
因此 Kindle 端每分钟的正确流程应该是:
- 先重画一张本地
clock-face.png - 再叠加新的时针素材
- 再叠加新的分针素材
这等价于“先擦除,再重画”,并且整个流程不依赖网络。
所以本方案不是“背景图 + 两根指针”两层,而是:
kindlebg.png:全屏低频背景clock-face.png:本地静态表盘 patchhour-hand/*.png + minute-hand/*.png:本地高频指针素材
5. 数据刷新策略
5.1 背景层刷新
背景层刷新触发条件:
- 每
2 小时一次 - 跨天时立即刷新一次
- 天气接口异常恢复后可补刷一次
推荐调度:
00:00 / 02:00 / 04:00 / ... / 22:00
背景层刷新输出:
/Users/gavin/kindle-dash/calendar/dist/kindlebg.png
背景层对 Kindle 的访问地址固定为:
https://shell.biboer.cn:20001/kindlebg.png
5.2 静态表盘 patch 刷新
静态表盘 patch 不参加分钟级调度。
建议刷新方式:
- 随部署同步一次
- Figma 设计或尺寸变化时重新导出并同步
5.3 指针层刷新
指针层刷新触发条件:
- 每分钟一次
指针层数据只依赖 Kindle 本地时间:
- 小时
- 分钟
分钟刷新不需要联网。
6. 网页渲染模式设计
为了让 calendar/ 稳定产出背景与表盘素材,建议支持下面 3 种模式。
6.1 full
用途:
- 本地开发预览
- 对照 Figma 联调
输出内容:
- 背景层
- 表盘
- 指针预览
6.2 background
用途:
- 生成
kindlebg.png
输出内容:
- 只渲染背景层
- 时钟区域保留占位,但不绘制表盘与指针
6.3 clock-face
用途:
- 生成静态表盘 patch
输出内容:
- 只渲染表盘主体、刻度和中心底座
- 不绘制时针、分针
6.4 URL 约定
建议页面支持如下参数:
/?mode=full
/?mode=background
/?mode=clock-face
7. 产物约定
推荐最终产出这几类文件:
calendar/dist/kindlebg.png
calendar/dist/dashboard-manifest.json
kindle local:
/mnt/us/dashboard/assets/clock-face.png
/mnt/us/dashboard/assets/hour-hand/000.png ... 719.png
/mnt/us/dashboard/assets/minute-hand/00.png ... 59.png
manifest 建议至少包含这些字段:
{
"background": {
"path": "kindlebg.png",
"url": "https://shell.biboer.cn:20001/kindlebg.png",
"updatedAt": "2026-03-15T10:00:00+08:00",
"refreshIntervalMinutes": 120
},
"clockRegion": {
"x": 313,
"y": 0,
"width": 220,
"height": 220
},
"clockFace": {
"path": "clock-face.png",
"managedOnKindle": true
},
"clockHands": {
"hourPattern": "assets/hour-hand/%03d.png",
"minutePattern": "assets/minute-hand/%02d.png",
"refreshIntervalMinutes": 1,
"networkRequired": false
}
}
说明:
x/y/width/height先按设计稿记录- 真正接入 Kindle 时,要换算成最终截图分辨率下的实际像素值
8. Kindle 侧刷新策略
8.1 已确认的前提
eips 支持把 PNG/JPG 绘制到指定坐标,参数包含:
-g-x-y-f
MobileRead Wiki 明确写了:
eips -g|-b image_path [-w waveform -f -x xpos -y ypos -v]-x与-y以像素为单位
来源:https://wiki.mobileread.com/wiki/Eips
因此,对 Kindle Voyage 而言,“在固定时钟区域重画小图”这个前提是成立的。
8.2 推荐流程
启动或背景刷新时
- 通过 HTTPS 拉取:
https://shell.biboer.cn:20001/kindlebg.png
- 保存为本地背景缓存
- 使用全屏刷新显示背景图
- 在时钟区域重画一次:
clock-face.png- 当前时针
- 当前分针
每分钟刷新时
- 读取 Kindle 本机时间
- 计算:
minute_index = 00..59hour_index = ((hour % 12) * 60 + minute) = 000..719
- 在固定坐标先画:
clock-face.png
- 再画:
hour-hand/<hour_index>.png
- 再画:
minute-hand/<minute_index>.png
- 默认做局部/普通刷新
- 每
10到15分钟对时钟区域补一次全刷,清理残影
8.3 功耗模型
这套方式的功耗来源拆成两类:
- 背景刷新:
- 每 2 小时联网一次
- 全屏刷新一次
- 时钟刷新:
- 每分钟本地刷一次小区域
- 不联网
相比“每分钟拉一张整屏背景图”,这会明显省电。
9. 代码改造建议
9.1 calendar/
建议改造点:
- 新增
mode=background - 新增
mode=clock-face - 时钟区域从日历/天气/书摘中完全拆开
- 增加一个定时生成任务,每 2 小时把背景图写到:
/Users/gavin/kindle-dash/calendar/dist/kindlebg.png
- 生成
dashboard-manifest.json
9.2 dash/
建议改造点:
dash/src/local/fetch-dashboard.sh- 改成只拉取
kindlebg.png
- 改成只拉取
dash/src/dash.sh- 从“单一刷新循环”改为“背景刷新 + 本地时钟刷新”双节奏
- 新增例如:
dash/src/local/render-clock.shdash/src/local/render-clock-face.shdash/src/local/clock-index.sh
推荐新增配置项:
export BACKGROUND_URL="https://shell.biboer.cn:20001/kindlebg.png"
export BACKGROUND_REFRESH_SCHEDULE="0 */2 * * *"
export CLOCK_REGION_X=313
export CLOCK_REGION_Y=0
export CLOCK_REGION_WIDTH=220
export CLOCK_REGION_HEIGHT=220
export CLOCK_FULL_REFRESH_INTERVAL_MINUTES=15
10. 实施顺序
建议按下面顺序落地,避免一次改太多导致链路难排查。
阶段 1:calendar/ 分层输出
目标:
full/background/clock-face三种模式跑通- 每 2 小时把背景图写到
calendar/dist/kindlebg.png
输出:
- 浏览器可预览
kindlebg.png可被 nginx 直接访问
阶段 2:时钟静态素材准备
目标:
- 产出
clock-face.png - 产出
hour-hand与minute-hand素材库
输出:
- Kindle 本地时钟素材目录结构确定
阶段 3:Kindle 本地分钟时钟
目标:
- Kindle 每分钟本地重画时钟
- 不联网
输出:
- 背景低频更新 + 时钟本地高频更新的完整链路
11. 推荐结论
当前最稳妥的推进顺序是:
- 先让
calendar/每 2 小时稳定生成:/Users/gavin/kindle-dash/calendar/dist/kindlebg.png
- 再让 Kindle 只从:
https://shell.biboer.cn:20001/kindlebg.png拉背景图
- 时钟区域完全本地化:
- 本地
clock-face.png - 本地
hour-hand/*.png - 本地
minute-hand/*.png
- 本地
- 分钟刷新时:
- 先重画表盘
- 再重画时针
- 再重画分针
也就是说,背景是远端低频资源,时钟是本地高频资源,二者不要混在同一个刷新链路里。