Kindle 变身:打造极致低功耗的墨水屏日历

2026年1月11日 · 1570 字 · 4 分钟

手里有一台闲置多年的 Kindle 4,屏幕素质依然不错。与其让它在抽屉里吃灰,不如将其改造成一个桌面墨水屏日历。

虽然市面上已有类似项目(如 Kindle Dash),但它们大多依赖服务器端渲染(需要 Docker/Node.js),且 Kindle 必须时刻保持 WiFi 连接,这对续航是极大的考验。

于是,我开发了 Simple Kindle Dashboard。与其说它是一个客户端,不如说它是一套完整的离线运作体系

✨ 为什么重造轮子?

核心目标只有两个:极简省电

与其他方案相比,这个项目的杀手锏是 Offline 模式。利用 Kindle 的存储空间,我们可以预先生成未来半年的日历图片。这意味着 Kindle 在唤醒更新屏幕时完全不需要开启 WiFi,从而将功耗降至物理极限。

特性 本项目 (Offline Mode) 传统方案 (Online Web)
网络依赖 ❌ 无需网络 ✅ 必须 WiFi
单次刷新耗时 ~2 秒 ~15-30 秒 (含连网)
理论续航 1-2 个月 数天
复杂度 Shell + Python Docker + Server

🛠️ 核心技术栈

这个项目虽然小,但也“五脏俱全”,涉及到了多种技术的融合:

  • Python (Pillow): 用于在 PC 端生成像素级完美的 UI 图片。
  • Shell Script: 运行在 Kindle 上的生命周期管理(唤醒、绘图、休眠)。
  • Rust: 使用 next-wakeup 二进制工具处理复杂的 RTC (Real Time Clock) 调度,解决 Shell 处理跨月跨年的痛点。
  • uv: 现代化的 Python 包管理器,用于极速搭建生成环境。

🎨 UI 设计与实现

1. 像素级绘图 (generate_images.py)

Kindle 4 的分辨率为 600x800。为了获得最佳显示效果,我使用 Python 的 Pillow 库直接绘制 8 位灰度图 (mode='L')。

UI 设计包含以下元素:

  • 顶部:超大字号的日期显示 (使用开源的“LxgwWenKai”霞鹜文楷字体)。
  • 中部农历新年倒计时。这是一个动态计算模块,每天通过进度条和数字提醒你距离过年还有几天。
  • 底部:每日一句中文名言。

为了美观,代码中实现了基于 textwrap自动换行与垂直居中算法,确保无论名言长短,都能优雅地展示在屏幕中央。

# 自动排版逻辑片段
width_chars = 16 
lines = textwrap.wrap(quote, width=width_chars)
y_pos = 570
# 动态调整起始 Y 坐标
if len(lines) > 1:
    y_pos -= (len(lines) - 1) * 20

2. 图像预览

Dashboard Preview

⚡ 深度休眠与调度机制 (dashboard.sh)

这是项目最硬核的部分。Kindle 运行在 Linux 之上,我们利用 sysfs 接口直接控制电源管理。

精准唤醒

为了保证每天凌晨定时刷新,脚本会调用 next-wakeup 计算秒级的时间差,并写入 RTC:

# 计算等到明天凌晨 4 点还需要几秒
WAIT_SECONDS=$(./next-wakeup --schedule "0 4 * * *" --timezone "Asia/Shanghai")

# 写入硬件闹钟
echo 0 > /sys/class/rtc/rtc0/wakealarm
echo $(($(date +%s) + $WAIT_SECONDS)) > /sys/class/rtc/rtc0/wakealarm

电量焦虑治愈

加入了严格的低电量保护逻辑。当电量低于 10% 时:

  1. 屏幕显示 “Low Battery” 警告图。
  2. 清除 RTC 闹钟
  3. 进入永久深度睡眠 (STR),防止电池过放损坏。

🚀 如何部署

得益于 uv,本地环境的配置非常简单:

# 1. 克隆代码并初始化
uv init
uv add pillow

# 2. 生成未来 180 天的日历图片
uv run python generate_images.py
# 输出:✅ 完成!已生成 180 张图片到 imgs/ 目录。

之后,只需将生成的 imgs/ 文件夹和脚本上传到 Kindle,并通过 KUAL 插件启动即可。

🚧 填坑记录 (2026-01-12 更新)

在实际部署和长期运行中,解决了一些有趣的硬核技术问题:

1. 顽固残影 (Ghosting) 的消除

E-ink 屏幕如果刷新不彻底,会残留上一屏(如 Kindle 主页)的内容。测试发现,仅调用一次 eips -c 是不够的。

解决方案:实施了 “Triple Clear” (三连刷) 策略。在显示图片前,连续执行 3 次清屏指令,且每次间隔 1-2 秒。虽然刷新过程延长了,但换来了如纸般纯净的底色,彻底消除了深色 UI 的残留。

2. FAT32 文件系统的部署难题

Kindle 的用户分区 (/mnt/us) 是 FAT32 格式,这意味着它不支持 Linux/Unix 的文件权限 (Permissions) 和所有者 (Owner) 属性。传统的 scp 或者 rsync -a 往往会遇到权限错误或报错 Operation not permitted

解决方案:弃用 scp,改用参数调优后的 rsync

# 仅同步内容和时间戳,忽略权限与所有者
rsync -rltvz --no-p --no-o --no-g ...

3. 原生 eips 工具的 “缺字” Bug

Kindle 系统自带的 eips 绘图工具字库非常精简,竟然没有内置 % (百分号)!这导致脚本试图显示 “Batt: 98%” 时直接报错退出。

解决方案:改用朴素的 Bat:98 文本格式,并顺手加上了 实时时间显示 (如 Bat:98 08:30),弥补了全屏挂历模式下看时间的刚需。

📝 总结

通过几百行 Python 和 Shell 代码,这台 Kindle 成功从电子垃圾堆里“复活”了。它现在摆在我的桌面上,每天安安静静地更新一张日历,既不发光也不打扰,有着纸张般的质感。

如果你也想折腾,欢迎 check out 项目代码!