本篇记录 PiBoard 从运行问题修复到v0.1.2发布的过程,依据公开源码和 2026 年 11 月 12 日的验收记录整理。本文整理于 Nov 13, 2026,没有在写作时重新连接设备或复测外部服务。
前面几篇分别讨论了内容结构、数据来源和点阵排版。等这些部分能够协作之后,另一个问题变得越来越重要:怎样确认树莓派上运行的,确实是准备发布的那份代码?
看到屏幕亮着只能回答很小一部分问题。网页长连接可能堵住普通请求,错误参数可能已经写入配置,旧字体补丁也可能被误当成完整新版本。这一篇把运行修复与验收过程放在一起记录。
WebSocket 连上了,HTTP 却不能等着
控制台通过 HTTP 读取和提交数据,再通过 WebSocket 接收状态。早期单线程服务会被 WebSocket 长连接占住,普通请求也就跟着等待。
当前启动方式启用了请求线程,并移除了应用层的空闲断开逻辑。验证时不能只分别打开两个地址,而要保持 WebSocket 连接,再检查 HTTP 是否仍能响应,随后确认同一条 WebSocket 还能接收状态。
pygame 绘制仍然留在主线程。网页请求、后台数据获取和屏幕绘制分工不同,把服务改成可并发处理请求,也不意味着可以让任意线程调用 pygame。
状态恢复先完成检查,再替换
配置文件会保存页面、布局、来源和设备设置。读取时如果直接逐项覆盖全局状态,后面才遇到损坏字段,就可能留下部分新值和部分旧值。
现在的恢复逻辑先在副本中检查结构、补齐默认值,再整体替换;失败时保留原状态。保存则先写临时文件、同步数据,再通过
os.replace() 替换目标文件。这些做法降低了半写入和半恢复的风险,但没有让配置天然免疫所有故障。例如旧版本迁移还要保留手动城市的意图,不能先套上默认值,再把用户的选择误判成自动定位。恢复流程正确与迁移语义正确,是两个都要检查的问题。
运行中的写入也要校验
只在启动时检查文件还不够。控制台运行期间,HTTP 和 WebSocket 都能修改状态,错误结构仍可能进入持久化文件,甚至影响显示主循环。
v0.1.2 增加了共享写入校验,在状态修改前检查 JSON 对象、字段类型、布局和枚举值。例如 slots 需要是由合法来源标识组成的数组,不能塞进对象;Custom 标题也不能是数字。输入问题 | 处理目标 |
JSON 顶层是数组或其他错误结构 | 拒绝进入状态修改流程 |
未知布局、来源或非法 slots | 拒绝错误配置 |
数字进入应为字符串的标题字段 | 在绘制前阻止类型错误 |
WebSocket 消息不合法 | 返回错误,同时保留可继续使用的连接 |
回归记录新增了 8 项写入校验检查。设备验收还用少量无效 HTTP 写入确认返回 400 且状态不变;更广的错误组合放在隔离测试中,不拿私人配置反复试错。
这层校验解决了已覆盖的结构、类型和枚举问题。多设备设置冲突、完整业务语义以及身份认证,仍然是另外的工作。
补丁验收和整版验收要分开
在正式整合之前,项目已经分别把显示调整与人工确认的字体部署到树莓派。这些记录证明对应补丁在设备上工作,但不能自动证明后来加入的全部运行修复也已经部署。
因此历史记录保留了不同状态:旧正式版、局部 overlay、
v0.1.2-rc.1 候选版,以及最终 v0.1.2。候选版文档里“尚未完成完整设备验收”的描述,应该结合它自己的时间点理解。正式发布时需要重新对齐三件事:
- 本地准备发布的干净提交和版本标签。
- 树莓派实际部署的源文件与构建标记。
- 正在运行的服务通过
/api/version返回的版本和提交。
设备端不一定有 Git 仓库,所以仅比较版本字符串还不够。此次部署同步 Git 跟踪的文件,生成运行标记,并逐文件校验 SHA256,使代码身份有独立证据。
部署要保留用户的数据
天气地点、列车配置和私人订阅属于设备上的运行数据,不应被公共示例配置覆盖。
这次发布先在项目内部保留代码归档与私人状态备份,再同步公开跟踪文件,不使用删除式同步去清理整个目录。验收过程中临时切换页面,结束后恢复原来的布局、当前应用和轮播设置,并比较解析后的持久化 JSON。
失败时也需要一条可执行的恢复路径:停止原服务,恢复项目归档和原状态,再启动同一个服务,读回旧标记和配置。单纯说“有 Git,可以回滚”,不足以处理设备端没有仓库、代码与状态又分开保存的情况。
这里记录的是项目自身的部署策略,没有通过改路由、DNS 或系统配置来掩盖运行问题。
验收结果,按证据能回答的问题来写
v0.1.2 的公开记录包含本地和 Pi 两侧的编译检查、41 项 unittest、6 项发布 smoke 与 4 项视觉 smoke,以及多个桌面和手机宽度的控制台检查。服务 active/enabled,实际进程使用 kmsdrm 后端,五个页面的 API 切换后渲染进程仍存活。这些结果覆盖软件运行路径,但还需要逐个解释真实数据:
来源 | 当次验收结果 | 不能据此推出的结论 |
天气 | 保存地点的 Open-Meteo 获取与映射成功 | 自动定位必然正确,或所有天气服务都通过 |
日历 | 已有私人 iCal 获取和解析成功,窗口内 0 事件 | 重复规则和跨日事件已完整支持 |
列车 | 两个已配置上游返回 HTTP 500,显示等待或不可用 | 实时车次已经验收成功 |
Custom | 手工内容路径可用 | 属于实时数据 |
列车外部服务失败时,设备仍能处理错误并保持运行,这可以算错误路径通过;实时数据可用性则需要明确保留为未通过。把这两个结果分开,后续查问题时才不会被“全部通过”误导。

此图是整合运行期间在 Pi 上离屏渲染的公开样例:日历和列车使用演示数据,天气使用公开 London 请求。它不展示私人日程或地点,不是物理面板照片,也不证明私人列车来源已经恢复。
性能数字要注明测量条件
整合运行的短时采样记录为:温度 48.3°C,CPU 约为单核的 6.4%(5 秒窗口),RSS 约 115 MiB,节流标记
0x0。这些是当次历史测量,不是本文写作时的新结果,也不是最终每个运行状态的固定数值。这些数字没有全部达到早期静态 CPU 小于 3%、内存小于 80MB 的目标。保留低频静态重绘机制,与已经达成性能目标,是两件不同的事。
长时间运行、长中文内容、持续动画、面板光学效果还要继续观察。离屏测试和短采样都不能替代热稳定性或真实观看体验。
给以后自己的检查入口
阅读公开记录时,可以从这些层次查证:
- 先看版本标签、提交与
/api/version,确认正在讨论哪份代码。
- 再看服务、HTTP / WebSocket 与页面切换,确认软件能持续运行。
- 然后检查来源成功、空结果、演示和过期状态,确认数据含义。
- 最后看配置恢复、资源占用与硬件画面,确认部署后的实际表现。
仓库提供了
tests/pi_release_acceptance.py 用于复现部分验收。它带有临时切页与恢复行为,需要先准备明确的私人配置备份,不能把它当成完全只读的健康检查随手运行。控制台目前仍没有登录保护,只适合受信任的局域网;状态接口可能返回私人配置。新增参数校验不改变这个使用边界。iCal 完整语义、OpenWeatherMap 概览兼容、多控制端覆盖和列车上游可用性,也仍是后续工作。
这次发布留下了什么
对 PiBoard 而言,
v0.1.2 让几处已经发现的运行问题有了修复,也让“验证过什么”有了更清楚的记录。以后再继续改功能时,可以从这份基线往前走,而不用只凭某张截图猜测设备状态。这个系列先记录到这里:从一个车站屏的视觉想法,到共享内容结构、点阵排版,再到实际部署。剩下的问题继续留在记录里,等它们有了新的证据,再写下一篇。