增加测量并发送手机接口
This commit is contained in:
@@ -16,7 +16,8 @@ API 接口:
|
||||
POST /connect {port} 打开蓝牙 COM 口, 等待手机连接
|
||||
POST /disconnect 断开
|
||||
POST /command {cmd} 命令: send <r> <hd> 发送测量 | disconnect 断开
|
||||
GET /status 手机连接状态 + 待发送队列
|
||||
GET /status 手机连接状态
|
||||
POST /measure-and-send 触发水准仪测量(FML)→获取数据→发到手机 (一键操作) + 待发送队列
|
||||
|
||||
协议说明:
|
||||
手机→PC: 0x02F0... 握手 | ?0100 轮询 | 0x050B8D 控制码 | KENC 编码
|
||||
@@ -29,6 +30,8 @@ import sys
|
||||
import time
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import urllib.request
|
||||
import threading
|
||||
import asyncio
|
||||
import argparse
|
||||
@@ -46,6 +49,7 @@ from pydantic import BaseModel
|
||||
|
||||
DEFAULT_HTTP_PORT = 58100
|
||||
DEFAULT_BAUDRATE = 9600
|
||||
_config = {"level_url": "http://127.0.0.1:58000"} # 水准仪服务地址
|
||||
|
||||
# ── 协议常量 ──
|
||||
HANDSHAKE_PHONE = bytes([0x02, 0xF0, 0x00, 0x00, 0xDE, 0x03, 0x00, 0x07])
|
||||
@@ -488,6 +492,10 @@ class CommandRequest(BaseModel):
|
||||
cmd: str
|
||||
|
||||
|
||||
class MeasureAndSendRequest(BaseModel):
|
||||
level_url: str = "" # 留空则使用默认地址
|
||||
|
||||
|
||||
# ════════════════════════════════════════════════════════════════
|
||||
|
||||
@asynccontextmanager
|
||||
@@ -585,6 +593,80 @@ async def disconnect():
|
||||
return await loop.run_in_executor(None, _do)
|
||||
|
||||
|
||||
# ── POST /measure-and-send ──
|
||||
|
||||
@app.post("/measure-and-send")
|
||||
async def measure_and_send(req: MeasureAndSendRequest = MeasureAndSendRequest()):
|
||||
"""
|
||||
一键操作: 触发水准仪测量(FML) → 拿到数据 → 发到手机蓝牙。
|
||||
|
||||
请求体 (均可选):
|
||||
{ "level_url": "http://127.0.0.1:58000" } # 水准仪服务地址
|
||||
"""
|
||||
level_url = req.level_url.strip() or _config["level_url"]
|
||||
|
||||
def _do():
|
||||
# 1. 检查本服务蓝牙已连接
|
||||
if not svc.connected:
|
||||
raise HTTPException(status_code=400,
|
||||
detail="手机蓝牙未连接, 请先 POST /connect")
|
||||
|
||||
# 2. 向水准仪服务发 FML 触发测量
|
||||
try:
|
||||
fm_req = urllib.request.Request(
|
||||
f"{level_url}/command",
|
||||
data=json.dumps({"cmd": "FML"}).encode("utf-8"),
|
||||
headers={"Content-Type": "application/json"},
|
||||
method="POST",
|
||||
)
|
||||
with urllib.request.urlopen(fm_req, timeout=15) as resp:
|
||||
fm_result = json.loads(resp.read().decode("utf-8"))
|
||||
except urllib.error.URLError as e:
|
||||
raise HTTPException(
|
||||
status_code=502,
|
||||
detail=f"无法连接到水准仪服务 {level_url}: {e.reason}"
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=502,
|
||||
detail=f"调用水准仪服务失败: {e}"
|
||||
)
|
||||
|
||||
# 3. 解析测量结果
|
||||
if fm_result.get("status") != "ok":
|
||||
raise HTTPException(
|
||||
status_code=502,
|
||||
detail=f"水准仪测量失败: {fm_result.get('error_desc') or fm_result.get('raw_text') or '未知错误'}"
|
||||
)
|
||||
|
||||
r = fm_result.get("staff_reading")
|
||||
hd = fm_result.get("distance")
|
||||
if r is None or hd is None:
|
||||
raise HTTPException(
|
||||
status_code=502,
|
||||
detail=f"水准仪返回数据不完整: {json.dumps(fm_result, ensure_ascii=False)}"
|
||||
)
|
||||
|
||||
# 4. 直接发到手机蓝牙
|
||||
ok = svc.send_measurement(r, hd)
|
||||
|
||||
return {
|
||||
"status": "ok" if ok else "send_error",
|
||||
"measurement": {
|
||||
"staff_reading": r,
|
||||
"distance": hd,
|
||||
"height_diff": fm_result.get("height_diff"),
|
||||
"std_dev": fm_result.get("std_dev"),
|
||||
"raw_text": fm_result.get("raw_text"),
|
||||
},
|
||||
"level_service": level_url,
|
||||
"phone_sent": ok,
|
||||
}
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
return await loop.run_in_executor(None, _do)
|
||||
|
||||
|
||||
# ── POST /command ──
|
||||
|
||||
@app.post("/command")
|
||||
@@ -670,8 +752,13 @@ def main():
|
||||
help=f"HTTP 服务端口 (默认 {DEFAULT_HTTP_PORT})")
|
||||
parser.add_argument("--bt-port", default=None,
|
||||
help="启动时自动连接的蓝牙 COM 口 (如 COM3)")
|
||||
parser.add_argument("--level-url", default=_config["level_url"],
|
||||
help=f"水准仪服务地址 (默认 {_config['level_url']})")
|
||||
args = parser.parse_args()
|
||||
|
||||
# 更新全局配置
|
||||
_config["level_url"] = args.level_url
|
||||
|
||||
# ── 打印可连接 COM 口 ──
|
||||
print_com_list()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user