简介

MLink协议,是IOT-FAST云平台为开发者提供的设备与云端之间数据交换的标准协议,采用JSON格式。

协议特点

每一帧应都带上msgId,该字段用于设备端和云端做消息请求匹配,msgId以13位的当前时间戳作为值,如果某些如果短时间内msgId一样即可认为是一对请求和回复;如果不填则每条消息都默认为0。云端允许范围是 有符号 int64范围,设备端可以根据自身资源情况设计,比如可以设计成2Byte无符号范围;如果超出int64范围则会造成数值溢出,导致msgId回应不准确。

重要说明

云端对设备发送的数据中一定包含 pk和devId,如果设备不需要这些信息,可以使用自定义解码器进行过滤后再转发。

文档格式说明

  • 为了文档清晰,下面的 json 指令均进行了格式化输出,在实际发送数据的时候应该将json数据压缩成一行并且没有多余空格的数据,只保留最后一个换行符发送。比如下面的指令只是为了阅读方便 { “action”: “devSend” } 设备实际发送的的数据应该是 {“action”:”devSend”}

    MLink指令详解

    指令列表

    | 指令功能 | 发送形式 | 详情 | | —- | —- | —- | | 设备上报数据 | D => C | devSend | | 云端回复设备上报数据 | C => D | devSendResp | | 网关批量上报设备数据 | D => C | batchDevSend | | 云端回复网关批量上报设备数据 | C => D | batchDevSendResp | | 云端给设备下发指令 | C => D | cloudSend | | 设备回复云端下发指令 | D => C | cloudSendResp | | 设备上报实时数据 | D => C | devSendLive | | 网关批量上报设备实时数据 | D => C | batchDevSendLive | | 设备上报固件信息 | D => C | reportFirmware | | 云端回应设备上报固件信息 | C => D | reportFirmwareResp | | 云端给设备下发固件升级指令 | C => D | devUpgrade | | 设备回应固件升级指令 | D => C | devUpgradeResp | | 设备上报升级进度 | D => C | devUpgradeProgress | | 动态注册设备 | D => C | register | | 云端回复动态注册设备 | C => D | registerResp | | 网关添加拓扑关系(子设备) | D => C | addTopo | | 云端回复网关添加拓扑关系(子设备) | C => D | addTopoResp | | 网关查询拓扑关系(子设备) | C => D | getTopo | | 云端回复网关查询拓扑关系(子设备) | D => C | getTopoResp | | 网关删除拓扑关系(子设备) | D => C | delTopo | | 云端回复网关删除子设备(子设备) | C => D | delTopoResp | | 子设备上线 | D => C | devLogin | | 云端回复子设备上线 | C => D | devLoginResp | | 子设备下线 | D => C | devLogout | | 云端回复子设备下线 | C => D | devLogoutResp | | 设备状态变化通知 | D => C | devStatusChange |

设备上报数据

D => C
{ “action”: “devSend”, “msgId”: 1615458095777, “pk”: “pk”, “devId”: “devId”, “data”: { “cmd”: “分组标识符”, “params”: { “temperature”: 1, “humidity”: 99.2 } } }

参数 必填 类型 说明
action string 动作,固定为 devSend。
msgId long 消息ID,13位时间戳。
pk string 要发送数据的设备产品PK,如果是子设备必填。
devId string 要发送数据的设备ID,如果是子设备必填。
data object 上报的指令和参数数据。
data.cmd string 分组标识符
data.params object 参数,如果只有指令,没有参数允许不填;否则应该填写该指令下的参数分组标识符。 可以少不能多,值做强较验(类型,长度等必须符合协议规定)。

注意: 如果是子设备上报数据,且是透传数据,需要在网关上统一解码成云端要求的格式,否则云端解码失败。

云端回复设备上报数据

C => D
注意: 云端回复非强制要求,以实际业务需求而定。
{ “action”: “devSendResp”, “pk”: “pk”, “devId”: “devId”, “msgId”: 1615458095777, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 devSendResp。
pk string 设备所属产品PK。
devId string 设备ID。
code uint 如果没有错误回复 0。

网关批量上报设备数据

D => C
{ “action”: “batchDevSend”, “msgId”: 1615458095777, “pk”: “pk”, “devId”: “devId”, “data”: [{ “pk”: “pk”, “devId”: “devId”, “cmd”: “分组标识符”, “params”: { “temperature”: 1, “humidity”: 99.2 } },{ “pk”: “pk1”, “devId”: “devId2”, “cmd”: “分组标识符”, “params”: { “temperature”: 1, “humidity”: 99.2 } }] }

参数 必填 类型 说明
action string 动作,固定为 batchDevSend
msgId long 消息ID,13位时间戳。
pk string 网关设备产品PK。
devId string 网关设备ID。
data.pk string 子设备的 productKey
data.devId string 子设备的 devId
data.cmd string 分组标识符
data.params object 参数,如果只有指令,没有参数允许不填;否则应该填写该指令下的参数分组标识符。

云端回复网关批量上报设备数据

C => D
注意: 云端回复非强制要求,以实际业务需求而定。
{ “action”: “batchDevSendResp”, “pk”: “pk”, “devId”: “devId”, “msgId”: 1615458095777, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 batchDevSendResp。
pk string 设备所属产品PK。
devId string 设备ID。
code uint 如果没有错误回复 0。

云端给设备下发指令

云端给设备(包括子设备)下发指令,设备需要处理所接收的数据。
C => D
{ “action”: “cloudSend”, “pk”: “pk”, “devId”: “devId”, “msgId”: 1615458095777, “data”: { “cmd”: “cmdFlag”, “params”: { “temperature”: 1, “humidity”: 99.2 } } }

参数 必填 类型 说明
action string 动作,固定为 cloudSend
pk string 设备所属产品PK。
devId string 要控制的设备ID。
data object 指令数据。
data.cmd string 分组标识符。
data.params object 参数,如果只有指令,没有参数允许不填,否则应该填写该指令下的参数分组标识符。

设备回复云端下发指令

D => C
注意: 设备回复云端非强制要求,以实际业务需求而定。
{ “action”: “cloudSendResp”, “pk”:”pk”, “devId”:”devId”, “msgId”: 1615458095777, “code”: 0 }
设备必须回复,如果没有错误是0;错误码在产品上增加说明。 如果云端没有收到回复则认为是设备没有收到控制指令,控制失败。

参数 必填 类型 说明
action string 动作,固定为 cloudSendResp。
pk string 设备所属产品PK,如果是子设备必填。
devId string 要控制的设备ID,如果是子设备必填。
code uint 如果没有错误回复 0。

设备上报实时数据

D => C
{ “action”: “devSendLive”, “msgId”: 1615458095777, “pk”: “pk”, “devId”: “devId”, “data”: { “cmd”: “分组标识符”, “params”: { “temperature”: 1, “humidity”: 99.2 } } }

参数 必填 类型 说明
action string 动作,固定为 devSendLive。
pk string 要发送数据的设备产品PK,如果是子设备必填。
devId string 要发送数据的设备ID,如果是子设备必填。
data object 上报的指令和参数数据。
data.cmd string 分组标识符
data.params object 参数,如果只有指令,没有参数允许不填;否则应该填写该指令下的参数分组标识符。 可以少不能多,值做强较验(类型,长度等必须符合协议规定)。

注意: 如果是子设备上报实时数据,且是透传数据,需要在网关上统一解码成云端要求的格式,否则云端解码失败。

网关批量上报设备实时数据

D => C
{ “action”: “batchDevSendLive”, “msgId”: 1615458095777, “pk”: “pk”, “devId”: “devId”, “data”: [{ “pk”: “pk”, “devId”: “devId”, “cmd”: “分组标识符”, “params”: { “temperature”: 1, “humidity”: 99.2 } },{ “pk”: “pk1”, “devId”: “devId2”, “cmd”: “分组标识符”, “params”: { “temperature”: 1, “humidity”: 99.2 } }] }

参数 必填 类型 说明
action string 动作,固定为 batchDevSendLive
msgId long 消息ID,13位时间戳。
pk string 网关设备产品PK。
devId string 网关设备ID。
data.pk string 子设备的 productKey
data.devId string 子设备的 devId
data.cmd string 分组标识符
data.params object 参数,如果只有指令,没有参数允许不填;否则应该填写该指令下的参数分组标识符。

设备上报固件信息

D => C
{ “action”: “reportFirmware”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “type”: “module/mcu/config”, “version”: “1.2.1” }

参数 必填 类型 说明
action string 动作,固定为 reportFirmware。
pk string 设备所属产品PK。
devId string 要控制的设备ID。
type string module/mcu/config。
version string 版本,格式随意,比如可以是 a.b.c,也可以是 1.0.1。

云端回应设备上报固件信息

C => D
{ “action”: “reportFirmwareResp”, “pk”:”pk”, “devId”:”devId”, “msgId”: 1, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 reportFirmwareResp。
pk string 设备所属产品PK, 如果是子设备必填。
devId string 要控制的设备ID,如果是子设备必填。
code uint 如果没有错误回复 0。

云端给设备下发固件升级指令

C => D
{ “action”: “devUpgrade”, “msgId”: 1, “pk”:”pk”, “devId”:”devId”, “url”: “http://xx.xx/ss.bin“, “md5”: “md5”, “type”: “module/mcu/config”, “version”:”currentVersion” }

参数 必填 类型 说明
action string 动作,固定为 devUpgrade。
pk string 要控制的设备所属产品PK。
devId string 要控制的设备ID。
url string 固件下载地址(http,非https)。
md5 string 固件的md5值。
type string 更新类型 module(模组),mcu(mcu),config(远程配置)。
version string 目标版本。

设备回应固件升级指令

设备必须回复,否则云端认为下发指令失败,设备未收到控制指令。
D => C
{ “action”: “devUpgradeResp”, “pk”:”pk”, “devId”:”devId”, “type”: “module/mcu”, “msgId”: 1, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 devUpgradeResp。
pk string 要控制的设备的所属产品PK, 如果是子设备必填。
devId string 要控制的设备ID,如果是子设备必填。
code uint 如果没有错误回复 0。
type string 升级类型 module,mcu。

设备上报升级进度

注意 只是记录升级进度,具体升级到什么版本还需要设备主动上报,参见上报固件版本
D => C
{ “action”: “devUpgradeProgress”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “progress”: 19, “type”: “module/mcu/config”, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 devUpgradeProgress。
pk string 要控制的设备的所属产品PK, 如果是子设备必填。
devId string 要控制的设备ID,如果是子设备必填。
type string 升级类型 module,mcu,config。
code uint 如果没有错误回复 0。
progress uint 取值范围 [0,100]。

如果code=0,progress=100 只能代表设备端升级完成,真正升级完成必须是上报的版本和预期的一样。设备升级完成,需要再次发送上报固件信息到云端以便更新云端设备固件版本信息,如果版本号跟预期不一样算作失败处理。

动态注册设备

D => C
{ “action”: “register”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “random”: “random”, “hashMethod”: “method”, “sign”: “sign” }

参数 必填 类型 说明
action string 动作,固定为 register。
pk string 要注册的设备的所属产品PK。
devId string 要注册的设备ID。
sign string 要注册的设备的产品认证签名。
random string 设备加密校验,随机字符串,可以使用当前时间毫秒数的字符串,也可以使用uuid生成的,也可以是 math.random()等等。
hashMethod string hash 方法,选填 HmacMD5、HmacSHA1、HmacSHA256 或者 HmacSHA512。

注意 在产品上设置有安全开关:动态注册设备是否需要鉴权,如果开启则 sign,random 和 hashMethod 字段必填,关闭则不需要填写。开启能够增强注册设备的安全性,建议开启。

sign算法说明

sign=hash(pk+productSecrect+random),加密密钥(密码)填写 productSecrect
其中 hash 算法支持: HmacMD5、HmacSHA1、HmacSHA256 和 HmacSHA512。
比如 pk=pk123,productSecrect=excvw2cw,random=QWExm,则要hash的值应该为 pk123excvw2cwQWExm 使用不同 hash 算法得到的值如下,可以使用在线工具测试 进行测试。 使用 hash 算法得到sign后,需要使用对应的 toHex 方法将其编码为 hex string。

  • HmacMD5: fea83bd79fb090b1529f1468bb1051f7
  • HmacSHA1: 2c32e0bfbdee359eb71afb9efeb7ad922e1321c7
  • HmacSHA256: 09e17c16188da122ff5cf6dd384df44260f546c5a38b6764c7e9f4b05f8e2452
  • HmacSHA512: 0009dcd96b7f0d6c5667aa0a1b0aa8a354391598d7375152342c37a30fab5ec2ba17f85b9006dded114181447e29bb9ad616f61c24e77a103c99b9f25ccc9f59

    云端回复动态注册设备

    云端允许多次调用激活指令,注册成功后返回该设备的信息。
    C => D
    { “action”: “registerResp”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “devSecret”: “devSecret”, “code”: 0 }
参数 必填 类型 说明
action string 动作,固定为 registerResp。
pk string 设备所属产品PK。
devId string 设备ID。
devSecret string 设备的密钥,添加拓扑关系的时候需要使用。
code uint 如果没有错误回复 0。

网关添加拓扑关系(子设备)

设备如果要构建自身和子设备的拓扑关系,同时,这种拓扑关系也是一种约束,只有在这个网关下的子设备才允许通过该网关上报数据,所以需要向云端发送添加子设备的指令,将子设备添加到网关拓扑关系中。

  1. 添加拓扑的时候,如果云端没有注册该子设备,则会自动注册子设备。
  2. 添加关系的时候,云端会自动设置子设备状态为在线状态。
  3. 支持一次性添加一个
  4. 支持多级拓扑关系,如下图
  5. 允许重复请求(防止云端添加成功,网关本地没有添加成功)
  6. 网关应该等待云端回复网关添加子设备返回信息,code=0的时候才将子设备信息挂载到自身下。

    1. dev1 ---| 在该拓扑关系中,加上网关(顶层dev1)设备 / \ | 一有3层,最多支持3层。 dev2 dev3 | / \ | dev1 是 dev2 和 dev3 的网关节点; dev4 dev5 | 反过来说,dev2 和 dev3 是 dev1 子设备节点。 <br />**注意:**
  • 不允许两个设备相互设置为子设备
  • 子设备层级最多支持2级
  • 整个网关所包含的设备最多支持400个
  • 添加的子设备必的父级设备必须已经挂载到该拓扑中

D => C
{ “action”: “addTopo”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “sub”: { “pk”: “pk”, “devId”: “devId”, “random”: “random”, “sign”: “sign”, “hashMethod”: “hashMethod” } }

参数 必填 类型 说明
action string 动作,固定为 addTopo。
pk string 父级设备节点所属产品PK,如果是子设备必填。
devId string 父级设备节点设备ID,如果是子设备必填。
sub object 子设备节点。
sub.pk string 子设备节点所属产品PK。
sub.devId string 子设备节点设备ID。
sub.random string 同设备登录认证的 random 意义。
sub.sign string 子设备认证签名,算法说明。 MQTT登录认证
sub.hashMethod string hash 方法。

注意 子设备上有安全开关:添加拓扑关系,是否关闭安全认证,如果关闭,random、sign和hashMethod不需要填,开启则必填。出于安全考虑,建议开启安全认证。

添加拓扑子设备 sign 计算方法

设备连接MQTT认证方式一致

云端回复网关添加拓扑关系(子设备)

C => D
{ “action”: “addTopoResp”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “sub”: { “pk”: “pk”, “devId”: “devId” }, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 addTopoResp。
pk string 父设备节点所属产品PK。
devId string 父设备节点设备ID。
sub object 子设备节点信息。
sub.pk string 子设备节点所属产品PK。
sub.devId string 子设备节点设备ID。
code uint 如果没有错误回复 0。

网关查询拓扑关系(子设备)

注意 只支持查询直属下级的设备,不支持查询所有设备。
C => D
{ “action”: “getTopo”, “msgId”: 1, “pk”: “pk”, “devId”: “devId” }

参数 必填 类型 说明
action string 动作,固定为 addTopo。
pk string 父级设备节点所属产品PK,如果是子设备必填。
devId string 父级设备节点设备ID,如果是子设备必填。

云端回复网关查询拓扑关系(子设备)

D => C
{ “action”: “getTopoResp”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “subs”: [ { “pk”: “pk”, “subPk”: “subPk”, “devId”: “subDevId” } ] }

参数 必填 类型 说明
action string 动作,固定为 addTopo。
pk string 父级设备节点所属产品PK,如果是子设备必填。
devId string 父级设备节点设备ID,如果是子设备必填。
subs array 直属下级的所有设备,如果没有则数组为空。

网关删除拓扑关系(子设备)

前置条件:网关设备已经登录并保持连接。
网关删除拓扑关系,仅仅是在逻辑上解除了与子设备的关系,并没有删除设备注册信息。
D => C
{ “action”: “delTopo”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “sub”: { “pk”: “pk”, “devId”: “devId” } }

参数 必填 类型 说明
action string 动作,固定为 delTopo。
pk string 父设备节点所属产品PK,如果是子设备必填。
devId string 父设备节点设备ID,如果是子设备必填。
sub object 子设备节点信息。
sub.pk string 子设备节点所属产品PK。
sub.devId string 子设备节点设备ID。

云端回复网关删除子设备(子设备)

C => D
{ “action”: “delTopoResp”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “sub”: { “pk”: “pk”, “devId”: “devId” }, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 delTopoResp。
pk string 父设备节点所属产品PK。
devId string 父设备节点设备ID。
sub object 子设备节点信息。
sub.pk string 子设备节点所属产品PK。
sub.devId string 子设备节点设备ID。
code uint 如果没有错误回复 0。

子设备上线

注意,该指令仅供子设备使用
前置条件:网关设备已经登录并保持连接。
D => C
{ “action”: “devLogin”, “msgId”: 1, “pk”: “pk”, “devId”: “devId” }

参数 必填 类型 说明
action string 动作,固定为 devLogin。
pk string 子设备节点所属产品PK。
devId string 子设备节点设备ID。

云端回复子设备上线

C => D
{ “action”: “devLoginResp”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 devLoginResp。
pk string 子设备节点所属产品PK。
devId string 子设备节点设备ID。
code uint 如果没有错误回复 0。

子设备下线

注意,该指令仅供子设备使用
前置条件:网关设备已经登录并保持连接。
D => C
{ “action”: “devLogout”, “msgId”: 1, “pk”: “pk”, “devId”: “devId” }

参数 必填 类型 说明
action string 动作,固定为 devLogout。
pk string 子设备节点所属产品PK。
devId string 子设备节点设备ID。

云端回复子设备下线

C => D
{ “action”: “devLogoutResp”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “code”: 0 }

参数 必填 类型 说明
action string 动作,固定为 devLogoutResp。
pk string 子设备节点所属产品PK。
devId string 子设备节点设备ID。
code uint 如果没有错误回复 0。

设备状态变化通知

当设备状态改变时通知,如设备上线、离线等。
D => C
{ “action”: “devStatusChange”, “msgId”: 1, “pk”: “pk”, “devId”: “devId”, “status”: “online” }

参数 必填 类型 说明
action string 动作,固定为 devStatusChange。
pk string 设备节点所属产品PK。
devId string 设备节点设备ID。
status string 设备状态,上线:online、离线:offline。