笔者参考了这篇文章和阿里云的官方文档使用BC26作为网关连接阿里云,很多不具有联网能力的设备就可以通过BC26中转数据,把数据发送到云平台了。
介绍
在很多物联网场景中,终端设备本身没有连接互联网能力,那么数据如何上阿里云呢?
IoT物联网平台支持设备MQTT直连,也支持的设备挂载到网关上,作为网关的子设备,由网关代理接入IoT物联网平台。
这时候网关设备除了自身作为IoT网关设备(拥有身份三元组)与IoT物联网平台建立MQTT连接,收发数据,还要负责子设备的管理,包括:
①网关添加子设备网络拓扑关系
②子设备复用网关mqtt连接通道上线
③网关把子设备数据上报到云端
④网关接收指令,并转发给子设备
⑤网关上报子设备下线
⑥网关删除子设备网络拓扑关系
网关和子设备通信的协议由本地网络决定,可以是http,mqtt,ZigBee,Modbus,BLE等,这部分逻辑由网关实现。拓扑关系如下:
云平台配置
创建网关产品
创建网关产品时,需要选择节点类型:网关设备,其他的根据自己的情况选择。
在产品下创建设备
创建网关子设备产品
创建网关子设备产品时,需要选择节点类型:网关子设备,其他的根据自己的情况选择。
在产品下创建设备:
还可以使用批量添加,多创建几个子设备:
在网关设备中添加子设备
在网关设备中有添加子设备的选项,把前面创建的子设备选中到这里来,添加效果如下:
此时就在阿里云上创建好网关和子设备以及他们的从属关系了。
网关实体设备
网关实体设备负责沟通子设备和阿里云,可以选择运行阿里云提供的Link SDK,运行条件要求主机支持TCP/IP协议栈,可以移植到linux、FreeRTOS 等操作系统运行。详情可看链接
如果自己的应用环境过于复杂或过于简单,Link SDK不能满足要求,那么阿里云提供了网关与云平台的通信协议——Alink协议,按照通信协议可以自己写代码实现连接。详情可看链接
根据Alink协议,子设备接入流程通过网关发起,具体接入方式有两种:
第一种:使用一机一密提前烧录设备证书(ProductKey、DeviceName和DeviceSecret),子设备上报设备证书给网关,网关添加拓扑关系,复用网关的通道上报数据。
第二种:使用动态注册方式提前烧录ProductKey,子设备上报ProductKey和DeviceName给网关,物联网平台校验DeviceName成功后,下发DeviceSecret。子设备将获得的设备证书信息上报网关,网关添加拓扑关系,通过网关的通道上报数据。
接下来,使用BC26作为网关通过动态注册的方式接入阿里云,流程如下:
网关连接阿里云
BC26作为网关,先得让自己连接上阿里云,才能替子设备连接阿里云。连接过程和设备直连过程一样,不多说,AT命令如下:
AT+QMTCFG=ALIAUTH,0,"a1On2jjXyRD","Gateway","d2088fbc331b66471f7004e7c69621a1"
AT+QMTOPEN=0,"iot-as-mqtt.cn-shanghai.aliyuncs.com",1883
AT+QMTCONN=0,"Gateway"
从阿里云上可以看到网关设备已上线:
一般网关下会挂很多个子设备,现在我们以子设备Gateway_Sub为例进行连接的流程说明。
子设备身份注册
网关类型的设备,可以通过上行请求为子设备发起动态注册,返回成功注册的子设备的设备证书。
• 请求Topic:/sys/{productKey}/{deviceName}/thing/sub/register
• 响应Topic:/sys/{productKey}/{deviceName}/thing/sub/register_reply
请求数据格式:
{
"id": "123",
"version": "1.0",
"params": [
{
"deviceName": "deviceName1234",
"productKey": "a1234******"
}
],
"method": "thing.sub.register"
}
响应数据格式:
{
"id": "123",
"code": 200,
"data": [
{
"iotId": "12344",
"productKey": "a1234******",
"deviceName": "deviceName1234",
"deviceSecret": "xxxxxx"
}
]
}
因此按照上面说的Topic格式,先执行指令:
AT+QMTSUB=0,1,"/sys/a1On2jjXyRD/Gateway/thing/sub/register_reply",0
进行子设备注册成功的消息订阅,这样当子设备注册成功后,会返回URC。执行
AT+QMTPUB=0,1,1,0,"/sys/a1On2jjXyRD/Gateway/thing/sub/register","{"id":"123","version":"1.0","params":[{"deviceName":"Gateway_Sub","productKey":"a1qXCUy08wV"}],"method":"thing.sub.register"}"
发起子设备注册,注册成功,阿里云会下发消息,BC26接收到后会返回:
+QMTRECV: 0,0,"/sys/a1On2jjXyRD/Gateway/thing/sub/register_reply","{"code":200,"data":[{"iotId":"R8ZxPHezvoA8er1kjXye000000","deviceSecret":"764e171c09bc728907914a333b5ae59c","productKey":"a1qXCUy08wV","deviceName":"Gateway_Sub"}],"id":"123","message":"success","method":"thing.sub.register","version":"1.0"}"
从返回可以得到动态注册的deviceSecret,用来进行后续的操作。
添加设备拓扑关系
网关类型的设备,可以通过该Topic上行请求添加它和子设备之间的拓扑关系,返回成功添加拓扑关系的子设备。
• 请求Topic:/sys/{productKey}/{deviceName}/thing/topo/add
• 响应Topic:/sys/{productKey}/{deviceName}/thing/topo/add_reply
请求数据格式:
{
"id": "123",
"version": "1.0",
"params": [
{
"deviceName": "deviceName1234",
"productKey": "1234556554",
"sign": "xxxxxx",
"signmethod": "hmacSha1",
"timestamp": "1524448722000"
}
],
"method": "thing.topo.add"
}
响应数据格式:
{
"id": "123",
"code": 200,
"data": [
{
"deviceName": "deviceName1234",
"productKey": "1234556554"
}
]
}
先订阅操作成功消息:
AT+QMTSUB=0,1,"/sys/a1On2jjXyRD/Gateway/thing/topo/add_reply",0
数据发送内容中有"sign"、“signmethod”。
首先“signmethod”是签名算法,从hmacSha1、hmacSha256、hmacMd5、Sha256中选一个。
“sign”是子设备签名,用来认证,它通过如下方法得到:1)将所有提交给服务器的参数(sign,signMethod除外)按照字母顺序排序,然后将参数和值依次拼接(无拼接符号)。2)对加签内容通过signMethod指定的算法,使用设备的DeviceSecret值,进行签名计算。
比如本次数据内容有:“deviceName”、“productKey”、“timestamp”,他们的首字母为“d”、“p”、“t”,因此排序为"deviceName"、“productKey”、“timestamp”,再把他们的值加上,得到加签内容为:
deviceNameGateway_SubproductKeya1qXCUy08wVtimestamp1524448722000
打开在线加密网站
得到数据内容后,发送:
AT+QMTPUB=0,1,1,0,"/sys/a1On2jjXyRD/Gateway/thing/topo/add","{"id":"123","version":"1.0","params":[{"deviceName":"Gateway_Sub","productKey":"a1qXCUy08wV","sign":"b4ba897c6f3656ed2b110dc051a1d326609562ce","signmethod":"hmacSha1","timestamp":"1524448722000"}],"method":"thing.topo.add"}"
发送成功后,返回:
+QMTRECV: 0,0,"/sys/a1On2jjXyRD/Gateway/thing/topo/add_reply","{"code":200,"data":[{"productKey":"a1qXCUy08wV","deviceName":"Gateway_Sub"}],"id":"123","message":"success","method":"thing.topo.add","version":"1.0"}"
子设备上线
• 请求Topic:/ext/session/
p
r
o
d
u
c
t
K
e
y
/
{productKey}/
productKey/{deviceName}/combine/login
• 响应Topic:/ext/session/
p
r
o
d
u
c
t
K
e
y
/
{productKey}/
productKey/{deviceName}/combine/login_reply
请求数据格式:
{
"id": "123",
"params": {
"productKey": "al12345****",
"deviceName": "device1234",
"clientId": "al12345****&device1234",
"timestamp": "1581417203000",
"signMethod": "hmacmd5",
"sign": "9B9C732412A4F84B981E1AB97CAB****",
"cleanSession": "true"
}
}
响应数据格式:
{
"id":"123",
"code":200,
"message":"success"
"data":{
"deviceName": "device1234",
"productKey": "al12345****"
}
}
同样的发送,订阅平台返回:
AT+QMTSUB=0,1,"/ext/session/a1On2jjXyRD/Gateway/combine/login_reply",0
根据字母排序,加签内容为:
clientIdxuhongdeviceNameGateway_SubproductKeya1qXCUy08wVtimestamp1524448722000
发送指令,让子设备上线:
AT+QMTPUB=0,1,1,0,"/ext/session/a1On2jjXyRD/Gateway/combine/login","{"id":"123","params":{"productKey":"a1qXCUy08wV","deviceName":"Gateway_Sub","clientId":"xuhong","timestamp":"1524448722000","signMethod":"hmacSha1","sign":"60f5703f81b5d970d6511f82cc5367b15f4562eb","cleanSession":"true"}}"
发送成功后,返回:
+QMTRECV: 0,0,"/ext/session/a1On2jjXyRD/Gateway/combine/login_reply","{"code":200,"data":{"productKey":"a1qXCUy08wV","deviceName":"Gateway_Sub"},"id":"123","message":"success"}"
此时看到云平台上,子设备已经上线:
子设备上报数据等操作同样道理不再一一例举。