rack:界面改版(仪器前面板风格 + 暗色模式)+ 底板温度曲线

- 总览:每块板一块面板、五个刀片槽(状态灯 + DIN 读数 + 最近两分钟电流小曲线,平线 = 疑似卡死);
  只有异常 / 故障 / 执行中上色;顶上一句话概况,有问题直接列出是哪几路
- 单板页:新增「底板温度」(两路 NTC + 风扇占空比,上下两块共用时间轴,10 分钟 ~ 7 天);
  每路电流 / 电压去掉双 Y 轴,改上下两块,电压固定 3.5~4.1 V;名称 / 位置就地编辑
- 主题:theme.css 亮 / 暗两套变量(跟随系统,Element Plus 暗色变量同挂 html.dark),图表切换时重画;
  读数用系统自带 DIN 系字体(不加载网络字体);温度两色按本页亮暗底色跑过 dataviz validate_palette.js 全通过
- 后端:board_tele_min 分钟聚合(温度带 min/max,留 90 天)+ GET /api/boards/{id}/history(Db.board_history)
- 修一个偶发失败的测试(test_ota_events_are_named_by_arg:只推一次遥测,赶上 Hub 正在同步时会漏触发);
  后端 42 例本机 + 服务器全绿,已部署;线上已取到板 B 温度 24.4 / 26.0 °C

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
zhou yang
2026-09-27 15:03:24 +08:00
共同撰写人 Claude Opus 5.5
父节点 1cd4fd4082
当前提交 9858b6c98e
共修改 25 个文件,包含 828 行新增和 225 行删除
+7 -2
查看文件
@@ -199,8 +199,13 @@ def test_ota_events_are_named_by_arg(env):
c, hub, sim = env
sim._ev(0, 18, 3, 3, 996064) # 失败:哈希不对
sim._ev(0, 18, 5) # 回滚
sim.tick(now_ms())
assert wait_for(lambda: len([e for e in c.get("/api/events").json() if e["type"] == 18]) == 2)
# 每次检查前都推一条遥测:Hub 正在同步上一批事件(启动时的 BOOT)时会跳过这一条遥测带来的
# 「有新事件」,只推一次的话偶尔再也没人触发同步(服务器上 3 次里红过 1 次)。真板 1 s 一条,没有这个问题。
def synced():
sim.tick(now_ms())
return len([e for e in c.get("/api/events").json() if e["type"] == 18]) == 2
assert wait_for(synced)
ev = {e["arg"]: e for e in c.get("/api/events").json() if e["type"] == 18}
assert ev[3]["name"] == "固件升级(失败):哈希不对" and ev[3]["severe"] is True
assert ev[5]["name"] == "固件升级(回滚)" and ev[5]["severe"] is True