Skip to content

任意Topic主题 ​

这页复用 MQTT 任意主题 / 第三方 Broker 接入说明,方便在当前目录下直接查看。

1. 适合哪些设备 ​

自建 MQTT 接入适合下面这类设备:

  1. 设备 Topic 改不了。
  2. 设备已经接在第三方 Broker 上。
  3. 存量设备很多,不方便改成平台标准 Topic。

要先说明一件很容易误解的事:

"任意主题设备"不等于"只能透传"。

在自建接入模式里,你仍然可以把主题类型配置成:

  1. THING_MODEL:消息体已经是标准物模型 JSON。
  2. PASSTHROUGH:消息体还是厂商自定义格式,需要编解码。
MQTT 自建接入 · 快速接入主线

接外置 Broker / 任意 Topic,按这 6 步走

01先把产品身份定下来

创建 MQTT 产品

接入方式选 MQTT,联调期建议打开 allowInsert。

02平台去连第三方 Broker

创建 MQTT 网络组件

填 host、port、username、password、clientIdPrefix。

03决定消息归属产品与处理方式

配置主题映射

每条映射填 topicPattern + topicCategory + productKey + qos。

04绑定成功模式会变自建

绑定产品 + 添加设备

产品详情 → 连接信息 → 管理自建接入,切到自建接入模式,再添加设备。

05一键复制,不用再回产品

设备详情拿连接信息

进入设备详情 → 设备连接信息,直接复制自建 host、账号、ClientID。

06最终用主题测试工具验证

写 preDecode + 跑通上下行

脚本里写 preDecode 提取 deviceId,透传再补 decode/encode。

2. 先分清 4 个对象 ​

任意主题模式里,最容易混的是"到底该在哪一层配"。

对象你在哪里配它负责什么
产品产品管理定义产品标识、物模型、编解码、自动注册和下行主题
连接信息产品详情 → 连接信息绑定自建 MQTT 网络组件,查看当前接入模式
MQTT 网络组件网络组件 → MQTT连接第三方 Broker,订阅任意 Topic,做主题映射
协议脚本产品驱动 / IDE 调试器识别设备,并转换上行、下行数据

3. 先看懂 Topic 配置 ​

设备发布的是真实 Topic,平台配置的是用于订阅的 Topic 模式。这两者不一定完全相同。

例如设备实际发布:

text
mqtt/device001/PublishEvent

如果同一产品下有多个设备,平台应配置:

text
mqtt/+/PublishEvent

这里的 + 只匹配一层内容,因此可以匹配 device001、device002 等设备编号;它不会出现在平台发给设备的实际 Topic 中。# 可以匹配后续多层内容,范围更宽,联调时不建议直接使用。

如果只接入一个固定设备,也可以直接配置完整 Topic:

text
mqtt/device001/PublishEvent

文档中的 <deviceId>、<productKey> 只是“这里填实际值”的说明写法,不是要原样填入配置框的文字。

设备回复和平台下行也要使用实际 Topic。例如:

用途示例
设备上行mqtt/device001/PublishEvent
设备回复mqtt/device001/PublishEvent/ack
平台下行mqtt/device001/OperateDevice

回复和下行 Topic 不要再作为上行消息订阅,否则平台可能把自己发出的消息再次当成设备上报。

4. 平台处理链路 ​

任意主题模式下,平台大致按这个顺序处理:

  1. MQTT 网络组件先连上第三方 Broker。
  2. 网络组件按已配置的 Topic 模式订阅消息。
  3. 平台先根据主题映射确定这条消息属于哪个产品。
  4. 平台执行设备识别脚本(preDecode),获取 deviceId。
  5. 如果消息格式是 THING_MODEL,平台按标准 JSON 继续处理;如果是 PASSTHROUGH,上行使用 decode,下行需要时再使用 encode。
  6. 下行时再根据产品绑定的网络组件,把消息发回对应 Broker。

这里有两个关键细节:

  1. 主题映射最好直接指定产品,避免平台无法判断这条消息属于哪个产品。
  2. 即使消息已经是标准物模型 JSON,也要确认平台能从 Topic 或消息体中识别出 deviceId。

5. 接入步骤 ​

第一步:创建 MQTT 产品 ​

在产品管理里新建产品时,接入方式还是选 MQTT。

第一次联调时,产品层建议先确认这 3 项:

  1. 自动注册(页面字段通常为 allowInsert):联调期可暂时开启,正式环境建议按实际需求控制。
  2. 数据格式:确认上报和下行使用的编码方式。
  3. 下行 Topic(页面字段通常为 downTopic):如果设备订阅固定主题,先配置完整 Topic。

mqtt-create

第二步:创建 MQTT 网络组件 ​

网络组件负责的是"平台怎么去连 Broker",不是"设备怎么连平台"。

第一次联调时,先把这些基础连接参数填好:

字段作用
host第三方 Broker 地址
portBroker 端口
usernameBroker 账号
passwordBroker 密码
clientIdPrefix平台作为客户端连上去的 ClientID 前缀
connectTimeout连接超时时间(毫秒)

network-add

第三步:配置主题映射 ​

进入网络组件详情 → 主题订阅,逐条添加要订阅的 Topic。

每一条主题映射,最关键的配置是:

字段作用第一次联调建议
订阅 Topic(页面字段通常为 topicPattern)平台实际订阅的主题模式,支持 + 和 #先用最小范围,不要一上来订 #
消息格式(页面字段通常为 topicCategory)按物模型还是透传处理必填
qosMQTT QoS一般先用 1
产品把这条 Topic 明确归属到哪个产品建议直接选择产品
enabled是否启用联调时保持启用

消息格式选择规则:

选项什么时候选
THING_MODELpayload 已经是标准物模型 JSON
PASSTHROUGHpayload 还是私有协议,需要编解码

update-topic

用主题模式测试工具

网络组件详情页有一个"主题模式测试工具",输入设备实际 Topic,立刻告诉你能否匹配、匹配到了哪个产品。联调时强烈推荐先在这里自测一次。

tools

第四步:绑定网络组件到产品 ​

路径就在 产品详情 → 连接信息:

  1. 打开"连接信息"页。
  2. 点击 管理自建接入。
  3. 选择一个已经配置完整、而且处于运行状态的 MQTT 组件。
  4. 绑定成功后,回到连接信息页确认当前模式切到了 自建接入。

第五步:添加设备并拿连接信息(推荐) ​

新版本推荐直接从 设备详情 拿连接信息,不用再回产品详情翻。

路径:设备管理 → 新增设备 → 设备详情 → 设备连接信息。

自建接入模式下,页面会直接给出:

  1. 连接地址:自建 MQTT 网络组件的 host / port
  2. Username / Password:来自网络组件配置
  3. ClientID:按下面规则拼好并支持一键复制
  4. 该设备要发送和订阅的 Topic 列表

自建接入 ClientID 规则

text
ClientID = ProductKey.DeviceId

host、用户名、密码都来自产品绑定的 MQTT 网络组件。

第六步:识别设备 ​

任意主题模式下,真正最容易卡住的是 deviceId。

平台会执行产品脚本里的 preDecode 去识别设备号。识别来源可以是:

  1. Topic
  2. payload
  3. Topic 和 payload 结合

下面这个例子演示从 mqtt/device001/PublishEvent 的第二段取设备号:

javascript
var preDecode = (payload, topic) => {
  var parts = topic.split("/");
  if (parts.length != 3 || parts[0] != "mqtt" || parts[2] != "PublishEvent") {
    throw new Error("unexpected uplink topic");
  }
  return { deviceId: parts[1] };
};

如果脚本没有识别出设备号,且产品允许自动注册,平台可能会先把消息放到系统预置的调试设备(设备 ID 为 nexiotDebugDeviceId)。这只是联调兜底,正式接入必须返回稳定的真实 deviceId。

如果消息是透传模式,还要继续补:

  1. decode:把设备上报转成属性或事件。
  2. encode:把平台下发转成设备能识别的报文。

第七步:下行与自动回复 ​

如果设备订阅的下行 Topic 不是平台默认主题,第一次联调建议先在产品里把 downTopic 固定住。

下行 Topic 可以使用占位符,平台发送时会替换成实际值。常用写法是:

text
产品:{{productKey}}
设备:{{deviceId}}

如果页面提示了其他占位符写法,以页面提示为准。

订阅 Topic 中的 +、# 只用于匹配上行消息,不能直接当成下行 Topic。下行时必须生成具体设备 Topic。

down-topic

如果你在 decode 结果里返回了 replyPayload,平台会自动尝试回复。

自动回复踩坑提醒

  • 返回 1 条带 replyPayload 的结果,平台就回 1 次。
  • 返回 10 条都带 replyPayload,平台就会回 10 次。

联调期通常只建议保留一条回复。

auto-reply

6. 最稳的联调顺序 ​

建议按这个顺序来:

  1. 先创建产品。
  2. 再创建并启动 MQTT 网络组件。
  3. 在主题映射里明确选择产品。
  4. 把消息格式选对。
  5. 写通 preDecode,确认能稳定拿到 deviceId。
  6. 如果是透传,再补 decode 和 encode。
  7. 最后调下行和自动回复。

7. 最容易踩的坑 ​

  1. 设备实际 Topic 是 mqtt/device001/PublishEvent,却把 mqtt/<deviceId>/PublishEvent 原样填入订阅配置。应根据实际情况填写完整 Topic 或 mqtt/+/PublishEvent。
  2. 消息格式选错,导致 JSON 被当透传,或者透传被当 JSON。
  3. preDecode 没返回稳定的 deviceId。
  4. Broker 权限(ACL)不够,平台没法订阅上行 Topic 或发布下行 Topic。
  5. 网络组件虽然配置了,但没启动,或者产品还没绑定这个组件。
  6. 忘了绑定产品,连接信息页面仍然停留在"平台直连"模式。

继续排查可以直接看 MQTT 常见问题。

8. 配置完成检查 ​

任意 Topic 接入至少要确认下面几项:

检查项需要确认的内容
产品接入方式为 MQTT,物模型已保存,已绑定正确的自建 MQTT 网络
网络Broker 地址和认证信息正确,网络处于运行状态
主题上行 Topic 能匹配,已明确关联产品,消息格式选择正确
设备preDecode 能稳定识别设备 ID,或已按产品策略准备自动注册
下行设备实际订阅的下行 Topic 已配置,必要时补充 encode

推荐先发送一条无副作用的心跳或测试消息,依次确认:平台收到消息、识别到正确设备、物模型产生数据、回复或下行 Topic 正确。

9. 多个产品共用一个网络 ​

一个 MQTT 网络可以被多个产品复用,因此每条上行订阅都要明确它属于哪个产品。

因此需要注意:

  1. 每条订阅都选择正确的产品,不要让多个产品共用一条无法区分归属的订阅。
  2. 设备回复 Topic 和平台下行 Topic 不要配置为上行订阅。
  3. 订阅范围尽量只覆盖设备真正发布的上行 Topic,避免使用过宽的 #。

10. 网关与网关子设备 ​

当一个 MQTT 网关下挂多个传感器、仪表或 Modbus 从设备时,网关和子设备需要分别建立产品与设备关系。

10.1 基本关系 ​

对象作用
网关产品配置 MQTT 网络、订阅网关上行 Topic、解析网关报文
网关设备表示实际连接 Broker 的那台网关
子设备产品定义子设备的物模型和编解码规则
子设备表示网关下挂的具体传感器或仪表

通常只有网关产品订阅任意 Topic。子设备不需要重复订阅同一个 Topic,网关收到报文后再把数据分发给对应子设备。

10.2 接入流程 ​

text
网关上报消息
    ↓
识别网关设备
    ↓
解析出子设备编号、地址或其他标识
    ↓
匹配子设备产品和设备
    ↓
更新子设备属性、事件和状态

网关解析报文时,需要同时输出两类信息:

  1. 子设备产品,以及温度、电量等属性或事件数据。
  2. 能稳定定位子设备的编号,例如 Modbus 从站地址、传感器编号、序列号或通道号。

字段名称由设备协议和脚本约定决定,关键是每次上报都能用同一编号找到同一子设备。

10.3 子设备配置要点 ​

  1. 网关产品设置为网关类型,子设备产品设置为网关子设备类型。
  2. 建议提前创建子设备;不要默认网关的自动注册会自动创建所有子设备。
  3. 子设备需要关联所属网关,并保存网关设备 ID、子设备地址等信息。
  4. 子设备 ID 必须稳定。同一个网关下的同一个从站,不能每次上报都生成不同的设备 ID。
  5. 子设备产品的物模型和 decode 必须与网关转发的实际数据一致。

常见的 Modbus 子设备 ID 形式是:

text
网关设备ID-从站地址

例如网关设备 ID 为 gateway-001、从站地址为 2,子设备 ID 可以是 gateway-001-2。如果厂商已有自己的编号规则,应以厂商规则为准。

10.4 下行控制 ​

平台控制网关子设备时,消息通常仍然通过网关发送:

  1. 使用子设备产品的 encode 生成子设备命令。
  2. 使用网关的连接和通信通道发送命令。
  3. 如果厂商为子设备提供专用下行 Topic,在子设备配置中填写;否则使用网关产品的下行 Topic。

下行 Topic 需要区分网关和子设备信息。配置时按页面支持的占位符填写网关设备 ID、子设备 ID;如果厂商只要求网关 Topic,就使用网关产品的下行 Topic。不要把 +、# 直接写入下行 Topic,也不要把网关设备 ID 和子设备 ID 混用。

10.5 主动注册注意事项 ​

如果没有编写 preDecode,且产品允许自动注册,平台可能会先把消息放到调试设备 nexiotDebugDeviceId。这只能帮助联调主消息,不能代替真实的网关与子设备关系配置。

要验证子设备接入成功,至少需要同时看到:

  1. 网关设备被正确识别;
  2. 报文中能解析出子设备标识;
  3. 子设备产品和设备能够匹配;
  4. 子设备物模型产生属性或事件数据。

10.6 常见问题 ​

现象优先检查
网关有数据,子设备没有数据网关 decode 是否返回子设备标识,子设备是否已创建并关联网关
子设备设备 ID 不断变化子设备 ID 生成规则是否稳定,是否使用了固定地址或序列号
子设备命令没有到达网关连接是否正常,下行 Topic 是否使用了正确的网关和子设备占位符
所有数据都进入调试设备preDecode 是否能识别真实网关 ID,是否误用了自动注册兜底
一条报文包含多个子设备但只有一个有数据检查协议是否为每个子设备返回独立的解析结果,并进行实际联调验证

网关和子设备的具体字段会因设备协议不同而变化,但总体原则都是:网关负责连接和转发,子设备负责独立的产品模型和数据归属。