embedded-host-platform

08 浏览器控制台

问题

想给没有硬件、不装 PyQt6 的人一个能直接打开的入口——包括只是路过这个仓库、只有一个浏览器的人。

被否决的形态:数据大屏

一台设备、三个通道撑不起一块大屏。地图、翻牌器、3D 这类组件堆上去只是装饰。

改为做一个控制台,重心放在这个项目别处看不到的两样东西上:看得见的串口链路,与可追溯的问答。

四个页签

页签 内容
监测 三通道读数、越限状态、滚动曲线;实时模式下可切换风扇模式、改通风阈值
串口链路 每一帧的判定:正常、重同步、CRC 失败、格式错误、忽略、载荷错误;点开一帧,逐字段拆开,并把帧里声明的 CRC 与浏览器现场重算的 CRC-32 并列
环境问答 每个回答的全过程,按发生顺序逐步点亮:规则识别、取数层给出的事实、模板原句、模型收到了什么、模型原文、复核或分类的标签、五道出口检查逐道的结果、重试、执行与最终答案
历史 整段曲线

决定

放在顶级目录 web/,不放进网关包。 网关是无界面服务,Android 客户端也不在网关里。 把页面塞进网关,等于让一个呈现端住进另一个呈现端的包里。页面由启动脚本挂载到 /web/,网关包本身不知道它存在。

不引入前端构建链。 原生 JavaScript 与 Canvas,没有 npm、没有打包。一个要先 npm install 才能打开的演示, 对访客来说是多出来的故障点。

普通脚本,不用 ES 模块。 浏览器禁止 file:// 页面加载模块脚本,而这个页面要能直接双击打开。 所以用普通 <script> 加一个全局命名空间;回放数据也是一个 .js 文件,用动态插入 <script> 加载——fetch 在 file:// 下同样不可用。

不让网页直连串口。 浏览器有 Web Serial API,可以直接读串口。不用它:那会让一个呈现端绕过全部分层、感知底层通信方式。

同一个页面,三种打开方式

打开方式 数据从哪来
网关托管(http://<PC>:8000/web/) 实时:REST + WebSocket,断线按 1→32 秒指数退避重连
双击 web/index.html 先尝试连本机网关,连不上就进入回放
GitHub Pages 直接回放,不探测网关

视图不区分数据源。两种数据源推给状态仓库的是同一种消息;能力不同的地方(回放里不能改设置)由数据源声明, 视图据此把控件置灰并写明原因。

回放数据不是演示数据

回放数据由 scripts/build_web_replay.py 离线生成,生成过程就是在线系统本身:

录制的读数 ─► 按协议重新编码成帧 ─► 字节管道 ─► 真实的 HardwareDeviceReceiver + LinkMonitor
          ─► 真实的报警、统计、通风判定 ─► 网关自己的序列化函数 ─► 与在线时 WebSocket 收到的一模一样的消息

只有时间戳被改写成读数当时的时刻。所以回放不是一份用 JavaScript 另写的演示逻辑,而是换了数据源的在线管线。 脚本里有断言:一小时的会话必须是 3489 帧、零校验错误;故障注入会话里,判出的重同步数必须等于注入的杂散字节数, CRC 失败数必须等于翻转数。

一个诚实的说明:一小时实验采集时只保存了读数、没有保存原始字节,所以回放里的帧是按协议重新编码的,页面上照实写明。

为此改动的后端

改动 为什么
网关加通风接口 直译已有的 ApiInterface 方法
LinkMonitor + ApiInterface 两个新方法 链路健康原本只是接收器内部的两个整数,任何呈现端都看不到。监视器只听不判:拼帧与校验仍由原来的代码完成,不接监视器时行为逐字节不变
问答答案附带追溯记录 出口检查从”只给结论”拆出一个”给结论与判定代码”的版本;一组逐项对照的测试保证两者对任何输入给出相同的文本与来源——只增加可见性,不改变任何判定
字节管道与 --mode virtual 模拟模式没有字节流,链路页无从显示。要在没有开发板时看到真实的帧,需要一个走真实接收链路的模式(见 01)

追溯记录不违反”模型不接触数值”(02):它是对已经发生之事的只读记录, 模型没有因此多拿到任何输入或权力;页面显示的模型原文,正是出口检查已经采纳或拒绝过的那一句。

一句回答是怎么来的:实时流程

最初的追溯是事后的:问答结束才推一条完整记录,中间发生了什么——被拦下之后的重试、规则没认出时模型回了哪个标签、 指令复核一致与否——页面上只剩一个结果。后来改成按发生顺序、带时间推送:

判定不变是这样确认的:改动前后,用固定读数、固定时钟和确定性的脚本模型,把全部题库 340 句在接模型与不接模型两种模式下各跑一遍, 答案文本、来源、意图、执行结果、改写与判定逐字节相同。

回放里有一组用真实模型录下的实时流程(experiment-data/assistant/),按录制时的原始耗时重演, 没有模型也能看到一句回答是怎么来的。模型的思考链(thinking 输出)没有做:它要打开模型的思考模式,改变输出分布, 已有的实测数据就都不再适用。

做的过程中发现的问题

写这个控制台的同一天,新增的依赖规则测试第一次运行就查出一处违规:网关为了链路事件的两个值类型直接 import 了 application。 值类型随即移入 core。见 architecture.md。

浏览器里逐页试用时修掉的问题,典型的几个:

没做的