Files
smartweatherstation_v2.0/src/main.cpp
2024-04-09 10:40:58 +08:00

642 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include"Define.h"
#include <GSMMannager.h>
#include <HTTPClient.h>
#include <ArduinoHttpClient.h>
#include<driver/periph_ctrl.h>
#include "SensorOptoSky.h"
#include <SoftwareSerial.h>
#include <Ticker.h>
#include <updatebyme.h>
//#include "MyWebServer.h"
#include "SDmanger.h"
//#include "HttpsOTAUpdate.h"
#include "slave.h"
#include "log.h"
#include <wifidebug.h>
#define LOGGING
//myPort将原来ESP8266对内通讯改为485对内的通讯
// #define MYPORT_TX 45
// #define MYPORT_RX 46
int hassend = 0;
GSMMannger *gsmmanger;
UpDateClassByme *ProgrameUper;
HttpClient *http;
bool ishttpbusy = false;
SensorOptoSky IS1Sensor;
// SoftwareSerial myPort(MYPORT_RX, MYPORT_TX, false);
// HardwareSerial myPort(1);
// swSer(14, 12, false, 256);
// u_char a[]={0x01,0x04,0x00,0x00,0x00,0x06,0x70,0x08};
u_char ret[17];
u_char windret[17];
Ticker ticker;
slave myslave;
String log_path;
String log_data;
String getnetData()
{
write_log(log_path,100,"http->get11111");
int err = http->get("/weather/php/Date.php");
if (err != 0)
{
SerialMon.println(F("Date failed to connect"));
// delay(10000);
vTaskDelay(10000);
return "";
}
write_log(log_path,100,"http->responseStatusCode222");
int status = http->responseStatusCode();
if (!status)
{
vTaskDelay(10000);
return "";
}
// SerialMon.println(F("Response Headers:"));
write_log(log_path,100,"http->headerAvailable333");
int times_try = 0;
while (http->headerAvailable())
{
if(times_try > 1000)
{
write_log(log_path,100,"http->headerAvailable failed ...");
return "-1";
}
String headerName = http->readHeaderName();
String headerValue = http->readHeaderValue();
// SerialMon.println("Date: " + headerName + " : " + headerValue);
vTaskDelay(100);
times_try++;
}
write_log(log_path,100,"http->isResponseChunked4444");
if (http->isResponseChunked())
{
// SerialMon.println(F("Date The response is chunked"));
}
write_log(log_path,100,"http->responseBody555");
String body = http->responseBody();
http->stop();
return body;
}
bool UpdateData(String path, char *str, size_t lenth, String Contenttype = "")
{
http->beginRequest();
http->post(path);
if (Contenttype != "")
{
http->sendHeader(HTTP_HEADER_CONTENT_TYPE, Contenttype);
/* code */
}
http->sendHeader(HTTP_HEADER_CONTENT_LENGTH, lenth);
http->endRequest();
int err = http->write((const byte *)str, lenth);
delay(1000);
Serial.print("send date size");
Serial.println(err);
/*
for (size_t i = 0; i < lenth; i++)
{
Serial.print("0x");
Serial.print(str[i],HEX);
Serial.print(" ");
if (i%20==0)
{
Serial.println(" ");
}
}
*/
// http->write((const byte*)IS1Sensor.UpData, IS1Sensor.SensorInfo.BandNum*2);
// http->stop();
Serial.println("hear1");
if (err == 0)
{
http->stop();
return false;
}
int status = http->responseStatusCode();
Serial.println("hear3");
if (!status)
{
http->stop();
return false;
}
int length = http->contentLength();
Serial.println("hear4");
if (length == 0)
{
http->stop();
return false;
}
String body = http->responseBody();
Serial.println("body:"+body);
if (body != "ok")
{
http->stop();
return false;
}
http->stop();
return true;
}
void ReuploadData(String path, String webpath, String content = "")
{
vTaskDelay(1);
Vector<String> files;
String vec[20]; //每次处理20个
files.setStorage(vec);
while (!sdcard::ListDir(path.c_str(), files))
{
if (files.size() != 0)
{
Serial.println("find " + String(files.size()) + "file");
for (size_t i = 0; i < files.size(); i++)
{
File nowfile = SD_MMC.open(files.at(i).c_str(), "rb");
size_t size = nowfile.size();
char *arr = new char[size];
nowfile.readBytes(arr, size);
bool flagsucc = UpdateData(webpath, arr, size, content);
if (!flagsucc)
{
return;
/* code */
}
delete[] arr;
sdcard::deleteFolderOrFile(files.at(i).c_str());
vTaskDelay(1);
/* code */
}
}
vTaskDelay(1);
}
if (files.size() != 0)
{
Serial.println("find " + String(files.size()) + "file not enough 20");
for (size_t i = 0; i < files.size(); i++)
{
vTaskDelay(1);
File nowfile = SD_MMC.open(files.at(i).c_str(), "rb");
size_t size = nowfile.size();
char *arr = new char[size];
nowfile.readBytes(arr, size);
Serial.println("run here now");
bool flagsucc = UpdateData(webpath, arr, size, content);
if (!flagsucc)
{
return;
/* code */
}
delete[] arr;
sdcard::deleteFolderOrFile(files.at(i).c_str());
/* code */
}
}
vTaskDelay(1);
}
String fenge(String str, String fen, int index)
{
int weizhi;
String temps[str.length()];
int i = 0;
do
{
weizhi = str.indexOf(fen);
if (weizhi != -1)
{
temps[i] = str.substring(0, weizhi);
str = str.substring(weizhi + fen.length(), str.length());
i++;
}
else
{
if (str.length() > 0)
temps[i] = str;
}
} while (weizhi >= 0);
if (index > i)
return "-1";
return temps[index];
}
void Reuploaddata(void *) //重新上传数据
{
ReuploadData("/down", "/weather/php/SpectralDataUp.php");
ReuploadData("/up", "/weather/php/SpectralDataUp.php");
ReuploadData("/other", "/weather/php/WindsensorUp.php", "application/json");
}
void Reuploaddata() //重新上传数据
{
ReuploadData("/down", "/weather/php/SpectralDataUp.php");
ReuploadData("/up", "/weather/php/SpectralDataUp.php");
ReuploadData("/other", "/weather/php/WindsensorUp.php", "application/json");
}
String Datenow="";
void printbytcp(String str)
{
//tcpserver.SendDataToClinet(str);
Serial.println(str);
str=Datenow+"#######"+str;
int lennn=str.length();
char *temp = new char[lennn];
memcpy(temp, str.c_str(), str.length());
bool flagsucc = UpdateData("/weather/php/log.php", temp, lennn);
vTaskDelay(3000);
delete[] temp;
}
void readmeichaung()
{
/////////////////////////////////now///////////////////////////
double temprature = myslave.getMLX();
Serial.println("wendu");
Serial.println(temprature);
Serial.println("hello word");
////////////////////////////////now////////////////////////////
myslave.getWehter();
memcpy(windret,myslave.ret,17);
float VV = (windret[3] * 256 + windret[4]) * 1.0 / 100;
float DD = (windret[5] * 256 + windret[6]) * 1.0 / 10;
float TT = (windret[7] * 256 + windret[8]) * 1.0 / 100;
float HH = (windret[9] * 256 + windret[10]) * 1.0 / 100;
long PP = (windret[13] * 256 + windret[14]) * 256 * 256 + (windret[11] * 256 + windret[12]);
Serial.println("VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
}
String get_GPS(void)
{
Serial.println("check GPS...");
gsmmanger->modem->sendAT(GF("+CGNSPWR?"));
gsmmanger->modem->waitResponse("OK");
Serial.println("Open GPS...");
gsmmanger->modem->sendAT(GF("+CGNSPWR=1"));
gsmmanger->modem->waitResponse("OK");
gsmmanger->modem->sendAT(GF("+CGNSAID=31,1,1,1"));
gsmmanger->modem->waitResponse("OK");
Serial.println("get GNSS...");
gsmmanger->modem->sendAT(GF("+CGNSINF"));
String gpsbac;
gsmmanger->modem->waitResponse(5000,gpsbac);
// Serial.println(gps);
write_log(log_path,10,"gpsbac is " + gpsbac);
String Date = gpsbac.substring(18,32);
write_log(log_path,10,"get gps data is " + Date);
String temp = Date.substring(0,4) + "-" + Date.substring(4,6) + "-" +Date.substring(6,8) + " " + Date.substring(8,10) + ":" +Date.substring(10,12) + ":" +Date.substring(12,-1);
Date = temp;
write_log(log_path,10,"gps time is" + Date);
if(Date.indexOf(",") != -1)
{
return "-1";
}
Serial.println(gpsbac);
write_log(log_path,10,"gpsdate:"+Date);
return Date;
}
// String get_ti()
// {
// return gsmmanger->modem->getNetworkTime;
// }
void setup()
{
Serial2.begin(115200);
Serial.begin(115200);
sdcard::init_sdcard();
sdcard::testwriet();
sdcard::Mkdir("/up");
sdcard::Mkdir("/down");
sdcard::Mkdir("/other");
sdcard::Mkdir("/gps");
sdcard::Mkdir("/log");
beginWIFI();
// sdcard::mylistDir("/",2);
{
}
// pinMode(21, OUTPUT);
// digitalWrite(21, HIGH);
myslave.init(46,45);
sleep(3);
readmeichaung();
//原来的SIM800改为现在的AIR780E4G模块使用的是串口2。
gsmmanger = new GSMMannger(2, 19, 20);
http = new HttpClient(*gsmmanger->client, "82.156.1.111");
String Date = getnetData();
Serial.println("date is :"+Date);
String tem = fenge(Date," ",0);
log_path = "/log/"+tem+".log";
log_data = Date+"\r\nSystem starts working.";
write_log(log_path,10,"");
write_log(log_path,10,log_data);
write_log(log_path,10,"AIR780E Init Success.");
gsmmanger->modem->sendAT(GF("+CGPIO=1,11,1")); //点灯
gsmmanger->modem->waitResponse("OK");
// while (1)
// {
// Serial.println(gsmmanger->GetDataAndTime());
// delay(1000);
// }
write_log(log_path,10,"GPS Init ....");
for(int a = 0 ; a<100 ;a++)
{
String gpsbac = get_GPS();
if (gpsbac != "-1")
{
Serial.println(gpsbac);
write_log(log_path,10,"GPS Init Success.");
break;
}
vTaskDelay(1000);
}
vTaskDelay(1000);
//////////////////////////////初始化http模块//////////////////////////////////////////////
// http = new HttpClient(*gsmmanger->client, "82.156.1.111");
ProgrameUper = new UpDateClassByme(http);
IS1Sensor.initSensor();
String StationID = IS1Sensor.SensorInfo.serialnumber;
String SensorID = IS1Sensor.SensorInfo.SensorName;
ProgrameUper->initme(Curentvsion);
ProgrameUper->StationID=StationID;
ProgrameUper->CheckAndUpdate();
write_log(log_path,10,"Http Init Success.");
// ProgrameUper->DownloadFirmwareForurl("");
////////////////////////////上传IS1设备信息//////////////////////////////////////////////
//////////////////////////////初始化IS1///////////////////////////////////////////////////
// String Date=getnetData();
String Upheader = StationID + "##" + SensorID + "##" + String(IS1Sensor.SensorInfo.BandNum) + "##"
+ String(IS1Sensor.SensorInfo.a1,9) + ":" + String(IS1Sensor.SensorInfo.a2,9) + ":" + String(IS1Sensor.SensorInfo.a3,9) + ":" + String(IS1Sensor.SensorInfo.a4,9)+"##"+ProgrameUper->CurrentVersion;
http->beginRequest();
http->post("/weather/php/SensorInfoUp.php");
http->sendHeader(HTTP_HEADER_CONTENT_LENGTH, Upheader.length());
http->endRequest();
http->write((const byte *)Upheader.c_str(), Upheader.length());
http->stop();
ticker.attach(60 * 60, Reuploaddata);
write_log(log_path,10,"IS1 Init Success.");
///////////////////////////////////////////////////////////////////////////////////////
log_data = "System Init Success";
write_log(log_path,10,log_data);
// Serial.println(gsmmanger->GetDataAndTime());
}
String lastdate="";
void loop()
{
String Date;
/////////////////NOW/////////////////////
// String tem = fenge(Date," ",0);
// log_path = "/log/"+tem+".txt";
write_log(log_path,10,"");
write_log(log_path,10,Date);
String yuliang = String(myslave.getYuliang());
delay(1010);
Serial.println("yuliang "+yuliang);
write_log(log_path,10,"getYuliang :"+yuliang);
/////////////////NOW/////////////////////
String yuliangfz = String(myslave.getYuliang());
delay(1010);
Serial.println("fuzhao " + yuliangfz);
log_data ="fuzhao :"+yuliangfz;
write_log(log_path,10,log_data);
////////////////////////////NOW///////////////////////////
myslave.getWehter();
memcpy(windret,myslave.ret,17);
float VV = (windret[3] * 256 + windret[4]) * 1.0 / 100;
float DD = (windret[5] * 256 + windret[6]) * 1.0 / 10;
float TT = (windret[7] * 256 + windret[8]) * 1.0 / 100;
float HH = (windret[9] * 256 + windret[10]) * 1.0 / 100;
long PP = (windret[13] * 256 + windret[14]) * 256 * 256 + (windret[11] * 256 + windret[12]);
Serial.println("VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
write_log(log_path,10,"VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
////////////////////////////NOW///////////////////////////
String temprature =String(myslave.getMLX());
Serial.println("wendu");
Serial.println(temprature);
log_data ="wendu :"+temprature;
write_log(log_path,10,log_data);
////sim 循环
write_log(log_path,10,"start gsmmanger->loop()");
gsmmanger->loop();
#ifdef DINBIAO
String Datenow1=getnetData();
Datenow =fenge(Datenow1, " ", 0) + "_" + fenge(fenge(Datenow1, " ", 1), ":", 0) + "_" + fenge(fenge(Datenow1, " ", 1), ":", 1) + "_" + fenge(fenge(Datenow1, " ", 1), ":", 2);
IS1Sensor.PrintFunc=printbytcp;
#endif
write_log(log_path,10,"start TakeOneJob()");
IS1Sensor.TakeOneJob(); ////IS1采集一次
String StationID = IS1Sensor.SensorInfo.serialnumber;
String SensorID = IS1Sensor.SensorInfo.SensorName;
///////////////获取时间
////////通过GPS获取时间如果获取失败就通过4G访问网页获取。如果获取成功那就对GPS数据进行分割解析出时间。
String gpsbac;
for(int i = 0 ;i < 201 ; i++)
{
write_log(log_path,10,"start getnetData()");
Date = getnetData();
if(Date == "-1")
{
write_log(log_path,10,"start get_GPS()");
Date = get_GPS();
if(Date != "-1")
{
if(hassend == 0)
{
gpsbac = StationID+"#"+Date;
int lennn = gpsbac.length();
char *temp = new char[lennn];
memcpy(temp, gpsbac.c_str(), gpsbac.length());
bool flagsucc = UpdateData("/weather/php/StationGPSinfo.php", temp, lennn);
if (!flagsucc)
{
// sdcard::WriteStringToFile(nameoffile, temp, lennn);
}
else{
Serial.println("Finish Put StationGPSinfo Data");
}
delete[] temp;
}
if(hassend >= 0)
{
hassend--;
}
}
}
else
{
break;
}
if (i==200)
{
write_log(log_path,10," get_GPS and getnetData failed,esp_restart");
esp_restart();
}
vTaskDelay(500);
}
write_log(log_path,10,"Date is : "+Date);
// delay(15000);
if (fenge(Date, " ", 0)!=lastdate)
{
lastdate=fenge(Date, " ", 0);
log_path = "/log/"+lastdate+".log";
myslave.claeryuliang();
ProgrameUper->CheckAndUpdate();
}
/////////*获取相关信息*//////////////////////////
String datestring=fenge(Date, " ", 0) + "_" + fenge(fenge(Date, " ", 1), ":", 0) + "_" + fenge(fenge(Date, " ", 1), ":", 1) + "_" + fenge(fenge(Date, " ", 1), ":", 2);
String Upheader = Date + "##" + StationID + "##" + SensorID + "##" + "UP" + "##"+String(IS1Sensor.shutterup)+"##";
String Upname = "/up/" +datestring+ "_" + StationID + "_" + SensorID + "_" + "UP";
String Downheader = Date + "##" + StationID + "##" + SensorID + "##" + "DOWN" + "##"+String(IS1Sensor.shutterdown)+"##";
String Downname = "/down/" + datestring + "_" + StationID + "_" + SensorID + "_" + "DOWN";
String senderID = Date + "##" + StationID + "##" + SensorID + "##" + String(temprature) + "##"+yuliang+"##"+yuliangfz+"##";
String othername = "/other/" +datestring + "_" + StationID + "_" + SensorID + "_" + String(temprature);
// Serial.println(senderID);
// Serial.println( Upheader);
// Serial.println(Upheader.length());
//////////////////////上传up数据//////////////////
write_log(log_path,10,"put up data");
size_t lennn = IS1Sensor.SensorInfo.BandNum * 2 + Upheader.length();
char *temp = new char[IS1Sensor.SensorInfo.BandNum * 2 + Upheader.length()];
memcpy(temp, Upheader.c_str(), Upheader.length());
char *str=(char *)IS1Sensor.UpData;
int lenofis=IS1Sensor.SensorInfo.BandNum * 2 ;
for (size_t i = 0; i < IS1Sensor.SensorInfo.BandNum * 2; i++)
{
//temp[Upheader.length()+i]=str[i];
}
memcpy(temp + Upheader.length(), IS1Sensor.UpData,IS1Sensor.SensorInfo.BandNum * 2);
bool flagsucc = UpdateData("/weather/php/SpectralDataUp.php", temp, lennn);
vTaskDelay(3000);
if (!flagsucc)
{
sdcard::WriteStringToFile(Upname, temp, lennn);
log_data ="Up_data upload failed,save to SD.";
write_log(log_path,10,log_data);
}
else
{
Serial.println("finish Put Up Data");
log_data ="finish Put Up Data.";
write_log(log_path,10,log_data);
}
delete[] temp;
//////////////////////上传Down数据//////////////////
write_log(log_path,10,"put dowm data");
lennn = IS1Sensor.SensorInfo.BandNum * 2 + Downheader.length();
temp = new char[lennn];
memcpy(temp, Downheader.c_str(), Downheader.length());
str=(char *)IS1Sensor.DownData;
lenofis=IS1Sensor.SensorInfo.BandNum * 2 ;
for (size_t i = 0; i < IS1Sensor.SensorInfo.BandNum * 2; i++)
{
// temp[Downheader.length()+i]=str[i];
}
memcpy(temp + Downheader.length(), IS1Sensor.DownData,IS1Sensor.SensorInfo.BandNum * 2);
flagsucc = UpdateData("/weather/php/SpectralDataUp.php", temp, lennn);
vTaskDelay(3000);
if (!flagsucc)
{
sdcard::WriteStringToFile(Downname, temp, lennn);
log_data ="Down_data upload failed,save to SD.";
write_log(log_path,10,log_data);
}else{
Serial.println("finish Put Down Data");
log_data ="finish Put Down Data.";
write_log(log_path,10,log_data);
}
delete[] temp;
//////////////////////上传其他数据//////////////////
lennn = 12 + senderID.length();
temp = new char[lennn];
memcpy(temp, senderID.c_str(), senderID.length());
memcpy(temp + senderID.length(), windret + 3, 12);
flagsucc = UpdateData("/weather/php/WindsensorUp.php", temp, lennn, "application/json");
vTaskDelay(3000);
if (!flagsucc)
{
sdcard::WriteStringToFile(othername, temp, lennn);
log_data ="put Other Data failed,save to SD.";
write_log(log_path,10,log_data);
}else{
Serial.println("finish Put Other Data");
log_data ="finish Put Other Data.";
write_log(log_path,10,log_data);
}
delete[] temp;
//结束并等待一定时间
// http->stop(); delay(100);return;
delay(120000);
#ifdef DINBIAO
abort();
ESP.restart();
#endif
return;
}