查看: 2492|回复: 4

玩转OneNET物联网平台之MQTT服务① —— OneNetMqtt全方位调试

[复制链接]
  • TA的每日心情
    开心
    2020-7-1 09:10
  • 签到天数: 817 天

    [LV.10]以坛为家III

    发表于 2019-6-27 09:49 | 显示全部楼层 |阅读模式
    本帖最后由 单片机菜鸟 于 2019-11-28 09:17 编辑

    个人免费交流群:ESP物联网开发之旅 622368884

    image

    1.MQTT简介

        MQTT协议是一个面向物联网应用的即时通信协议,使用TCP/IP提供网络连接,能够对负载内容实现消息屏蔽传输,开销小,可以有效降低网络流量。
        参考博主线上博文:玩转PubSubClient MQTT库

    特点及功能

    • 长连接协议(保持心跳,keepAlive)
    • 终端数据点上报,支持的数据点类型包括

    整型(int)
    浮点数(float)
    字符串(string)
    JSON格式
    二进制数据

    • 平台消息下发
    • 基于Topic的订阅、发布以及消息推送,可以实现设备间的消息单播以及组播

    典型应用场景
        MQTT协议适用于设备和平台需要保持长连接的使用场景,MQTT特点在于可以实现设备间的消息单播以及组播,可以不依赖于其他服务(下发命令服务,推送服务等)实现让设备以应用服务器的方式对真实设备进行管理和控制。

    读者所需知识储备

    • 玩转PubSubClient MQTT库
    • 玩转OneNET物联网平台之简介

    2.MQTT接入说明

        接入流程分为:

    • 平台域(也就是OneNet平台上的操作)
    • 设备域(8266设备上的SDK,我们这里用PubSubClient)

    image

        接入步骤如下:

    2.1 Step1 —— 创建产品,选择接入协议

    • 首先您需要在平台创建一个接入协议为MQTT的产品,查看产品创建
    • 创建产品后,记录该产品的产品ID(ProductId)

    2.2 Step2 —— 创建设备,记录设备ID等信息

    创建设备有两种方式:

    • 第一种 可以通过页面点击添加设备,输入设备名称鉴权信息(即设备编号,在8266中我们可以使用 ESP+Mac地址的方式或者ESP+ChipId的方式),具体平台的资源模型可详情请查看第一章 资源模型,并记录下该设备编号(deviceId).
    • 第二种 可以通过调用创建设备API 实现设备的创建,输入设备的设备名、接入协议、鉴权信息以及MasterKey等信息,即可在平台上创建设备(博主比较喜欢这一种,也比较灵活)。

    2.3 Step3 —— 建立设备与平台间的协议连接

    • MQTT服务器地址域名为:mqtt.heclouds.com

        使用Step1和Step2中的参数作为登录参数,使用SDK中的对应接口组织MQTT连接报文,发送到平台,与平台建立MQTT连接

        若已经连接成功,在设备信息中会看到一个在线标记:
    image

        对于初学者,博主建议先用OneNet提供的MQTT调试工具来试玩一下,已亲测可用。

    image

    2.4 Step4 —— 数据流创建,数据点上传

    • 利用SDK中提供的接口函数,编写代码将数据上传到平台

    2.5 Step5 —— 数据流展示,查看数据点

    • 在OneNET上的设备管理下点击数据展示,进入数据展示页面,点击下拉菜单,查看近期上传的数据点;也可以选择时间区间来查看历史时间

    3. MQTT API

        API根据用途做了几种分类,博主这里不重复,请参考 玩转OneNET物联网平台之简介

        当然,OneNet为了简单方便调试API,也给我们提供了调试界面,具体请参考

    image

        博主在这里不会去讲解各个API的详细用法,请大家自行去查阅官方文档(查阅官方文档也是锻炼能力的一种)。

    3.1 新增设备

    • 具体参考 OneNet官方文档 - 新增设备
    • 此方法比较重要,请仔细理解

    3.2 注册设备

    3.3 更新设备信息

    3.4 查询设备详情

    3.5 批量查询设备信息

    3.6 批量查询设备状态

    3.7 删除设备

    3.8 新增数据流

    3.9 更新数据流属性

    3.10 查询数据流详情

    3.11 批量查询数据流信息

    3.12 删除数据流

    3.13 查询设备历史数据

    3.14 批量查询设备最新数据

    3.15 新增数据点

    3.16 上传文件

    3.17 获取文件

    3.18 发送命令

    3.19 查询命令状态

    3.20 查询命令响应

    3.21 查询设备历史命令

    3.22 新增触发器

    3.23 更新触发器

    3.24 查询触发器

    3.25 删除触发器

    3.26 新增apikey

    3.27 更新apikey

    3.28 查询apikey

    3.29 删除apikey

    3.30 发布消息

    3.31 查询订阅topic的设备

    3.32 查询设备订阅的topic

    3.33 查询产品的topic

    4.设备端接入MQTT流程

    前提

    • 读者已经了解MQTT协议
    • 读者已经在OneNet上建立了Mqtt协议产品,比如博主这里建立了彩灯-MQTT项目

    4.1 连接鉴权

        在 2.3 Step3 —— 建立设备与平台间的协议连接中说到,我们第一步就是和OneNet平台建立连接鉴权:

    image

    • 设备向平台发起 connect 请求.connect 中携带鉴权信息
    • 平台拿到鉴权信息进行鉴权
    • 鉴权通过后,如果 cleansession=0, 平台将会加载保存的设备的一些信息.如订阅列表; 如果 cleansession=1, 设备没有保存信息在平台,则不加载设备相关信息
    • 返回鉴权结果 ConnAck 报文

    4.2 消息发布

    4.2.1 数据点上报协议说明

        设备使用publish报文来上传数据点, 报文格式如下:

    • VariableHeader
    字段 Field名称 说明 格式
    Field1 TopicName=”$dp” $dp为系统上传数据点的指令 2字节字串长度 + utf8字串
    • Payload
      Payload包含真正的数据点内容,支持的格式如下:

    image

    数据类型 1(type == 1)格式说明:
    image

    数据类型 2(type == 2)格式说明:
    image

    数据类型 3(type == 3)格式说明:
    image

    数据类型 4(type ==4)格式说明:
    image

    数据类型 5(type ==5)格式说明:
    image

    数据类型 6(type ==6)格式说明:
    image

    数据类型 7(type == 7)格式说明:(每次最多 500 个数据流的浮点数):
    image

    4.2.2  数据点上报 —— 质量等级Qos0(Client->Server)

    image

    • 设备发布 Qos0 消息(上报数据点)
    • 平台收到上报数据点后保存起来.

    4.2.3  数据点上报 —— 质量等级Qos1(Client->Server)

    image

    • 设备发布 Qos1 消息(上报数据点)
    • 平台收到上报数据点后保存起来.
    • 平台给设备回复相应的 PubAck报文

    4.2.4  数据点上报 —— 质量等级Qos2(Client->Server)

    image

    • 设备发布 Qos2 消息(上报数据点)
    • 平台收到上报数据点后保存起来
    • 平台给设备回复相应的 PubRec 报文
    • 设备需回复平台 PubRel 报文,如超时不回平台则会断开相应连接
    • 平台给设备回复 PubComp 报文

    注意

    • 数据点上报功能不支持 Retain 特性

    4.2.5 下发平台命令协议说明

        平台使用publish 报文来下发平台指令, 报文格式如下:

    FixHeader

    • 参考MQTT篇关于固定头的说明

    VariableHeader

    字段 Field名称 说明 格式
    Field1 TopicName=”$creq/cmduuid” $creq 为系统下发Cmd 的指令,cmduuid 为该条指令的uuid 2 字节字串长度+ utf8 字串

    Payload:

    • Payload 包含真正的指令内容

    注意点

    • 因为这里的cmduuid为某条指令的uuid,所以我们可以考虑正则表达式的topic

    4.2.6 下发平台命令 —— 质量等级Qos0(Server->Client)

    image

    • 平台向设备发送topic 为$creq 的消息(该topic 为平台命令).
      设备收到topic 为$creq 的topic 时,需将其作为平台下发的指令来处理.

    注意

    • 目前命令下发以Qos0 级别进行推送

    4.2.7 命令回复协议说明

        平台使用publish 报文来回复平台指令, 报文格式如下:

    FixHeader

    • 参考MQTT篇关于固定头的说明
    VariableHeader
    字段
    Field名称 说明 格式
    Field1 TopicName=”$crsp/cmduuid” $crsp为系统处理设备回复cmd 的指令,cmduuid 为该条指令的uuid 2 字节字串长度+ utf8 字串

    Payload:

    • Payload 包含真正的指令内容

    注意点

    • 因为这里的cmduuid为某条指令的uuid,所以我们可以考虑正则表达式的topic

    4.2.8 命令回复 —— 质量等级Qos0(Client->Server)

    image

    4.2.9 命令回复 —— 质量等级Qos1(Client<-> Server)

    image

    • 如果设备回复响应时以Qos1 回复,则平台需要给设备回复一个Puback 报文

    4.2.10 命令回复 —— 质量等级Qos2(Client<-> Server)

    image

    如果设备回复响应时以Qos2 回复,则:

    • 1.平台需回复设备一个PubRec 报文
    • 2.设备在收到PubRec 后需向平台回复PubRel 报文
    • 3.平台收到PubRel 报文后,向设备回复PubComp 报文

    4.3 创建Topic

    image

    • 设备通过发送HTTP 请求进行topic 的创建操作.
    • 平台收到请求后创建topic 并返回结果.

    请求及响应定义如下

    image

    4.4 订阅

    image

    • 设备发起订阅请求报文
    • 平台收到请求后更新topic 列表
    • 平台给设备回复SubAck报文

    注意

    • subscribe 的request qos 级别可以为0、1、2

    4.5 取消订阅

    image

    • 设备发起取消订阅请求
    • 平台收到请求后更新topic 列表
    • 平台给设备回复UnSubAck

    4.6 推送设备Topic

    4.6.1 Publish 报文推送协议说明

    FixHeader

    • 参考MQTT篇关于固定头的说明
    VariableHeader
    字段
    Field名称 说明 格式
    Field1 TopicName 填写设备订阅的topic 2 字节字串长度+ utf8 字串

    Payload:

    • Payload 为设备自定义内容

    4.6.2 Publish 报文推送 —— 质量等级Qos0

    image

    • 设备发起推送topic 请求(以Qos0 级别)
    • 平台收到请求后,将topic 以Qos0 级别推送到相关订阅设备(支持离线设备推送)
    • 平台不返回PubAck 或PubRec 等报文

    4.6.3 Publish 报文推送 —— 质量等级Qos1

    image

    • 设备发起推送topic 请求(以Qos1 级别)
    • 平台收到请求后,将topic 以Qos1 级别推送到相关订阅设备(支持离线设备推送)
    • 平台返回PubAck 报文

    4.6.4 Publish 报文推送 —— 质量等级Qos2

    image

    • 设备发起推送topic 请求(以Qos2 级别)
    • 平台收到请求后,回复PubRec 报文
    • 设备收到PubRec 后需回复PubRel 报文(如超时不回复,平台会断开与设备的连接)
    • 平台收到PubRel 报文后,回复PubComp 给设备
    • 平台在回复PubComp 后会以Qos2 级别推送到相关订阅设备(支持离线设备推送)
    • 设备需回复PubRec 报文(如超时不回复,平台会断开与设备的连接)
    • 平台发送PubRel 报文给设备
    • 设备需回复PubComp(发布完成)

    4.6.5 HTTP 请求推送

    image

    • 设备以HTTP 的方式发起推送topic 请求
    • 平台收到请求后,将topic 推送到相关订阅设备.(目前只支持在线推送)
    • 平台返回推送结果

    请求及响应定义如下

    image

    4.7 离线Topic

        普通推送(上面的推送设备Topic)只针对在线设备进行topic消息的推送,离线设备不会收到订阅的topic 的消息。   

        离线Topic则会将该消息推送给在线以及离线设备。

    注意点

    • 如果设备在上线时设置了clean session flag,服务端会删除其订阅的topic 及相关的离线topic 消息。
    • 如果设备没有设置clean session flag,如果有与该设备相关的离线topic 消息,则在鉴权成功后将离线消息
      推送给设备。
    • 遗嘱消息(will msg)只会推送给订阅了该will topic 的在线的设备,离线设备不会收到。
    • 离线消息的有效期默认为2 天(暂不支持用户设定有效期),服务器只会推送在2 天内的最近10 条消息。

    4.8 数据点订阅

    含义

    • 同一产品下的设备可以订阅其他设备的数据点,订阅的topic 格式为:/deviceid/数据流名称。即
      被关注的设备在上传了该数据流名称的数据点后,订阅了该topic 的其他设备都会收到上传的数据点。

    例子

    • A、B 设备的deviceid 分别为9277、9278。
    • A 设备订阅了名为/9278/9527 的topic(9278 为设备B 的id,9527 为B 设备上传的数据流名称)。
    • B 设备上传了名为9527 的数据流(数据点为11; 15;78…)。
    • A 设备会收到多条(取决于设备B 上传的数据点的个数)推送的topic 名为/9278/9527 的publish 消息,消息的
      payload 中则包含设备B 上传的数据点。

    注意点

    • 目前支持订阅的数据点的类型为Type1~Type7

    5.常见问题

    5.1 MQTT连接鉴权时,Payload中ClientIdentifier;UserName;UserPassword分别填写什么?

    • ClientIdentifier: 创建设备时得到的设备ID,为数字字串;
    • UserName: 注册产品时,平台分配的产品ID,为数字字串;
    • UserPassword: 为设备的鉴权信息(即唯一设备编号,SN),或者为apiKey,为字符串。

    5.2 MQTT需要在连接鉴权通过后才能发送其它报文吗?

    • 是的,MQTT协议必须在鉴权通过后(收到ConnAck后),才能发送后续报文进行交互,不然服务器会直接丢弃报文。

    5.3 MQTT可以订阅Topic有什么限制?

    • OneNET不支持订阅$开头的系统Topic。

    5.4 如何利用MQTT协议上传数据到云平台?

    • 设备完成连接鉴权之后,将数据按照一定的格式(见协议文档说明)打包,将数据发布到$dp系统Topic上即可。

    5.5 订阅之前是否需要创建Topic?

    • 设备在执行订阅时,OneNET会自动判断该Topic是否存在,若不存在则自动创建该Topic。

    5.6 设备可否通过订阅的方式,获取其他设备的数据流信息?

    • 可以,可以通过订阅 /device_id/数据流名 的方式,及时获取到某设备最新的数据点信息。

    5.7 设备发布消息(Publish)有什么限制??

    • 发布消息只能在同一产品ID下进行,不能进行跨产品间的Publish消息推送。

    6. 新手手把手感受OneNet MQTT案例

        博主这里认为大家已经注册了OneNet账号。接下来请按照下面步骤进行:

    6.1 创建 ESP8266智能灯系统 产品(MQTT协议)

    image

    注意点

    • 务必选择MQTT协议

        创建完毕后,我们点击查看具体的产品信息:

    image

    注意点

    • 需要记录产品ID,其用来区分产品唯一标识符
    • Master-APIkey,网络请求鉴权信息,接口调用需要带入

    6.2 API调试创建 deviceA和deviceB两个设备

    API接口定义

    操作步骤

    • 通过API调试工具创建deviceA

    image

    http body

    {
        "title": "mqtt_device_A",
        "desc": "mqtt_device_A",
        "tags": ["china", "mobile"],
        "location": {
            "lon": 109,
            "lat": 23.54
        },
        "auth_info": "mqtt_device_A",
        "other": {
            "version": "1.0.0",
            "manufacturer": "china mobile"
        }
    }
    • 通过API调试工具创建deviceB

    image

    http body

    {
        "title": "mqtt_device_B",
        "desc": "mqtt_device_B",
        "tags": ["china", "mobile"],
        "location": {
            "lon": 109,
            "lat": 23.54
        },
        "auth_info": "mqtt_device_B",
        "other": {
            "version": "1.0.0",
            "manufacturer": "china mobile"
        }
    }
    • 查看设备列表

    image

    6.3 官方工具调试deviceA和deviceB

        读者请自行下载 MQTT-device 工具。下载完工具之后请复制出两份,一个工具代表deviceA,一个工具代表deviceB,我们模拟Mqtt操作。

    6.3.1 配置deviceA

    image

    注意点

    • 重点关注博主标红的地方,DeviceID和ProductID、AuthInfo需要填写读者自身创建的
    • 配置完毕连接服务器

    6.3.2 配置deviceB

    image

    注意点

    • 重点关注博主标红的地方,DeviceID和ProductID、AuthInfo需要填写读者自身创建的
    • 配置完毕连接服务器

    6.3.3 deviceA订阅主题“deviceB_to_A”

    image

    注意点

    • 主题名为“deviceB_to_A”

    6.3.4 deviceB订阅主题“deviceA_to_B”

    image

    注意点

    • 主题名为“deviceA_to_B”

    6.3.5 deviceB发布信息给deviceA

    image

    6.3.6 deviceA发布信息给deviceB

    image

    6.3.7 平台下发命令给deviceA

    image

    image

    6.3.8 deviceA上传数据点到平台

    image

    image

    7.总结

    本篇作为OneNet Mqtt篇的开头篇,主要讲解了Mqtt的使用注意事项,并且在调试工具下模拟Mqtt的常用操作,请关注接下来的篇章。


    该用户从未签到

    发表于 2019-10-29 16:27 | 显示全部楼层
    您好,我按照您博客上的教程https://blog.csdn.net/dpjcn1990/article/details/92831686#41_mqtt8266_1163 中的4.1 mqtt-8266案例,在arduino IDE里面编译出错,显示'class PubSubClient' has no member named 'state' 还有'class PubSubClient' has no member named 'setServer',头文件我已经包含了#include <PubSubClient.h>,这是为什么
  • TA的每日心情
    开心
    2020-7-1 09:10
  • 签到天数: 817 天

    [LV.10]以坛为家III

     楼主| 发表于 2019-10-29 16:42 | 显示全部楼层
    Ashbur 发表于 2019-10-29 16:27
    您好,我按照您博客上的教程https://blog.csdn.net/dpjcn1990/article/details/92831686#41_mqtt8266_1163  ...

    先看看有没有下载库

    该用户从未签到

    发表于 2019-10-29 19:44 | 显示全部楼层
    单片机菜鸟 发表于 2019-10-29 16:42
    先看看有没有下载库

    犯了低级错误了,因为我编译自带官方相关示例没有报错,我以为加载好了,还差一个,现在好了,谢谢
  • TA的每日心情
    开心
    2020-7-1 09:10
  • 签到天数: 817 天

    [LV.10]以坛为家III

     楼主| 发表于 2019-11-28 10:11 | 显示全部楼层
    自我顶一下  https://blog.csdn.net/dpjcn1990
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    热门推荐

    5分钟带你快速了解新一代开发板:M5STACK
    5分钟带你快速了解新一代
    一、什么是M5Stack M5Stack是一种模块化、可堆叠扩展的开发板,每个模块
    创客火首发无人机编队套装,开启不一样的人工智能教育
    创客火首发无人机编队套装
    2017年国务院发布《新一代人工智能发展规划》,提出要广泛开展人工智能科普活动,在中
    [2019-4-20]RPG无人世界
    [2019-4-20]RPG无人世界
    剧情:主角玄影,为了逃避██的追杀迫不得已发动████在濒死状态来到█
    Arduino串口监视器出现乱码
    Arduino串口监视器出现乱
    我用Arduinio Due将GNRMC数据Serial.prinln出来,通过串口监视器,我们可以发现有时GN
    为什么单击开关按键后会调用其他控件的函数
    为什么单击开关按键后会调
    BlinkerButton Kelvinator_power("btn-pwr"); BlinkerButton Kelvinator_Light("btn-d
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表