docs+release: CHANGELOG/llms.txt/SDK README/API.md,0.1.0 候选
This commit is contained in:
1 parent
122023cdf4
commit
2b90d3891f
4 files changed
+258
-90
No files matched your search
@@ -1,129 +1,104 @@
|
||||
# ppclock — 4.2寸墨水屏设备离线 CLI 上位机
|
||||
# ppclock — 4.2寸墨水屏设备离线 SDK 与 CLI
|
||||
|
||||
替代厂商 Web 上位机(mspppclock.tech)与 Android App 的**完全离线**命令行工具,
|
||||
面向 agent 编排设计:所有命令支持 `--json` 机器可读输出,`batch` 子命令支持 JSONL 批量执行。
|
||||
替代厂商 Web 上位机(mspppclock.tech)与 Android App 的**完全离线**开发包:
|
||||
Python SDK(`PPClient`)+ CLI(`ppclock`)+ BLE 桥(`ppclock-bridge`),
|
||||
全部功能经真机验证(协议三线逆向 + 实机互证)。
|
||||
|
||||
设备:4.2" 400×300 黑/白/红三色墨水屏,Dialog DA14585 BLE SoC(广播名前缀 `NRF-`)。
|
||||
|
||||
> AI 消费向项目卡见 [`llms.txt`](llms.txt);签名级 API 见 [`docs/sdk/API.md`](docs/sdk/API.md)。
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
.venv/bin/pip install -e . # 依赖:bleak、pillow(离线 wheel 即可,运行零网络)
|
||||
.venv/bin/ppclock --help
|
||||
.venv/bin/pip install -e ".[dev]" # 依赖:bleak、pillow(dev: pytest)
|
||||
```
|
||||
|
||||
运行环境要求:Linux + 蓝牙适配器(bleak/D-Bus)。**不需要互联网**。
|
||||
运行要求:蓝牙适配器(本机 bleak)**或** 他机蓝牙经 `ppclock-bridge` 桥接。**不需要互联网**。
|
||||
|
||||
## 快速开始
|
||||
## SDK 用法(二次开发)
|
||||
|
||||
```python
|
||||
from ppclock import PPClient
|
||||
|
||||
async with PPClient.via_local() as dev: # 本机蓝牙
|
||||
await dev.set_time(tz=8) # 北京时间
|
||||
await dev.set_mode("clock1")
|
||||
|
||||
async with PPClient.via_bridge("192.168.61.35:8971") as dev: # 经 bridge
|
||||
await dev.upload_image("photo.jpg", slot=0) # 传图(6 种抖动可选)
|
||||
await dev.render_template("custom", {"text": "你好【红字】"})
|
||||
await dev.countdown(date(2026, 12, 31), prefix="目标")
|
||||
await dev.activate_auto() # 离线激活(无需厂商服务器)
|
||||
```
|
||||
|
||||
设备操作全集:对时(tz)/模式/切换/传图/6 模板/倒计时/休眠/停车牌/轮播/LUT/WiFi/raw/OTA,
|
||||
见 [`docs/sdk/API.md`](docs/sdk/API.md)。
|
||||
|
||||
## CLI 用法
|
||||
|
||||
```bash
|
||||
ppclock scan # 扫描设备(NRF- 前缀)
|
||||
ppclock --mac AA:BB:CC:DD:EE:FF time # 对时(免扫描直连)
|
||||
ppclock mode clock1 # 时钟模式一
|
||||
ppclock image photo.jpg --slot 0 # 传图到图一(默认 atkinson 抖动+三色)
|
||||
ppclock scan # 扫描设备(NRF- 前缀)
|
||||
ppclock --mac AA:BB:CC:DD:EE:FF time --tz 8 # 对时(北京时间)
|
||||
ppclock image photo.jpg --slot 0 # 传图到图一
|
||||
ppclock template custom --data '{"text":"你好【世界】"}'
|
||||
ppclock countdown 2026-12-31 --prefix "目标" # 倒计时
|
||||
ppclock batch job.jsonl --json # 批量执行(单连接)
|
||||
ppclock countdown 2026-12-31 --prefix 目标
|
||||
ppclock batch job.jsonl --json # 批量执行(单连接)
|
||||
```
|
||||
|
||||
## 命令一览
|
||||
- 全命令支持 `--json` 机器可读输出(`{"ok","cmd","data"|"error"}`,退出码 0/1/2/3)
|
||||
- `batch`:JSONL 批量(`{"argv":[...]}` 每行一条,单连接执行,agent 编排友好)
|
||||
|
||||
| 命令 | 功能 | 对应 Web 上位机功能 |
|
||||
|------|------|---------------------|
|
||||
| `scan` | 扫描设备 | 搜索设备 |
|
||||
| `time [ISO]` | 对时 | 设置时间 |
|
||||
| `mode NAME` | clock1-3/calendar1-3/image0-3/tricolor/mono | 时钟/日历/图片模式、三色/黑白 |
|
||||
| `toggle NAME` | invert/font/rotate180/hour_format/clock_color | 反色/字体/旋转/12-24h/颜色 |
|
||||
| `clear` | 刷屏 | 刷屏 |
|
||||
| `image PATH` | 传图(6 种抖动+亮度/对比度/饱和度/旋转/缩放+槽位) | 4.2传图/上传图片 |
|
||||
| `template NAME` | 本地渲染 6 模板并上传 | 模板系统 |
|
||||
| `countdown` | 倒计时日期/前缀文字/日历中文字/关闭 | 倒计时 |
|
||||
| `sleep` | 休眠时段 | 休眠 |
|
||||
| `parking NUM` | 停车牌 | 停车牌 |
|
||||
| `rotation` | 轮播数量/间隔 | 轮播 |
|
||||
| `lut HEX` | 红/黑 LUT 校准 | LUT |
|
||||
| `activate` | 激活码下发/读取设备 ID | 激活 |
|
||||
| `wifi` | WiFi+城市配置 | WiFi 配置 |
|
||||
| `raw HEX` | 高级命令直发 | 高级命令 |
|
||||
| `batch FILE` | JSONL 批量(单连接) | —(增强) |
|
||||
## BLE bridge(蓝牙在他机时)
|
||||
|
||||
## JSON 输出契约(`--json`)
|
||||
本机无蓝牙(或 USB/IP 透传断流)时,把 BLE 桥接到蓝牙物理所在机:
|
||||
|
||||
成功:`{"ok": true, "cmd": "<cmd>", "data": {...}}`
|
||||
失败:`{"ok": false, "cmd": "<cmd>", "error": "<msg>"}`
|
||||
退出码:0 成功 / 1 参数错误 / 2 传输(BLE)错误 / 3 其他错误。
|
||||
```bash
|
||||
# 蓝牙所在机(Windows/Linux,仅需 bleak)
|
||||
pip install bleak
|
||||
ppclock-bridge --host 0.0.0.0 --port 8971 # 或 python -m ppclock.bridge_server
|
||||
|
||||
## batch JSONL 格式
|
||||
|
||||
每行一条命令:`{"argv": ["mode", "clock1"]}`,输出 `{"ok":true,"cmd":"batch","data":{"results":[...]}}`。
|
||||
整个批量在**一次 BLE 连接**内完成;`--stop-on-error` 遇错即停。
|
||||
|
||||
## 定时推送(增强)
|
||||
|
||||
CLI 全部为单次执行语义,调度交给系统 cron:
|
||||
|
||||
```cron
|
||||
# 每小时整点更新倒计时画面
|
||||
0 * * * * /path/.venv/bin/ppclock --mac AA:BB:CC:DD:EE:FF countdown 2026-12-31 --prefix 目标 --json >> /var/log/ppclock.log 2>&1
|
||||
# 使用方(全部 SDK/CLI 透明可用)
|
||||
ppclock --via bridge://192.168.61.35:8971 --json scan
|
||||
export PPCLOCK_VIA=bridge://192.168.61.35:8971
|
||||
```
|
||||
|
||||
## 离线说明
|
||||
协议:JSONL over TCP v1(`ping/scan/connect/write/read/request_device_id/ota/services/close`),
|
||||
仅限可信 LAN(无鉴权)。详见 `docs/sdk/API.md` §Bridge RPC。
|
||||
|
||||
- 激活:原厂流程依赖云端 `key_generator.php`。本工具的本地化方案见
|
||||
`docs/firmware-analysis.md`(激活校验分析)与 `docs/protocol.md` §7。
|
||||
- 模板渲染、二维码生成(本地 qrcode 库)、抖动算法全部本地实现,无任何 CDN/服务器依赖。
|
||||
- 天气(CITY 代码)属原厂云功能,本地化范围外;`wifi` 命令仅透传配置。
|
||||
## 固件工具
|
||||
|
||||
```bash
|
||||
.venv/bin/python tools/fw_info.py app/firmware-PP_da14585_4.2_CH.img # 镜像头解析
|
||||
.venv/bin/python tools/fw_pack.py body.bin out.img # 修改后重打包(CRC 重算)
|
||||
ppclock --json ota firmware.img # 预检(不烧录)
|
||||
ppclock --json ota firmware.img --yes # SUOTA 烧录(高危,需授权)
|
||||
```
|
||||
|
||||
本机设备为裸闪存布局(无产品头)→ SUOTA 止于设备内部门禁;工厂布局与线刷恢复路径见
|
||||
[`docs/firmware-layout.md`](docs/firmware-layout.md)。
|
||||
|
||||
## 真机全链路测试
|
||||
|
||||
设备到场后执行(计划:`docs/field-test-plan.md`):
|
||||
|
||||
```bash
|
||||
.venv/bin/python tools/field_test.py # 引导式:自动判定+目视确认
|
||||
.venv/bin/python tools/field_test.py --ota # 含高危固件烧录阶段(默认跳过)
|
||||
```
|
||||
|
||||
结果自动写入 `docs/field-test-result.md`。
|
||||
|
||||
## BLE bridge(蓝牙在他机时)
|
||||
## 离线说明
|
||||
|
||||
当本机无蓝牙(或蓝牙经 USB/IP 透传不稳定)时,把 BLE 操作桥接到蓝牙物理所在机:
|
||||
|
||||
**服务端**(蓝牙所在机,如 Windows host-win;单文件,仅依赖 bleak):
|
||||
|
||||
```bash
|
||||
pip install bleak
|
||||
python tools/bridge_server.py --host 0.0.0.0 --port 8971
|
||||
```
|
||||
|
||||
**客户端**(本机,全部 CLI 命令透明可用):
|
||||
|
||||
```bash
|
||||
ppclock --via bridge://192.168.61.35:8971 --json scan
|
||||
export PPCLOCK_VIA=bridge://192.168.61.35:8971 # 或环境变量一次设定
|
||||
ppclock --json image photo.jpg --slot 0
|
||||
PPCLOCK_VIA=bridge://192.168.61.35 .venv/bin/python tools/field_test.py
|
||||
```
|
||||
|
||||
协议:JSONL over TCP(`ping/scan/connect/write/read/request_device_id/ota/close`),
|
||||
OTA 进度以事件流回。仅限可信 LAN 使用(无鉴权)。
|
||||
|
||||
## 本机蓝牙经 USB/IP 透传的已知问题
|
||||
|
||||
大 MTU GATT 流量会触发断流(详见 DECISIONS.md 2026-07-28)。保留缓解:
|
||||
`/sys/bus/usb/devices/1-1/power/control=on`(禁用 runtime PM)。重启后失效,固化:
|
||||
|
||||
```bash
|
||||
echo 'ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="8087", ATTR{idProduct}=="0029", ATTR{power/control}="on"' | sudo tee /etc/udev/rules.d/99-ax200-pm.rules
|
||||
```
|
||||
|
||||
根治请用上面的 bridge 模式。
|
||||
- **激活**:原厂流程依赖云端 `key_generator.php`;本 SDK 用固件逆向出的本地 keygen
|
||||
(`activate_auto`:EFEF 取 ID → MAC 反解 → 本地算码),实机验证。
|
||||
- 模板渲染、二维码(本地 qrcode 库)、六种抖动全部本地实现,无 CDN/服务器依赖。
|
||||
- 天气(CITY 代码)属原厂云功能,本地化范围外;`wifi` 命令仅透传(且本固件 no-op)。
|
||||
|
||||
## 开发
|
||||
|
||||
```bash
|
||||
.venv/bin/python -m pytest tests/ -q # 150 测试
|
||||
.venv/bin/python -m pytest tests/ -q # 165 测试
|
||||
```
|
||||
|
||||
治理规则见 `GOVERNANCE.md`;计划见 `PLAN.md`;协议规范见 `docs/protocol.md`。
|
||||
治理规则见 `GOVERNANCE.md`;变更记录 `CHANGELOG.md`;决策日志 `DECISIONS.md`。
|
||||
协议规范(唯一事实源):`docs/protocol.md`;固件内部:`docs/firmware-analysis.md`。
|
||||
Reference in new issue
Block a user