QT使用MQTT协议对接华为IOT平台
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协议来完成这样的功能,下面是此次实验过程中的记录。
一、环境说明
- 开发环境:Ubuntu16.04 x64
- 软件:Qt 5.5.1 for Embedded
- 交叉编译工具链:arm-Linux-guneabihf
- 硬件平台:正点原子ALPHA Linux开发板
二、QMQTT源码编译
目前Qt5.11中已经提供了类似TCP或者UDP的MQTT类,但是想要在低于此版本的Qt中使用MQTT协议,就需要自行编译开源MQTT消息服务EMQTT为Qt提供的QMQTT源码。下面具体介绍在Ubuntu下使用该源码的方式。
- 下载QMQTT源码,在Linux终端中使用git 下载源码
git clone https://github.com/emqtt/qmqtt
- 网上有网友将QMQTT的源码编译成了.so或者dll的库文件,我在使用交叉编译工具链编译的时候出现了问题,没有解决,就采用了一位网友简单粗暴的方式,将所有的.cpp和.h文件copy到工程目录下并添加的到工程,编译出来的可执行文件大约7M。打开下载好的文件进入src目录下,将mqtt文件夹复制到工程目录下,并添加到工程中。
- QT工程的修改
(1)pro文件的修改(2)在qt直接使用就可以了,包含头文件#include <mqtt/qmqtt.h>
三、对接华为IoT平台
- 华为设备接入开发文档
在MQTT设备快速接入这篇文章中,详细说明了如何通过设备id以及设备密钥生成接入信息的步骤。下面将一步步的演示这些步骤。
- 创建产品并注册设备,这里直接借用华为文档中的图片。
- 生成连接信息,这部分也是文档中的一部分,点击文档中的 连接信息生成工具 即可下载。
下载完成后,打开填入自己的设备ID和设备密钥,点击Generate生成,会在Message框中显示需要的
ClientID、username、password
。(注:这个工具需要安装JDK,在华为云文档中有链接)。 - 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平台相关推荐
- 技术实践丨手把手教你使用MQTT方式对接华为IoT平台
摘要:本文主要讲述使用MQTT方式对接华为云IoT平台的具体过程. 使用的方案:目标板为STM32L431BearPI(带E53扩展板); TCPIP功能由开发板的ESP8266提供:MQTT使用Pa ...
- 移远BC20模组使用LwM2M协议接入华为IoT平台(NB-IoT专栏—进阶篇2)
目录 1.背景 2.部署华为云 3.华为云与BC20模组进行数据收发实验 1.背景 最近在做一个智慧路灯项目,构思使用STM32结合NB-IoT模组实现数据上传和联动控制,并且可以使用GPS模块上传路 ...
- .Net Core下使用MQTT协议直连IoT平台
[摘要] .Net平台通过原生MQTT接口,作为南向设备对接OceanConnect平台 因为种种历史原因吧,目前华为平台上对.net的支持案例SDK确实比较少,当看到各种语言的SDK和Demo,唯独 ...
- NB-IoT使用CoAP协议接入华为IoT平台教程
文章目录 1.准备 1.1.NB-IoT模组 1.2.NB-IoT SIM卡 1.3.IoT平台 2.模块配置与IMEI号的获取 3.设备注册 该文章为本人原创,首发在华为云社区 上一次我们讲了&qu ...
- NB-IoT使用CoAP协议接入华为IoT平台(NB-IoT项目实战专栏—8)
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_38106923/article/ ...
- 移远BC95使用CoAP协议接入华为IoT平台(NB-IoT专栏—进阶篇1)
目录 1.华为 NB-IoT CoAP总体方案拓扑 2.华为IoT平台环境搭建 3.NB-IoT上传数据到云平台 BC95的CoAP测试需要云平台配合,当前的支持CoAP协议的平台有华为OceanCo ...
- OpenHarmony通过MQTT连接 “改版后的华为IoT平台”
一.前言 本篇文章我们使用的是BearPi-HM_Nano开发板:小熊派的主板+E53_IA1扩展板 源码用的是D6_iot_cloud_oc,点击下载BearPi-HM_Nano全量源码 那么为什么 ...
- 华为IoT平台NB编解码插件开发详细教程【上篇】
目录 0.前言 一.环境搭建 1.1 安装JDK 1.2 安装eclipse 1.3 安装Maven 二.Profile说明 三.插件编写 3.1 源文件说明 3.2 修改文件路径(包含) 3.3 修 ...
- 移远BC28指令对接电信IOT平台基本流程
目录 概述 一.Coap协议基本流程 1.AT //串口波特率自行匹配 1.AT+NRB //软重启模组 2.AT+ ...
最新文章
- 字节跳动大佬的Python自学笔记.pdf
- 如何修剪字符串中的空格?
- 一次心血来潮的C程序编译 makefile
- 从内存细看static
- Linux 文件系统引起的云盘文件系统异常导致 MySQL 数据页损坏事故恢复复盘
- Java DatagramSocket(UDP)要注意的问题
- With在sql server 2005中的用法
- camel 多个 to_具有多个查询参数的Camel CXF服务
- 无法获取未定义或 null 引用的属性“text”_【CSS】是时候开始用 CSS 自定义属性了...
- php mysql 值是否丰在_php 查询数据库表 判断 某值是否存在
- SiamFC++,90 fps的单目标跟踪SOTA
- 网站繁简体切换(二)
- 与,或,非,异或进行位运算的总结
- mac系统linux不能ping外网,Mac上配置Linux网络适配器(NAT模式),无法ping通
- Windows 上好用的7款下载工具
- 无线投影服务器连接投影仪,无线投屏器怎么与投影机连接
- Word使用中常用的快捷键
- 制作 macOS Mojave U盘USB启动安装盘方法教程 (全新安装 Mac 系统)
- 你所谓的诗和远方,不过是虚荣感作祟
- selenium实例登陆拉勾网 外加手动验证验证码
热门文章
- 小型超声波风速风向传感器
- 随机过程学习笔记1:泊松过程
- c# lu分解的代码_矩阵LU分解分块算法实现
- 通过Python自动爬取某宝网上的商品信息
- 人工智能的数学基础 | AI基础
- Unity 之 切换语言导致报错:System.FormatException:String was not recognized as a valid DateTime.
- Linux 下面FireFox 看CCTV直播
- VC++6.0安装(解决win10,win11无法打开)
- leetcode_1579. 保证图可完全遍历
- avi文件格式详解(一)