# termux-dashboard **Repository Path**: void-bug/termux-dashboard ## Basic Information - **Project Name**: termux-dashboard - **Description**: termux-dashboard - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-28 - **Last Updated**: 2026-09-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Termux 仪表盘(termux-dashboard) 跑在小米 12 · Termux 里的手机状态仪表盘:Python 后端 + H5 卡片式前端, 由 `sv`(termux-services / runit)作为系统服务托管。 ![](https://img.shields.io/badge/python-stdlib--only-blue) ![](https://img.shields.io/badge/deps-none-success) ## 功能 | 卡片 | 指标 | 数据来源 | | --- | --- | --- | | 电池 | 电量、充放电状态、供电方式、温度、电流、健康度 | `termux-battery-status`,失败时回退 `/sys/class/power_supply` | | CPU | 使用率、核心数、1/5/15 负载、当前频率、SoC | `/proc/stat`、`/proc/loadavg`、`cpufreq` | | 内存 | 已用/总量/可用、Swap | `/proc/meminfo` | | 存储 | Termux home / prefix / 内部存储 占用 | `os.statvfs` | | Wi-Fi | SSID、IP、RSSI、信号格、速率、频段、BSSID | `termux-wifi-connectioninfo` | | SIM / 移动网络 | 运营商、网络类型、dBm、信号格、SIM 状态、漫游、小区数 | `termux-telephony-deviceinfo` / `termux-telephony-cellinfo` | | Tailscale | Tailscale IP、主机名、在线状态、在线节点数 | `tailscale ip -4` / `tailscale status --json` | | Termux 服务 (sv) | 按「挂掉 / 未运行 / 运行中」分组列出每个 sv 服务的状态、PID、运行时长、是否开机自启、日志大小,挂掉的服务直接显示日志最后一行 + 自定义健康检查 | `sv status `、`$PREFIX/var/service`、`$PREFIX/var/log/sv//current` | | 温度 | 各温度传感器温度 | `/sys/class/thermal` | | 设备与系统 | 型号、厂商、Android/SDK、内核、架构、主机名、运行时长 | `getprop`、`/proc` | 页面为纯 H5 单页,深色**方块卡片 Bento 布局**:卡片大小不一(小/中/大/超大按断点占不同列数), `100dvh` 高度自适应、断点 2 / 4 / 6 列栅格自动密排,默认 5 秒轮询,页面切到后台自动暂停省电。 ## 目录结构 ``` termux-dashboard/ ├── server.py # HTTP 后端(仅标准库) ├── config.json # 运行配置 ├── collectors/ # 指标采集器(每个都容错降级) │ ├── base.py # 进程/文件/TTL 缓存等公共工具 │ ├── system.py # CPU / 内存 / 存储 / 温度 / 设备 │ ├── power.py # 电池 │ ├── network.py # Wi-Fi / SIM / Tailscale / 网卡 │ └── services.py # sv 服务发现 + 健康检查 ├── web/ # 前端(无构建步骤) │ ├── index.html # 方块卡片 Bento 布局,按 s/m/l/xl 声明各断点跨度 │ ├── style.css │ └── app.js ├── sv/termux-dashboard/ # sv 服务定义(模板) │ ├── run # 启动脚本(install.sh 注入安装路径) │ ├── log/run # 日志 -> $PREFIX/var/log/sv/termux-dashboard/current │ └── finish # 进程退出时记录退出码 ├── install.sh # 一键部署到 sv ├── uninstall.sh # 卸载 └── requirements.txt # 说明:无 pip 依赖 ``` ## 为什么这样选型(针对小米 12 / Termux) - **后端只用 Python 标准库**:Termux 上 `pip install` 慢、占空间,还要编译。 `http.server.ThreadingHTTPServer` 足够支撑单手机仪表盘,零依赖、启动即用。 - **`termux-api` 调用很贵**:每次调用都是一次 Android IPC(约 100–400 ms), 所以采集器做了**并行采集**(线程池)和 **TTL 缓存**,整个快照通常 < 1 s。 - **权限不足是常态**:任何指标取不到都不会让页面挂掉,而是显示「不可用 + 原因 + 解决提示」。 - **省电**:默认 5 秒轮询、页面隐藏时暂停、快照缓存 2 秒,避免频繁唤醒 CPU。 - **路径**:自动适配 `$PREFIX=/data/data/com.termux/files/usr` 与 `$SVDIR=$PREFIX/var/service`。 ## 部署流程 ### 1. 安装系统包 ```sh pkg update && pkg upgrade pkg install -y python termux-api iproute2 termux-services ``` `tailscale` 可选(要用 Tailscale 卡片就装): ```sh pkg install -y tailscale && tailscale up ``` ### 2. 安装 Termux:API 应用并授权(关键) `pkg install termux-api` 只是命令行桥接,**必须再安装 Termux:API 这个安卓应用** (F-Droid 搜索 “Termux:API”,需与 Termux 同签名同来源)。 安装后在系统设置里授予权限,否则电池 / SIM / Wi-Fi 明细会缺失: - **位置信息(Location)**:Wi-Fi 与基站信息在 Android 上属于位置数据,必须给。 - **电话(Phone)**:读取 SIM 运营商与网络类型。 - 建议同时在「电池 - 电池优化」里把 Termux 设为**不受限制**,否则后台服务容易被杀。 ### 3. 放到 Termux 并安装服务 把项目目录放到 Termux 的 home 下(不要放在 `/sdcard`,那里不可执行),例如: ```sh cd ~/termux-dashboard sh install.sh # 已手动装好依赖 # 或一步到位: sh install.sh --deps # 顺带 pkg install 依赖 ``` `install.sh` 会: 1. 把程序安装到 `~/termux-dashboard`(可用 `--dir` 改); 2. 生成 `$PREFIX/var/service/termux-dashboard/run`(注入安装路径)、`log/run`、`finish` 并 `chmod +x`; 3. 建好日志目录 `$PREFIX/var/log/sv/termux-dashboard`; 4. 执行 `sv-enable termux-dashboard`(**删除 `down` 文件 = 开机自启**)并 `sv up`; 5. 打印访问地址与 `sv status`。 常用参数: ```sh sh install.sh --port 9000 # 改端口 sh install.sh --host 127.0.0.1 # 只监听本机 sh install.sh --dir ~/apps/td # 改安装目录 ``` > 若 `sv status` 提示 `unknown`:说明 termux-services 的守护进程还没有加载新服务, > **重启一次 Termux**(或在交互 shell 里执行 `service-daemon start`)即可。 ### 4. 打开仪表盘 手机浏览器直接访问: ``` http://127.0.0.1:8787/ ``` 其它设备(手机/电脑)通过 Tailscale 访问: ```sh tailscale ip -4 # 例如 100.x.y.z # 浏览器打开 http://100.x.y.z:8787/ ``` ### 5. 让服务稳定常驻 - 在 Termux 通知栏点击 **Acquire wakelock**(或终端里执行一次 `termux-wake-lock`), 避免安卓在息屏后冻结 Termux。 - 关闭 Termux 的电池优化。 - 不要把 Termux 从最近任务里划掉。 ## sv 管理速查 ```sh sv status termux-dashboard # 查看状态(run:/down:/fail:) sv restart termux-dashboard # 改了 config.json 后重启 sv down termux-dashboard # 停止 sv up termux-dashboard # 启动 sv-disable termux-dashboard # 关闭开机自启(创建 down 文件) sv-enable termux-dashboard # 重新开机自启 tail -f $PREFIX/var/log/sv/termux-dashboard/current # 实时日志 ``` `sv status` 输出含义:`run:` 运行中、`down:` 未运行、`fail:` 启动失败 (失败时先看日志 `$PREFIX/var/log/sv/termux-dashboard/current`)。 仪表盘里的「Termux 服务 (sv)」卡片就是读取 `$PREFIX/var/service/*` 并对每个服务执行 `sv status`,因此你会看到包括 `termux-dashboard` 自身在内的所有 sv 服务。 ## 配置 `config.json` | 字段 | 默认 | 说明 | | --- | --- | --- | | `host` | `0.0.0.0` | 监听地址;只想本机访问改 `127.0.0.1` | | `port` | `8787` | 监听端口 | | `refresh_seconds` | `5` | 前端轮询间隔(同时驱动后端缓存) | | `snapshot_cache_seconds` | `2` | 后端快照缓存,合并并发请求 | | `termux_api_timeout` | `8` | 单次 `termux-*` 调用超时(秒) | | `shell_timeout` | `5` | 普通 shell 命令超时(秒) | | `auth_token` | `""` | 非空则开启鉴权,见下方安全建议 | | `services.auto_discover` | `true` | 自动发现 `$PREFIX/var/service` 下的服务 | | `services.show_disabled` | `true` | 是否显示被禁用(有 `down` 文件)的服务 | | `services.checks` | 见文件 | 自定义健康检查列表 | 自定义健康检查支持两种: ```json "checks": [ { "name": "dashboard", "type": "http", "url": "http://127.0.0.1:8787/api/health", "expect_status": 200, "timeout": 3 }, { "name": "sshd", "type": "cmd", "command": "pgrep -x sshd", "expect_exit": 0, "timeout": 3 } ] ``` 改完执行 `sv restart termux-dashboard` 生效。重装时 `install.sh` 会保留已有 `config.json`。 ## HTTP API | 路径 | 说明 | | --- | --- | | `GET /` | H5 仪表盘页面 | | `GET /static/*` | 静态资源(CSS/JS/图标) | | `GET /api/metrics` | 全量指标快照 JSON | | `GET /api/health` | 轻量健康检查(不触发 `termux-api`,供 sv / 探针使用) | | `GET /api/config` | 前端需要的少量配置(不含 token) | 命令行调试(不启服务): ```sh python server.py --check # 打印环境能力与每个采集器的可用性 python server.py --once # 直接输出一份快照 JSON python server.py --host 127.0.0.1 --port 8787 # 前台运行 ``` ## 安全建议 默认监听 `0.0.0.0`,通过 Tailscale 访问时已在加密网络内;但若手机同时连着 公共 Wi-Fi,端口也会暴露在局域网。建议二选一: 1. 只监听本机:`config.json` 里 `host` 改为 `127.0.0.1`(这样 Tailscale 也访问不到,需自行取舍); 2. 开启令牌:`config.json` 设置 `"auth_token": "一串随机字符串"`, 然后访问 `http://:8787/?token=那串字符串`,页面会把它存到 `localStorage`, 并自动附加到后续 `/api/metrics` 请求。未带令牌的 API 返回 401。 不要把端口直接暴露到公网。 ## 排错 | 现象 | 处理 | | --- | --- | | 页面整体连不上 | `sv status termux-dashboard`;`tail -f $PREFIX/var/log/sv/termux-dashboard/current` | | 服务 `unknown` / 起不来 | 重启 Termux 让 termux-services 加载;确认 `pkg install termux-services` | | 电池/SIM/Wi-Fi 显示不可用 | 安装 Termux:API 应用并授予位置/电话权限;确认 `pkg install termux-api` | | Wi-Fi 有 IP 但没 SSID/信号 | 缺位置权限 | | Tailscale 卡片无 IP | `pkg install tailscale && tailscale up`;`tailscale ip -4` 验证 | | CPU 使用率一直 0 | 首次采样需要两次 `/proc/stat` 间隔,稍等一个刷新周期;部分 ROM 限制 `/proc/stat` | | 端口被占用 | 改 `config.json` 的 `port`,`sv restart termux-dashboard` | | `/sdcard` 下无法执行 | `install.sh` 会把程序复制到 `$HOME/termux-dashboard`,从那里运行 | ## 卸载 ```sh sh uninstall.sh # 停止并移除 sv 服务 sh uninstall.sh --purge # 连同日志和 ~/termux-dashboard 一起删除 ``` ## 资源占用 - 常驻内存:Python 进程约 15–30 MB。 - CPU:空闲几乎为 0;每次刷新因并行调用 `termux-*` 产生短暂波动。 - 想更省电:把 `refresh_seconds` 调到 `10`~`30`,并保持页面关闭/后台时自动暂停。