手机主板温度:代理 0.8.0 上报,rack 拓扑图显示
- 机架代理 0.8.0(Thermal.java):读 /sys/class/thermal 的 quiet_therm(主板热敏)和最热的 CPU 核, 每次长轮询拼在 URL 后面(&tb=&tc=,m°C),不为它多醒一次。电池那一路不报(电池拆了)。 - rack 后端 prrack/fleet.py:每 5 秒读 AppTask 后端的 /api/fleet/phones,按机架位 B-n 对到第 n 路, 放进快照 phones[].live(在线 / 在跑活 / 代理版本 / 温度);变了才推 phones_live。只显示,不参与自动恢复。 读不到就清空,不留旧值。服务单元加 --apptask-env。 - 前端拓扑图每台手机多一行「主板 / CPU」温度(50 °C 橙、60 °C 红,只改颜色)。 - agent_upgrade_safe.sh:升级后 4 分钟没开机就 power_cycle 救一次并补收尾。 五台已升到 0.8.0(两路并行推);第 2、1、5 路 staged 重启后卡死 / 僵住,断电重启后版本都已是新的。 后端测试 58 项全过;已部署。 Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
+11
-1
@@ -46,6 +46,7 @@ class Hub:
|
||||
self._clients: Set[asyncio.Queue] = set()
|
||||
self._tasks: List[asyncio.Task] = []
|
||||
self.tele_observers: List[Callable[[str, int, dict], None]] = []
|
||||
self.phone_live: Dict[tuple, dict] = {} # (board, rail) → 手机自己报的那一半(fleet.py),只显示
|
||||
|
||||
# ---- 生命周期 ------------------------------------------------------------
|
||||
async def start(self):
|
||||
@@ -222,7 +223,16 @@ class Hub:
|
||||
return {"id": board, "name": meta[0]["name"] if meta else "", "location": meta[0]["location"] if meta else "",
|
||||
"online": b["online"], "stale": stale, "fw": b["fw"], "ip": b["ip"],
|
||||
"last_tele": b["last_tele"], "status": b["status"], "pd": self.pd(board),
|
||||
"phones": [dict(p) for p in phones]}
|
||||
"phones": [dict(p, live=self.phone_live.get((board, p["rail"]))) for p in phones]}
|
||||
|
||||
def set_phone_live(self, live: Dict[tuple, dict]):
|
||||
"""fleet.py 每轮读完调一次。只把**变了的板子**推给网页(温度几秒才动一下,不值得每轮都推)。"""
|
||||
old, self.phone_live = self.phone_live, live
|
||||
for board in {k[0] for k in old} | {k[0] for k in live}:
|
||||
a = {r: v for (b, r), v in old.items() if b == board}
|
||||
b_ = {r: v for (b, r), v in live.items() if b == board}
|
||||
if a != b_:
|
||||
self.broadcast({"t": "phones_live", "board": board, "live": b_})
|
||||
|
||||
def boards(self) -> List[dict]:
|
||||
return [self.snapshot(b) for b in sorted(self.latest)]
|
||||
|
||||
在新工单中引用
屏蔽一个用户