feat: 添加 GPIO 电平检测触发亮屏/息屏

新增 GPIOEventDetector 后台线程,以 50ms 间隔轮询 GPIO 引脚。
检测到电平变化时唤醒屏幕并启动 60 秒倒计时,到期无新变化则息屏。

- 添加 GPIOEventDetector 类,支持 RPi.GPIO 硬读取和 Mock 回退
- 集成到 PadSleepApp 主循环,GPIO 触发优先级高于定时亮屏时段
- TUI 状态面板新增 GPIO 行,显示引脚号和倒计时
- 支持通过配置文件调整引脚号(gpio_pin)和倒计时长度
- install.sh 修复:补装 rpi-lgpio 依赖

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kushidou
2026-07-19 16:10:42 +08:00
co-authored by Claude Fable 5
parent da8ad4d17d
commit 9940db451f
6 changed files with 254 additions and 13 deletions
+73 -6
View File
@@ -6,6 +6,7 @@
- **定时控制**:根据配置的时间段自动亮屏/息屏
- **超时保护**:屏幕亮起超过设定时长且不在亮屏时间段内 → 自动息屏
- **GPIO 触发**:(新增)检测 GPIO 电平变化 → 亮屏 + 60 秒倒计时 → 倒计时结束息屏
- **无线 ADB**:支持通过 TCP/IP 连接安卓设备(无线调试)
- **TUI 管理**:提供终端界面工具,方便查看状态和修改配置
- **IPC 通信**:通过 Unix Socket 与 TUI 工具通信
@@ -40,26 +41,43 @@ 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. 启动 IPC 服务(`/tmp/padsleep.sock`
4. 进入主循环,定期检查屏幕状态
3. 启动 GPIO 电平检测(默认 BCM 17
4. 启动 IPC 服务(`/tmp/padsleep.sock`
5. 进入主循环,定期检查屏幕状态
### 启动 TUI 管理工具
```bash
# 新终端窗口
python padsleep_tui.py
# 或使用安装后的命令行入口
padsleep-config
```
TUI 快捷键:
@@ -94,7 +112,10 @@ TUI 快捷键:
"adb_device_serial": "",
"adb_wireless_host": "",
"adb_wireless_port": 5555,
"adb_wireless_auto_connect": false
"adb_wireless_auto_connect": false,
"gpio_enabled": true,
"gpio_pin": 17,
"gpio_countdown_seconds": 60
}
```
@@ -109,6 +130,48 @@ TUI 快捷键:
| `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 连接
@@ -147,19 +210,23 @@ TUI 快捷键:
```
padsleep_adb/
├── padsleep.py # 守护程序主程序
├── padsleep.py # 守护程序主程序(含 GPIO 检测)
├── padsleep_tui.py # TUI 管理工具
├── config.json # 配置文件(首次运行自动生成)
├── config.json # 配置文件
├── requirements.txt # Python 依赖
── README.md # 本文档
── 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 自动降级为模拟模式(不影响主功能)
## 许可证