- web_ui.py: major refactor with improved runner, mode selection, progress tracking - scripts: add device_runtime, device_calibrate, calibration_trace, record_android_flow - docs: add phone-control-manual, update device-adaptation and windows-migration - invoice_tool: enhance H5 automation flow and visual fallback - calibrate.py: expand calibration capabilities - add skills/ and tests/ directories - remove obsolete .opencode/skills/invoice-wrapup Co-Authored-By: Claude <noreply@anthropic.com>
81 lines
2.9 KiB
Python
81 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""以一位用户指定的乘客执行真实全流程设备校准。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
import calibrate
|
|
import calibration_trace
|
|
import device_runtime
|
|
import invoice_tool
|
|
|
|
|
|
def latest_status(masked_name: str) -> dict[str, str]:
|
|
rows = [row for row in invoice_tool.read_progress() if row.get("masked_name") == masked_name]
|
|
return rows[-1] if rows else {}
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
parser = argparse.ArgumentParser(description="对指定乘客执行一次真实设备校准")
|
|
parser.add_argument("--masked-name", required=True, help="当前 H5 页面上可见的脱敏姓名")
|
|
parser.add_argument("--session-dir", default="", help="证据目录,默认按设备 serial 和时间生成")
|
|
args = parser.parse_args(argv)
|
|
|
|
fingerprint = device_runtime.device_fingerprint()
|
|
stamp = time.strftime("%Y%m%d-%H%M%S")
|
|
session = Path(args.session_dir) if args.session_dir else (
|
|
invoice_tool.PROJECT_ROOT / "work" / "calibration" / fingerprint["serial"] / stamp
|
|
)
|
|
os.environ["AUTOTRAIN_CALIBRATION_DIR"] = str(session)
|
|
session.mkdir(parents=True, exist_ok=True)
|
|
(session / "run.json").write_text(json.dumps({
|
|
"masked_name": args.masked_name,
|
|
"fingerprint": fingerprint,
|
|
"started_at": time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
}, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
calibration_trace.capture("start")
|
|
# 先保存当前设备的比例手势参数,保证本次真实流程本身就使用新设备配置。
|
|
if not (calibrate.load_device_profile().get("computed") or {}):
|
|
calibrate.save_device_profile()
|
|
|
|
error = ""
|
|
try:
|
|
rc = invoice_tool.main([
|
|
"android-h5-page-run",
|
|
"--only-masked-name", args.masked_name,
|
|
"--max-actions", "1",
|
|
"--no-final-retry-pass",
|
|
])
|
|
except Exception as exc:
|
|
rc = 2
|
|
error = str(exc)
|
|
calibration_trace.capture("finish")
|
|
progress = latest_status(args.masked_name)
|
|
success = rc == 0 and progress.get("status") == "completed"
|
|
profile = calibrate.load_device_profile()
|
|
profile["status"] = "verified" if success else "failed"
|
|
profile["calibration"] = {
|
|
**(profile.get("calibration") or {}),
|
|
"automatic_run": {
|
|
"status": "verified" if success else "failed",
|
|
"masked_name": args.masked_name,
|
|
"session_dir": str(session.relative_to(invoice_tool.PROJECT_ROOT)),
|
|
"progress": progress,
|
|
"error": error,
|
|
"finished_at": time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
},
|
|
}
|
|
device_runtime.upsert_profile(profile)
|
|
print(json.dumps({"success": success, "session_dir": str(session), "progress": progress, "error": error}, ensure_ascii=False))
|
|
return 0 if success else 2
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|