Files
padsleep_adb/README.md
T
kushidouandClaude Fable 5 e6fbe550bb 重构屏幕控制引擎 + 新增 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>
2026-07-20 00:15:07 +08:00

255 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# padsleep_adb
基于树莓派,通过 ADB 控制安卓平板自动亮屏和息屏的守护程序。
## 功能特性
- **定时控制**:根据配置的时间段自动亮屏/息屏
- **超时保护**:屏幕亮起超过设定时长且不在亮屏时间段内 → 自动息屏
- **GPIO 触发**:(新增)检测 GPIO 电平变化 → 亮屏 + 60 秒倒计时 → 倒计时结束息屏
- **无线 ADB**:支持通过 TCP/IP 连接安卓设备(无线调试)
- **TUI 管理**:提供终端界面工具,方便查看状态和修改配置
- **IPC 通信**:通过 Unix Socket 与 TUI 工具通信
- **自动重连**:无线连接断开后自动尝试重新连接
## 系统要求
- 树莓派(或其他 Linux 设备)
- Python 3.10+
- ADB (Android Debug Bridge)
- 安卓平板(已开启 USB 调试或无线调试)
## 安装
### 1. 安装系统依赖
```bash
# Debian/Ubuntu
sudo apt update
sudo apt install adb python3-curses
# 树莓派 OS
sudo apt install adb
```
### 2. 安装 Python 依赖
```bash
cd padsleep_adb
pip install -r requirements.txt
```
依赖列表:
- `adbutils>=2.12.0` — Python ADB 库
- `rpi-lgpio>=0.6` — 树莓派 GPIO 控制(仅在树莓派上需要)
### 3. 快速安装
```bash
sudo ./install.sh
```
安装脚本会将程序部署到 `/opt/apps/padsleep`,创建命令行入口和 systemd 服务。
## 使用方法
### 启动守护程序
```bash
# 直接启动
python padsleep.py
# 或使用安装后的命令行入口
padsleep
```
守护程序会自动:
1. 加载配置文件 `config.json`
2. 检测 ADB 设备
3. 启动 GPIO 电平检测(默认 BCM 17
4. 启动 IPC 服务(`/tmp/padsleep.sock`
5. 进入主循环,定期检查屏幕状态
### 启动 TUI 管理工具
```bash
# 新终端窗口
python padsleep_tui.py
# 或使用安装后的命令行入口
padsleep-config
```
### 启动 Web 监控面板
```bash
# 新终端窗口(需先启动守护进程)
python padsleep_web.py
# 或使用安装后的命令行入口
padsleep-web
```
然后在浏览器打开 `http://树莓派IP:5000` 查看仪表盘。
Web 面板功能:
- **GPIO 电平实时监控**:独立线程 50ms 轮询 GPIO 引脚,毫秒级变化展示
- **守护进程状态**:屏幕状态、亮屏事件、ADB 连接、传感器触发等
- **电平事件日志**:实时记录所有 GPIO 电平变化
- **历史波形**:最近 40 次电平变化可视化
TUI 快捷键:
| 按键 | 功能 |
|------|------|
| `↑/k` `↓/j` | 选择亮屏时间段 |
| `A` | 新增亮屏时间段 |
| `E` | 编辑选中时间段 |
| `D` | 删除选中时间段 |
| `S` | 选择 ADB 设备 |
| `W` | 无线连接设备 |
| `R` | 刷新状态 |
| `L` | 重载守护进程配置 |
| `F` | 强制息屏 |
| `N` | 强制亮屏 |
| `T` | 重新连接守护进程 |
| `H` | 显示帮助 |
| `Q` | 退出 |
## 配置说明
配置文件 `config.json` 示例:
```json
{
"screen_on_periods": [
{"start": "08:00", "end": "22:00"}
],
"check_interval_seconds": 30,
"auto_sleep_delay_minutes": 5,
"adb_device_serial": "",
"adb_wireless_host": "",
"adb_wireless_port": 5555,
"adb_wireless_auto_connect": false,
"gpio_enabled": true,
"gpio_pin": 17,
"gpio_countdown_seconds": 60
}
```
### 字段说明
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `screen_on_periods` | array | `[{"start":"08:00","end":"22:00"}]` | 亮屏时间段列表,支持跨天(如 22:00~08:00 |
| `check_interval_seconds` | int | `30` | 检查间隔(秒) |
| `auto_sleep_delay_minutes` | int | `5` | 非亮屏时段屏幕亮起多久后自动息屏(分钟) |
| `adb_device_serial` | string | `""` | 指定 USB 设备 serial,空表示自动选择第一个 |
| `adb_wireless_host` | string | `""` | 无线设备 IP 地址,空表示不使用无线连接 |
| `adb_wireless_port` | int | `5555` | 无线设备端口 |
| `adb_wireless_auto_connect` | bool | `false` | 启动时是否自动连接无线设备 |
| `gpio_enabled` | bool | `true` | 是否启用 GPIO 电平检测 |
| `gpio_pin` | int | `17` | GPIO 引脚号(BCM 编号),如 GPIO17 = 物理 pin 11 |
| `gpio_countdown_seconds` | int | `60` | GPIO 触发后倒计时秒数,到期无新变化则息屏 |
## GPIO 电平检测
> 由于购买的模块有问题,无法稳定输出电平,但是人来人走时会发生短暂电平切换,
> 因此采用这个折中的法子:检测到 GPIO 电平变化就亮屏并重置倒计时,
> 倒计时结束且无新变化则息屏。
### 工作原理
1. **后台线程** 以 50ms 间隔高频轮询 GPIO 引脚
2. **检测到任意电平变化**(上升或下降沿)→ 立即亮屏,重置倒计时
3. **倒计时期间再次触发** → 倒计时重置,保持亮屏
4. **倒计时到期无新变化** → 息屏(除非当前在定时亮屏时段内)
### 决策优先级
```
GPIO 触发(60s 倒计时) > 定时亮屏时段 > 超时息屏
```
### 接线参考
GPIO 引脚号(BCM 编号)对照:
| BCM 编号 | 物理引脚 | 功能 |
|----------|----------|------|
| GPIO17 | Pin 11 | 默认 GPIO 检测引脚 |
| GND | Pin 6 / 9 / 14 / ... | 接地 |
将传感器信号线接 GPIO17,GND 接树莓派 GND 即可。
### 日志记录
所有 GPIO 事件记录在 `padsleep.log` 中:
```
[2026-07-19 15:59:25] GPIO触屏 — BCM 17 电平变化,60s 倒计时
[2026-07-19 15:59:28] GPIO息屏 — BCM 17 在 60s 内无电平变化
```
## 无线 ADB 连接
### 方式一:配置文件预设
`config.json` 中设置:
```json
{
"adb_wireless_host": "192.168.1.100",
"adb_wireless_port": 5555,
"adb_wireless_auto_connect": true
}
```
### 方式二:TUI 手动连接
1. 启动 TUI 工具
2.`W`
3. 输入 IP 地址和端口
4. 确认连接
### 开启安卓设备无线调试
1. 连接 USB,执行 `adb tcpip 5555`
2. 或在设备上:设置 → 开发者选项 → 无线调试 → 开启
### 连接优先级
程序采用 **USB 优先** 策略:
1. 首先尝试 USB 连接
2. 如果 USB 不可用且配置了无线,尝试无线连接
3. 无线连接断开后自动重连(最多 3 次)
## 文件结构
```
padsleep_adb/
├── padsleep.py # 守护程序主程序(含 GPIO 检测)
├── padsleep_tui.py # TUI 管理工具
├── padsleep_web.py # Web 监控面板(Flask + SocketIO
├── templates/
│ └── index.html # Web 面板前端
├── config.json # 配置文件
├── requirements.txt # Python 依赖
├── install.sh # 安装脚本
├── padsleep.service # systemd 服务文件
└── README.md # 本文档
```
## 开发说明
- 在 Windows 上开发,在树莓派上运行
- 使用 `adbutils` 库与 ADB Server 通信
- GPIO 使用 `RPi.GPIO`(通过 `rpi-lgpio` 驱动 `lgpio` 内核模块)
- IPC 使用 Unix Socket + JSON 行协议
- TUI 使用 Python `curses`
- 非树莓派环境 GPIO 自动降级为模拟模式(不影响主功能)
## 许可证
MIT License