rack:PD 供电信息、每日耗电量与平均功率
PD 供电(板卡页新增一格):
- 优先用遥测里的实时值 status.pd(固件 ≥0.1.17);老固件退回最近一条 PD_LIMIT 事件(快照的 pd)。
显示 20 V / 档位电流 / 整板功率上限 / 输入功率占上限的比例。
- PD_LIMIT 事件写成「PD 20 V / 3.00 A,上限 60 W」,不再把那两列当电压电流显示;arg 2 = 运行中换档。
耗电量(板卡页新增卡片):
- 新表 energy_day(永久保留):从分钟聚合滚出每日能量与有数据秒数,rail 0 = 底板 12 V 输入,1~5 = 各路主板。
每分钟重算今天 / 昨天,更早的只补缺不覆盖(分钟数据 90 天后会被清)。按服务器本地零点切日。
- GET /api/boards/{id}/energy;前端 EnergyCard:今日 / 昨日 / 近 7 天 / 近 30 天 / 累计(各带平均功率)、
每日柱状图、今日各路主板。量的是 12 V 输入,不含 PD 20→12 V 降压损耗。
后端测试 57 项全过;已部署。
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -114,6 +114,15 @@ def create_app(hub: Hub, rec: RecoveryManager, static_dir: Optional[str] = None,
|
||||
_board_or_404(hub, board)
|
||||
return hub.db.board_history(board, start, end or now_ms())
|
||||
|
||||
@app.get("/api/boards/{board}/energy")
|
||||
def energy(board: str, days: int = 90):
|
||||
"""每日耗电量(Db.energy_rollup)。单位 mW·s 与秒,换算留给前端;`today` 是服务器本地日期。
|
||||
今天这一行最多滞后两分钟(分钟聚合 + 60 s 一次的滚动)。"""
|
||||
_board_or_404(hub, board)
|
||||
today = hub.db.q("SELECT date(?/1000,'unixepoch','localtime') d", (now_ms(),))[0]["d"]
|
||||
return {"today": today, "days": hub.db.energy(board, max(1, min(days, 3660))),
|
||||
"total": hub.db.energy_total(board)}
|
||||
|
||||
@app.get("/api/boards/{board}/rails/{rail}/history")
|
||||
def history(board: str, rail: int, start: int, end: Optional[int] = None):
|
||||
_board_or_404(hub, board)
|
||||
@@ -188,6 +197,13 @@ def create_app(hub: Hub, rec: RecoveryManager, static_dir: Optional[str] = None,
|
||||
if d["arg"] == 3:
|
||||
d["name"] += ":" + protocol.OTA_ERR_NAMES.get(d["mv"], str(d["mv"]))
|
||||
d["severe"] = d["arg"] in (3, 5)
|
||||
elif d["type"] == protocol.EV_PD_LIMIT:
|
||||
pd = protocol.pd_from_event(d["arg"], d["mv"], d["ua"])
|
||||
d["name"] += "(%s,上限 %g W)" % (
|
||||
"CH224A 读不到,按保守值" if pd["ma"] is None else
|
||||
"%sPD %g V / %.2f A" % ("运行中换档:" if d["arg"] == protocol.PD_EV_CHANGED else "",
|
||||
pd["mv"] / 1000, pd["ma"] / 1000), pd["limit_mw"] / 1000)
|
||||
d["mv"] = d["ua"] = None # 两列装的是上限和档位电流,不是当时的电压电流
|
||||
elif d["type"] == 21:
|
||||
a = d["arg"]
|
||||
d["name"] += "(%s)" % ("手动关" if a == protocol.CHG_EV_OFF else
|
||||
|
||||
在新工单中引用
屏蔽一个用户