docs: 全面更新——README/API/DEVELOPMENT 摘除 STF 章节(设备池/型号/看屏/新端点文档,技术红线改为共享 transport 表述)
This commit is contained in:
+73
-48
@@ -343,7 +343,7 @@
|
||||
|
||||
(权限:设备控制)
|
||||
|
||||
释放当前账户占用的所有 STF 设备(清理用)。
|
||||
(已随 STF 摘除移除,此接口不再存在;设备互斥由调度器内存锁保证)
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
@@ -557,7 +557,7 @@
|
||||
|
||||
### GET /api/apks/install/devices
|
||||
|
||||
可安装设备列表:STF 在线设备池 + 本机 adb 设备(**含 USB 有线连接**,serial 无冒号标记 `usb`)。
|
||||
可安装设备列表:设备池在线设备(标记 `pool`)+ 本机 adb 设备(**含 USB 有线连接**,serial 无冒号标记 `usb`)。
|
||||
安装弹窗用此列表,USB 设备安装时跳过 adb connect 直接安装。
|
||||
|
||||
**响应**:
|
||||
@@ -598,26 +598,81 @@
|
||||
## 13. 维护 / 工具(仅管理员)
|
||||
|
||||
以下接口都**仅管理员可用**(普通用户即使有业务权限也访问不了,返回 403)。
|
||||
维护页现仅含 STF 服务管理;adb 终端、Tailscale 管理、应用管理、STF 设备管理等
|
||||
已集中到"工具"页(页内子分栏),API 不变。
|
||||
设备池管理、远程看屏、adb 终端等集中在"工具"页(页内子分栏)。
|
||||
|
||||
### POST /api/stf/restart
|
||||
### GET /api/devices/pool
|
||||
|
||||
一键重启 STF Docker 容器。通过 SSH 到部署机执行 `docker restart`,随后轮询 STF API 确认恢复。
|
||||
|
||||
- 目标与容器名:`STF_SSH_TARGET`(默认 `[email protected]`)、`STF_DOCKER_CONTAINER`(默认 `stf`)环境变量配置
|
||||
- 前置条件:本机可免密 SSH 到部署机
|
||||
- **有任务在运行时返回 409 拒绝执行**(STF 重启会重置设备占用状态)
|
||||
- 失败返回 502(SSH 不可达/容器名错误);执行超时返回 408
|
||||
设备池清单(SQLite devices 表),含实时在线状态。**权限**:`devices`。
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{"ok": true, "msg": "STF 容器已重启", "detail": "stf: Up 3 seconds", "api_alive": true}
|
||||
{"ok": true, "devices": [
|
||||
{"serial": "100.100.10.20:5555", "name": "", "model": "22120RN86C",
|
||||
"enabled": true, "online": true, "note": "", "created_at": "2026-08-17 11:10"}
|
||||
]}
|
||||
```
|
||||
|
||||
### POST /api/devices/pool/add
|
||||
|
||||
添加/更新设备(upsert)。**权限**:`devices`。
|
||||
**请求**(JSON):`{"serial": "100.100.10.20:5555", "name": "备注", "note": ""}`
|
||||
IP:5555 设备添加后立即尝试 adb connect,并后台采集型号(getprop ro.product.model)。
|
||||
|
||||
### POST /api/devices/pool/toggle
|
||||
|
||||
启用/停用设备(停用后不参与任务调度)。**权限**:`devices`。
|
||||
**请求**(JSON):`{"serial": "...", "enabled": false}`
|
||||
|
||||
### POST /api/devices/pool/remove
|
||||
|
||||
从设备池删除(不再参与调度,不影响设备本身)。**权限**:`devices`。
|
||||
**请求**(JSON):`{"serial": "..."}`
|
||||
|
||||
### POST /api/devices/pool/reconnect
|
||||
|
||||
一键重连:并发 adb connect 池内全部 IP:5555 设备(后台执行),完成后自动批量刷新型号。**权限**:`devices`。
|
||||
|
||||
### POST /api/devices/pool/refresh_models
|
||||
|
||||
批量采集池内在线设备的型号(后台执行)。**权限**:`devices`。
|
||||
|
||||
### GET /api/screen/stream
|
||||
|
||||
远程看屏:MJPEG 实时画面流(`multipart/x-mixed-replace`)。**权限**:`devices`。
|
||||
|
||||
`?serial=xxx` 指定设备;浏览器 `<img src>` 直接渲染,客户端断开自动停止。数据源 u2(atx-agent minicap,约 3-6 帧/秒)。
|
||||
|
||||
### POST /api/screen/tap
|
||||
|
||||
点击设备屏幕。**权限**:`devices`。
|
||||
**请求**(JSON):`{"serial": "...", "x": 360, "y": 800}`(设备原生分辨率坐标)
|
||||
|
||||
### POST /api/screen/swipe
|
||||
|
||||
滑动。**请求**(JSON):`{"serial": "...", "x1": 360, "y1": 1200, "x2": 360, "y2": 600, "duration": 0.2}`
|
||||
|
||||
### POST /api/screen/key
|
||||
|
||||
按键。**请求**(JSON):`{"serial": "...", "key": "back"}`。
|
||||
支持:back/home/recent/menu/power/volume_up/volume_down/enter/delete/search/camera
|
||||
|
||||
### POST /api/screen/text
|
||||
|
||||
输入文字(需焦点在输入框)。**请求**(JSON):`{"serial": "...", "text": "你好"}`
|
||||
|
||||
### POST /api/device/screen_all
|
||||
|
||||
批量亮屏/息屏(并发)。**权限**:`devices`。
|
||||
|
||||
**请求**(JSON):
|
||||
```json
|
||||
{"mode": "on", "serials": ["100.100.10.11:5555"]}
|
||||
```
|
||||
`serials` 可选:指定设备(离线自动过滤);不带则作用于全部在线设备。息屏会中断运行中的任务,前端有确认提示。
|
||||
|
||||
### GET /api/adb/devices
|
||||
|
||||
维护终端设备列表:本地 adb 已连接(含 offline)+ STF 在线设备池(标记 `stf`)。
|
||||
维护终端设备列表:本地 adb 已连接(含 offline)+ 设备池已配置设备(标记 `pool`)。
|
||||
供终端设备选择器使用——选中后前端自动附加 `-s <serial>`。
|
||||
|
||||
**响应**:
|
||||
@@ -639,7 +694,7 @@ adb 远程终端:用平台 adb 二进制执行任意 adb 命令(20s 超时
|
||||
```
|
||||
(开头的 `adb` 前缀可省略)
|
||||
|
||||
**安全红线**:包含 `kill-server` / `disconnect` 的命令直接拒绝(400)——会断开 STF provider 共享的 adb transport,导致全部设备被 STF 误判离线。
|
||||
**安全红线**:包含 `kill-server` / `disconnect` 的命令直接拒绝(400)——会断开共享的 adb transport,导致全部设备连接重建。
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
@@ -653,7 +708,7 @@ adb 远程终端:用平台 adb 二进制执行任意 adb 命令(20s 超时
|
||||
### POST /api/steps/test
|
||||
|
||||
在指定设备上单步试执行(步骤编辑器"测试此步骤"按钮),验证选择器是否命中。
|
||||
只读连接(adb connect + u2),不占用/释放 STF,与运行中任务互不干扰。
|
||||
只读连接(adb connect + u2),与运行中任务互不干扰。
|
||||
|
||||
**请求**(JSON):
|
||||
```json
|
||||
@@ -721,7 +776,7 @@ adb 远程终端:用平台 adb 二进制执行任意 adb 命令(20s 超时
|
||||
{"ipv4": "100.100.10.16"}
|
||||
```
|
||||
|
||||
⚠ 改 IP 会断开设备当前 tailscale 会话;平台设备池 serial 随之变化,需同步更新 STF 设备池/分组/任务目标。
|
||||
⚠ 改 IP 会断开设备当前 tailscale 会话;平台设备池 serial 随之变化,需同步更新设备池/分组/任务目标。
|
||||
|
||||
### DELETE /api/tailscale/devices/:device_id
|
||||
|
||||
@@ -746,7 +801,7 @@ adb 远程终端:用平台 adb 二进制执行任意 adb 命令(20s 超时
|
||||
|
||||
## 16. 工具(仅管理员)
|
||||
|
||||
工具页(剪贴板注入 / 应用版本管理 / STF 设备管理)接口,均仅管理员可用。
|
||||
工具页(剪贴板注入 / 应用版本管理 / 设备池管理)接口,均仅管理员可用。
|
||||
|
||||
### POST /api/tools/clipboard/set
|
||||
|
||||
@@ -756,7 +811,7 @@ adb 远程终端:用平台 adb 二进制执行任意 adb 命令(20s 超时
|
||||
```json
|
||||
{"serials": ["100.100.10.11:5555", "0123456789ABCDEF"], "text": "要注入的文字"}
|
||||
```
|
||||
设备来源与维护终端一致(本地 adb 含 USB + STF 池)。
|
||||
设备来源与维护终端一致(本地 adb 含 USB + 设备池)。
|
||||
实现:u2 `jsonrpc.setClipboard`(实测 `cmd clipboard` 在 MIUI 上不存在),支持中文/引号/换行;
|
||||
IP 设备先 adb connect(已连接跳过,绝不 disconnect),USB 设备首次自动推送 atx-agent。
|
||||
|
||||
@@ -781,33 +836,3 @@ IP 设备先 adb connect(已连接跳过,绝不 disconnect),USB 设备
|
||||
"results": {"100.100.10.11:5555": {"installed": true, "version_name": "28.5.0", "version_code": "280500"}}}
|
||||
```
|
||||
未安装返回 `installed: false`;查询失败的设备带 `error` 字段。
|
||||
|
||||
### GET /api/stf/devmgmt/status
|
||||
|
||||
STF 设备管理状态:connect_devices.sh 脚本配置的 IP 列表 + 220 上 adb 实际连接状态。
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{"ok": true,
|
||||
"configured": ["100.100.10.10", "100.100.10.11"],
|
||||
"connected": [{"serial": "100.100.10.10:5555", "state": "device"}]}
|
||||
```
|
||||
|
||||
### POST /api/stf/devmgmt/add
|
||||
|
||||
添加设备:写入 220 上 `connect_devices.sh` 的 DEVICES 列表 + 立即 `docker exec adb adb connect`。
|
||||
设备不可达时 connect 会 15 秒超时兜底(220 侧 `timeout`),但仍保留在脚本中,cron 每 5 分钟自动重试。
|
||||
|
||||
**请求**(JSON):`{"ip": "100.100.10.20"}`(可带 `:5555`,自动归一化)
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{"ok": true, "msgs": ["已写入脚本 /mnt/data/openstf/connect_devices.sh", "连接超时(设备当前不可达),已保留在脚本中,cron 会每 5 分钟自动重试"]}
|
||||
```
|
||||
|
||||
### POST /api/stf/devmgmt/remove
|
||||
|
||||
移除设备:从脚本 DEVICES 删除 + `adb disconnect`(设备从 STF 池下线,任务不再分配)。
|
||||
注意:断开的是 220(STF provider 侧)的 adb 连接,与本机任务直连的 adb 相互独立。
|
||||
|
||||
**请求**(JSON):`{"ip": "100.100.10.20"}`
|
||||
|
||||
+17
-15
@@ -13,7 +13,7 @@
|
||||
| `dev` | **开发分支**,所有新功能/修复都在这里开发 |
|
||||
| `main` | **生产分支**(主分支),只放已确认的稳定版本 |
|
||||
|
||||
生产环境 = STF 主机 `192.168.20.220` 的 `/mnt/data/openstf/auto_control`(python-app 容器运行 `web_server.py`)。
|
||||
生产环境 = 部署机 `192.168.20.220` 的 `/mnt/data/openstf/auto_control`(python-app 容器运行 `web_server.py`)。
|
||||
|
||||
### 1.2 git 操作铁律(重要)
|
||||
|
||||
@@ -42,47 +42,49 @@
|
||||
| 环境 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| 开发机 | 本机(192.168.20.57) | `.venv` + 本地运行 `web_server.py` |
|
||||
| 生产机 | STF 主机 220 的 `auto_control` | python-app 容器,`network_mode: host` |
|
||||
| STF 服务 | `192.168.20.220:7100` | 设备农场(REST API) |
|
||||
| 设备 | Tailscale `100.100.10.x:5555` | 5 台 Xiaomi,本机 `100.100.10.2` 在 tailnet 内 |
|
||||
| 生产机 | 部署机 220 的 `auto_control` | python-app 容器,`network_mode: host` |
|
||||
| STF 服务 | ~~`192.168.20.220:7100`~~ | 已停用(2026-08-18 `docker stop stf`,代码已摘除依赖) |
|
||||
| adb 容器 | 220 上 `adb`(host 网络 5037) | USB 设备远程 adb server;网络设备补连用 |
|
||||
| 设备 | Tailscale `100.100.10.x:5555` | Xiaomi 舰队,本机 `100.100.10.2` 在 tailnet 内 |
|
||||
| uiautodev | 本机 `20242` | 元素抓取服务(web_server 自动拉起) |
|
||||
|
||||
### 2.1 adb key(关键)
|
||||
|
||||
- 本机 `~/.android/adbkey` 已换成 **STF adb 容器的 key**(5 台设备都信任)
|
||||
- 本机 `~/.android/adbkey` 沿用历史 key(原取自 STF adb 容器,全部设备都信任)
|
||||
- **不要随意更换 key**——设备会变 unauthorized 连不上
|
||||
- 旧 key 备份在 `~/.android/adbkey.local.bak`
|
||||
- 生产环境的容器也需要用这把 key(部署时处理)
|
||||
|
||||
### 2.2 设备连接方式
|
||||
|
||||
- 设备 serial 是 `IP:5555`(Tailscale 地址),**直连**优先
|
||||
- STF 桥接(remoteConnect)在此环境**不可用**(隧道 adb key 认证失败,显示 unauthorized)
|
||||
- 设备 serial 是 `IP:5555`(Tailscale 地址),**直连**优先(只 connect、绝不 disconnect)
|
||||
- USB 设备(serial 无冒号):插本机走本地 adb;插 220 走远程 adb server(`USB_ADB_HOST:5037`)
|
||||
- 本机已在 tailnet 内,直连可靠且快(<1s)
|
||||
- 设备加入/退出平台:工具 → 设备池管理(SQLite 清单,自动连接 + 型号采集)
|
||||
|
||||
---
|
||||
|
||||
## 3. 技术红线(开发限制)—— 违反会打断 STF,需人工恢复
|
||||
## 3. 技术红线(开发限制)—— 违反会打断共享 adb transport,需人工恢复
|
||||
|
||||
这些是踩过坑后总结的,**任何修改都不能引入**。违反任何一条都会导致设备被 STF 误判离线、需人工处理:
|
||||
这些是踩过坑后总结的,**任何修改都不能引入**。违反任何一条都会导致设备连接被全部重建(历史原因:STF provider 共享同一 adb transport,摘除 STF 后仍保留此约束):
|
||||
|
||||
1. **绝不 `adb kill-server`**
|
||||
- 会断开所有设备的 adb transport,STF 对全网设备误判离线并触发重连
|
||||
- 会断开所有设备的 adb transport,全部设备连接被重建,运行中任务中断
|
||||
- 见 `core/adb_helper.py`
|
||||
|
||||
2. **绝不对 `IP:5555` 设备 `adb disconnect`**
|
||||
- STF provider 共享该地址的 adb transport,disconnect 会断 STF
|
||||
- 该地址的 adb transport 是共享的(历史与 STF provider 共用),disconnect 会断掉全部相关连接
|
||||
- 直连模式下 `release()` 不 disconnect
|
||||
- 见 `core/device_worker.py` `STFDevice.release()`
|
||||
|
||||
3. **空闲设备扫描不主动 connect/disconnect**
|
||||
- STF provider 内部通过 IP:5555 维持连接,外部 connect/disconnect 会让 STF 误判离线
|
||||
- IP:5555 的 transport 由多方共享(历史与 STF provider 共用),外部 connect/disconnect 会扰动共享连接
|
||||
- `_ForegroundScanner._scan_free` 对空闲设备直接返回"空闲",不碰 adb
|
||||
- 见 `core/task_manager.py`
|
||||
|
||||
4. **adb key 保持为 STF 容器的 key**(见 2.1)
|
||||
4. **adb key 保持历史 key 不变**(见 2.1,设备信任该 key)
|
||||
|
||||
5. **直连优先,不引入 STF 桥接**(见 2.2)
|
||||
5. **直连优先,不引入第三方桥接**(见 2.2)
|
||||
|
||||
### 3.1 其他开发限制
|
||||
|
||||
@@ -92,7 +94,7 @@
|
||||
- **数据库是 SQLite**(`data/users.db`,WAL 模式):运行时数据不提交 git
|
||||
- **前端 JS 在 `static/admin/monitor.js`**(已从 HTML 拆分),HTML 里用 `<script src>` 引用
|
||||
- **监控页/大列表已加分页**:100 台设备也只渲染 10 行/页,不要移除分页逻辑
|
||||
- **任务批量触发已错峰**(`_START_STAGGER_SEC`):避免大量设备同时启动造成 adb/STF 风暴,不要移除
|
||||
- **任务批量触发已错峰**(`_START_STAGGER_SEC`):避免大量设备同时启动造成 adb 连接风暴,不要移除
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user