客户端封装与工具
项目提供一套可复用的客户端封装,以及图形化控制面板和用例脚本,覆盖从"几行代码调通接口"到"图形界面手动调试"的不同需求。
客户端封装
封装不依赖图形库,是二次开发的推荐入口。模块组成:
| 模块 | 说明 |
|---|---|
api_catalog.py | 接口清单单一数据源(ApiInterface / Endpoint / Direction) |
proto_codec.py | ProtoCodec:JSON 与 Protobuf 互转、默认模板 |
openapi_client.py | OpenApiClient / ClientOptions:MQTT 连接、请求-响应、订阅 |
ClientOptions
from example.core import ClientOptions
opts = ClientOptions(
host="192.168.55.1",
port=1883,
use_tls=False, # MQTTS 时置 True
username="",
password="",
openapi_key="", # 自动写入 header.openapi_key
device_id="",
client_id="", # MQTT 客户端 ID,留空则自动生成
connect_timeout=10.0,
request_timeout=10.0,
)
请求-响应
from example.core import OpenApiClient, ClientOptions
with OpenApiClient(ClientOptions(host="192.168.55.1", openapi_key="<由 XGRIDS 提供>")) as client:
rsp = client.request(
req_topic="lixel/application/request/device_info",
req_message="DeviceInfoRequest",
payload={}, # dict 或 JSON 字符串
rsp_topic="lixel/application/response/device_info",
rsp_message="DeviceInfoResponse",
)
print(rsp) # 解码后的 dict
request() 内部先订阅响应 Topic、再发布请求、阻塞等待第一条响应、解码返回;超时抛出 TimeoutError。
订阅上报
import time
from example.core import ClientOptions, OpenApiClient
def on_status(topic, data): # data 已解码为 dict
print(topic, data)
with OpenApiClient(ClientOptions(host="192.168.55.1", openapi_key="<由 XGRIDS 提供>")) as client:
client.subscribe(
"lixel/application/report/device_status",
"DeviceStatusReport",
on_status,
)
time.sleep(5) # 保持连接,等待上报
对 JSON 负载(心跳),message 传空字符串,回调收到字符串。回调里抛出的异常会被记录到日志(Python 默认输出到终端),不会中断其他订阅。
API 速览
| 方法 | 说明 |
|---|---|
connect() / disconnect() | 连接 / 断开(支持 with 上下文) |
is_connected | 连接状态 |
publish(topic, message, payload) | 发布一条消息 |
subscribe(topic, message, callback) | 订阅并注册回调 |
subscribe_raw(topic_filter, callback) | 按通配符订阅,回调收到原始字节 |
unsubscribe(topic) | 取消订阅 |
request(req_topic, req_message, payload, rsp_topic, rsp_message, timeout=None) | 请求-响应同步调用 |
codec | 内置 ProtoCodec |
图形化控制面板
控制面板按功能分组用选项卡展示全部接口,每个接口一张卡片,可编辑 JSON 负载发送请求,或订阅上报查看输出。
python python/example/main.py # 默认英文界面
python python/example/main.py --lang zh # 启动即中文(也可在菜单实时切换)
界面结构:
- 菜单栏:设置 → 语言(中英文实时切换,无需重启);关于(显示程序版本,构建时注入,从源码直接运行时为
V0.0.0)。 - 顶部连接栏:地址 / 端口 / 协议(MQTT·MQTTS)/ 用户名 / 密码 / OpenAPI Key / 连接。默认地址
192.168.55.1;用户名与密码仅在选择 MQTTS 时显示,需要手动填写厂商提供的账号;切回 MQTT 时隐藏并清空。 - 左侧「发布消息」:Topic 下拉(预填所有可发布 request topic)、消息类型下拉、加载模板、接口说明、JSON 编辑框、发布按钮。
- 右侧「订阅消息」:Topic 下拉、订阅 / 订阅全部、通配符订阅(默认
lixel/#)、当前订阅列表、收到的消息列表(双击看完整解码内容)。
注:发布只发送请求、不阻塞界面;响应与上报统一在右侧「订阅消息」面板查看。发布请求前,先在订阅面板订阅对应的响应 Topic(或用通配符
lixel/#)。
用例脚本
python/example/usage/ 下为每个接口提供独立可运行脚本,是最直接的二次开发参考,全部基于客户端封装、不依赖图形界面:
cd python/example/usage
python device_info.py --host 192.168.55.1 --port 1883 --key <由 XGRIDS 提供>
python modeling.py --host 192.168.55.1 --key <由 XGRIDS 提供> --project demo --watch 5 # 设备需处于待机;完整流程需要一分钟以上
python heartbeat.py --host 192.168.55.1 --seconds 15 # 心跳不需要 Key
通用参数:--host / --port / --tls / --username / --password / --key / --timeout。设备只响应带有效 OpenAPI Key 的请求,所以除心跳等订阅外都要传 --key;不传 --host 时默认使用有线地址 192.168.55.1(1.0.0 的默认值是 192.168.12.1,请使用 1.0.1 及以上版本或显式传 --host)。
modeling.py 会先确认设备处于待机,启动扫描后等设备真正进入扫描中,再观察 --watch 秒,然后停止扫描并等待回到待机;设备不在待机时直接以退出码 2 退出。退出码含义:0 成功;1 启动或停止等待超时;2 设备不在待机;3 AC_START 的响应码不是成功(例如密钥错误);4 AC_START 或 AC_STOP 没有响应;130 被 Ctrl-C 中断。AC_START 发出后总会补发 AC_STOP,AC_START 没有响应(退出码 4)时除外,此时设备状态未知,需要自行检查。等待时间可用 --start-timeout(默认 90 秒)和 --stop-timeout(默认 180 秒)调整。完整的脚本清单见仓库里的 python/example/usage/README.md。
注:
lio_pcl.py演示点云解压,需额外安装pip install lz4 zstandard;未安装时脚本会打印提示并跳过点云解码。
本地化
控制面板中所有用户可见文本都支持多语言。界面默认英文,可在「设置 → 语言」菜单实时切换,也可用 --lang <code> 在启动时指定。新增语言只需复制翻译文件并翻译、编译,再在源码常量 LANGUAGES(python/example/gui/control_panel.py)中登记,菜单即出现该语言。