fix(屏幕): 一键息屏不再唤醒已眠设备 + 「保持亮屏」对不充电的设备生效
用户反馈两条: 1. 监控页「一键息屏」像是把设备**唤醒**了(按钮行为"反"); 2. 任务里的「保持亮屏」没用。 根因: 1. `POST /api/device/screen_all` 的 off 分支发 `input keyevent 26`(KEYCODE_POWER)—— 那是电源键**开关**:对亮着的设备是熄屏,对**已经息屏的设备反而是唤醒**。 2. `keep_screen` 只发 `svc power stayon true`,它管的是「**充电时**屏幕常亮」 (stay_on_while_plugged_in)。设备走 WiFi 跑任务、没插充电器 → 完全不生效。 修法: - 息屏改用 `KEYCODE_SLEEP(223)`(单向:只熄不亮)。 - 保持亮屏改成把系统**息屏超时**顶到最大(`settings put system screen_off_timeout 2147483647`)+ 顺带 `svc power stayon true` + 立刻 `KEYCODE_WAKEUP` 唤醒一次; `mode=off` 时写回原值(进入时读一次记在内存;进程重启丢了记录就写回 10 分钟兜底, `settings get` 返回 "null" 的机型也走兜底)。 - 文案/文档同步:编辑器里的步骤说明、TASK_DEV 步骤表、API.md 的接口行为。 自测(按用户要求不动机器):py_compile / node --check 通过;用假设备对象断言命令序列—— 保持亮屏发 `settings get` → `stayon true` → `put …2147483647` → `keyevent 224` 并记住原值; 恢复写回原值 60000 且清空备份;原值为 null 时兜底 600000。
This commit is contained in:
+30
-5
@@ -45,6 +45,13 @@ _log = get_logger("task.generic")
|
||||
_LEGACY_IDX_XPATH = re.compile(r'^(//\*\[@[^\]]+\])\[(\d+)\](.*)$')
|
||||
|
||||
|
||||
# ---- 「保持亮屏」用的系统设置 ----
|
||||
# 系统息屏超时(毫秒):保持亮屏时顶到最大,恢复时写回原值
|
||||
_SCREEN_TIMEOUT_MAX = "2147483647"
|
||||
_SCREEN_TIMEOUT_DEFAULT = "600000" # 兜底恢复值:10 分钟(原值记不住时用)
|
||||
_SCREEN_TIMEOUT_BACKUP = {} # serial -> 原始 screen_off_timeout
|
||||
|
||||
|
||||
def _norm_legacy_xpath(sel_val):
|
||||
"""把历史 `//*[@attr=…][k]` 纠正为 `(//*[@attr=…])[k]`(只改整体前缀,保留后续子路径)。
|
||||
|
||||
@@ -228,17 +235,35 @@ class GenericStepsWorker(BaseWorker):
|
||||
def _exec_keep_screen(self, d, params, depth=0):
|
||||
"""保持亮屏 / 恢复自动息屏。
|
||||
|
||||
长任务(养号看视频数小时)时屏幕会按系统超时自动熄灭导致任务无法执行,
|
||||
用 svc power stayon 让充电时屏幕常亮;任务结束前用 mode=off 恢复自动息屏。
|
||||
⚠️ 只用 `svc power stayon true` **不管用**:它管的是「**充电时**屏幕常亮」
|
||||
(= stay_on_while_plugged_in)。设备走 WiFi 跑任务、没插充电器时它完全不起作用
|
||||
——以前"保持亮屏"看着像没生效就是这个原因(2026-09-14 用户反馈)。
|
||||
|
||||
真正管用的是把系统**息屏超时**顶到最大(`screen_off_timeout`):不充电也不会
|
||||
自动黑屏。进入时记下原值,`mode=off` 写回;进程重启丢了记录就写回常规的 10 分钟。
|
||||
"""
|
||||
mode = params.get("mode", "on")
|
||||
try:
|
||||
if mode == "off":
|
||||
d.shell("svc power stayon false")
|
||||
_log.info(f"[{self.serial}] 恢复自动息屏")
|
||||
orig = _SCREEN_TIMEOUT_BACKUP.pop(self.serial, _SCREEN_TIMEOUT_DEFAULT)
|
||||
d.shell(f"settings put system screen_off_timeout {orig}")
|
||||
_log.info(f"[{self.serial}] 恢复自动息屏(超时 {orig}ms)")
|
||||
else:
|
||||
d.shell("svc power stayon true")
|
||||
_log.info(f"[{self.serial}] 保持亮屏(充电时屏幕常亮)")
|
||||
cur = ""
|
||||
try:
|
||||
cur = (d.shell("settings get system screen_off_timeout") or "").strip()
|
||||
except Exception:
|
||||
pass
|
||||
if self.serial not in _SCREEN_TIMEOUT_BACKUP:
|
||||
# 没设过时 `settings get` 会返回 "null"(走系统默认)——别把 null 写回去
|
||||
_SCREEN_TIMEOUT_BACKUP[self.serial] = \
|
||||
cur if cur.isdigit() else _SCREEN_TIMEOUT_DEFAULT
|
||||
d.shell("svc power stayon true") # 充电场景(顺带)
|
||||
d.shell(f"settings put system screen_off_timeout {_SCREEN_TIMEOUT_MAX}")
|
||||
d.shell("input keyevent 224") # 立刻唤醒(KEYCODE_WAKEUP,单向)
|
||||
_log.info(f"[{self.serial}] 保持亮屏(息屏超时→最大,原值 "
|
||||
f"{_SCREEN_TIMEOUT_BACKUP.get(self.serial)}ms)")
|
||||
except Exception as e:
|
||||
_log.warning(f"[{self.serial}] keep_screen({mode}) 异常: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user