万维网网站服务的名称,东平做网站,外贸企业网站建设哪家好,收费企业邮箱哪家好智能家居入门5#xff08;QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派#xff09; 前言一、QT界面设计二、云平台产品创建与连接三、下位机端QT代码总览#xff1a;四、微信小程序端代码总览五、板端测试 前言
前四篇智能家居相关文章都是使用STM32作为主控#xf… 智能家居入门5QT、微信小程序、HTTP协议、ONENET云平台、旭日x3派 前言一、QT界面设计二、云平台产品创建与连接三、下位机端QT代码总览四、微信小程序端代码总览五、板端测试 前言
前四篇智能家居相关文章都是使用STM32作为主控本篇使用旭日x3派作为主控这是一款嵌入式linux开发板运行linux操作系统。本项目在开发板端运行QT使用http协议与onenet云平台通信微信小程序作为移动端可以接收到下位机上传至服务器的数据也可以下发指令到服务器开发板端不断获取指令进而执行指令。界面设置是在QTcreator中进行相较于代码设计来说更简单然后是在电脑虚拟机的ubuntu中进行设计和测试成功之后直接将项目移植到板端即可这里是因为开发板能直接运行qt所以可以直接移植项目如果板端不能直接运行qt的话就参考正点原子的交叉编译最好是使用他官方的开发板。
本文使用的是onenet平台的多协议接入目前对于新用户已经没有这个功能了然后老用户之前没创建产品的话现在也创建不了了所以本篇文章仅给使用多协议接入的小伙伴参考新版onenet的接入也已经实现可以到这篇文章参考。 由于本文的目的主要是在linux下实现双向通信和QT练习所以没有真的连接温湿度传感器等外设。最终现象如下视频所示 本文中开发板端称为下位机微信小程序称为上位机ONENET云平台称为服务器。 环境 ubuntu20.04 QT5 旭日x3派 微信开发者工具 一、QT界面设计
虚拟机端的QT5安装直接网上搜有很多一般用命令行安装比较快。 这里直接使用视频的方式来简单展示搭建的过程主要包括添加资源文件qrc添加qss样式表界面设计等。 视频中用到的qss样式表代码参考如下都给出了注释很好理解 ①QRadiobutton
QRadioButton::indicator{ //设置点击区域的长和宽width:45px;height:30px;
}
QRadioButton::indicator:unchecked{ //设置未点击时的显示图像image: url(:/images/switch_off.png);
}
QRadioButton::indicator:checked{ //设置点击时的显示图像image: url(:/images/switch_on.png);
}②QWidget
QWidget#widget { // #特指某个对象从右上角的类和对象中可以看当前选中的是哪个对象。background-color:rgb(150, 150, 150); //背景颜色background-image: url(:/images/light.png); //背景图片background-repeat: no-repeat; //表示不要应用到子对象上不设置的话开关里面也会添加一张背景图片background-position: top left; //显示到左上角border-radius: 18px; //边框圆角
}视频中用到的图像可以到阿里巴巴矢量图标库中找到下载png图像即可然后最好将图像大小重新设置成60*60不然就有问题 ps这里最后设计成自己喜欢的样子就可以了当然可以不参考我的设计如果只对通信感兴趣的直接往后看就好了本文的重点也是在双向通信上。
二、云平台产品创建与连接
1、云平台产品创建
前言中已经提到了多协议接入的问题这里不再赘述使用最新物联网组件的小伙伴可以评论区讨论我看了官方文档的http接入只看到了数据上传没有看到获取指令或者数据的部分是不是新版的onenet中http不支持双向了呢MQTT协议好像还是和之前差不多的只是不再是以前的三元组了。
2、云平台连接测试 这部分可以直接参考正点原子的视频写一个tcp客户端就可以正常连接云平台了注意连接的ONENET云平台的IP地址是183.230.40.33端口号是80。 建议直接跟着视频写一下TCP客户端程序编写主要是防止后续代码看不懂。
三、下位机端QT代码总览
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindow
#include QRadioButton
#include QDebug
#include QTimer
//日期时间
#include QDateTimeEdit
#include QTimeEdit
#include QDateEdit
//tcp客户端通过http协议连接云服务器
#include QTcpSocket
#include QJsonObject
#include QByteArray
#include QJsonDocument
#include QHostAddress
#include QJsonArray
#include QJsonValueQT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();bool deng_flag 0;int last_mainkongtiaoValue;const char *str[4] {POST /devices/1188390993/datapoints HTTP/1.1,api-key:4T1J3khTpmZO99YYNDHvM5EZiI,Host:api.heclouds.com,};QString getbtnRequest GET /devices/1188390993/datastreams/ HTTP/1.1\r\napi-key:4T1J3khTpmZO99YYNDHvM5EZiI\r\nHost:api.heclouds.com\r\n\r\n ;private:Ui::MainWindow *ui;QDateTimeEdit *dateTimeEdit;QTimer *timer;QTcpSocket *tcpsocket;private slots:void onRadioButtonToggled(bool checked);//五个radiobuttonvoid onRadioButton2Toggled(bool checked);void onRadioButton3Toggled(bool checked);void onRadioButton4Toggled(bool checked);void onRadioButton5Toggled(bool checked);void updateDateTimeEdit();//刷新日期时间上传数据至云服务器void receiveMessage();//tcp相关void mStateChange(QAbstractSocket::SocketState);void on_pushButton_clicked();void on_pushButton_2_clicked();};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include mainwindow.h
#include ui_mainwindow.hMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);//tcp客户端通过http连接云服务器this-setWindowTitle(智能家居);tcpsocket new QTcpSocket(this);connect(tcpsocket, SIGNAL(readyRead()), this, SLOT(receiveMessage()));connect(tcpsocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(mStateChange(QAbstractSocket::SocketState)));connect(ui-pushButton,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked()));connect(ui-pushButton_2,SIGNAL(clicked()),this,SLOT(on_pushButton_2_clicked()));//显示当前的时间和日期dateTimeEdit new QDateTimeEdit(QDateTime::currentDateTime(),this);dateTimeEdit-setGeometry(50,400, 200, 40);timer new QTimer(this);connect(timer, QTimer::timeout, this, MainWindow::updateDateTimeEdit);timer-start(1000);//下面是按钮对应的信号与槽连接connect(ui-radioButton,SIGNAL(toggled(bool)), this, SLOT(onRadioButtonToggled(bool)));connect(ui-radioButton_2,SIGNAL(toggled(bool)), this, SLOT(onRadioButton2Toggled(bool)));connect(ui-radioButton_3,SIGNAL(toggled(bool)), this, SLOT(onRadioButton3Toggled(bool)));connect(ui-radioButton_4,SIGNAL(toggled(bool)), this, SLOT(onRadioButton4Toggled(bool)));connect(ui-radioButton_5,SIGNAL(toggled(bool)), this, SLOT(onRadioButton5Toggled(bool)));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::receiveMessage()
{QString response tcpsocket-readAll();qDebug() 接收到服务器下发消息 endl;// 提取 JSON 部分int jsonStartIndex response.indexOf({);QString jsonString response.mid(jsonStartIndex);// 解析 JSONQJsonDocument jsonResponse QJsonDocument::fromJson(jsonString.toUtf8());QJsonObject jsonObject jsonResponse.object();QJsonArray dataArray jsonObject[data].toArray();for (const QJsonValue value : dataArray){QJsonObject obj value.toObject();if (obj[id].toString() led_ctl){int ledCtlValue obj[current_value].toInt();//qDebug() LED Control Value: ledCtlValue;// 可以在这里处理 ledCtlValue如更新 UI 显示if(ledCtlValue 0){ui-textBrowser-append(手机控制关闭客厅灯);ui-radioButton-setText(客厅灯|离线);ui-radioButton-setChecked(0);}else if(ledCtlValue 1){ui-textBrowser-append(手机控制打开客厅灯);ui-radioButton-setText(客厅灯|在线);ui-radioButton-setChecked(1);}}else if (obj[id].toString() mainroom_kongtiao){int mainkongtiaoValue obj[current_value].toInt();bool ischecked ui-radioButton_3-isChecked();if((ischecked 1) (mainkongtiaoValue 0)){ui-textBrowser-append(手机控制关闭主卧空调);ui-radioButton_3-setText(空调|离线);ui-radioButton_3-setChecked(0);}else if((ischecked 0) (mainkongtiaoValue 1)){ui-textBrowser-append(手机控制打开主卧空调);ui-radioButton_3-setText(空调|在线);ui-radioButton_3-setChecked(1);}}}
}void MainWindow::mStateChange(QAbstractSocket::SocketState state)
{switch (state) {case QAbstractSocket::UnconnectedState:ui-textBrowser-append(因某种原因与服务端连接断开尝试重连);qDebug() 因某种原因与服务端连接断开尝试重连 endl;tcpsocket-connectToHost(QHostAddress(183.230.40.33),80);ui-pushButton-setEnabled(true);ui-pushButton_2-setEnabled(false);break;case QAbstractSocket::ConnectedState:qDebug() 已连接服务器 endl;ui-textBrowser-append(已连接服务端);ui-pushButton-setEnabled(false);ui-pushButton_2-setEnabled(true);break;default:break;}
}//开启关闭客厅灯
void MainWindow::onRadioButtonToggled(bool checked)
{if (checked) {ui-radioButton-setText(客厅灯|在线);//deng_flag 1;qDebug() 客厅灯打开 endl;} else {ui-radioButton-setText(客厅灯|离线);//deng_flag 0;qDebug() 客厅灯关闭 endl;}
}//场景选择居家
void MainWindow::onRadioButton2Toggled(bool checked)
{if (checked) {qDebug() 居家模式已打开 endl;} else {qDebug() 居家模式已关闭 endl;}
}//开启关闭主卧空调
void MainWindow::onRadioButton3Toggled(bool checked)
{if (checked) {ui-radioButton_3-setText(空调|在线);qDebug() 主卧空调打开 endl;} else {ui-radioButton_3-setText(空调|离线);qDebug() 主卧空调关闭 endl;}
}//场景选择暂时出门
void MainWindow::onRadioButton4Toggled(bool checked)
{if (checked) {//ui-radioButton_3-setForegroundRole();qDebug() 暂时出门模式已打开 endl;} else {//ui-radioButton_3-setText(空调|离线);qDebug() 暂时出门模式已关闭 endl;}
}//场景选择出远门
void MainWindow::onRadioButton5Toggled(bool checked)
{if (checked) {qDebug() 出远门模式已打开 endl;} else {qDebug() 出远门模式已关闭 endl;}
}void MainWindow::on_pushButton_clicked()
{tcpsocket-connectToHost(QHostAddress(183.230.40.33),80);
}void MainWindow::on_pushButton_2_clicked()
{tcpsocket-disconnectFromHost();
}//定时器刷新时间、上传数据至服务器、刷新本地显示数据
void MainWindow::updateDateTimeEdit() {static int flag 0;dateTimeEdit-setDateTime(QDateTime::currentDateTime());//请求设备数据这里会读回来所有的数据比如温适度和数据流模板QByteArray getbtnRequestBytes getbtnRequest.toUtf8();if(tcpsocket-state() QAbstractSocket::ConnectedState) {tcpsocket-write(getbtnRequestBytes);//qDebug() 请求已发送 endl;;} else {ui-textBrowser-append(请先连接服务端);//qDebug() 请先连接服务器 endl;;}if(flag 10){ui-label_6-setText(14度);ui-label_8-setText(70);ui-label_10-setText(9.7 ppm);QJsonObject postData;postData[temp] 14;postData[humi] 70;QJsonDocument jsonDoc(postData);QByteArray jsonData jsonDoc.toJson(QJsonDocument::Compact);// 计算请求体的长度int contentLength jsonData.size();// 构建HTTP请求QString httpRequestString POST /devices/1188390993/datapoints?type3 HTTP/1.1\r\napi-key:4T1J3khTpmZO99YYNDHvM5EZiI\r\n // 请注意api-key的值需要是您的实际API密钥Host: api.heclouds.com\r\nContent-Length: QString::number(contentLength) \r\n // 设置正确的内容长度\r\n // 请求头和请求体之间的空行 QString(jsonData) // 添加JSON请求体;QByteArray httpRequest(httpRequestString.toUtf8());if(tcpsocket-state() QAbstractSocket::ConnectedState) {tcpsocket-write(httpRequest);qDebug() 请求已发送 endl;} else {ui-textBrowser-append(请先连接服务端);//qDebug() 请先连接服务器 endl;;}flag 0;}flag;
}
只要简单学过QT上述的代码都能看懂并不是直接复制就能用如果自己画的ui界面和我的不一样那就要改代码有兴趣的可以私聊拿原项目。
四、微信小程序端代码总览
有用的目录格式如下 各部分的代码如下注意只测试了温度和湿度其他的想加很简单(微信小程序直接使用的b站up的代码彼岸有光我们有船) index.js:
Page({data: {temp:0},// 事件处理函数getinfo(){var that thiswx.request({url: https://api.heclouds.com/devices/1188390993/datapoints, //将请求行中的数字换成自己的设备IDheader: {api-key: 4T1J3khTpmZO99YYNDHvM5EZiI},method: GET,success: function (e) {console.log(获取成功,e)that.setData({temp:e.data.data.datastreams[0].datapoints[0].value,humi:e.data.data.datastreams[2].datapoints[0].value,})console.log(temp,that.data.temp),console.log(humi,that.data.humi)}});},kai:function(){let data{datastreams: [ {id: led_ctl,datapoints:[{value: 1}]},//led是数据流的名称value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:https://api.heclouds.com/devices/1188390993/datapoints,header: {content-type: application/json,api-key:4T1J3khTpmZO99YYNDHvM5EZiI},method: POST,data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log(成功,res.data)},fail(res){console.log(失败,res)}})
},guan:function(){let data{datastreams: [ {id: led_ctl,datapoints:[{value: 0}]},//led是数据流的名称value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:https://api.heclouds.com/devices/1188390993/datapoints,header: {content-type: application/json,api-key:4T1J3khTpmZO99YYNDHvM5EZiI},method: POST,data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log(成功,res.data)},fail(res){console.log(失败,res)}})
},kaikong:function(){let data{datastreams: [ {id: mainroom_kongtiao,datapoints:[{value: 1}]},//led是数据流的名称value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:https://api.heclouds.com/devices/1188390993/datapoints,header: {content-type: application/json,api-key:4T1J3khTpmZO99YYNDHvM5EZiI},method: POST,data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log(成功,res.data)},fail(res){console.log(失败,res)}})
},guankong:function(){let data{datastreams: [ {id: mainroom_kongtiao,datapoints:[{value: 0}]},//led是数据流的名称value是要传上去的数值] }//按钮发送命令控制硬件wx.request({url:https://api.heclouds.com/devices/1188390993/datapoints,header: {content-type: application/json,api-key:4T1J3khTpmZO99YYNDHvM5EZiI},method: POST,data: JSON.stringify(data),//data数据转换成JSON格式success(res){console.log(成功,res.data)},fail(res){console.log(失败,res)}})
},onLoad() {var that thissetInterval(function(){that.getinfo()},5000)}})index.wxml:
view classuserinfoimage classimg src../images/温度 .png/imagetext温度:{{temp}}℃/text
/viewview classuserinfoimage classimg src../images/湿度.png/imagetext湿度:{{humi}}%/text
/viewview classuserinfoimage classimg src../images/甲烷.png/imagetext天然气:{{gas_ch4}}PPM/text
/viewview classuserinfoimage classimg src../images/可燃气体.png/imagetext可燃气体:{{ranqi}}PPM/text
/viewbutton typeprimary stylemargin-top: 20px; bindtapkai开灯/button
button typewarn bindtapguan关灯/buttonbutton typeprimary stylemargin-top: 20px; bindtapkaikong开主卧空调/button
button typewarn bindtapguankong关主卧空调/button
index.wxss:
/**index.wxss**/
.userinfo {display: flex;flex-direction: column;align-items: center;color: rgb(141, 10, 10);font-size: 15px;
}.img {width: 100rpx;height: 100rpx;
}.usermotto {margin-top: 200px;
}index.json:
{usingComponents: {}
}也是非常简单比起qt还要更简单简单看看就能看懂。愉快的测试即可。
五、板端测试
虚拟机端代码跑通之后其实就可以到板子上跑了。直接远程登录开发板然后安装QT5
sudo apt-get install qt5-default qt5-qmake qtcreator随后将项目拷贝至任意目录下打开qtcreator然后打开项目即可运行。 文章转载自: http://www.morning.ptxwg.cn.gov.cn.ptxwg.cn http://www.morning.fgsct.cn.gov.cn.fgsct.cn http://www.morning.zqcsj.cn.gov.cn.zqcsj.cn http://www.morning.btlmb.cn.gov.cn.btlmb.cn http://www.morning.ynstj.cn.gov.cn.ynstj.cn http://www.morning.jfmyt.cn.gov.cn.jfmyt.cn http://www.morning.kyzxh.cn.gov.cn.kyzxh.cn http://www.morning.bmbnc.cn.gov.cn.bmbnc.cn http://www.morning.jkwwm.cn.gov.cn.jkwwm.cn http://www.morning.psxcr.cn.gov.cn.psxcr.cn http://www.morning.djpzg.cn.gov.cn.djpzg.cn http://www.morning.xdfkrd.cn.gov.cn.xdfkrd.cn http://www.morning.hxhrg.cn.gov.cn.hxhrg.cn http://www.morning.zrlwl.cn.gov.cn.zrlwl.cn http://www.morning.lyjwb.cn.gov.cn.lyjwb.cn http://www.morning.xhxsr.cn.gov.cn.xhxsr.cn http://www.morning.jnhhc.cn.gov.cn.jnhhc.cn http://www.morning.cfnsn.cn.gov.cn.cfnsn.cn http://www.morning.rpwck.cn.gov.cn.rpwck.cn http://www.morning.rhfh.cn.gov.cn.rhfh.cn http://www.morning.gpnwq.cn.gov.cn.gpnwq.cn http://www.morning.cpktd.cn.gov.cn.cpktd.cn http://www.morning.gnzsd.cn.gov.cn.gnzsd.cn http://www.morning.xpqsk.cn.gov.cn.xpqsk.cn http://www.morning.jfjfk.cn.gov.cn.jfjfk.cn http://www.morning.wlqll.cn.gov.cn.wlqll.cn http://www.morning.mftdq.cn.gov.cn.mftdq.cn http://www.morning.mlnzx.cn.gov.cn.mlnzx.cn http://www.morning.skpdg.cn.gov.cn.skpdg.cn http://www.morning.stbhn.cn.gov.cn.stbhn.cn http://www.morning.lgnbr.cn.gov.cn.lgnbr.cn http://www.morning.rmpkn.cn.gov.cn.rmpkn.cn http://www.morning.dyxzn.cn.gov.cn.dyxzn.cn http://www.morning.jwcmq.cn.gov.cn.jwcmq.cn http://www.morning.xcxj.cn.gov.cn.xcxj.cn http://www.morning.gbcnz.cn.gov.cn.gbcnz.cn http://www.morning.rqbkc.cn.gov.cn.rqbkc.cn http://www.morning.rcqyk.cn.gov.cn.rcqyk.cn http://www.morning.rcklc.cn.gov.cn.rcklc.cn http://www.morning.wwwghs.com.gov.cn.wwwghs.com http://www.morning.kdbcx.cn.gov.cn.kdbcx.cn http://www.morning.qbwmz.cn.gov.cn.qbwmz.cn http://www.morning.sbpt.cn.gov.cn.sbpt.cn http://www.morning.ptslx.cn.gov.cn.ptslx.cn http://www.morning.rzdzb.cn.gov.cn.rzdzb.cn http://www.morning.dkbgg.cn.gov.cn.dkbgg.cn http://www.morning.wnywk.cn.gov.cn.wnywk.cn http://www.morning.lgmty.cn.gov.cn.lgmty.cn http://www.morning.rjqtq.cn.gov.cn.rjqtq.cn http://www.morning.csjps.cn.gov.cn.csjps.cn http://www.morning.wmfr.cn.gov.cn.wmfr.cn http://www.morning.mnbgx.cn.gov.cn.mnbgx.cn http://www.morning.trffl.cn.gov.cn.trffl.cn http://www.morning.jgnst.cn.gov.cn.jgnst.cn http://www.morning.hhnhb.cn.gov.cn.hhnhb.cn http://www.morning.dkgtr.cn.gov.cn.dkgtr.cn http://www.morning.kmqlf.cn.gov.cn.kmqlf.cn http://www.morning.mzcrs.cn.gov.cn.mzcrs.cn http://www.morning.kycwt.cn.gov.cn.kycwt.cn http://www.morning.zydr.cn.gov.cn.zydr.cn http://www.morning.xshkh.cn.gov.cn.xshkh.cn http://www.morning.pjxlg.cn.gov.cn.pjxlg.cn http://www.morning.lwbhw.cn.gov.cn.lwbhw.cn http://www.morning.zlhbg.cn.gov.cn.zlhbg.cn http://www.morning.wngpq.cn.gov.cn.wngpq.cn http://www.morning.ctqbc.cn.gov.cn.ctqbc.cn http://www.morning.glnfn.cn.gov.cn.glnfn.cn http://www.morning.qmbpy.cn.gov.cn.qmbpy.cn http://www.morning.zfxrx.cn.gov.cn.zfxrx.cn http://www.morning.tnbsh.cn.gov.cn.tnbsh.cn http://www.morning.lmpfk.cn.gov.cn.lmpfk.cn http://www.morning.zdbfl.cn.gov.cn.zdbfl.cn http://www.morning.kqbzy.cn.gov.cn.kqbzy.cn http://www.morning.xsfg.cn.gov.cn.xsfg.cn http://www.morning.pxbrg.cn.gov.cn.pxbrg.cn http://www.morning.ghjln.cn.gov.cn.ghjln.cn http://www.morning.cbnxq.cn.gov.cn.cbnxq.cn http://www.morning.qtnmp.cn.gov.cn.qtnmp.cn http://www.morning.nxzsd.cn.gov.cn.nxzsd.cn http://www.morning.skdrp.cn.gov.cn.skdrp.cn