Skip to content

MQTT 接入

MQTT 接入用于把已有设备改造成可被设备智能体控制和查询的真实设备。设备端不需要使用设备端 SDK,也不需要重写原有驱动或业务逻辑,只需要增加一层 MQTT 适配:订阅命令、调用原有设备能力、返回执行结果,并按设备规格上报状态和事件。

获取接入信息

进入设备智能体工作区,点击 接入设备,选择 已有设备。控制台会给出接入所需的信息:

  • productId:当前设备智能体标识。
  • namespace:当前运行空间,默认是 default
  • deviceId:真实设备的唯一标识,同一个设备智能体下不要重复。
  • MQTT 服务地址、用户名和密码状态。
  • 命令、响应、遥测、事件和时间同步主题。
  • 命令、响应、上线状态、状态遥测和设备事件的消息体示例。
  • 当前设备规格中的命令、遥测和事件字段。

如果运行配置中修改过 MQTT 主题模板,以控制台显示的主题为准。

已有设备 MQTT 接入信息

选择适配位置

适配层放在哪里,取决于哪里最容易读取状态并执行动作:

  • 设备固件:设备本身支持 MQTT,直接在固件中订阅命令并上报状态。
  • 边缘网关:网关通过 Modbus、BLE、串口或私有协议连接设备,再转换为 MQTT。
  • 后端服务:已有云端或本地服务可以控制设备,新增一个 MQTT 适配进程,把命令转成原有 API 调用。

无论适配层在哪里,对设备智能体来说都是同一套 MQTT 合约。

改造步骤

先把设备规格和已有设备能力对齐:

设备规格映射到已有设备MQTT 动作
命令驱动调用、HTTP API、串口指令或业务函数订阅命令主题,执行后发布响应
遥测当前状态、传感器读数、运行模式发布上线状态和 state 遥测
事件告警、异常、任务完成、按键回调发布 event 事件

最小适配逻辑如下:

text
启动:
  连接 MQTT
  订阅命令主题
  发布上线状态和当前状态快照

收到命令:
  根据 cmd 和 params 调用原有设备能力
  发布命令响应,requestId 保持一致
  如果状态变化,发布最新状态快照

设备状态变化:
  发布 state 遥测

设备发生告警、异常或任务完成:
  发布 event 事件

设备智能体会从主题路径解析 productIddeviceId。消息体里的 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.statestate 遥测必须使用设备规格中的遥测字段。
  • 事件名和事件字段必须匹配设备规格中的事件定义。
  • 未定义字段、错误类型或未知事件名会产生校验错误,不会写入当前设备状态。

上线状态

设备连接 MQTT 后,先向遥测主题发布上线状态。首次成功上报后,这台设备会出现在设备列表中。

json
{
  "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 使用 onlineofflineerrorstate 建议上报完整状态快照。设备断开前可以主动上报 offline;如果支持 MQTT Will Message,也可以把离线状态配置为遗嘱消息。

状态遥测

设备运行中向遥测主题上报状态变化。常用 typestatedata 中只放设备规格中定义过的遥测字段。

json
{
  "type": "state",
  "data": {
    "current_temperature": 27.1,
    "target_temperature": 24,
    "humidity": 60,
    "mode": "auto"
  },
  "ts": 1710000005000,
  "metadata": {
    "productId": "thermostat",
    "source": "existing-device"
  }
}

建议在启动后、命令执行后和关键状态变化后上报完整快照。只上报部分字段时,控制台只能更新这些字段。

命令响应

当用户通过对话控制设备时,设备智能体会向命令主题发布命令。

json
{
  "cmd": "set_target_temperature",
  "params": {
    "target_temperature": 24
  },
  "requestId": "req-001",
  "ts": 1710000010000
}
字段类型必填说明
cmdstring设备规格中定义的命令名。
paramsobject命令参数,必须匹配该命令的参数定义。无参数时使用 {} 或省略。
requestIdstring本次命令请求 ID。
tsnumberUnix 毫秒时间戳。

设备执行后向响应主题发布结果。requestId 必须和收到的命令一致。

json
{
  "code": 0,
  "msg": "ok",
  "requestId": "req-001",
  "data": {
    "target_temperature": 24,
    "mode": "auto"
  },
  "ts": 1710000011000,
  "metadata": {
    "productId": "thermostat",
    "source": "existing-device"
  }
}
字段类型必填说明
codenumber0 表示成功,非 0 表示失败。
msgstring执行结果说明。
requestIdstring必须等于命令中的 requestId
dataany返回给设备智能体的执行结果。
tsnumberUnix 毫秒时间戳。

如果命令改变了设备状态,响应后立即再上报一次最新 statusstate,用户才能在状态面板中看到执行结果。

设备事件

事件表示设备主动发生的一次性变化,例如告警、异常、阈值触发、任务完成或用户按键。设备向事件主题发布 type: "event" 的消息体。

json
{
  "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
  • productIdthermostat
  • deviceIdthermostat-001

如果 MQTT 服务没有启用用户名和密码,去掉命令中的 -u-P

先打开一个终端订阅命令主题,用来观察设备智能体下发的命令:

bash
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'

再用另一个终端模拟设备上线:

bash
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 后,可以继续模拟状态变化:

bash
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"}}'

也可以模拟设备主动上报事件:

bash
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 复制到响应消息中:

bash
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 发布订阅逻辑即可。

时间同步

如果设备需要估算本地时间与网关服务的时间差,可以使用时间同步主题。

设备向请求主题发布:

json
{
  "deviceSendTime": 1710000030000
}

设备从响应主题收到:

json
{
  "deviceSendTime": 1710000030000,
  "serverRecvTime": 1710000030120,
  "serverSendTime": 1710000030122
}

deviceSendTime 是设备发送请求时的本地 Unix 毫秒时间戳。serverRecvTimeserverSendTime 分别是网关服务收到请求和发出响应的时间。

验证接入

完成设备端适配后,按下面顺序检查:

  1. 设备已连接 MQTT,命令主题已订阅成功。
  2. 遥测主题收到第一条 statusstate 后,设备列表中出现这台设备。
  3. 当前数据能看到设备规格中定义的遥测字段。
  4. 对话中下发命令后,设备端能收到命令,并向响应主题返回同一个 requestId
  5. 命令改变状态后,设备端有新的状态或遥测上报。
  6. 主动上报事件后,最近上报事件中能看到记录。

如果设备没有出现,先检查 MQTT 服务地址和认证信息,再检查 productIddeviceId、主题路径和 metadata.productId。如果设备出现但当前数据不更新,优先检查遥测字段名和类型是否与设备规格一致。更多运行配置见 配置

下一步