rack:主板 / 底板功率与功率曲线;底板曲线加电压电流、开机重按事件

- 每路主板功率(V×I):总览槽位、单板卡片、单路曲线新增「功率」一张
- 底板:单板页新增功率仪表(底板输入 / 五路主板合计 / 损耗),底板曲线加
  功率图(输入 vs 主板合计);board_history 每点多回一列 rails_mw
- 底板曲线改为纵向 N 张(温度 / 风扇 / 输入电压 / 输入电流 / 功率),断档断线
- LOG_EV_BOOT_CHECK(19)事件命名,只有「没开起来」标红

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
zhou yang
2026-09-28 08:39:47 +08:00
共同撰写人 Claude Opus 5.5
父节点 1f6862ac38
当前提交 830b4cdff8
共修改 14 个文件,包含 1288 行新增和 1122 行删除
+10 -3
查看文件
@@ -215,7 +215,8 @@ class Db:
def board_history(self, board: str, t0: int, t1: int, max_points: int = 1500) -> dict:
"""[t0, t1) 的整板曲线:两路 NTC 温度(m°C,带每桶 min/max)、风扇占空比(‰)、输入电压电流。
取数规则同 `history()`:近期短跨度回原始 1 s,否则回分钟聚合。
points:[t, t0, t0_min, t0_max, t1, t1_min, t1_max, fan, in_mv, in_ua];读不到的是 None。"""
points:[t, t0, t0_min, t0_max, t1, t1_min, t1_max, fan, in_mv, in_ua, rails_mw];读不到的是 None。
rails_mw 是五路手机主板合计功率(mW),和输入功率 in_mv×in_ua 一比就是板上损耗。"""
span = max(1, t1 - t0)
raw_ok = t0 >= now_ms() - RAW_KEEP_S * 1000 and span <= 6 * 3600 * 1000
if raw_ok:
@@ -234,6 +235,12 @@ class Db:
"CAST(AVG(in_mv_avg) AS INTEGER) mv, CAST(AVG(in_ua_avg) AS INTEGER) ua FROM board_tele_min "
"WHERE board_id=? AND ts>=? AND ts<? GROUP BY t ORDER BY t", (bucket, bucket, board, t0, t1))
res = "minute"
# 五路主板合计功率(mW):每个时刻五路 mv×ua 求和,再按桶取均值(除以桶里的时刻数,不是行数)。
# 分钟聚合只有各路均值,拿 mv_avg×ua_avg 近似 —— 电压几乎不动,误差可以忽略。
src = ("mv*ua", "tele") if res == "raw" else ("mv_avg*ua_avg", "tele_min")
rails_mw = {r["t"]: r["p"] for r in self.q(
"SELECT ts/?*? AS t, CAST(SUM(%s)/1e6/COUNT(DISTINCT ts) AS INTEGER) p FROM %s "
"WHERE board_id=? AND ts>=? AND ts<? GROUP BY t" % src, (bucket, bucket, board, t0, t1))}
return {"resolution": res, "bucket_ms": bucket,
"points": [[r["t"], r["a0"], r["n0"], r["x0"], r["a1"], r["n1"], r["x1"], r["f"], r["mv"], r["ua"]]
for r in rows]}
"points": [[r["t"], r["a0"], r["n0"], r["x0"], r["a1"], r["n1"], r["x1"], r["f"], r["mv"], r["ua"],
rails_mw.get(r["t"])] for r in rows]}