- 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>
190 lines
6.3 KiB
Bash
Executable File
190 lines
6.3 KiB
Bash
Executable File
#!/bin/bash
|
||
# padsleep_adb 安装脚本
|
||
# 用法: sudo ./install.sh
|
||
#
|
||
# 将程序安装到 /opt/apps/padsleep,创建命令行软链接。
|
||
# 自动创建 Python 虚拟环境并安装依赖。
|
||
# 代码中 SCRIPT_DIR 使用 Path(__file__).resolve().parent,
|
||
# 会自动适配安装路径,无需修改代码。
|
||
|
||
set -e
|
||
|
||
INSTALL_DIR="/opt/apps/padsleep"
|
||
BIN_DIR="/usr/local/bin"
|
||
SERVICE_DIR="/etc/systemd/system"
|
||
VENV_DIR="$INSTALL_DIR/.venv"
|
||
PYTHON_BIN="$VENV_DIR/bin/python3"
|
||
|
||
# 颜色
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m'
|
||
|
||
info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||
error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
|
||
# ── 检查 root ──
|
||
if [ "$EUID" -ne 0 ]; then
|
||
error "请使用 sudo 运行此安装脚本"
|
||
echo " sudo $0"
|
||
exit 1
|
||
fi
|
||
|
||
# ── 确定源目录(脚本所在目录)──
|
||
SRC_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
if [ ! -f "$SRC_DIR/padsleep.py" ]; then
|
||
error "在 $SRC_DIR 中未找到 padsleep.py"
|
||
echo "请在 padsleep_adb 项目目录中运行此脚本"
|
||
exit 1
|
||
fi
|
||
|
||
# ── 确定运行用户(sudo 的原用户)──
|
||
RUN_USER="${SUDO_USER:-}"
|
||
if [ -z "$RUN_USER" ]; then
|
||
if [ -f "$SRC_DIR/padsleep.service" ]; then
|
||
RUN_USER=$(grep '^User=' "$SRC_DIR/padsleep.service" | head -1 | cut -d= -f2)
|
||
fi
|
||
fi
|
||
if [ -z "$RUN_USER" ]; then
|
||
RUN_USER="$(whoami)"
|
||
fi
|
||
RUN_USER_HOME=$(eval echo "~$RUN_USER" 2>/dev/null || echo "/home/$RUN_USER")
|
||
|
||
info "源目录: $SRC_DIR"
|
||
info "安装目标: $INSTALL_DIR"
|
||
info "运行用户: $RUN_USER"
|
||
|
||
# ── 创建目标目录 ──
|
||
mkdir -p "$INSTALL_DIR"
|
||
info "已创建目录 $INSTALL_DIR"
|
||
|
||
# ── 复制文件 ──
|
||
cp "$SRC_DIR/padsleep.py" "$INSTALL_DIR/"
|
||
cp "$SRC_DIR/padsleep_tui.py" "$INSTALL_DIR/"
|
||
cp "$SRC_DIR/padsleep_web.py" "$INSTALL_DIR/" 2>/dev/null || true
|
||
cp -r "$SRC_DIR/templates" "$INSTALL_DIR/" 2>/dev/null || true
|
||
cp "$SRC_DIR/requirements.txt" "$INSTALL_DIR/" 2>/dev/null || true
|
||
|
||
# 配置文件:目标不存在则复制,存在则保留
|
||
if [ ! -f "$INSTALL_DIR/config.json" ]; then
|
||
cp "$SRC_DIR/config.json" "$INSTALL_DIR/"
|
||
info "已创建默认配置文件 $INSTALL_DIR/config.json"
|
||
else
|
||
warn "配置文件已存在,保留现有配置: $INSTALL_DIR/config.json"
|
||
fi
|
||
|
||
# 日志文件:创建空文件
|
||
touch "$INSTALL_DIR/padsleep.log"
|
||
chmod 644 "$INSTALL_DIR/padsleep.log"
|
||
|
||
# ── 创建 Python 虚拟环境并安装依赖 ──
|
||
# 进入目标目录确保 venv 上下文正确
|
||
cd "$INSTALL_DIR"
|
||
|
||
if [ ! -d "$VENV_DIR" ]; then
|
||
info "正在创建 Python 虚拟环境..."
|
||
python3 -m venv .venv
|
||
info "虚拟环境已创建: $VENV_DIR"
|
||
else
|
||
info "虚拟环境已存在,跳过创建"
|
||
fi
|
||
|
||
info "正在安装 Python 依赖 (requirements.txt)..."
|
||
if [ -f "$INSTALL_DIR/requirements.txt" ]; then
|
||
.venv/bin/pip install --quiet -r requirements.txt 2>&1 || {
|
||
warn "pip 安装失败,尝试逐个安装..."
|
||
.venv/bin/pip install --quiet adbutils rpi-lgpio flask flask-socketio 2>&1 || {
|
||
warn "pip 安装仍然失败,请手动执行: cd $INSTALL_DIR && .venv/bin/pip install -r requirements.txt"
|
||
}
|
||
}
|
||
else
|
||
.venv/bin/pip install --quiet adbutils rpi-lgpio flask flask-socketio 2>&1 || \
|
||
warn "pip 安装失败,请手动安装依赖"
|
||
fi
|
||
info "Python 依赖安装完成"
|
||
|
||
cd "$SRC_DIR" # 回到源目录
|
||
|
||
# 设置执行权限
|
||
chmod 755 "$INSTALL_DIR/padsleep.py"
|
||
chmod 755 "$INSTALL_DIR/padsleep_tui.py"
|
||
|
||
# 修正所有权和权限:确保运行用户有权读写配置和日志
|
||
chown -R "$RUN_USER:$RUN_USER" "$INSTALL_DIR" 2>/dev/null || chown -R "$RUN_USER" "$INSTALL_DIR" 2>/dev/null
|
||
chmod 755 "$INSTALL_DIR"
|
||
chmod 644 "$INSTALL_DIR/padsleep.log" 2>/dev/null
|
||
info "文件所有权已设置为 $RUN_USER"
|
||
|
||
# ── 创建命令包装脚本(使用 venv Python)──
|
||
create_wrapper() {
|
||
local script="$1" # padsleep.py 或 padsleep_tui.py
|
||
local link="$2" # /usr/local/bin/padsleep
|
||
# 先移除旧文件/软链接,避免 cat 跟随链接覆盖源文件
|
||
rm -f "$link"
|
||
cat > "$link" <<WRAPPER
|
||
#!/bin/bash
|
||
exec "$PYTHON_BIN" "$INSTALL_DIR/$script" "\$@"
|
||
WRAPPER
|
||
chmod 755 "$link"
|
||
}
|
||
|
||
create_wrapper "padsleep.py" "$BIN_DIR/padsleep"
|
||
create_wrapper "padsleep_tui.py" "$BIN_DIR/padsleep-config"
|
||
if [ -f "$INSTALL_DIR/padsleep_web.py" ]; then
|
||
create_wrapper "padsleep_web.py" "$BIN_DIR/padsleep-web"
|
||
fi
|
||
info "已创建命令入口:"
|
||
info " $BIN_DIR/padsleep → 启动守护进程 ($PYTHON_BIN)"
|
||
info " $BIN_DIR/padsleep-config → 启动 TUI 配置工具 ($PYTHON_BIN)"
|
||
info " $BIN_DIR/padsleep-web → 启动 Web 监控面板 ($PYTHON_BIN)"
|
||
|
||
# ── 可选:复制 systemd 服务 ──
|
||
install_service() {
|
||
local src="$1"
|
||
local dst="$2"
|
||
local script="$3"
|
||
if [ ! -f "$src" ]; then
|
||
warn "服务文件不存在: $src,跳过"
|
||
return
|
||
fi
|
||
cp "$src" "$dst"
|
||
sed -i "s|WorkingDirectory=.*|WorkingDirectory=$INSTALL_DIR|" "$dst"
|
||
sed -i "s|ExecStart=.*|ExecStart=$PYTHON_BIN $INSTALL_DIR/$script|" "$dst"
|
||
sed -i "s|^User=.*|User=$RUN_USER|" "$dst"
|
||
info "已安装 $dst"
|
||
}
|
||
|
||
install_service "$SRC_DIR/padsleep.service" "$SERVICE_DIR/padsleep.service" "padsleep.py"
|
||
install_service "$SRC_DIR/padsleep-web.service" "$SERVICE_DIR/padsleep-web.service" "padsleep_web.py"
|
||
|
||
systemctl daemon-reload
|
||
info "systemd 已重载"
|
||
echo ""
|
||
info "启用服务(自启动 + 立即启动):"
|
||
info " sudo systemctl enable --now padsleep padsleep-web"
|
||
|
||
# ── 检查 ADB ──
|
||
if command -v adb &>/dev/null; then
|
||
info "ADB 已安装: $(adb --version 2>&1 | head -1)"
|
||
else
|
||
warn "ADB 未安装,请执行: sudo apt install adb"
|
||
fi
|
||
|
||
# ── 完成 ──
|
||
echo ""
|
||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|
||
info "安装完成!"
|
||
echo ""
|
||
info "使用方法:"
|
||
echo " 1. 启动守护进程: padsleep"
|
||
echo " 2. 打开 TUI 配置界面: padsleep-config"
|
||
echo " 3. 打开 Web 监控面板: padsleep-web"
|
||
echo " 4. 注册系统服务: sudo systemctl enable --now padsleep padsleep-web"
|
||
echo " 5. Web 面板地址: http://树莓派IP:31400"
|
||
echo ""
|
||
info "配置文件: $INSTALL_DIR/config.json"
|
||
info "日志文件: $INSTALL_DIR/padsleep.log"
|
||
echo -e "${GREEN}═══════════════════════════════════════${NC}"
|