QT使用MQTT协议对接华为IOT平台文章目录QT使用MQTT协议对接华为IOT平台一、环境说明二、QMQTT源码编译三、对接华为IoT平台四、效果验证    最近想使用QT通过MQTT协议接入华为的IOT平台,实现数据的上报以及命令的接收,经过查找资料,可以使用QT的MQTT协议来完成这样的功能,下面是此次实验过程中的记录。一、环境说明开发环境:Ubuntu16.04 x64软件:Qt 5.5.1 for Embedded交叉编译工具链:arm-Linux-guneabihf硬件平台:正点

文章目录

  • 一、环境说明
  • 二、QMQTT源码编译
  • 三、对接华为IoT平台
  • 四、效果验证

    最近想使用QT通过MQTT协议接入华为的IOT平台,实现数据的上报以及命令的接收,经过查找资料,可以使用QT的MQTT协议来完成这样的功能,下面是此次实验过程中的记录。

一、环境说明

  1. 开发环境:Ubuntu16.04 x64
  2. 软件:Qt 5.5.1 for Embedded
  3. 交叉编译工具链:arm-Linux-guneabihf
  4. 硬件平台:正点原子ALPHA Linux开发板

二、QMQTT源码编译

    目前Qt5.11中已经提供了类似TCP或者UDP的MQTT类,但是想要在低于此版本的Qt中使用MQTT协议,就需要自行编译开源MQTT消息服务EMQTT为Qt提供的QMQTT源码。下面具体介绍在Ubuntu下使用该源码的方式。

  1. 下载QMQTT源码,在Linux终端中使用git 下载源码
git clone https://github.com/emqtt/qmqtt
  1. 网上有网友将QMQTT的源码编译成了.so或者dll的库文件,我在使用交叉编译工具链编译的时候出现了问题,没有解决,就采用了一位网友简单粗暴的方式,将所有的.cpp和.h文件copy到工程目录下并添加的到工程,编译出来的可执行文件大约7M。打开下载好的文件进入src目录下,将mqtt文件夹复制到工程目录下,并添加到工程中。

  2. QT工程的修改
    (1)pro文件的修改

    (2)在qt直接使用就可以了,包含头文件#include <mqtt/qmqtt.h>

三、对接华为IoT平台

  1. 华为设备接入开发文档

        在MQTT设备快速接入这篇文章中,详细说明了如何通过设备id以及设备密钥生成接入信息的步骤。下面将一步步的演示这些步骤。

  2. 创建产品并注册设备,这里直接借用华为文档中的图片。

  3. 生成连接信息,这部分也是文档中的一部分,点击文档中的 连接信息生成工具 即可下载。

        下载完成后,打开填入自己的设备ID和设备密钥,点击Generate生成,会在Message框中显示需要的 ClientID、username、password。(注:这个工具需要安装JDK,在华为云文档中有链接)。

  4. QT工程中使用,完成上述步骤后,在QT中就可以直接编写一个MQTT Client来实现对接到华为云的功能。
    (1)初始化MQTT
//MqttClient.h
#ifndef MQTTCLIENT_H
#define MQTTCLIENT_H#include <QObject>
#include <macroinclude.h>
#include <mqtt/qmqtt.h>class MqttClient : public QObject
{Q_OBJECT
public:explicit MqttClient(QObject *parent = 0);void mqttInit(QString domainName, quint16 Port);
signals:public slots:void onMQTT_Received(QMQTT::Message message);void connectTOHuaWeiIOT(QString domainName, quint16 Port);void disConnectTOHuaWeiIOT();void MQTT_SendMessage(QMQTT::Message msg);
private:QMQTT::Client mqttclient;
};#endif // MQTTCLIENT_H
//MqttClient.pp
#include "MqttClient.h"MqttClient::MqttClient(QObject *parent) : QObject(parent)
{}
//mqtt 初始化
void MqttClient::mqttInit(QString domainName, quint16 Port)
{QHostInfo info = QHostInfo::fromName(domainName);QString host = info.addresses().first().toString(); // 代理服务器 IPqDebug() << host;//    mqttclient = new QMQTT::Client(QHostAddress(host),Port);mqttclient.setKeepAlive(120);mqttclient.setHost(QHostAddress(host));mqttclient.setPort(Port);mqttclient.setClientId(CLIENTID);mqttclient.setUsername(USERNAME);mqttclient.setPassword(PASSWORD);mqttclient.cleanSession();mqttclient.setVersion(QMQTT::MQTTVersion::V3_1_1); // 设置mqtt版本connect(&mqttclient,SIGNAL(received(QMQTT::Message)),this,SLOT(onMQTT_Received(QMQTT::Message)));
}//链接到华为物联网平台
void MqttClient::connectTOHuaWeiIOT(QString domainName, quint16 Port)
{//初始化 MQTTmqttInit(domainName,Port);mqttclient.connectToHost();qDebug()<<"connect to host success!!";
}//断开与平台的链接
void MqttClient::disConnectTOHuaWeiIOT()
{mqttclient.disconnectFromHost();qDebug()<<"disconnect huaweiIOT!!";
}//接收消息的槽函数
void MqttClient::onMQTT_Received(QMQTT::Message message)
{QString str(message.payload());qDebug()<<"onMQTT_Received: "<<str;QMQTT::Message message();}//发送消息的槽函数
void MqttClient::MQTT_SendMessage(QMQTT::Message msg)
{mqttclient.publish(msg);
}

(2)Widget.cpp中使用,主要是连接按钮和断开连接按钮以及一个发送按钮信号槽的编写,这边直接展示槽函数,信号由Button触发。

//构造函数中
MqttClient *MQTTClient;
MQTTClient = new MqttClient(this);
//连接华为IOT
void Widget::connectToHuaweiIoT_slot(QString domainName,quint16 port)
{MQTTClient->connectTOHuaWeiIOT(domainName,port);
}//断开连接华为Iot
void Widget::disconnectTOHuaweiIoT_slot()
{MQTTClient->disConnectTOHuaWeiIOT();
}
//设备属性上报
connect(ui->toolButton,&QToolButton::clicked,[this](){QString topic = EQUIPMENT_REPORT_TOPIC;qDebug()<<topic;QByteArray array = getEquipmentReportJson();qDebug()<<array;QMQTT::Message msg(0,topic,array);MQTTClient->MQTT_SendMessage(msg);});

    其中在设备属性上报中,EQUIPMENT_REPORT_TOPIC是华为IOT平台提供的一个topic,MQTT实质是一种发布订阅模式,此topic是设备上报属性时用的topic,其他topic在华为设备接入文档API参考中有详细介绍。直接附图。

    根据开发文档给的示例格式,我们需要封装一个这样的JSON数据包,在QT中有相关的JSON类,例如 JSONObject,JSONArray,JSONValue,JSONDocument等等,下面是我封装的一个设备属性上报的JSON数据包,并使用QJSONDocument转换为QByteArray(原因下面介绍)。

#include "JsonUtils.h"//设备属性上报JSON封装
/*{"service_id": "Battery","properties": {"batteryLevel": 80},"event_time": "20201212T121212Z"}
*/
QByteArray getEquipmentReportJson()
{//构建 JSON 对象 propertiesQJsonObject propertiesObj;propertiesObj.insert("batteryLevel",80);//构建 JSON 对象QJsonObject jsonObj;jsonObj.insert("service_id","Battery");jsonObj.insert("event_time",getSystemTime());jsonObj.insert("properties",QJsonValue(propertiesObj));//添加到JSON数组 servicesQJsonArray jsonarray;jsonarray.push_back(jsonObj);//构建 JSON 总体对象QJsonObject json;json.insert("services",QJsonValue(jsonarray));//构建 JSON 文档QJsonDocument document;document.setObject(json);QByteArray byteArray = document.toJson(QJsonDocument::Compact);return byteArray;
}//获取当前系统时间 IOT平台那边接受的是格林威治时间,GMT+8.00
QString getSystemTime()
{QDateTime currentTime = QDateTime::currentDateTime();QString currentTimeStr = currentTime.toString("yyyyMMddThhmmssZ");QTime current_time =QTime::currentTime();int hour_int =  current_time.hour();if(hour_int >= 8) hour_int -= 8;else hour_int = 24 + hour_int - 8;QString hour = QString::number(hour_int);//当前的小时QString result = currentTimeStr.mid(0,9)+hour+currentTimeStr.mid(11);return result;
}

    这边的一个getSystemTime()是本人编写的一个获取系统时间的函数(写的有点复杂,好在能用),由于华为IOT平台那边使用的GMT+8.00,会在我们上报的时间基础上再加上8小时,所以我们上报时,要将上报时间减去八小时。
    通过getEquipmentReportJson()这个函数就输出了我们需要上报的数据,为什么要使用QByteArray这样的数据呢,这个是由QMQTT::Message的构造函数决定。我们上报数据使用的是

quint16 QMQTT::Client::publish(const Message& message);

    而QMQTT::Message的构造函数如下:

//qmqtt_message.cpp
Message::Message(const quint16 id, const QString &topic, const QByteArray &payload,const quint8 qos, const bool retain, const bool dup): d(new MessagePrivate(id, topic, payload, qos, retain, dup))
{
}
//qmqtt_message.h
explicit Message(const quint16 id, const QString &topic, const QByteArray &payload,const quint8 qos = 0, const bool retain = false, const bool dup = false);

    Message的构造函数有六个参数,其中后三个参数都是有默认值的,第一个参数为id,第二个为发布的topic(由物联网平台或者用户自己订阅),第三个是要发送的数据,是一个QByteArray类型,因此就有了通过JSON来生成QByteArray这样的一个步骤。

四、效果验证

    这边可以看到在2020/08/09 23:54:18 GMT+08:00我上报的最新的消息为80.

QT使用MQTT协议对接华为IOT平台相关推荐

  1. 技术实践丨手把手教你使用MQTT方式对接华为IoT平台

    摘要:本文主要讲述使用MQTT方式对接华为云IoT平台的具体过程. 使用的方案:目标板为STM32L431BearPI(带E53扩展板); TCPIP功能由开发板的ESP8266提供:MQTT使用Pa ...

  2. 移远BC20模组使用LwM2M协议接入华为IoT平台(NB-IoT专栏—进阶篇2)

    目录 1.背景 2.部署华为云 3.华为云与BC20模组进行数据收发实验 1.背景 最近在做一个智慧路灯项目,构思使用STM32结合NB-IoT模组实现数据上传和联动控制,并且可以使用GPS模块上传路 ...

  3. .Net Core下使用MQTT协议直连IoT平台

    [摘要] .Net平台通过原生MQTT接口,作为南向设备对接OceanConnect平台 因为种种历史原因吧,目前华为平台上对.net的支持案例SDK确实比较少,当看到各种语言的SDK和Demo,唯独 ...

  4. NB-IoT使用CoAP协议接入华为IoT平台教程

    文章目录 1.准备 1.1.NB-IoT模组 1.2.NB-IoT SIM卡 1.3.IoT平台 2.模块配置与IMEI号的获取 3.设备注册 该文章为本人原创,首发在华为云社区 上一次我们讲了&qu ...

  5. NB-IoT使用CoAP协议接入华为IoT平台(NB-IoT项目实战专栏—8)

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_38106923/article/ ...

  6. 移远BC95使用CoAP协议接入华为IoT平台(NB-IoT专栏—进阶篇1)

    目录 1.华为 NB-IoT CoAP总体方案拓扑 2.华为IoT平台环境搭建 3.NB-IoT上传数据到云平台 BC95的CoAP测试需要云平台配合,当前的支持CoAP协议的平台有华为OceanCo ...

  7. OpenHarmony通过MQTT连接 “改版后的华为IoT平台”

    一.前言 本篇文章我们使用的是BearPi-HM_Nano开发板:小熊派的主板+E53_IA1扩展板 源码用的是D6_iot_cloud_oc,点击下载BearPi-HM_Nano全量源码 那么为什么 ...

  8. 华为IoT平台NB编解码插件开发详细教程【上篇】

    目录 0.前言 一.环境搭建 1.1 安装JDK 1.2 安装eclipse 1.3 安装Maven 二.Profile说明 三.插件编写 3.1 源文件说明 3.2 修改文件路径(包含) 3.3 修 ...

  9. 移远BC28指令对接电信IOT平台基本流程

    目录 概述 一.Coap协议基本流程 1.AT                           //串口波特率自行匹配 1.AT+NRB                 //软重启模组 2.AT+ ...

最新文章

  1. 字节跳动大佬的Python自学笔记.pdf
  2. 如何修剪字符串中的空格?
  3. 一次心血来潮的C程序编译 makefile
  4. 从内存细看static
  5. Linux 文件系统引起的云盘文件系统异常导致 MySQL 数据页损坏事故恢复复盘
  6. Java DatagramSocket(UDP)要注意的问题
  7. With在sql server 2005中的用法
  8. camel 多个 to_具有多个查询参数的Camel CXF服务
  9. 无法获取未定义或 null 引用的属性“text”_【CSS】是时候开始用 CSS 自定义属性了...
  10. php mysql 值是否丰在_php 查询数据库表 判断 某值是否存在
  11. SiamFC++,90 fps的单目标跟踪SOTA
  12. 网站繁简体切换(二)
  13. 与,或,非,异或进行位运算的总结
  14. mac系统linux不能ping外网,Mac上配置Linux网络适配器(NAT模式),无法ping通
  15. Windows 上好用的7款下载工具
  16. 无线投影服务器连接投影仪,无线投屏器怎么与投影机连接
  17. Word使用中常用的快捷键
  18. 制作 macOS Mojave U盘USB启动安装盘方法教程 (全新安装 Mac 系统)
  19. 你所谓的诗和远方,不过是虚荣感作祟
  20. selenium实例登陆拉勾网 外加手动验证验证码

热门文章

  1. 小型超声波风速风向传感器
  2. 随机过程学习笔记1:泊松过程
  3. c# lu分解的代码_矩阵LU分解分块算法实现
  4. 通过Python自动爬取某宝网上的商品信息
  5. 人工智能的数学基础 | AI基础
  6. Unity 之 切换语言导致报错:System.FormatException:String was not recognized as a valid DateTime.
  7. Linux 下面FireFox 看CCTV直播
  8. VC++6.0安装(解决win10,win11无法打开)
  9. leetcode_1579. 保证图可完全遍历
  10. avi文件格式详解(一)