跳至主要內容

网关 MQTT 接入

约 2803 字大约 9 分钟

网关 MQTT 接入

在物联网中,网关的作用是将那些本身不能直接连接云平台的设备,通过网关的中转,让设备接入云平台。网关起到的作用是数据转发和协议转换。

网关和云平台的通信主要分为:

  • 网关设备自身和云平台的通信,例如:上报网关自身的设备状态和属性,接收云平台对网关的控制指令等。
  • 网关子设备和云平台的通信,例如:网关连接的 Zigbee 温湿度传感器向云平台上报温湿度,以及网关连接的 RS485/Modbus 8路继电器,接收云平台下发的实时指令。这些子设备的通信都需要经过网关的转发。

提示

网关本身也是一类设备,网关自身和云平台的通信,和普通设备接入完全相同,请浏览 MQTT 接入

这一节,我们主要介绍的是网关如何实现子设备和云平台的通信,ThingsCloud 提供了一套网关专用的 MQTT 协议,包括独立的主题和消息格式。

为网关添加子设备

在使用网关 MQTT 协议时,需要先在 ThingsCloud 云平台上为网关和子设备绑定关系。

设备类型

首先,网关和子设备都是 设备,它们的区别仅仅在于所属的 设备类型 不同:

  • 网关设备必须归属于 网关 设备类型。
  • 网关子设备必须归属于 网关子设备 设备类型。

创建子设备

对于网关设备,在 设备详情页 > 子设备 中可以添加子设备,如下图:

在云平台的设备视角中,网关和子设备是同样的存在形式,如下图:

网关和子设备具有和其它直连设备同样的功能,例如:属性、事件、命令、规则、任务、OTA固件升级、可视化、零代码应用开发等。

子设备地址

子设备地址是子设备的身份标识,帮助云平台和网关识别不同的子设备。因此,子设备地址在同一个网关的多个子设备中需保持唯一,

在网关中添加子设备后,您可以为每个子设备设置子设备地址,如下图:

未设置子设备地址的子设备,无法通过网关设备上报数据,也无法接收云平台通过网关下发给它的数据。

根据不同的子设备通信方式,子设备地址有不同的格式要求。例如:

  • Modbus 子设备地址,就是子设备的从机站号。
  • BLE 子设备通常使用模组芯片的 UUID。

您也可以按照一定的规则生成 子设备地址 ,可以是数字或字符串,只要确保在同一个网关中唯一即可,然后将它烧录到子设备中。

网关与云平台的连接

要实现子设备和云平台的通信,首先必须让网关通过 MQTT 接入云平台。网关设备的 MQTT 接入点和身份认证方式,和普通直连设备完全相同,详细介绍请浏览 MQTT 接入

网关 MQTT 主题一览

对于子设备和云平台的通信,网关可使用以下 MQTT 主题:

发布主题

网关设备通过以下主题,将子设备的消息上报到云平台。

消息类型主题
子设备已连接gateway/connect
子设备已断开gateway/disconnect
上报子设备属性gateway/attributes
获取子设备属性gateway/attributes/get
上报子设备事件gateway/event/report
上报子设备命令回复gateway/command/reply

订阅主题

网关设备通过以下主题,接收云平台下发给子设备的消息。

消息类型主题
接收子设备连接响应gateway/connect/response
接收子设备上报属性的响应gateway/attributes/response
接收子设备获取属性的响应gateway/attributes/get/response
接收下发给子设备的属性gateway/attributes/push
接收子设备事件上报的响应gateway/event/response
接收下发给子设备的命令gateway/command/send

下面我们重点介绍一些常用的发布主题和订阅主题。

子设备已连接

当网关确定子设备已连接时,可上报消息通知云平台。

发布主题

gateway/connect

消息格式

提示

网关 MQTT 的所有消息都必须是 JSON 格式,如果发布的不是 JSON 格式,设备会被云平台主动断开 MQTT 连接。

{
    "device": "SUB_DEVICE_ADDR"
}
  • device:子设备地址。

子设备已断开

当网关确定子设备已断开时,可上报消息通知云平台。

发布主题

gateway/disconnect

消息格式

{
    "device": "SUB_DEVICE_ADDR"
}
  • SUB_DEVICE_ADDR:子设备地址。

上报子设备属性

当网关接收子设备的属性变化时,向云平台上报子设备属性。

发布主题

gateway/attributes

消息格式

{
    "SUB_DEVICE_ADDR1": {
        "ATTRIBUTES1": VALUE1,
        "ATTRIBUTES2": VALUE2
    },
    "SUB_DEVICE_ADDR2": {
        "ATTRIBUTES1": VALUE1,
        "ATTRIBUTES2": VALUE2
    }
}

网关支持一次上报多个子设备的属性。

  • SUB_DEVICE_ADDR1SUB_DEVICE_ADDR2:子设备地址。

举个例子,网关上报多个子设备的属性,如下:

{
    "SUB_DEVICE_ADDR1": {
         "battery": 100,
        "occupancy": false
    },
    "SUB_DEVICE_ADDR2": {
        "battery": 98,
        "occupancy": true
    }
}

这时,在控制台的子设备详情页,会实时更新显示设备属性的最新值。

如果我们事先打开子设备的调试状态,可以看到这条上报的消息。虽然是上报给网关设备的,但是消息被转发给了子设备。如下:

接收下发给子设备的属性

网关订阅这个主题,可以实时接收云平台下发给子设备的属性消息。

订阅主题

gateway/attributes/push

消息格式

接收到的消息格式如下:

{
    "device": "SUB_DEVICE_ADDR1",
    "attributes": {
        "ATTRIBUTES1": VALUE1,
        "ATTRIBUTES2": VALUE2
	}
}
  • device:表示子设备地址。

举个例子,我们子设备详情页下发属性,如图:

这时,网关会通过该订阅的主题,收到下发给子设备的消息,如图:

收到的消息如下:

{
    "device": "SUB_DEVICE_ADDR1",
    "attributes": {
        "relay1": true
    }
}

接下来网关可通过自身的运行机制,将消息转发给 子设备地址SUB_DEVICE_ADDR1 的子设备,或者在转发前对数据包进行必要的处理。

获取子设备属性

网关可以获取子设备在云平台的属性,例如用来初始化子设备的运行状态。

发布主题

gateway/attributes/get

发布消息格式

{
    "device": "SUB_DEVICE_ADDR1",
    "get": {
        "keys": ["KEY1", "KEY2"]
    }
}
  • device:表示子设备地址。
  • keys:要读取的属性标识符数组,空数组 [] 标识读取所有属性。

订阅主题

网关订阅以下主题,用来接收云平台回复的子设备属性。

gateway/attributes/get/response

回复消息格式

{
    "device": "SUB_DEVICE_ADDR1",
    "response": {
        "result": 1,
        "attributes": {
            "KEY1": VALUE1,
            "KEY1": VALUE2
        }
    }
}
  • device:表示子设备地址。
  • response:读取子设备属性的回复内容。

上报子设备的事件

在前边的介绍中,我们已经知道,事件 通常用于设备向云平台发送一些通知或请求,但不希望将相关参数记录到设备属性中。

网关同样可以上报子设备的事件,并触发云平台对子设备设置的事件规则。

发布主题

gateway/event/report

消息格式

{
    "device": "SUB_DEVICE_ADDR1",
    "event": {
        "method": "EVENT_IDENTIFIER",
        "params": {
            "PARAM1": VALUE1,
            "PARAM2": VALUE2
        },
        "id": 1000
    }
}
  • device:表示子设备地址。
  • event:事件消息体。与直连设备事件上报的格式相同。

例如,网关上报子设备请求 OTA 固件版本检查的事件,如下:

在子设备的 设备详情页 > 事件 列表中,可以看到刚刚收到的事件上报。

提示

ThingsCloud 提供的 OTA 固件升级功能,对子设备无缝兼容,使用方法和直连设备的 OTA 升级完全相同。详细介绍请浏览 OTA 固件升级

接收下发给子设备的命令

订阅主题

gateway/command/send

消息格式

接收到的消息格式如下:

{
    "device": "SUB_DEVICE_ADDR1",
    "command": {
        "method": "COMMAND_IDENTIFIER",
        "params": {
            "PARAM1": VALUE1,
            "PARAM2": VALUE2
        },
        "id": 1000
    }
}
  • device:表示子设备地址。
  • command:命令消息体。与直连设备下发命令消息的格式相同。

举个例子,我们在云平台向子设备下发命令,如图:

这时,网关通过订阅该主题,可以实时接收到下发的命令消息,如下图:

收到的消息如下:

{
    "device": "SUB_DEVICE_ADDR1",
    "command": {
        "method": "restart",
        "params": {
            "delay": 30
        },
        "id": 1000
    }
}

上报子设备的命令回复

子设备收到命令消息后,在设备端实现特定的功能后,可以回复命令,也可以不回复命令。

云平台会自动接收回复命令,并和下发命令进行匹配,在控制台的设备命令历史中,您可以看到一组包含下发和回复的命令日志。一次下发命令只能接收一次回复命令,它们的匹配是通过使用一致的 <id> 来保证。

当应用端通过 HTTP API 使用同步命令下发模式时,子设备如果成功上报命令回复,应用端会在 HTTP 响应消息中同步接收设备的命令回复,这可以帮助您实现一些在应用端希望同步获得设备端响应消息的场景。

发布主题

gateway/command/reply

消息格式

{
    "device": "SUB_DEVICE_ADDR1",
    "command": {
        "method": "EVENT_IDENTIFIER",
        "params": {
            "result": VALUE,
        },
        "id": 1000
    }
}
  • device:表示子设备地址。
  • command:命令消息体。与下发命令的格式相同。

自动注册子设备

在一些面向终端用户的场景中,用户可根据自己的实际需要,将不同子设备连接到网关,当网关识别到新的子设备后,我们需要能够在云平台自动创建新的子设备。

例如:智能家居 Zigbee 网关识别到传感器子设备,或草莓温室中的 DTU 识别到新的 Modbus 光照传感器。

ThingsCloud 云平台支持网关自动注册子设备,任何使用云平台网关协议的网关硬件,都可以自动注册子设备。

自动注册子设备的动作发生在 网关上报子设备已连接 时,当子设备地址不存在时,可自动创建子设备,发布主题同上,即:

gateway/connect

这里支持两种方式,原理类似于直连或网关设备动态获取证书时自动创建设备。

使用设备类型 TypeKey

消息格式如下:

{
    "device": "SUB_DEVICE_ADDR",
    "type_key": "TYPE_KEY"
}
  • type_key:设备类型的 TypeKey。需要事先创建好设备类型,接入类型必须是网关子设备,且设备类型开启了允许自动创建设备。

使用产品识别码

消息格式如下:

{
    "device": "SUB_DEVICE_ADDR",
    "product_key": "PRODUCT_KEY"
}
  • product_key:产品识别码。应使用已发布的产品识别码,以便在任何 ThingsCloud 项目中可以自动创建该设备类型。详细介绍请浏览 产品识别码