rack:自动恢复的平线判据按实测重定(p95−p05 + 中位数下限)
原判据「窗口内 max − min < 5 mA」抓不到真卡死:10-04 第 1 路平在 520 mA 五个半小时, 偶发尖峰让 590 个窗口的 max − min 都在 17 mA 以上,一个都判不出来。 - 平线改成:p95 − p05 < flat_ua(30 mA)且中位数 ≥ flat_min_ua(100 mA,新增参数)。 下限是给空闲低功耗留的:睡着的手机平在 ~10 mA 是正常的。 - 过低不变(窗内最大值 < 30 mA):睡着的手机每 25 s 被长轮询叫醒,窗内最大值都在 213 mA 以上。 - 真实遥测回放:两次真卡死(10-04 第 1 路、10-05 09:40 第 5 路平在 382 mA)都判出; 亮屏常醒 ~26 h × 4 路、空闲睡着 ~6 h × 5 路、试验 / OTA 期间零误判。 - 测试 +4(带尖峰的平线 / 睡着是健康的 / 睡下去再没醒 = 过低 / 低位平线不下结论),恢复页加「中位数不低于」。 依据和局限写在 recovery.py 模块头。已部署;五路的自动恢复开关仍然全关,还没真正触发过一次。 Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -237,6 +237,34 @@ def test_low_current_is_detected_and_normal_is_not():
|
||||
assert feed(ph2, 0, 61, lambda s: 800 + s % 3)[-1][2][0] == "low"
|
||||
|
||||
|
||||
# 2026-10-06 按实测改的平线判据(recovery.py 模块头的表):下面三条钉的是「改之前判错」的那几种形状。
|
||||
|
||||
def test_flat_tolerates_occasional_spikes():
|
||||
"""真卡死(10-04 第 1 路):平在 ~520 mA,偶尔冒一个 +150 mA 的尖峰。max − min 判据一个窗口都抓不到。"""
|
||||
ph = PhoneRecovery(Params(window_s=60, settle_s=30))
|
||||
r = feed(ph, 0, 61, lambda s: 520000 + (s % 3) * 4000 + (150000 if s % 25 == 0 else 0))
|
||||
assert r and r[-1][1] == SOFT and r[-1][2][0] == "flat"
|
||||
|
||||
|
||||
def test_sleeping_phone_is_healthy():
|
||||
"""空闲睡着:平在 ~10 mA,每 25 s 被长轮询叫醒一秒(~250 mA)。既不是平线(低)也不是过低(有尖峰)。"""
|
||||
ph = PhoneRecovery(Params(window_s=300, settle_s=30))
|
||||
assert feed(ph, 0, 900, lambda s: 250000 if s % 25 == 0 else 9000 + s % 4 * 1000) == []
|
||||
|
||||
|
||||
def test_asleep_and_never_waking_is_low():
|
||||
"""睡下去之后再也没醒(代理不轮询了):5 分钟里一个尖峰都没有 ⇒ 过低。"""
|
||||
ph = PhoneRecovery(Params(window_s=300, settle_s=30))
|
||||
r = feed(ph, 0, 301, lambda s: 9000 + s % 4 * 1000)
|
||||
assert r and r[-1][2][0] == "low"
|
||||
|
||||
|
||||
def test_flat_but_low_level_is_not_flat():
|
||||
"""平在 60 mA(低于 flat_min_ua、高于 low_ua):不下结论 —— 没见过卡死的手机掉到这么低。"""
|
||||
ph = PhoneRecovery(Params(window_s=60, settle_s=30))
|
||||
assert feed(ph, 0, 200, lambda s: 60000 + s % 3 * 1000) == []
|
||||
|
||||
|
||||
def test_rate_limit_gives_up():
|
||||
ph = PhoneRecovery(Params(window_s=60, settle_s=30, max_per_hour=2))
|
||||
t = 0
|
||||
|
||||
在新工单中引用
屏蔽一个用户