NBIOT-北向开发之PC桌面 基于QT 5.9 北向接入华为OceanConnect云平台
该软件与上一章节提供的的平台profile是对应的,如果profile的关键参数不一致,需要同步修改软件代码!
切记!!!
1、软件介绍
通过前面的学习,数据可以上报到华为云平台了,但是我们是通过登陆华为OceanConnect云后台,才看到数据,这样其实是不太友好的,我们更加希望自己编写代码来查阅数据,结合华为发布的API文档,这里我们带领同学们采用QT平台来开发一个简单的PC软件。
这里夸下QT, 一直很喜欢QT的文档说明,例子、函数等说的很清楚,夸平台不用说。如果正在打算学习一款PC开发的平台,QT也是不错的选项
本次用QT实现与华为OceanConnect云平台(以下简称华为云)的对接,主要包括
1、用户根据appid password登陆
2、自动查询当前应用下,所有设备
3、定时向华为云查询数据最新
4、用户可以根据时间段,查询云端的历史数据
2、效果预览
2.1、用户需要登录时输入其appId/password(其值为野牛NBIOT 环境监测项目—华为OceanConnect云平台配置(四))中邮件中的“应用对接信息"按钮。
2.2、登录之后,点击“查询设备”,如果有设备,在下拉框中选择,需要查阅的设备,注意这里显示的为设备名。
2.3、设置更新周期,该周期指的是,软件定时向云端获取数据的周期。默认是5秒请求一次
2.4、可以根据时间段,查询数据
3、预备的关键知识
3.1、需要了解网络编程中客户端通过http协议向服务器请求数据,比如如何向服务器端获取数据,有哪几种方法(POST、GET)、请求头、请求数据域、响应报文等,这里用后面需要用到的《华为IoT平台北向API参考.pdf》中的鉴权给大家举个实际例子:
客户端(也就是我们的电脑/手机/ipad等设备)向服务器发送POST请求,其中server为服务器的IP地址,port为端口号(其具体的值,在实验室申请时,返回的邮件的应用对接信息中),请求的内容如下:
https://server:port/iocm/app/sec/v1.1.0/loginContent-Type:application/x-www-form-urlencodedappId={appId}&secret={secret}
服务器接收到上述请求,正常情况下会做出回应,那么请求的返回数据中有token值,这个在文档中有说明,拿到这个token才能做后续的事情,相对于一个认证,而且这个认证是有有效时间的,返回的内容如下:
Status Code: 200 OKContent-Type: application/json{"scope":"default","tokenType":"bearer","expiresIn":"*******","accessToken":"*******","refreshToken":"*******"}
具体这块东西,同学们还是需要在日常中多学习下,日后的网络交互是必不可少的
3.2、QT中http/https的配置
因为是基于QT的平台做开发做完成https,必定要了解https的初始化流程,这里不再过多介绍,后面章节有直接的源码
3.3、QT的槽函数、信号机制
对于玩过QT的同学,应该问题不大,要是之前没有相关基础,可能需要问下度娘QT槽函数与信号,可以理解为一个事件,当每个信号触发时,调用相应的函数,这个是QT的核心。
4、代码介绍
这个Demo软件,界面上分为两个,一个是登陆、一个是实际用户操作的界面
4.1、登陆界面主要完成,通过用户输入的IP地址、port、appid、password,连接服务器并进行鉴权认证,拿到token,这里主要有个证书双向认证的流程,导入证书、私钥、信用库,其中导入证书的代码如下:
QFile file;QString path = "./certificate/";file.setFileName( path + "cert.pem");file.open(QIODevice::ReadOnly);QSslCertificate local( &file , QSsl::Pem );m_sslConfig.setLocalCertificate( local );file.close();
4.2、通过QT API访问华为云
QT里面使用QNetworkAccessManager对华为云进行访问,QNetworkRequest设置其请求头
QString url = "";QString form = "";QByteArray bytePost;url = QString("https://%1:%2/iocm/app/sec/v1.1.0/login").arg(DC_ucfg.ip).arg(DC_ucfg.port);DC_request.setUrl(QUrl(url));DC_request.setRawHeader("content-type","application/x-www-form-urlencoded"); form = QString("appId=%1&secret=%2").arg(DC_ucfg.appid).arg(DC_ucfg.password);bytePost.append(form); DC_signType = SIGN_TYPE_AUTH;pReply= DC_pManager->post(DC_request, bytePost);
4.3、API接收完成
在上一章节中的网络操作,发送与接收是异步的,当https接收完成或者异常等事件,会调用注册的对应槽函数来处理,具体的连接函数如下,finished信号与用户的onFinished()槽函数连接在一起
connect(DC_pReply , SIGNAL(finished()) , this, SLOT(onFinished()));
所以当HTTPS正常收发完成后,会在onFinished()函数里面进行出处理,这里就可以对接收的数据进行解析,获取到我们想要的数据信息。比如下面客户端发起获取设备信息的请求时,对接收的数据做如下处理(主要还是json数据流的解析):
else if(DC_signType == SIGN_TYPE_GETDEVLIST){QNetworkReply *pReplay = qobject_cast<QNetworkReply*>(sender());QByteArray replyContent = pReplay->readAll();QJsonObject devRootObj;QJsonParseError json_error;QJsonDocument jsonDoc(QJsonDocument::fromJson(replyContent, &json_error));if(json_error.error != QJsonParseError::NoError){qDebug() << "SIGN_TYPE_GETDEVLIST json data is error!";return;}devRootObj = jsonDoc.object();if(devRootObj.contains("devices") && devRootObj.value("devices").isArray()){DC_devRootArray = devRootObj.value("devices").toArray();emit signMsgToMain(SIGN_CODE_GETDEVLIST_SUCCESS);}}
4.4、通知主界面处理
通过QNetworkAccessManager API接口获取到数据,我们要将其显示出来,所以在onFinished()函数的最后发送一个自定义的信号到主界面线程中,代码如下
emit signMsgToMain(SIGN_CODE_GETDEVLIST_SUCCESS);
4.5、主界面根据信号对数据进行图形化
例如:
for(int i = 0; i < g_DC.DC_devRootArray.size();i++){QJsonObject devObj = g_DC.DC_devRootArray.at(i).toObject();QJsonObject devinfoObj = devObj.value("deviceInfo").toObject();QStringdevName = devinfoObj.value("name").toString();ui->comboBox_Dev->addItem(devName); }
有问题可以加入QQ群或者淘宝店铺旺旺联系:
野牛物联网
QQ交流群:897268542
淘宝店铺(点击跳转链接)