MQTT 接入
MQTT 接入用于把已有设备改造成可被设备智能体控制和查询的真实设备。设备端不需要使用设备端 SDK,也不需要重写原有驱动或业务逻辑,只需要增加一层 MQTT 适配:订阅命令、调用原有设备能力、返回执行结果,并按设备规格上报状态和事件。
获取接入信息
进入设备智能体工作区,点击 接入设备,选择 已有设备。控制台会给出接入所需的信息:
productId:当前设备智能体标识。namespace:当前运行空间,默认是default。deviceId:真实设备的唯一标识,同一个设备智能体下不要重复。- MQTT 服务地址、用户名和密码状态。
- 命令、响应、遥测、事件和时间同步主题。
- 命令、响应、上线状态、状态遥测和设备事件的消息体示例。
- 当前设备规格中的命令、遥测和事件字段。
如果运行配置中修改过 MQTT 主题模板,以控制台显示的主题为准。

选择适配位置
适配层放在哪里,取决于哪里最容易读取状态并执行动作:
- 设备固件:设备本身支持 MQTT,直接在固件中订阅命令并上报状态。
- 边缘网关:网关通过 Modbus、BLE、串口或私有协议连接设备,再转换为 MQTT。
- 后端服务:已有云端或本地服务可以控制设备,新增一个 MQTT 适配进程,把命令转成原有 API 调用。
无论适配层在哪里,对设备智能体来说都是同一套 MQTT 合约。
改造步骤
先把设备规格和已有设备能力对齐:
| 设备规格 | 映射到已有设备 | MQTT 动作 |
|---|---|---|
| 命令 | 驱动调用、HTTP API、串口指令或业务函数 | 订阅命令主题,执行后发布响应 |
| 遥测 | 当前状态、传感器读数、运行模式 | 发布上线状态和 state 遥测 |
| 事件 | 告警、异常、任务完成、按键回调 | 发布 event 事件 |
最小适配逻辑如下:
启动:
连接 MQTT
订阅命令主题
发布上线状态和当前状态快照
收到命令:
根据 cmd 和 params 调用原有设备能力
发布命令响应,requestId 保持一致
如果状态变化,发布最新状态快照
设备状态变化:
发布 state 遥测
设备发生告警、异常或任务完成:
发布 event 事件设备智能体会从主题路径解析 productId 和 deviceId。消息体里的 metadata.productId 也建议保留,便于自动注册、调试和自定义主题模板下的绑定。如果需要强绑定 MQTT Client ID 和设备 ID,应在 MQTT 服务侧配置认证或 ACL。
主题
默认主题如下。实际接入时复制控制台中的主题。
| 方向 | 用途 | 默认主题 |
|---|---|---|
| 设备订阅 | 接收命令 | device-agent/{productId}/device/{deviceId}/commands |
| 设备发布 | 返回命令响应 | device-agent/{productId}/device/{deviceId}/responses |
| 设备发布 | 上报在线状态和遥测 | v1/{productId}/{deviceId}/telemetry |
| 设备发布 | 上报设备事件 | v1/{productId}/{deviceId}/event |
| 设备发布 | 发起时间同步请求 | device-agent/{productId}/device/{deviceId}/ntp/request |
| 设备订阅 | 接收时间同步响应 | device-agent/{productId}/device/{deviceId}/ntp/response |
建议使用 QoS 1、retain: false,避免旧状态或旧事件被重复消费。
消息体规则
所有消息体都是 UTF-8 JSON 对象。不要使用旧的单主题 envelope,也不要新增自定义 shadow topic。
| 字段 | 说明 |
|---|---|
ts | 可选,Unix 毫秒时间戳,用于调试和排序。 |
metadata | 可选对象。建议至少包含 productId,例如 { "productId": "thermostat", "source": "existing-device" }。 |
data | 上报数据对象。状态和遥测字段必须来自当前设备规格。 |
设备规格是运行时校验依据:
- 命令名和参数必须匹配设备规格中的命令定义。
status.data.state和state遥测必须使用设备规格中的遥测字段。- 事件名和事件字段必须匹配设备规格中的事件定义。
- 未定义字段、错误类型或未知事件名会产生校验错误,不会写入当前设备状态。
上线状态
设备连接 MQTT 后,先向遥测主题发布上线状态。首次成功上报后,这台设备会出现在设备列表中。
{
"type": "status",
"data": {
"status": "online",
"state": {
"current_temperature": 26.5,
"target_temperature": 24,
"humidity": 61,
"mode": "auto"
}
},
"ts": 1710000000000,
"metadata": {
"productId": "thermostat",
"source": "existing-device"
}
}status 使用 online、offline 或 error。state 建议上报完整状态快照。设备断开前可以主动上报 offline;如果支持 MQTT Will Message,也可以把离线状态配置为遗嘱消息。
状态遥测
设备运行中向遥测主题上报状态变化。常用 type 是 state,data 中只放设备规格中定义过的遥测字段。
{
"type": "state",
"data": {
"current_temperature": 27.1,
"target_temperature": 24,
"humidity": 60,
"mode": "auto"
},
"ts": 1710000005000,
"metadata": {
"productId": "thermostat",
"source": "existing-device"
}
}建议在启动后、命令执行后和关键状态变化后上报完整快照。只上报部分字段时,控制台只能更新这些字段。
命令响应
当用户通过对话控制设备时,设备智能体会向命令主题发布命令。
{
"cmd": "set_target_temperature",
"params": {
"target_temperature": 24
},
"requestId": "req-001",
"ts": 1710000010000
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
cmd | string | 是 | 设备规格中定义的命令名。 |
params | object | 否 | 命令参数,必须匹配该命令的参数定义。无参数时使用 {} 或省略。 |
requestId | string | 是 | 本次命令请求 ID。 |
ts | number | 否 | Unix 毫秒时间戳。 |
设备执行后向响应主题发布结果。requestId 必须和收到的命令一致。
{
"code": 0,
"msg": "ok",
"requestId": "req-001",
"data": {
"target_temperature": 24,
"mode": "auto"
},
"ts": 1710000011000,
"metadata": {
"productId": "thermostat",
"source": "existing-device"
}
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
code | number | 是 | 0 表示成功,非 0 表示失败。 |
msg | string | 是 | 执行结果说明。 |
requestId | string | 是 | 必须等于命令中的 requestId。 |
data | any | 否 | 返回给设备智能体的执行结果。 |
ts | number | 否 | Unix 毫秒时间戳。 |
如果命令改变了设备状态,响应后立即再上报一次最新 status 或 state,用户才能在状态面板中看到执行结果。
设备事件
事件表示设备主动发生的一次性变化,例如告警、异常、阈值触发、任务完成或用户按键。设备向事件主题发布 type: "event" 的消息体。
{
"type": "event",
"data": {
"event": "temperature_alert",
"current_temperature": 38.5,
"level": "warning"
},
"ts": 1710000020000,
"metadata": {
"productId": "thermostat",
"source": "existing-device"
}
}data.event 必须是设备规格中定义过的事件名,其余字段只能使用该事件定义的输出字段。事件不会自动写入当前数据,但会出现在最近上报事件中。阈值类事件建议做边沿触发或冷却时间,避免重复上报。
用 MQTTX 快速验证
在改造真实设备前,可以先用 MQTTX CLI 模拟一台设备。下面示例假设:
- MQTT 服务:
127.0.0.1:1883 productId:thermostatdeviceId:thermostat-001
如果 MQTT 服务没有启用用户名和密码,去掉命令中的 -u 和 -P。
先打开一个终端订阅命令主题,用来观察设备智能体下发的命令:
mqttx sub \
-h 127.0.0.1 \
-p 1883 \
-u your-username \
-P 'your-password' \
-q 1 \
-t 'device-agent/thermostat/device/thermostat-001/commands'再用另一个终端模拟设备上线:
mqttx pub \
-h 127.0.0.1 \
-p 1883 \
-u your-username \
-P 'your-password' \
-q 1 \
-t 'v1/thermostat/thermostat-001/telemetry' \
-m '{"type":"status","data":{"status":"online","state":{"current_temperature":26.5,"target_temperature":24,"humidity":61,"mode":"auto"}},"metadata":{"productId":"thermostat","source":"mqttx"}}'设备列表中出现 thermostat-001 后,可以继续模拟状态变化:
mqttx pub \
-h 127.0.0.1 \
-p 1883 \
-u your-username \
-P 'your-password' \
-q 1 \
-t 'v1/thermostat/thermostat-001/telemetry' \
-m '{"type":"state","data":{"current_temperature":27.1,"target_temperature":24,"humidity":60,"mode":"auto"},"metadata":{"productId":"thermostat","source":"mqttx"}}'也可以模拟设备主动上报事件:
mqttx pub \
-h 127.0.0.1 \
-p 1883 \
-u your-username \
-P 'your-password' \
-q 1 \
-t 'v1/thermostat/thermostat-001/event' \
-m '{"type":"event","data":{"event":"temperature_alert","current_temperature":38.5,"level":"warning"},"metadata":{"productId":"thermostat","source":"mqttx"}}'最后在对话中让设备智能体控制这台设备。订阅命令的终端会收到一条带 requestId 的命令,把这个 requestId 复制到响应消息中:
mqttx pub \
-h 127.0.0.1 \
-p 1883 \
-u your-username \
-P 'your-password' \
-q 1 \
-t 'device-agent/thermostat/device/thermostat-001/responses' \
-m '{"code":0,"msg":"ok","requestId":"替换为收到的 requestId","data":{"target_temperature":24,"mode":"auto"},"metadata":{"productId":"thermostat","source":"mqttx"}}'这组命令可以验证完整链路:设备上线、状态上报、事件上报、命令接收和命令响应。真实设备接入时,把这些 MQTTX 命令替换为固件、网关或后端服务中的 MQTT 发布订阅逻辑即可。
时间同步
如果设备需要估算本地时间与网关服务的时间差,可以使用时间同步主题。
设备向请求主题发布:
{
"deviceSendTime": 1710000030000
}设备从响应主题收到:
{
"deviceSendTime": 1710000030000,
"serverRecvTime": 1710000030120,
"serverSendTime": 1710000030122
}deviceSendTime 是设备发送请求时的本地 Unix 毫秒时间戳。serverRecvTime 和 serverSendTime 分别是网关服务收到请求和发出响应的时间。
验证接入
完成设备端适配后,按下面顺序检查:
- 设备已连接 MQTT,命令主题已订阅成功。
- 遥测主题收到第一条
status或state后,设备列表中出现这台设备。 - 当前数据能看到设备规格中定义的遥测字段。
- 对话中下发命令后,设备端能收到命令,并向响应主题返回同一个
requestId。 - 命令改变状态后,设备端有新的状态或遥测上报。
- 主动上报事件后,最近上报事件中能看到记录。
如果设备没有出现,先检查 MQTT 服务地址和认证信息,再检查 productId、deviceId、主题路径和 metadata.productId。如果设备出现但当前数据不更新,优先检查遥测字段名和类型是否与设备规格一致。更多运行配置见 配置。