- 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>
255 lines
6.9 KiB
Markdown
255 lines
6.9 KiB
Markdown
# 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
|