易点绘展厅触摸一体机 TCP / UDP 通信协议
| 项目 |
内容 |
| 协议名称 |
易点绘展厅 TCP/UDP 通信协议 |
| 协议版本 |
V1.0 |
| 发布日期 |
2026-08-30 |
| 适用产品 |
易点绘展厅触摸一体机(QBTTouch) |
| 通信方式 |
TCP / UDP(网络) |
| 适用范围 |
中控系统、第三方设备与本一体机之间的指令交互 |
1. 通信基础
1.1 连接方式
一体机支持三种网络通信方式,可同时启用:
| 方式 |
一体机角色 |
说明 |
| TCP 客户端 |
一体机主动连接中控服务器 |
一体机连接中控的 TCP 服务器(默认端口 7888),指令双向传输 |
| TCP 服务器 |
中控/第三方作为客户端连接一体机 |
一体机开启 TCP 监听(端口可配置,建议 7888),接收客户端指令 |
| UDP |
一体机监听 UDP 端口 |
一体机开启 UDP 监听(端口可配置),第三方向该端口发送数据报 |
1.2 编码与分帧
- 编码:指令与返回均为 UTF-8 编码的 JSON 文本。
- 分帧:
- TCP:一次连接发送一条指令(一次
Write),一体机按收到的数据段解析;建议每条指令以 \n 结尾(便于对端按行处理,一体机解析时兼容)。
- UDP:一个数据报 = 一条指令,天然分帧,无需结束符。
与串口协议不同,TCP/UDP 仅支持 JSON 文本指令(不支持 HEX 二进制帧,HEX 帧为串口协议专用)。
2. 指令格式
2.1 协议标准格式(cmd 字段)
{"cmd":"Page.Open","pageId":"PAGE_639199874094277296"}
| 字段 |
类型 |
必填 |
说明 |
| cmd |
string |
✅ |
指令名,见指令总览 |
| pageId |
string(推荐)/ number |
页面指令 |
目标页面 ID(形如 PAGE_639199874094277296;纯数字自动补 PAGE_ 前缀) |
| id |
number / string |
控件/弹窗/视频指令 |
目标控件 ID 或资源 ID |
| value |
number / bool |
音频指令 |
音量 0~100,或静音 true/false |
| time |
number |
视频指令(预留) |
跳转时间(秒) |
| sceneId |
string |
场景指令(预留) |
场景 ID |
2.2 指令总览
| 类别 |
指令 |
JSON cmd |
当前支持 |
| 页面 |
页面跳转 |
Page.Open |
✅ 支持 |
| 页面 |
返回上一页 |
Page.Back |
✅ 支持 |
| 页面 |
返回首页 |
Page.Home |
✅ 支持 |
| 控件 |
控件单击(触发鼠标单击事件) |
Control.Click |
✅ 支持 |
| 音频 |
设置音量 |
Audio.Volume |
✅ 支持 |
| 音频 |
静音 |
Audio.Mute |
✅ 支持 |
| 弹窗 |
打开/关闭弹窗 |
Popup.Open / Popup.Close |
⏳ 预留 |
| 视频 |
播放/暂停/停止/跳转 |
Video.* |
⏳ 预留 |
| 场景 |
场景联动 |
Scene.Run |
⏳ 预留 |
| 自定义 |
扩展指令 |
Light.* / Robot.* 等 |
⏳ 预留 |
✅ = 已实现动作;⏳ = 可识别并记录日志,尚未触发业务动作(预留扩展)。
2.3 指令示例
| 指令 |
发送内容(UTF-8,TCP 建议末尾带 \n) |
| 页面跳转 |
{"cmd":"Page.Open","pageId":"PAGE_639199874094277296"} |
| 返回上一页 |
{"cmd":"Page.Back"} |
| 返回首页 |
{"cmd":"Page.Home"} |
| 控件单击 |
{"cmd":"Control.Click","id":"btn001"} |
| 设置音量 50% |
{"cmd":"Audio.Volume","value":50} |
| 静音 |
{"cmd":"Audio.Mute","value":true} |
| 恢复音量 |
{"cmd":"Audio.Mute","value":false} |
2.4 兼容旧格式(项目内部 MessageCommand)
若 JSON 不含 cmd 字段,一体机会按项目原有指令格式解析,也可使用:
| 指令 |
发送内容 |
说明 |
| 页面跳转 |
{"Command_Type":1,"PageID":"PAGE_639199874094277296"} |
Command_Type: 1 = PAGE_SKIP |
| 控件事件 |
{"Command_Type":2,"ControlID":"btn001"} |
Command_Type: 2 = CONTROL_EVENT,触发控件点击事件 |
3. 指令行为说明
| 指令 |
一体机执行的动作 |
| 页面跳转(Page.Open) |
主屏跳转到指定页面。目标为项目页面 ID(形如 PAGE_639199874094277296);支持完整 ID / 纯数字自动补前缀 / 数字后缀容错匹配;未找到页面返回失败(1005) |
| 返回上一页(Page.Back) |
返回上一页(依据当前页记录的上一页 ID),无上一页则返回失败(1005) |
| 返回首页(Page.Home) |
跳转到当前项目首页 |
| 控件单击(Control.Click) |
触发当前页面指定控件的鼠标单击事件(控件需存在且配置了行为事件,如页面跳转/打开弹窗等),效果与用户鼠标单击一致;控件不存在或未配置事件返回失败(1005) |
| 设置音量(Audio.Volume) |
设置背景音乐音量,value 范围 0100,映射为 0.01.0 |
| 静音(Audio.Mute) |
静音(音量 0)或恢复(音量 1) |
4. 返回状态指令
一体机收到任意指令后,无论执行成功与否,都会向指令发送方返回一条 JSON 状态指令(按来源通道回发:TCP 服务器模式回给来源客户端、TCP 客户端模式回给服务器、UDP 回给来源 ip:port)。
成功:
{"result":true,"echoCmd":"Page.Open","message":"页面跳转:PAGE_639199874094277296"}
失败:
{"result":false,"errorCode":1005,"echoCmd":"Page.Open","message":"页面不存在"}
| 字段 |
类型 |
说明 |
| result |
bool |
true 成功 / false 失败 |
| echoCmd |
string |
回显请求的指令名(失败时也回显,便于定位) |
| message |
string |
描述信息 |
| errorCode |
number |
仅失败时出现 |
回执识别与防循环:result 与 errorCode 字段是一体机识别"响应回执"的标识。一体机收到含这两个字段(任一)的 JSON 时,会判定为回执并直接忽略、不再回发,以避免双向回执形成无限循环。因此对接方约定:① 业务指令中请勿使用 result / errorCode 字段名;② 对接方若也会对收到的指令返回回执,建议对带 result 字段的消息做同样的忽略处理。
编码说明:返回 JSON 中的中文(message 等)以 \uXXXX 转义形式传输(如 "页面不存在" → "\u9875\u9762\u4e0d\u5b58\u5728"),保证任意解码环境不乱码;用 JSON 解析器解析后自动还原为中文。
错误码
| 编号 |
说明 |
| 0000 |
成功 |
| 1001 |
未知指令 |
| 1002 |
参数错误 |
| 1003 |
设备不存在 |
| 1004 |
执行失败 |
| 1005 |
资源不存在(如页面不存在、控件不存在或未配置事件) |
5. 对接示例
5.1 Python TCP 客户端(第三方连接一体机 TCP 服务器)
import socket, json
# 一体机为 TCP 服务器,监听 7888;第三方作为客户端连接
sock = socket.create_connection(("192.168.1.100", 7888), timeout=5)
# 发送页面跳转指令(UTF-8,以 \n 结尾)
cmd = '{"cmd":"Page.Open","pageId":"PAGE_639199874094277296"}\n'
sock.sendall(cmd.encode("utf-8"))
# 接收返回状态
resp = sock.recv(4096).decode("utf-8")
print(resp) # {"result":true,"echoCmd":"Page.Open","message":"\u9875\u9762..."}
print(json.loads(resp)["result"]) # True(解析后 message 为中文)
# 触发控件单击
sock.sendall('{"cmd":"Control.Click","id":"btn001"}\n'.encode("utf-8"))
print(sock.recv(4096).decode("utf-8"))
sock.close()
5.2 Python UDP(第三方向一体机 UDP 监听端口发指令)
import socket, json
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 一体机 UDP 监听端口(如 9000)
addr = ("192.168.1.100", 9000)
# 一个数据报 = 一条指令
cmd = '{"cmd":"Page.Home"}'
sock.sendto(cmd.encode("utf-8"), addr)
# 接收返回状态(一体机回发给来源 ip:port)
data, _ = sock.recvfrom(4096)
print(json.loads(data.decode("utf-8")))
sock.close()
5.3 C# TCP 客户端示例(System.Net.Sockets)
using System.Net.Sockets;
using System.Text;
using (var tcp = new TcpClient())
{
await tcp.ConnectAsync("192.168.1.100", 7888);
var stream = tcp.GetStream();
// 发送控件单击指令
string cmd = "{\"cmd\":\"Control.Click\",\"id\":\"btn001\"}\n";
byte[] data = Encoding.UTF8.GetBytes(cmd);
await stream.WriteAsync(data, 0, data.Length);
// 接收返回状态
byte[] buf = new byte[4096];
int n = await stream.ReadAsync(buf, 0, buf.Length);
string resp = Encoding.UTF8.GetString(buf, 0, n);
// resp: {"result":true,"echoCmd":"Control.Click","message":"..."}
}
6. 注意事项
| 编号 |
说明 |
| 1 |
编码:指令与返回均为 UTF-8;含中文时不要用 GBK/ASCII 发送 |
| 2 |
TCP 分帧:一次连接发一条指令(一次 Write),建议以 \n 结尾;不要一次拼接多条指令,也不要半条指令分多次发 |
| 3 |
UDP 分帧:一个数据报 = 一条指令,长度不超过 UDP 单包上限(约 1472 字节,不含 IP 头) |
| 4 |
返回回执:状态指令回发给指令来源——TCP 服务器模式回给对应客户端、UDP 回给来源 ip:port;若一体机为 TCP 客户端模式,则回给其连接的服务器 |
| 5 |
页面 ID:目标页面 ID 需为一体机项目中实际存在的页面 ID(形如 PAGE_639199874094277296),纯数字会自动补 PAGE_ 前缀 |
| 6 |
控件 ID:为目标控件在项目编辑器中的 Id,且控件需配置了行为事件(BehaviorType != None),否则返回失败(1005) |
| 7 |
预留指令:弹窗 / 视频 / 场景 / 自定义指令当前仅识别并记录日志,不会触发动作 |
| 8 |
端口:一体机 TCP 服务器/UDP 监听的端口由一体机配置;TCP 客户端默认连接端口 7888 |
7. 版本记录
| 版本 |
日期 |
说明 |
| V1.0 |
2026-08-30 |
发布初版:定义 TCP/UDP JSON 指令(页面/控件/音频),与串口协议指令集对齐;返回 JSON 状态指令(回显字段 echoCmd,含回执防循环约定);含 Python/C# 对接示例 |