重构屏幕控制引擎 + 新增 Web 监控面板

- ScreenManager: 基于优先级(9/5/0)的统一屏幕控制引擎,替代 _tick 中的
  散乱 if-else 逻辑
- 四个亮屏事件: scheduled(p9), sensor(p9), manual(p5), external(p0)
- GPIO 回调: 电平变化立即触发亮屏(异步线程,不阻塞轮询)
- _fast_check: 每秒轻量评估,提高息屏超时精度(±1s 替代 ±30s)
- padsleep_web: 通过 IPC 读取守护进程状态的实时 Web 面板
  (GPIO 电平/屏幕状态/ADB 连接,端口 31400)
- padsleep-web.service: 关联 padsleep.service 的自启动服务
- install.sh: 修复 venv 初始化目录上下文,使用 requirements.txt
- IpcClient: 修复 socket 复用导致交替失败的问题
- padsleep_tui: 适配 ScreenManager 状态显示

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kushidou
2026-07-20 00:15:07 +08:00
co-authored by Claude Fable 5
parent 9940db451f
commit e6fbe550bb
8 changed files with 1134 additions and 103 deletions
+24 -4
View File
@@ -29,7 +29,7 @@ CONFIG_PATH = SCRIPT_DIR / "config.json"
# ═══════════════════════════════════════════════════════════════════
class IpcClient:
"""Unix Socket JSON 行协议客户端。"""
"""Unix Socket JSON 行协议客户端(每次 send 新建连接)"""
def __init__(self, socket_path=SOCKET_PATH):
self.socket_path = socket_path
@@ -58,9 +58,10 @@ class IpcClient:
self.connected = False
def send(self, cmd: str, **kwargs) -> dict:
if not self.sock:
if not self.connect():
return {"ok": False, "error": "未连接守护进程"}
"""发送命令,每次新建连接(守护进程每请求关闭连接)。"""
self.disconnect()
if not self.connect():
return {"ok": False, "error": "未连接守护进程"}
req = {"cmd": cmd, **kwargs}
try:
self.sock.sendall((json.dumps(req) + "\n").encode("utf-8"))
@@ -435,6 +436,25 @@ class TuiApp:
except curses.error:
pass
# ── 亮屏事件状态 ──
active_reason = s.get("active_reason")
if active_reason:
y += 1
reason_labels = {
"scheduled": "定时点亮",
"sensor": "传感器触发",
"manual": "手动控制",
"external": "外部亮屏",
}
label = reason_labels.get(active_reason, active_reason)
if y < h:
self._clear_line(y)
try:
self.stdscr.addstr(y, 4, "亮屏事件: ")
self.stdscr.addstr(f"{label}", curses.color_pair(3) | curses.A_BOLD)
except curses.error:
pass
# ── GPIO 状态 ──
gpio_avail = s.get("gpio_available", False)
if gpio_avail: