使用移动的ONENET实现数据上传与远程控制,数据上传使用MQTT协议(ESP8266),而数据查看和远程控制使用的HTTP(安卓端/QT),效果:
ONENET简单MQTT和HTTP使用
ESP8266通过MQTT上传和订阅数据我就不多赘述了,教程很多,我直接刷的MQTT固件,然后通过AT指令进行MQTT操作的
cpp
void esp_init(){
SendCmd(ATE0,"OK",10); //关闭回显
HAL_Delay(50);
SendCmd(AT,"OK",10);//发送AT指令
HAL_Delay(50);
SendCmd(CWJAP1,"IP",40);//连接WIFI,CWJAP1为连接的WiFi信息
HAL_Delay(50);
SendCmd(MQTTUSERCFG,"OK",10);//设置MQTT信息
HAL_Delay(100);
SendCmd(MQTTCONN,"OK",40);//连接MQTT
HAL_Delay(100);
SendCmd(MQTTSUB,"OK",40);//订阅MQTT
HAL_Delay(100);
}
cpp
#define AT "AT\r\n"
#define ATE0 "ATE0\r\n"
#define CWMODE "AT+CWMODE=1\r\n"
#define RST "AT+RST\r\n"
#define CIFSR "AT+CIFSR\r\n"
#define CWJAP "AT+CWJAP=\"Caneve16spro\",\"123456789\"\r\n"//网络连接信息
#define CWJAP1 "AT+CWJAP=\"CanEve17Pro\",\"12345678\"\r\n"
#define MQTTUSERCFG "AT+MQTTUSERCFG=0,1,\"FARM\",\"xxxxx\",\"version=2018-10-31&res=xxxxx\",0,0,\"\"\r\n" //这个就是MQTT的配置信息,根据自己的填
#define MQTTCONN "AT+MQTTCONN=0,\"mqtts.heclouds.com\",1883,0\r\n"//MQTT服务器
#define MQTTSUB "AT+MQTTSUB=0,\"$sys/xxxxx/FARM/thing/property/set\",1\r\n"//MQTT订阅
#define CIPSTART "AT+CIPSTART=\"TCP\",\"192.168.31.112\",20233\r\n"
#define CIPMODE "AT+CIPMODE=1\r\n"
#define CIPSEND "AT+CIPSEND\r\n"
#define CIPSTATUS "AT+CIPSTATUS\r\n"
#define CIPMODEOFF "AT+CIPMODE=0\r\n"
#define CIPCLOSE "AT+CIPCLOSE\r\n"
设备接入的具体配置详见官网:OneNET - 中国移动物联网开放平台
上传数据
cpp
void pub_dat(){//MQTT发布更新数据
memset(pub_dat_buf,0,sizeof pub_dat_buf);//清空发送数组
memset(topic,0,sizeof topic);
sprintf(pub_dat_buf,"{\"id\": \"123\",\"params\": {\"FAN\": {\"value\": %d},\"TEMP\": { \"value\": %.1f},\"LIGHT\": {\"value\": %d},\"LED\": {\"value\": %d},\"HUM\": {\"value\": %.0f},\"SOIL\": {\"value\": %.0f},\"PRE\": {\"value\": %.0f},\"PUMP\": {\"value\": %d}}}",mq_fan,mq_temp,mq_light,mq_led,humidity,soil_h,pressure,mq_pump);
sprintf(topic,"AT+MQTTPUBRAW=0,\"$sys/xxxxx/FARM/thing/property/post\",%d,0,0\r\n",strlen(pub_dat_buf));
SendCmd(topic,">",50);//发送需要发布的topic以及数据长度
HAL_Delay(50);
esp_send(pub_dat_buf);
}
Android端使用GET获取数据
java
public void Get() {
new Thread(() -> {
//接受温度
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url
("https://iot-api.heclouds.com/thingmodel/query-device-property?product_id=xxxxx&device_name=FARM")
.addHeader("Authorization", "version=2018-10-31&res=products%2Fxxxxx%2Fdevices%2FFARM&et=1736269477&method=md5&sign=fVpjPaZLpv1%2Btl5zcIcC9A%3D%3D").addHeader("Accept",Accept).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
if(!response.isSuccessful()) {
throw new IOException("Unexpected code" +response);
}else {
String responseBody = response.body().string();
Log.e("farm",responseBody);//输出响应内容
try {
JSONArray jsonArray = new JSONArray(responseBody.substring(responseBody.indexOf("["),responseBody.lastIndexOf("]")+1));
StringBuilder str= new StringBuilder("httpclient:\n");
for (int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObject2 = (JSONObject)jsonArray.opt(i);
String temp_id=jsonObject2.has("identifier")?jsonObject2.getString("identifier"):null;
String temp_val=jsonObject2.has("value")? jsonObject2.getString("value"):null;
str.append("第").append(i).append("个:").append(temp_id).append(": ").append(temp_val).append("\n");
check(temp_id,temp_val);
}
Log.e("zms", str.toString());
Calendar calendar = Calendar.getInstance();
str= new StringBuilder(calendar.get(Calendar.MINUTE) + ":" + calendar.get(Calendar.SECOND) + str);
check(String.valueOf(str));
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.e("zms", "err");
e.printStackTrace();
}
}
}
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.e("farm","get fail");
e.printStackTrace();
}
});
}).start();
}
Android端发送控制指令使用的POST
java
//异步post请求
public void Post() {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{" +
" \"product_id\": \"xxxxx\"," +
" \"device_name\": \"FARM\"," +
" \"params\": {" +
" \"LED\": 0" +
" }" +
" }");
Request request = new Request.Builder()
.url("https://iot-api.heclouds.com/thingmodel/set-device-property")
.post(requestBody)
.header("Authorization", "version=2018-10-31&res=products%2Fxxxxx%2Fdevices%2FFARM&et=1772735919&method=md5&sign=QwtaZir04FXz1BeO%2B9FPpQ%3D%3D")
.build();
OkHttpClient okHttpClient=new OkHttpClient();
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("farm","post fail");//输出响应内容
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String str=response.body().string();
//.........
Log.e("farmPOST",str);//输出响应内容
if(str.contains("success")){
check("set ok");
}
}
});
}
QT端和Android操作差不多,也是通过get和post
cpp
void MainWindow::SendGetRequst()
{
mNetworkManager = new QNetworkAccessManager(this);
QNetworkRequest _quest;
QString url = "https://iot-api.heclouds.com/thingmodel/query-device-property?product_id=xxxxx&device_name=FARM";
_quest.setUrl((QUrl(url)));
_quest.setRawHeader("Authorization","version=2018-10-31&res=products%2Fxxxxx%2Fdevices%2FFARM&et=1736269477&method=md5&sign=fVpjPaZLpv1%2Btl5zcIcC9A%3D%3D");
_quest.setRawHeader("Accept","application/json, text/plain, */*");//自定义
mReply = mNetworkManager->get(_quest);
QByteArray _data = mReply->readAll();//读出数据
//QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toUtf8().constData();
qInfo()<<"1_data ==> "<<_data;
//connect(mReply,&QNetworkReply::finished,this,&HttpOperate::ReplyFinshed);//方式一
// auto lambdaFun = [=]{ReplyFinshed();};//lambda函数
// connect(mReply,&QNetworkReply::finished,lambdaFun);//这里的信号的接受者可以省略不写
connect(mReply,&QNetworkReply::finished,[=]{//这里的信号的接受者可以省略不写
ReplyFinshed();
});
qInfo()<<"2_data ==> " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toUtf8().constData();
}
void MainWindow::SendPostRequst(uint8_t flag)//将控制命令发出去 0 led 1 pump 2 fan
{
mNetworkManager = new QNetworkAccessManager(this);
QNetworkRequest _quest;
_quest.setUrl((QUrl("https://iot-api.heclouds.com/thingmodel/set-device-property")));
_quest.setRawHeader("Authorization", "version=2018-10-31&res=products%2Fxxxxx%2Fdevices%2FFARM&et=1772735919&method=md5&sign=QwtaZir04FXz1BeO%2B9FPpQ%3D%3D");
_quest.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
QJsonDocument document;
QJsonObject obj,obj1;
obj.insert("product_id", "xxxxx");
obj.insert("device_name", "FARM");
switch (flag) {
case 0:
obj1.insert("LED",ui->comboBox->currentIndex());
break;
case 1:
obj1.insert("PUMP",ui->checkBox_4->isChecked() ? 1:0);
break;
case 2:
obj1.insert("FAN",ui->checkBox_2->isChecked() ? 1:0);
break;
default:
return;
break;
}
obj.insert("params", obj1);
document.setObject(obj);
QByteArray _postData = document.toJson(QJsonDocument::Compact);//以Json字符串的方式传参
qDebug()<<_postData;
_quest.setAttribute(QNetworkRequest::Http2AllowedAttribute, false);
mReply = mNetworkManager->post(_quest,_postData);
QByteArray _data = mReply->readAll();//读出数据
qDebug()<<"1_data ==> "<<_data;//此s时数据为空
connect(mReply,&QNetworkReply::finished,this,[=]{
ReplyFinshed();
});//方式三
qDebug()<<"2_data ==> ";
}