# 子设备代理接入

# 背景

在很多物联网场景中,终端设备本身没有连接互联网能力,那么数据如何上云呢?

这个时候我们就需要用到网关。瀚云平台支持设备MQTT直连,也支持将设备挂载到网关上,由网关代理接入瀚云平台。这些挂载到网关上的设备称为子设备

因此网关设备除了自身与瀚云平台建立MQTT连接,收发数据,还要负责子设备的管理,包括:子设备拓扑关系管理和子设备上下线、命令、数据的管理。

子设备拓扑关系指网关和子设备的映射关系,此拓扑关系可由网关在子设备初次连接时建立,也可由平台添加子设备时创建。基于安全性考虑,普通设备之间不能任意代理,否则可能出现一个设备随意代理其他设备情况,因此只有网关类型的设备才允许代理子设备。并且一个设备一旦成为某个网关的子设备,就不允许其他网关再代理该子设备。

1.子设备不允许直接通过MQTT连接到平台,只能通过网关连接到IoT平台。

2.子设备要变为普通设备必须在控制台解绑,再变更为普通设备;若要将A网关下的子设备转移到B网关下,需要先将A网关下的子设备解绑,再把设备重新添加到B网关下。

解绑:解除子设备与网关的拓扑关系

# 创建网关

网关设备的创建支持两种方式,用户可以在控制台手动创建:

也可以通过mqtt协议进行设备连接,设备只有在首次连接时可以指定设备类型为网关。 connect报文消息说明:

  • clientId:d:{productKey}:t-gateway:{sn}
    • 前缀d标识device,标识不带签名模式登陆,带签名则前缀为ds
    • {productKey} 表示取平台对应productKey的值
    • t-gateway, 表示设备类型为网关
    • {sn}为设备唯一序列号

其他报文消息见文档mqtt设备连接 (opens new window)

若设备不是首次连接,也可以复用以上报文,且设备的类型不会因connect报文中的clientId传递t-gateway或t-device而改变。

# 网关代理子设备

网关对子设备的代理工作主要分为同步拓扑结构同步子设备状态设置网络拓扑图

# 同步拓扑结构

网关自身的拓扑结构和云端保存的拓扑结构需要保持一致。因为网关代理子设备上报数据时,会先检查其在云端保存的子设备拓扑结构,如果该结构中没有这次代理的子设备,平台会将网关强制下线。因此网关需要同步本身的拓扑关系到云端以保持一致,同样当网关拓扑结构清空或云端拓扑结构改变时,网关也可以从云端获取最新的拓扑结构后保存,以保持与云端一致。

目前同步拓扑结构有以下两种场景:

# 1.控制台新增/解绑子设备

选择一个网关设备,进入"设备详情"-"子设备管理"中。点击"添加设备",新建/添加已有设备作为该网关的子设备,这里的已有设备只会是普通设备且未被任何网关代理;或者解绑子设备。

新建子设备

添加已有设备

解绑子设备

控制台执行的添加/解绑操作,实质上是云端在变更子设备拓扑结构,新的拓扑结构需要同步到网关,网关根据自身连接状态需要做相应的处理:

# a) 网关离线时云端变更拓扑结构

当网关重新登录后,可主动发送获取云端拓扑关系的topic proxy/structureGet,云端收到消息后,会通过 sync/{deviceKey}/structure 将子设备拓扑关系发送到网关设备端;网关收到结构后保存,最后由网关代理该拓扑关系下的子设备上线;

# b) 网关在线时云端变更拓扑结构

网关在线时,云端变更拓扑结构,云端会通过 sync/{deviceKey}/structure 发送拓扑结构到网关设备;网关收到结构后保存;最后由网关代理其保存的拓扑结构下的子设备上线。

# 2.网关自身改变拓扑结构

网关变更其挂载的子设备后,实质上是网关在变更子设备拓扑结构,新的拓扑结构需要同步到云端。网关需通过topic proxy/structureUp 上报结构到云端,才能同步子设备的上下线状态;若此时网关处于离线状态,则应在网关登录后执行以上操作。 如果没有上报结构而直接同步子设备状态,云端不会通过该子设备的结构检验,同步状态失败。

# 同步子设备状态

因为子设备不能直接通过MQTT连接到平台,所以子设备若需要处理上下线、命令、数据,必须通过网关代理的方式和平台做交互。

同步子设备状态具体指网关设备通过MQTT连接到平台后,当网关感知到其下挂载的子设备发生上下线事件后,网关通过topic proxy/structureStatus 上报子设备的上下线状态到平台,完成子设备状态的同步。

网关具体如何同步拓扑结构和同步子设备状态,见最佳实践

# 设置网络拓扑图

在某些应用场景,网关和子设备的关系并不是简单的单层结构,还会存在子设备下接入了其他子设备的情况,从而形成多层的图状结构。 针对这种特殊场景,平台提供新的topic来设置这样的多层结构,生成网络拓扑图,让网关和子设备的关系更加一目了然。

# 云端和网关上下行消息说明

# 1.网关向平台publish网关下子设备拓扑结构变更上行消息

topic说明

  • 返回全部子设备列表

topic:proxy/structureUp -- 表征网关下的子设备拓扑关系变更上报

上报成功后,平台会下发子设备拓扑结构下行通知,一次返回所有的子设备列表。响应topic说明:sync/{deviceKey}/structure,详情见“3.云端变更子设备拓扑关系后向网关publish结构变更下行消息”

如果网关多次上报拓扑结构,云端会取并集作为该网关的拓扑结构并下发

如:网关第一次上报["sn1"],云端返回["sn1"];网关第二次上报["sn2"],云端返回["sn1","sn2"];网关第三次上报["sn2","sn3"],云端返回["sn1","sn2","sn3"]

payload说明: (暂不进行数据加密的说明,相关内容可参考数据上传部分)

{
    "slaveDeviceSn": ["sn1","sn2"]
}

slaveDeviceSn部分为网关下新增子设备连接的拓扑sn号集合

  • 只返回上报子设备列表

topic: proxy/structureUpOnly -- 表征网关下的子设备拓扑关系变更上报

上报成功后,平台会下发子设备拓扑结构下行通知,且只返回本次上报的子设备列表。响应topic说明:sync/{deviceKey}/structure,详情见“3.云端变更子设备拓扑关系后向网关publish结构变更下行消息”

如:网关第一次上报["sn1"],云端返回["sn1"];网关第二次上报["sn2"],云端返回["sn2"];网关第三次上报["sn2","sn3"],云端返回["sn2","sn3"]

payload说明: 同"返回全部子设备列表"

  • 上报拓扑结构时携带子设备名称

topic:proxy/structureUpWithName -- 表征网关下的子设备拓扑关系变更上报,携带子设备名称

上报成功后,平台会下发子设备拓扑结构下行通知,根据payload中传递的参数返回所有的子设备列表或只返回本次上报的子设备列表。响应topic说明:sync/{deviceKey}/structure,详情见“3.云端变更子设备拓扑关系后向网关publish结构变更下行消息”

payload说明: (暂不进行数据加密的说明,相关内容可参考数据上传部分)

{
    "slaveDeviceInfos": [{"sn":"sn1", "deviceName":"子设备1"},{"sn":"sn2", "deviceName":"子设备2"}],
    "returnAllSlaves": true
}

slaveDeviceInfos部分为网关下新增子设备信息的集合,包含sn号和子设备名称;其中子设备名称不能超过64个字符 returnAllSlaves部分为平台响应子设备列表的方式,true为返回所有的子设备列表,false为只返回本次上报的子设备列表;此字段非必填,默认为true

说明1:使用proxy/structureUpWithNametopic上报时,若子设备不存在,则必须携带子设备名称;若子设备已存在,且子设备名称不为空,则会修改子设备名称,若名称为空,则不做处理

说明2:网关上报时,传输的payload数据包大小须在8kb以下,建议每次上报的最大设备数为100个

# 2.网关主动获取云端子设备拓扑关系

topic说明: proxy/structureGet --表征网关主动向云端请求该网关与子设备的拓扑关系

平台收到请求后,作为响应,会向网关下发其与其子设备拓扑结构,其中包含全部子设备列表。响应topic说明:sync/{deviceKey}/structure,详情见“3.云端变更子设备拓扑关系后向网关publish结构变更下行消息”

payload说明:

 {"connDeviceKey": "connDeviceKey"}

-connDeviceKey为当前网关链路设备的deviceKey

# 3.云端变更子设备拓扑关系后向网关publish结构变更下行消息

网关设备上报子设备拓扑关系或网关发送获取云端拓扑结构的消息后,下发云端全量设备拓扑关系

topic说明: sync/{deviceKey}/structure (下行)

payload说明:

 [{"slaveDeviceKey":"slaveKey01","sn":"sn01"},{"slaveDeviceKey":"slaveKey02","sn":"sn02"},...]

-slaveDeviceKey为网关下子设备的deviceKey -sn部分为网关下子设备的sn号

# 4.网关向平台publish网关下子设备状态变更上行消息

topic说明: proxy/structureStatus -- 表征网关下子设备登录状态的变更同步

payload说明: (暂不进行数据加密的说明,相关内容可参考数据上传部分)

{
    "onlineSns": ["sn1","sn2"],
    "offlineSns": ["sn3","sn4"]
}

onlineSns部分为网关下子设备上线的sn号集合,非必填 offlineSns部分为网关下子设备下线的sn号集合,非必填

说明:子设备状态上报之前,会先检查平台保存的子设备拓扑关系,检查成功才会上报状态;网关也可以主动获取或上报拓扑结构到云端,设备拓扑关系变更详情请看参考拓扑结构章节;上报之后,平台会下发rsp/proxy/notify 的topic消息;返回子设备登录结果。

# 5.平台向网关下发子设备登录结果信息

topic说明:rsp/proxy/notify

payload说明:

{
    "loginSuc": [{ "sn" : "sn1" , "deviceKey" : "deviceKey1" }],
    "loginFail": [{"code":"1" , "snSet":["sn2"] } ],
    "offlineSuc": [{"childDeviceKey":"childDeviceKey3" , "reasonCode":"1"}],
    "offlineFail": [{"childDeviceKey":"childDeviceKey4" , "reasonCode":"0"}]
}
  • loginSuc部分为登录成功的子设备,deviceKey为子设备的deviceKey,网关需对其进行记录,以便子设备的数据上传与命令下发等相应操作;
  • loginFail部分为登录失败的子设备,code为原因码("001": 鉴权不通过,"002": 子设备重复登录),snSet为登录失败子设备集合;
  • offlineSuc部分为下线成功的子设备,childDeviceKey为子设备deviceKey,reasonCode为原因码("1":网关请求下线, "2":子设备被平台强制下线)
  • offlineFail部分为下线失败的子设备,childDeviceKey为子设备deviceKey,reasonCode暂无明确意义

# 6.网关上报网络拓扑图

topic说明: api/setparent --表征网关向云端上报拓扑关系

payload说明:

 [{"sn": "sn1", "parent": "sn2"}]
  • sn为子设备的sn号
  • parent为sn对应子设备的父设备(parent为空时,默认子设备的父设备为当前网关)

# 子设备代理接入最佳实践

# 具体步骤:

1.网关连接到平台;

2.平台向网关下发welcome消息;

3.网关发送topic proxy/structureGet 获取云端最新的拓扑结构;

4.云端下发topic sync/{deviceKey}/structure 到网关,网关保存此拓扑结构,同步拓扑结构;

5.网关本身发生拓扑结构变更时,主动上报topic proxy/structureUp 到云端,同步拓扑结构;

6.云端下发topic sync/{deviceKey}/structure 返回全量子设备拓扑结构,网关保存此拓扑结构;

7.云端发生拓扑结构变更时,会主动下发topic sync/{deviceKey}/structure 到网关,网关保存此拓扑结构,同步拓扑结构;

8.子设备发生上下线时,网关上报topic proxy/structureStatus 到云端,同步子设备状态;

9.同步子设备状态后,平台会下发topicrsp/proxy/notify 的消息,返回子设备登录结果;

10.子设备成功登录的子设备,可通过topic data/{childDeviceKey}/{stream} 上报数据,通过topic event/{childDeviceKey}/{identifier} 上报事件, 通过topic cmdack/{childDeviceKey}/{commandId} 上报命令。

# 具体流程:

子设备代理接入流程图

# 旧版子设备接入流程

注:旧版本子设备接入topic proxy/{deviceKey}/tpChange 为兼容平台升级改造之前创建的子设备代理逻辑,平台升级后子设备使用新版本topic代理接入,并且在2021年二月以后创建的设备平台将不再支持以旧版本子设备接入的topic代理登录;

子设备mqtt接入流程

旧版和新版接入流程的主要区别在于:

旧版:只支持网关主动上报拓扑结构到平台,拓扑结构和子设备状态同时上报;

新版:除支持网关主动上报结构外,还支持网关主动获取云端拓扑结构,云端下发拓扑结构到网关,云端变更拓扑结构后,也能主动下发拓扑结构到网关; 同时,对拓扑结构和子设备状态的上报做了拆分,网关可以单独同步拓扑结构,单独同步子设备状态。

# 网关向平台publish网关与子设备拓扑结构变更上行消息(旧版)

topic说明: proxy/{deviceKey}/tpChange -- 表征子设备与网关连接拓扑关系的变更,deviceKey为网关deviceKey

payload说明: (暂不进行数据加密的说明,相关内容可参考数据上传部分)

 {
     "online": ["sn1","sn2"],
     "offline": ["sn3","sn4"]
 }

online部分为网关新增子设备连接拓扑的sn号集合,非必填 offline部分为网关删除子设备连接拓扑的sn号集合,非必填

新版上下行消息见云端和网关上下行消息说明