从抽屉里翻出一台吃灰好几年的 Kindle 7,屏幕完好,电池居然还能撑住,系统也还流畅。扔了可惜,卖掉不值几个钱,于是我顺手把它改成了一块桌面日历天气屏,放在书桌上当信息看板。整个改造从下午开始到傍晚基本收工,成本几乎为零,收获却是一块低功耗、不刺眼、能让人每天多看一眼的电子墨水屏。这篇就把完整的改造思路和步骤拆开讲,手里也有旧 Kindle 的朋友可以直接照着折腾。
我要先说明白这东西改了之后能干什么:每天早上扫一眼,日期、农历、距离节假日的天数、当天天气和未来几天预报全在一屏上;它不像手机那样容易让人分心,也不会像普通屏幕那样常亮烧眼睛,放在书桌一角就是个安静的信息台。适合的人很明确——手里有闲置 Kindle、愿意稍微动动手、想找个实用改造方案的人。
1. 为什么选 Kindle 7 当桌面日历屏
1.1 一块能显示信息的墨水屏,到底值多少钱
市面上的电子墨水屏信息牌,从几百到上千元都有,而且很多还得自己配外壳、配网关,到手就是一笔明显开销。二手 Kindle 7 本身已经是电子垃圾的价位,拿来改造,硬件上的额外投入基本是零。
关键是电子墨水屏这种屏幕,天生就适合“长期摆在那里显示固定信息”的场景。普通液晶屏或者手机屏幕常亮,一是有烧屏风险,二是一直亮着费电又费眼。而墨水屏在画面静止时几乎不耗电,只有刷新那一下才有明显功耗,所以一块旧 Kindle 改造出来的日历屏,本质上等于免费拿到了一块低功耗信息面板。
用 Kindle 做这个事还有一个隐性好处:它本来就是为阅读设计的设备,反射式显示在室内灯光下非常清楚,不会像手机那样在强光下看不清。放在书桌靠窗的位置,白天效果尤其好,比看手机上的天气 App 更自然,也不容易在打开屏幕之后顺便刷走十分钟。
1.2 Kindle 7 做日历屏的优点与局限
先说不吹不黑的优点:
- 电子墨水屏,静止画面不耗电,充满一次电撑一两周很正常,我现在这块基本没有续航焦虑。
- 屏幕尺寸 6 英寸,分辨率 600×800,显示日期、天气、几行日历事项刚好,放桌面不占地方。
- 系统足够封闭稳定,越狱后只干一件事,反而不容易崩溃,我连续运行一个月没出过问题。
- 外观本来就适合“小电器”的身份,底座都不用额外买,网上找个合适的 Kindle 支架或者用手机支架都能放稳。
再说几个必须提前知道的局限,免得你动手之后后悔:
- Kindle 7 没有背光,晚上如果环境光不够,屏幕根本看不清。我的解决方案是把它放在台灯旁边,或者用一个 USB 小灯补光。
- 分辨率不算高,信息卡设计时字号就得大一些,字体渲染如果没做好,会明显模糊。
- 处理器性能很弱,官方浏览器体验很差,不要指望在 Kindle 上直接打开一个复杂的网页当信息屏,老老实实用“脚本生成图片再显示”这个思路。
- 官方固件默认一段时间无操作会自动休眠,需要手动关掉,或者想办法保持唤醒状态,这一步在后面的实操里我会详细说。
2. 改造前的准备:型号、固件和工具
2.1 先确认你的 Kindle 到底是不是 Kindle 7
动手之前一定要确认型号。Kindle 7 是 2014 年发布的那款基础版,国内很多人叫它“Kindle 7代”或者“Kindle 7”。判断方法很简单:进设置——设备信息——查看型号,一般会显示类似“Kindle (7th Generation)”的字样,或者型号代码如 MKP7 之类。
这里有个坑:很多人手里其实是 Kindle Paperwhite 3 或者更早的 Kindle Keyboard,型号不同,越狱方案和屏幕命令不完全一样。尤其是屏幕分辨率,Paperwhite 系列是 300 PPI,分辨率跟 Kindle 7 不一样,直接套用后面的脚本,图片尺寸会不匹配,显示就会出问题。所以第一步务必花两分钟确认型号,不要看外观猜。
另外确认一下系统版本。同样进“设备信息”,里面会显示类似 5.15.1 这样的固件版本号。越狱工具都是针对特定固件版本的,版本不对不要说越狱,连安装包都不可用。如果你的 Kindle 已经自动升级到了新版本,先记下版本号,再去对应论坛找匹配的越狱资源。
2.2 固件版本与越狱包的匹配逻辑
Kindle 的越狱,本质上是利用官方固件底层的某个漏洞或者调试入口,拿到一个可以运行 shell 命令的通道。它不是刷安卓,也不是改系统,所以风险比很多人想象的低很多,但前提是版本要匹配。
我当时的流程是这样的:
- 把 Kindle 连接到电脑,确保能看到 Kindle 根目录。
- 进入“设置—设备选项”,手动关闭自动更新。这一步非常重要,因为固件一旦自动升级,越狱包可能会失效,前功尽弃。
- 去知名的 Kindle 技术社区(比如英文的 MobileRead 论坛)搜索对应固件版本的越狱包。一般帖子标题里会写清楚支持哪个版本区间。
- 按照帖子里的说明,把对应文件放到 Kindle 根目录,然后重启设备,再进 Kindle 的“收藏夹”或“设置”菜单里触发安装。
- 安装完成后,再装一个叫 KUAL 的启动器(Kindle Unified Application Launcher),它是后续所有操作的中枢。
工具方面其实非常简单:一台电脑、一根 micro-USB 数据线、一个能上网的阅读器(论坛上翻越狱包说明时需要)。不需要焊烙铁,不需要拆机,整个过程不需要动硬件。
3. 核心方案选型:为什么要“服务端渲染图片 + 定时刷新”
3.1 三种常见方案的对比
我在动手之前查了不少现成项目,也自己推演了几种方案,这里直接列出来对比:
| 方案 | 实现思路 | 优点 | 缺点 |
|---|---|---|---|
| 直接用 Kindle 浏览器打开网页 | 在 Kindle 自带的实验浏览器里打开一个天气日历网页 | 配置最少 | 浏览器 JS 能力弱、刷新很卡、经常白屏,基本不可用 |
| 在 Kindle 上装一个 Linux 应用直接绘制 | 通过越狱后的 shell 或第三方应用直接绘制界面 | 响应快,不依赖外部服务 | 实现复杂,不适合没有开发基础的人,而且 Kindle 性能有限 |
| 服务端生成图片,Kindle 定时下载并显示 | 电脑或服务器定期生成一张 PNG,Kindle 通过脚本下载图片并显示 | 稳定、对 Kindle 性能要求极低、显示效果可控性最高 | 需要一个能定时跑脚本的设备(电脑也行),依赖网络 |
我选的是第三种。原因很直接:Kindle 7 的硬件性能太弱,如果让它在本地渲染日历、拉取天气、计算农历,稍微复杂一点就卡。而把数据拉取和图片渲染放到电脑或者服务器上,Kindle 只负责“下载一张图并显示”这件事,它只需要一点网络能力和一个刷新命令就够了,稳得不行。
3.2 图片化方案里的关键组件拆解
图片化方案拆开来看,其实是三个独立模块在协作:
- 数据获取模块:从天气接口拿天气数据,从日历文件或者接口拿日历事件。
- 图片渲染模块:用代码把天气和日历文字排版成一张 600×800 的 PNG 图片。
- 定时刷新模块:分两部分,一边由电脑/服务器定时重新生成图片,另一边由 Kindle 定时下载新图片并刷新屏幕。
这种“生成图片—拉取—显示”的思路,其实很适合很多类似的改造项目。比如有人把 Kindle 改成电子相册、改成 TODO 看板、改成股票行情屏,底层逻辑都是同一个:把信息变成图片,再喂给墨水屏。
3.3 数据源选型:天气和日历从哪里来
天气数据我选的是 Open-Meteo,免费、无需注册、不用 API Key,对个人项目来说非常友好。它的接口是一个 URL,直接请求就能拿到 JSON 格式的预报数据,包括每天最高温、最低温和天气代码。
日历数据我用的最简单的方式:一个 JSON 文件,手动维护几件重要的事,比如“房贷还款日”“项目截止日期”“亲戚生日”等。如果想要更自动化,也可以读本地或者是远程的 .ics 日历文件,解析出最近的事件再渲染到图片里。考虑到 Kindle 7 屏幕有限,我建议日历事件不要超过 5 条,多了也看不清楚。
这里有一个特别容易踩的坑:时区。天气接口默认返回的是 UTC 时间,如果你不在 URL 里明确指定 timezone 参数,显示的“今天”可能跟你本地差一天。我一开始就吃了这个亏,周末界面显示的是周五的数据,排查半天才发现是 timezone 参数漏了。
4. 实操记录:从零到一块能用的日历天气屏
4.1 越狱、安装 KUAL、准备脚本目录
先按第 2 节的流程完成越狱和 KUAL 安装。KUAL 装好之后,你会看到 Kindle 的“收藏夹”里多出一个类似 “Kindle Launcher” 的入口,通过它可以启动一些扩展脚本。
然后创建一个脚本目录。Kindle 连接电脑后,根目录下通常有一个extensions文件夹,如果看不到就手动新建一个。我们的刷新脚本放在这个目录下,比如:
extensions/calendar-display/ ├── run.sh └── config.ini这个目录里的脚本可以直接在 KUAL 里通过菜单触发,方便调试时手动跑一次看看效果。
提醒一点:Kindle 的官方系统在连接电脑和充电时,一般不会进入休眠,但是在脱离电脑、长时间不操作后容易回到屏保或休眠状态。所以后面还要处理“保持唤醒”的问题,我第 5 节再展开。
4.2 在电脑或服务器上写一个真正的渲染脚本
下面这段 Python 代码是核心。它做的事情是:请求 Open-Meteo 天气接口,读取本地的 events.json 日历文件,用 Pillow(PIL)渲染出一张 600×800 的 PNG 图片。
先安装依赖:
pip install pillow requests然后写render_calendar.py:
import requests import json from datetime import datetime, timedelta from PIL import Image, ImageDraw, ImageFont # ---- 配置区域 ---- LAT = 31.2304 # 你的纬度 LON = 121.4737 # 你的经度 TIMEZONE = "Asia/Shanghai" FONT_PATH = "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc" # 或者用你系统里的中文字体 OUTPUT_PATH = "daily_display.png" # ---- 配置区域结束 ---- # 1. 拉取天气数据 weather_url = ( f"https://api.open-meteo.com/v1/forecast?" f"latitude={LAT}&longitude={LON}" f"&daily=temperature_2m_max,temperature_2m_min,weathercode" f"&timezone={TIMEZONE}" ) weather = requests.get(weather_url, timeout=10).json() daily = weather["daily"] today = datetime.now() today_str = today.strftime("%Y-%m-%d") # 找出今天和未来三天的数据 idx_today = daily["time"].index(today_str) if today_str in daily["time"] else 0 days = daily["time"][idx_today: idx_today + 4] temp_max = daily["temperature_2m_max"][idx_today: idx_today + 4] temp_min = daily["temperature_2m_min"][idx_today: idx_today + 4] weathercode = daily["weathercode"][idx_today: idx_today + 4] # 2. 读取本地日历事件 with open("events.json", "r", encoding="utf-8") as f: events = json.load(f) # 找出还没过期的、最近的事件 events.sort(key=lambda x: x["date"]) upcoming = [] for ev in events: ev_date = datetime.strptime(ev["date"], "%Y-%m-%d") if ev_date.date() >= today.date(): upcoming.append(ev) if len(upcoming) >= 5: break # 3. 开始渲染 img = Image.new("RGB", (600, 800), "white") draw = ImageDraw.Draw(img) # 字体设置 font_large = ImageFont.truetype(FONT_PATH, 42) font_mid = ImageFont.truetype(FONT_PATH, 28) font_small = ImageFont.truetype(FONT_PATH, 22) # 左上角日期 draw.text((30, 30), f"{today.month}月{today.day}日", font=font_large, fill="black") draw.text((30, 90), f"{today.year}年 星期{today.strftime('%A')}", font=font_small, fill="black") # 天气信息 y = 160 draw.text((30, y), f"今天 {temp_min[0]}°C ~ {temp_max[0]}°C", font=font_mid, fill="black") for i in range(1, 4): y += 50 draw.text((30, y), f"{days[i][5:]} {temp_min[i]}°C~{temp_max[i]}°C", font=font_small, fill="black") # 日历事件 y = 360 draw.text((30, y), "近期事项", font=font_mid, fill="black") y += 45 for ev in upcoming: ev_date = datetime.strptime(ev["date"], "%Y-%m-%d") diff = (ev_date.date() - today.date()).days label = f"{ev['name']} ({diff}天后)" if diff > 0 else f"{ev['name']} (今天)" draw.text((30, y), f"{ev['date']} {label}", font=font_small, fill="black") y += 40 img.save(OUTPUT_PATH) print("generated:", OUTPUT_PATH)这段代码不复杂,但要注意几个细节:
- 字体文件路径要改成你自己系统里的中文字体路径。Linux 上可以直接安装文泉驿微米黑:
apt install fonts-wqy-microhei。Windows 上可以填C:/Windows/Fonts/msyh.ttc(微软雅黑)。 - 天气代码
weathercode只是拿到了数字,实际显示可以进一步翻译成“晴/多云/雨”的中文,我为了简洁没有全展开,你可以按 Open-Meteo 的文档在脚本里加一个映射字典。 - Kindle 7 屏幕是 600×800 竖屏,但很多人在桌面摆放时习惯横着放,那渲染尺寸就要做成 800×600,或者在显示时用图片旋转参数处理。我的方案是横着放,所以直接把渲染尺寸反过来。
4.3 让电脑定时生成图片,Kindle 定时拉取
电脑端生成图片这一步,我用的是 cron 定时任务,每 30 分钟跑一次:
*/30 * * * * cd /path/to/script && python3 render_calendar.py渲染出来的daily_display.png需要能被 Kindle 通过网络访问到。最简单的方式是在同一台电脑上开一个静态文件服务:
cd /path/to/script && python3 -m http.server 8080 --bind 0.0.0.0这样 Kindle 就能访问http://你的电脑IP:8080/daily_display.png。如果不想让电脑一直开机,也可以把这个脚本放到一台低功耗服务器或者树莓派上,逻辑完全一样。
Kindle 端的刷屏脚本放在extensions/calendar-display/run.sh:
#!/bin/sh # 网络请求 wget -O /mnt/us/calendar/tmp.png "http://192.168.1.100:8080/daily_display.png" || exit 1 # 备份旧图,再显示新图 cp /mnt/us/calendar/tmp.png /mnt/us/calendar/current.png # 全屏刷新显示图片,-f 是全刷参数 eips -f -g /mnt/us/calendar/current.png注意,Kindle 的 eips 命令对图片格式和分辨率比较挑剔。分辨率不匹配时,有的机器会直接不显示,有的会显示成花屏。我的做法是让脚本端严格生成 800×600 的图片,然后在 Kindle 端不再做图像处理。
再写一个定时循环脚本/mnt/us/extensions/calendar-display/loop.sh,让 Kindle 每 30 分钟自己重新拉取一次:
#!/bin/sh while true; do sh /mnt/us/extensions/calendar-display/run.sh sleep 1800 done通过 KUAL 菜单启动一次loop.sh,它就会在后台一直跑。如果想开机自动启动,可以把启动命令写进 KUAL 的自动运行配置里,不过我觉得手动启动也够了,反正重启这种事很少发生。
4.4 处理休眠问题
Kindle 默认会在几分钟无操作后进入屏保状态。如果屏幕进入屏保,我们的日历图就被遮住了。我曾经就遇到过这个问题,一开始以为脚本有问题,后来发现是设备自己睡过去了。
最简单的解决办法是在 Kindle 的设置里把“自动休眠”关掉。部分固件版本在“设置—设备选项”里有这个开关,如果没有,就需要在越狱环境里装一个禁止休眠的小插件,或者在循环脚本里每几分钟模拟一次按键事件让系统认为设备还在被使用。后面这种办法有点土,但确实有效。
我的做法是关掉自动休眠后,再接上 USB 供电,让 Kindle 一直保持通电和联网状态,这样它基本不会主动睡过去。如果你想彻底省心,还可以把 Kindle 设置成“飞行模式”关闭再开,确保每次刷新前网络是正常的——不过这属于优化细节,后面再说。
5. 显示效果优化与功耗控制
5.1 残影、对比度和界面设计
墨水屏和普通屏幕不一样,刷新慢,而且黑白切换后会留残影。这个在刚刷新完的几秒钟内特别明显,尤其是前一天图片有大面积黑色块的时候,第二天换到白色背景,能隐隐看到原来的图案。
解决残影的办法就一件事:全刷。eips 命令默认是局部刷新,加上-f参数就是全刷。全刷会让整个屏幕黑白翻转一次,看似闪一下,但对残影的清理非常有效。我的做法是:每次刷新都用-f,宁可多闪一下,也不要让残影一直留在屏幕上。
界面设计上也有讲究。墨水屏最适合的是白底黑字、高对比度的极简风格。建议不要用大面积深色背景,不要用复杂的装饰边框,不要用低于 20 号的字体。等你实际看几天就会明白,这种显示屏不需要花哨,清晰才是第一位的。我现在这个界面就是黑字、白底、几条分割线,信息一目了然。
5.2 刷新频率怎么定才合理
原则上,墨水屏每个像素翻转都需要时间,刷新越频繁,耗电越快,残影也越明显。天气这种东西,半小时变化已经很快了,日历事件更是每天才变一次。
我的刷新策略是:
- 白天每 30 分钟刷新一次天气和日历图。
- 晚上 10 点到早上 7 点之间不刷新,让屏幕静止,这一夜的电量消耗几乎可以忽略。
- 每天早上 7 点半自动刷新一次,刚好能看到当天天气。
这个策略实施下来,一块 Kindle 7 的电池大约能撑 10 天到两周,已经是“不需要想着充电”的状态了。如果你追求更极限的续航,可以把刷新频率降低到每小时一次,效果也差不了多少。
5.3 供电和长期运行建议
如果你打算把它当成固定的桌面信息屏,我会推荐直接用 USB 线长期供电。Kindle 7 的充电口是 micro-USB,随手一根线就能解决。长期通电对墨水屏没有影响,它不发热,也没有烧屏风险。
但长期满电对锂电池不算友好,所以我建议用一个老旧的小电流充电头(5V/1A 甚至更低)配合供电,或者使用智能插座定时断电。如果设备已经充满电,可以设置成每天只充几个小时后断电,延长电池寿命。这不是必须的操作,但长期稳定运行的话值得考虑。
另外一个容易被忽略的点是网络。Kindle 7 的 WiFi 模块性能一般,长时间待机后偶尔会掉线。我在刷新脚本里加了一个简单的网络检测:如果 wget 失败,30 秒后重试一次,还不行就等下一次刷新再试。这样偶尔一次掉线不会让屏幕一直停在旧数据上。
6. 常见问题与排查实录
6.1 问题排查速查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 屏幕一直显示旧图片,不刷新 | Kindle 进入休眠,或者循环脚本没跑起来 | 关掉自动休眠;确认 KUAL 是否正常启动 loop.sh |
| 显示花屏或只有一半画面 | 图片分辨率不匹配,或没有用全刷参数 | 按要求生成 600×800(或 800×600)图片,使用eips -f -g |
| 图片下载失败,屏幕空白 | WiFi 断连,或电脑端 HTTP 服务没启动 | 检查网络;确认http.server进程是否存活 |
| 天气温度和手机 App 对不上 | 时间/时区设置错,或天气接口返回的数据源不同 | 检查 URL 中 timezone 参数;必要时切换到其他免费天气接口对比 |
| 越狱后 KUAL 打不开 | 固件版本不匹配,或自动更新覆盖了越狱 | 重新确认固件版本,去论坛找对应版本的越狱包,重刷一次 |
| 中文字体显示为方块/乱码 | 字体文件没找到,或字体不支持中文 | 安装中文字体,并在渲染脚本里明确设置字体路径 |
6.2 我踩过的几个坑
第一个坑是屏幕方向。我一开始按竖屏渲染图片,但桌面摆放时想横着放,结果图片是竖的,看起来总是不对劲。当时为了省事没调整渲染尺寸,而是想用 eips 命令参数旋转,结果折腾了一个小时没成功。后来乖乖把渲染尺寸改成 800×600,一下就正常了。Kindle 系统对图片旋转的支持很差,最靠谱的办法就是从源头生成对的方向。
第二个坑是字体渲染。Pillow 默认字体非常难看,中文显示完全没法看。我换上文泉驿微米黑之后,效果立刻不一样了,但需要注意的是字体文件路径要在脚本里写全,不能只写文件名。如果你在 Windows 上开发、Linux 上部署,两条路径还不一样,最好在脚本里做一次平台判断。
第三个坑是 eips 命令的图片格式问题。有些教程会告诉你可以显示 JPEG,但实测中 JPEG 偶尔会出现解码失败或者花屏,而 PNG 就没出过问题。所以我在渲染脚本里一直输出 PNG,不在 Kindle 端做格式转换。
另外一个小经验:刚开始调试时,建议先用 KUAL 手动触发一次刷新,确认图片能正常显示,再挂上自动循环。否则你都不知道是网络问题还是显示问题,排查起来很乱。
写在最后的一点体会
整个项目做完,我最大的感受是:旧设备的归宿不一定只有“吃灰”和“回收”两个选项。Kindle 7 的硬件放在今天确实落伍,但电子墨水屏这个属性让它有了完全不同的使用场景。改造成日历屏后,它每天安安静静地待在书桌上,反而比很多智能设备更让我觉得顺眼——它不会推送通知,不会诱导你点亮屏幕,它只在你需要看一眼的时候给出信息。
如果你手里没有 Kindle 7,但有一台其他型号的 Kindle 或者其他安卓电纸书,思路也完全一样:先确认分辨率,再设计渲染脚本,最后套上“定时拉取图片 + 本地显示”的壳。这个套路甚至可以扩展到电子相册、倒计时牌、习惯打卡表等场景,核心就是一句话:把动态信息渲染成一张静态图片,再让墨水屏去做它最擅长的事情。
最后再分享一个小技巧:如果你和我一样有点完美主义,可以在渲染脚本里加一个“农历和节假日”模块,稍微查一下农历换算的算法,就能把“距离中秋还有几天”“今天农历几号”也一并显示出来。这个功能我自己一直用到现在,比单纯显示公历实用得多。