From 149637d97a23d6d2a2d8227aa030b33159a19760 Mon Sep 17 00:00:00 2001 From: zhangsheng Date: Sat, 15 Feb 2025 18:49:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BB=88=E7=AB=AF=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/SH_CommonFunc.cpp | 81 ++++++ common/SH_CommonFunc.hpp | 2 + common/SH_global.h | 2 +- dbaccess/SH_SqlDB.cpp | 278 ++++++++++---------- jsonparse/SH_JsonCmd.hpp | 9 + jsonparse/cmt_parse.cpp | 460 +++++++++++++++++++++++++++++++++ localserver/SH_LocalServer.hpp | 19 ++ localserver/cmt_cmd.cpp | 90 +++++++ localserver/cmt_server.cpp | 93 +++++++ localserver/cmt_server.hpp | 263 +++++++++++++++++++ main.cpp | 5 +- platform/SH_PlatformInit.cpp | 2 +- threadfunc/SH_ThreadFunc.cpp | 10 +- threadfunc/SH_ThreadFunc.hpp | 1 + uart/SH_Uart.cpp | 46 ++-- 15 files changed, 1200 insertions(+), 161 deletions(-) create mode 100644 jsonparse/cmt_parse.cpp create mode 100644 localserver/cmt_cmd.cpp create mode 100644 localserver/cmt_server.cpp create mode 100644 localserver/cmt_server.hpp diff --git a/common/SH_CommonFunc.cpp b/common/SH_CommonFunc.cpp index 038c6ff..4267c4b 100644 --- a/common/SH_CommonFunc.cpp +++ b/common/SH_CommonFunc.cpp @@ -1408,6 +1408,64 @@ int getSysIntValue(char *key) fclose(fp);fp = NULL; return value; } +void GetSysStatusCMT(int& cpu_use,int& mem_use,int& disk_remain,int& cpu_temp) +{ + long mem_used = -1; + long mem_free = -1; + long mem_total = -1; + long mem_cached = -1; + char name1[20]; + std::string strMemTotal = GetFileContent("/proc/meminfo", 1); + std::string strMemFree = GetFileContent("/proc/meminfo", 2); + std::string strMemCache = GetFileContent("/proc/meminfo", 5); + + sscanf(strMemTotal.c_str(), "%s%ld", name1, &mem_total); + sscanf(strMemFree.c_str(), "%s%ld", name1, &mem_free); + sscanf(strMemCache.c_str(), "%s%ld", name1, &mem_cached); + mem_used = mem_total - mem_free; + float fMemRate = 1.0 * mem_used / mem_total; + + char name[8]; + double cpu_user = -1; + double cpu_total = -1; + long int user, nice, sys, idle, iowait, irq, softirq; + std::string strCpu1 = GetFileContent("/proc/stat", 1); + sscanf(strCpu1.c_str(), "%s%ld%ld%ld%ld%ld%ld%ld", name, &user, &nice, &sys, &idle, &iowait, &irq, &softirq); + sleep(1); + long int userNext, niceNext, sysNext, idleNext, iowaitNext, irqNext, softirqNext; + std::string strCpu2 = GetFileContent("/proc/stat", 1); + sscanf(strCpu2.c_str(), "%s%ld%ld%ld%ld%ld%ld%ld", name, &userNext, &niceNext, &sysNext, &idleNext, &iowaitNext, &irqNext, &softirqNext); + cpu_total = (userNext + niceNext + sysNext + idleNext + iowaitNext + irqNext + softirqNext) - (user + nice + sys + idle + iowait + irq + softirq); + cpu_user = userNext - user; + float rateUser = cpu_user * 100.0 / cpu_total; + if (rateUser > 95) { + rateUser = 92; + } + char hardTotal[32]; + char hardFree[32]; + char rateHardUse[32]; + char chRes[100]; + memset(chRes, 0, 100); + + char hardName[32]; + char hardUse[32]; + const char *getEmmcInfo = "df -h | grep /opt"; + system_custom(getEmmcInfo, chRes); + sscanf(chRes, "%s%s%s%s%s", hardName, hardTotal, hardUse, hardFree, rateHardUse); + + std::string strhardTotal(hardTotal); + std::string strhardFree(hardFree); + std::string strrateHardUse(rateHardUse); + + char key[128] = {0}; + memset(key, 0, sizeof(key)); + sprintf(key, "/sys/class/thermal/thermal_zone0/temp"); + int temp = getSysIntValue(key); + cpu_use = rateUser; + mem_use = fMemRate * 100; + disk_remain = atoi(strhardFree.substr(0, strhardFree.length() - 1).c_str()); + cpu_temp = temp / 1000.0; +} std::string GetSysStatus() { long mem_used = -1; @@ -2565,7 +2623,30 @@ void Binary_Bit(unsigned char* p_data, unsigned char position, int flag) *p_data &= ~(0x01 << (position)); } } +std::string get_file_md5(const std::string& file_path) { + // 使用 md5sum 命令计算文件的 MD5 值 + std::string command = "md5sum " + file_path + " | awk '{ print $1 }'"; + // 使用 popen 执行命令并获取输出 + std::array buffer; + std::string result; + std::shared_ptr pipe(popen(command.c_str(), "r"), pclose); + + if (!pipe) { + std::cerr << "Error: Unable to run md5sum command" << std::endl; + return ""; + } + + // 从命令的输出流中读取数据 + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + + // 去除末尾的换行符 + result.erase(result.find_last_not_of("\n") + 1); + + return result; +} static const char* JSON_FIELD_CMD = "cmd";//协议: 命令字段 static const char* JSON_FIELD_NAME = "dataWatchName";//协议: 终端名称 static const char* JSON_FIELD_dataNodeGatewayNo = "dataNodeGatewayNo"; diff --git a/common/SH_CommonFunc.hpp b/common/SH_CommonFunc.hpp index a6366ba..cc34f75 100644 --- a/common/SH_CommonFunc.hpp +++ b/common/SH_CommonFunc.hpp @@ -794,6 +794,7 @@ extern void ZoneConfig(std::string zoneid); * @return std::string CPU MEM DISK info */ extern std::string GetSysStatus(); +void GetSysStatusCMT(int& cpu_use,int& mem_use,int& disk_remain,int& cpu_temp); double GetHardDiskFree(); extern bool CheckIP(const char *ip); @@ -838,5 +839,6 @@ extern int Ping( const char *ips, int timeout); extern int get_netlink_status(const char *if_name); extern int compareVersions(const std::string& version1, const std::string& version2); extern void Binary_Bit(unsigned char* p_data, unsigned char position, int flag); +std::string get_file_md5(const std::string& file_path); extern Mutex g_tDbMutex; #endif diff --git a/common/SH_global.h b/common/SH_global.h index 614818d..f8c818c 100644 --- a/common/SH_global.h +++ b/common/SH_global.h @@ -21,7 +21,7 @@ enum enumZigBeeTransmitStatus { //#define NR5G_MODULE -//#define Q4G_MODULE +#define Q4G_MODULE //#define WIFI_MODULE //#define NR5G_MEIGE //#define G2UL_GATEWAY diff --git a/dbaccess/SH_SqlDB.cpp b/dbaccess/SH_SqlDB.cpp index fd5b31b..d234ecd 100644 --- a/dbaccess/SH_SqlDB.cpp +++ b/dbaccess/SH_SqlDB.cpp @@ -857,143 +857,155 @@ int SqliteDB::InsertData(const char* insertSql) } int SqliteDB::CalculateBattery() { - LOG_INFO("CalculateBattery start\n"); - char whereCon[1024] = {0}; - char selectSql[1024] = { 0 }; - memset(whereCon,0x00,sizeof(whereCon)); - memset(selectSql,0x00,sizeof(selectSql)); - char updateSql[1024] = { 0 }; - sprintf(selectSql," dataNodeNo,StaticTime,WaveTime,featureInterVal,waveInterVal,samplingRate,batteryPower "); - array_t vecRes = GetDataMultiLine(T_SENSOR_INFO(TNAME), selectSql, NULL); - print_info("res = %d\n",vecRes.size()); - if(vecRes.size() > 0){ - for(int i = 0; i < vecRes.size(); i++){ - float capacity = 0.0,startCapacity = 0.0; - memset(whereCon,0x00,sizeof(whereCon)); - memset(selectSql,0x00,sizeof(selectSql)); - sprintf(whereCon," dataNodeNo = '%s' and batteryRemain <> '' order by timeStamp desc limit 0,1 ",vecRes[i][0].c_str()); - vec_t vecResSig = sql_ctl->GetDataSingleLine(T_BATTERY_INFO(TNAME)," * ",whereCon); - vector vParam; - boost::split( vParam, vecRes[i][6], boost::is_any_of( "," ), boost::token_compress_on ); - if(vParam.size() <= 0 || vecResSig.size() <= 0){//第一次计算 - memset(whereCon,0x00,sizeof(whereCon)); - sprintf(whereCon,"dataNodeNo = '%s' ",vecRes[i][0].c_str()); - string Dip = sql_ctl->GetData(T_DATASTATIC_INFO(TNAME)," dip ",whereCon); - if(Dip == ""){ - continue; - } - capacity = (0.9+0.1*(90-atoi(Dip.c_str()))/90)*19000;//mAh //电池总量 - startCapacity = capacity; + LOG_INFO( "CalculateBattery start\n"); + char whereCon[1024] = {0}; + char selectSql[1024] = {0}; + memset(whereCon, 0x00, sizeof(whereCon)); + memset(selectSql, 0x00, sizeof(selectSql)); + char updateSql[1024] = {0}; + int res = 0; + sprintf(selectSql, " MeasurementID,StaticTime,WaveTime,featureInterVal,waveInterVal,samplingRate,batteryPower "); + array_t vecRes = GetDataMultiLine(T_SENSOR_INFO(TNAME), selectSql, NULL); + LOG_INFO( "Size = %d\n", vecRes.size()); + if (vecRes.size() > 0) { + for (size_t i = 0; i < vecRes.size(); i++) { + float capacity = 0.0, startCapacity = 0.0; + memset(whereCon, 0x00, sizeof(whereCon)); + memset(selectSql, 0x00, sizeof(selectSql)); + sprintf(whereCon, " dataNodeNo = '%s' and batteryRemain <> '' order by timeStamp desc limit 0,1 ", vecRes[i][0].c_str()); + vec_t vecResSig = GetDataSingleLine(T_BATTERY_INFO(TNAME), " * ", whereCon); + std::vector vParam; + boost::split(vParam, vecRes[i][6], boost::is_any_of(","), boost::token_compress_on); + if (vParam.size() <= 0 || vecResSig.size() <= 0) { // 第一次计算 + memset(whereCon, 0x00, sizeof(whereCon)); + sprintf(whereCon, "dataNodeNo = '%s' ", vecRes[i][0].c_str()); + std::string Dip = GetData(T_DATASTATIC_INFO(TNAME), " dip ", whereCon); + if (Dip == "") { + continue; + } + capacity = (0.9 + 0.1 * (90 - atoi(Dip.c_str())) / 90) * 19000; // mAh 电池总量 + startCapacity = capacity; - sprintf(updateSql,"batteryPower = '%f,%f' ",startCapacity,startCapacity); - - int iRet = UpdateTableData(T_SENSOR_INFO(TNAME), updateSql, whereCon); - memset(whereCon,0x00,sizeof(whereCon)); - sprintf(whereCon," dataNodeNo = '%s' order by timeStamp asc limit 0,1 ",vecRes[i][0].c_str()); - vecResSig = sql_ctl->GetDataSingleLine(T_BATTERY_INFO(TNAME)," * ",whereCon); - if(vecResSig.size() <= 0){//一条数据都没有 - - continue; - } - - }else{ - capacity = atof(vecResSig[7].c_str()); - } - - print_info("dip = %d\n",atoi(vecResSig[1].c_str())); - - print_info("capacity = %f\n",capacity); - sprintf(whereCon," dataNodeNo = '%s' and timeStamp > '%s'",vecRes[i][0].c_str(),vecResSig[8].c_str()); - array_t vecResbattery = GetDataMultiLine(T_BATTERY_INFO(TNAME), " * ", whereCon); - print_info("vecResbattery size = %d\n",vecResbattery.size()); - if(vecResbattery.size() <= 0){ - continue; - } - int y10_mins = 10 * 365 * 24 * 60; - int d200_mins = 200 * 24 * 60; - int x1 = 25,x2 = 60; - int y1 = 2; - float y2 = (float)y10_mins/(float)d200_mins; - - float k = (y2-y1)/(x2-x1); - vector vecb; - vector vecworkTime; - vector vecsendTime; - float to_math = 0.0; - print_info("vecResbattery = %d,temp = %s\n",vecResbattery.size(),vecResbattery[0][2].c_str()); - //LOG_INFO("vecResbattery = %d,temp = %s\n",vecResbattery.size(),vecResbattery[0][2].c_str()); - for (size_t j = 0; j < vecResbattery.size(); j++) - { - float b = 2 - 25 * k; - float dpm = k * atoi(vecResbattery[j][2].c_str()) + b;//温度 - float cost_e = dpm * atoi(vecRes[i][3].c_str());//特征值时间间隔 - float cost_h = cost_e / 60; - vecworkTime.push_back(atol(vecResbattery[j][3].c_str())); - vecsendTime.push_back(atol(vecResbattery[j][4].c_str())); - to_math += cost_h; - } - - print_info("自放电 = %f\n",to_math); - //LOG_INFO("自放电 = %f\n",to_math); - long sumworkTime = 0.0,sumsendTime = 0.0; - for(size_t j = 0 ; j < vecworkTime.size();j++) - { - sumworkTime += vecworkTime[j]; - } - for(size_t j = 0 ; j < vecsendTime.size();j++) - { - sumsendTime += vecsendTime[j]; - } - print_info("sumworkTime = %ld,sumsendTime = %ld\n",sumworkTime,sumsendTime); - //LOG_INFO("sumworkTime = %ld,sumsendTime = %ld\n",sumworkTime,sumsendTime); - float usageworkTime = ((float)sumworkTime/3600000) * 4; - float usagesendTime = ((float)sumsendTime/3600000) * 39; - print_info("work = %f,send = %f\n",usageworkTime,usagesendTime); - //LOG_INFO("work = %f,send = %f\n",usageworkTime,usagesendTime); - if(to_math < 0) - to_math = 0; - float usageBattery = usageworkTime + usagesendTime + to_math; - print_info("已经使用 = %f\n",atof(vecResSig[6].c_str())); - - float remainBattery = capacity - usageBattery * 0.2; - if (remainBattery < 10) - { - remainBattery = 10; - } - - LOG_INFO("dataNodeNo = %s,batteryUsage = %f,batteryRemain = %f\n",vecRes[i][0].c_str(),atof(vecResSig[6].c_str()),remainBattery); - memset(whereCon,0x00,sizeof(whereCon)); - sprintf(whereCon," dataNodeNo = '%s' order by timeStamp desc limit 0,1 ",vecRes[i][0].c_str()); - string strtimeStamp = sql_ctl->GetData(T_BATTERY_INFO(TNAME)," timeStamp ",whereCon); - - sprintf(updateSql, "batteryUsage='%f',batteryRemain='%f'",usageBattery,remainBattery); - memset(whereCon,0x00,sizeof(whereCon)); - sprintf(whereCon, "dataNodeNo ='%s' and timeStamp = '%s'", vecRes[i][0].c_str(),strtimeStamp.c_str()); - sql_ctl->UpdateTableData(T_BATTERY_INFO(TNAME), updateSql, whereCon); + sprintf(updateSql, "batteryPower = '%f,%f' ", startCapacity, startCapacity); + memset(whereCon, 0x00, sizeof(whereCon)); + sprintf(whereCon, "MeasurementID = '%s' ", vecRes[i][0].c_str()); + res = UpdateTableData(T_SENSOR_INFO(TNAME), updateSql, whereCon); + if(res !=0 ){ + LOG_ERROR("res = %d\n", res); + continue; + } + memset(whereCon, 0x00, sizeof(whereCon)); + sprintf(whereCon, " dataNodeNo = '%s' order by timeStamp asc limit 0,1 ", vecRes[i][0].c_str()); + vecResSig = GetDataSingleLine(T_BATTERY_INFO(TNAME), " * ", whereCon); + if (vecResSig.size() <= 0) { // 一条数据都没有 + continue; + } + } else { + capacity = atof(vecResSig[7].c_str()); + } - memset(whereCon,0x00,sizeof(whereCon)); - memset(updateSql,0x00,sizeof(updateSql)); - - char insertSql[1024]={0x00},deleteSql[1024]={0x00}; - sprintf(insertSql,"insert into t_battery_history select * from t_battery_info where timeStamp < '%s' and dataNodeNo = '%s'",strtimeStamp.c_str(),vecRes[i][0].c_str()); - ExeSql(insertSql); + LOG_INFO( "dip = %d\n", atoi(vecResSig[1].c_str())); - sprintf(deleteSql,"delete from t_battery_info where timeStamp < '%s' and dataNodeNo = '%s'",strtimeStamp.c_str(),vecRes[i][0].c_str()); - ExeSql(deleteSql); + LOG_INFO( "capacity = %f\n", capacity); + sprintf(whereCon, " dataNodeNo = '%s' and timeStamp > '%s'", vecRes[i][0].c_str(), vecResSig[8].c_str()); + array_t vecResbattery = GetDataMultiLine(T_BATTERY_INFO(TNAME), " * ", whereCon); + LOG_INFO( "vecResbattery size = %d\n", vecResbattery.size()); + if (vecResbattery.size() <= 0) { + continue; + } + int y10_mins = 10 * 365 * 24 * 60; + int d200_mins = 200 * 24 * 60; + int x1 = 25, x2 = 60; + int y1 = 2; + float y2 = (float)y10_mins / (float)d200_mins; - sprintf(whereCon,"dataNodeNo = '%s' ",vecRes[i][0].c_str()); - if(startCapacity > 0){ - sprintf(updateSql,"batteryPower = '%f,%f' ",startCapacity,remainBattery); - }else{ - sprintf(updateSql,"batteryPower = '%s,%f' ",vParam[0].c_str(),remainBattery); - } - - int iRet = UpdateTableData(T_SENSOR_INFO(TNAME), updateSql, whereCon); - string strData = sql_ctl->GetNodeConfigureInfor(whereCon); - data_publish(strData.c_str(), GlobalConfig::Topic_G.mPubConfig.c_str()); - } - } - LOG_INFO("CalculateBattery end\n"); + float k = (y2 - y1) / (x2 - x1); + std::vector vecb; + std::vector vecworkTime; + std::vector vecsendTime; + float to_math = 0.0; + LOG_INFO( "vecResbattery = %d,temp = %s\n", vecResbattery.size(), vecResbattery[0][2].c_str()); + + for (size_t j = 0; j < vecResbattery.size(); j++) { + float b = 2 - 25 * k; + float dpm = k * atoi(vecResbattery[j][2].c_str()) + b; // 温度 + float cost_e = dpm * atoi(vecRes[i][3].c_str()); // 特征值时间间隔 + float cost_h = cost_e / 60; + vecworkTime.push_back(atol(vecResbattery[j][3].c_str())); + vecsendTime.push_back(atol(vecResbattery[j][4].c_str())); + to_math += cost_h; + } + + LOG_INFO( "self discharge = %f\n", to_math); + long sumworkTime = 0.0, sumsendTime = 0.0; + for (size_t j = 0; j < vecworkTime.size(); j++) { + sumworkTime += vecworkTime[j]; + } + for (size_t j = 0; j < vecsendTime.size(); j++) { + sumsendTime += vecsendTime[j]; + } + LOG_INFO( "sumworkTime = %ld,sumsendTime = %ld\n", sumworkTime, sumsendTime); + + float usageworkTime = ((float)sumworkTime / 3600000) * 4; + float usagesendTime = ((float)sumsendTime / 3600000) * 39; + LOG_INFO( "work = %f,send = %f\n", usageworkTime, usagesendTime); + + if (to_math < 0) to_math = 0; + float usageBattery = usageworkTime + usagesendTime + to_math; + LOG_INFO( "have used = %f\n", atof(vecResSig[6].c_str())); + + float remainBattery = capacity - usageBattery * 0.2; + if (remainBattery < 10) { + remainBattery = 10; + } + + LOG_INFO( "dataNodeNo = %s,batteryUsage = %f,batteryRemain = %f\n", vecRes[i][0].c_str(), atof(vecResSig[6].c_str()), remainBattery); + memset(whereCon, 0x00, sizeof(whereCon)); + sprintf(whereCon, " dataNodeNo = '%s' order by timeStamp desc limit 0,1 ", vecRes[i][0].c_str()); + std::string strtimeStamp = GetData(T_BATTERY_INFO(TNAME), " timeStamp ", whereCon); + + sprintf(updateSql, "batteryUsage='%f',batteryRemain='%f'", usageBattery, remainBattery); + memset(whereCon, 0x00, sizeof(whereCon)); + sprintf(whereCon, "dataNodeNo ='%s' and timeStamp = '%s'", vecRes[i][0].c_str(), strtimeStamp.c_str()); + res = UpdateTableData(T_BATTERY_INFO(TNAME), updateSql, whereCon); + if(res !=0 ){ + LOG_ERROR("res = %d\n", res); + continue; + } + memset(whereCon, 0x00, sizeof(whereCon)); + memset(updateSql, 0x00, sizeof(updateSql)); + + char insertSql[1024] = {0x00}, deleteSql[1024] = {0x00}; + sprintf(insertSql, "insert into t_battery_history select * from t_battery_info where timeStamp < '%s' and dataNodeNo = '%s'", strtimeStamp.c_str(), vecRes[i][0].c_str()); + res = ExeSql(insertSql); + if(res !=0 ){ + LOG_ERROR("res = %d\n", res); + continue; + } + sprintf(deleteSql, "delete from t_battery_info where timeStamp < '%s' and dataNodeNo = '%s'", strtimeStamp.c_str(), vecRes[i][0].c_str()); + res = ExeSql(deleteSql); + if(res !=0 ){ + LOG_ERROR("res = %d\n", res); + continue; + } + sprintf(whereCon, "MeasurementID = '%s' ", vecRes[i][0].c_str()); + if (startCapacity > 0) { + sprintf(updateSql, "batteryPower = '%f,%f' ", startCapacity, remainBattery); + } else { + sprintf(updateSql, "batteryPower = '%s,%f' ", vParam[0].c_str(), remainBattery); + } + + UpdateTableData(T_SENSOR_INFO(TNAME), updateSql, whereCon); + std::string strData = GetNodeConfigureInfor(whereCon); + res = data_publish(strData.c_str(), GlobalConfig::Topic_G.mPubConfig.c_str()); + if(res !=0 ){ + LOG_ERROR("data_publish res = %d\n", res); + continue; + } + } + } + LOG_INFO("CalculateBattery end\n"); + return res; diff --git a/jsonparse/SH_JsonCmd.hpp b/jsonparse/SH_JsonCmd.hpp index 2a7d5cc..6b282cd 100644 --- a/jsonparse/SH_JsonCmd.hpp +++ b/jsonparse/SH_JsonCmd.hpp @@ -76,6 +76,15 @@ public : std::string JsonCmd_Cgi_57(Param_57 ¶m); std::string JsonCmd_Cgi_default(); + //CMT tcp + void CmtCmd_80(char* send_data,int& return_length); + void CmtCmd_81(char* recv_body,int& count,char* send_data,int& return_length); + void CmtCmd_82(char* MeasurementID,char* send_data,int& channel,int& return_length); + void CmtCmd_83(char* recv_body,int& count,char* send_data,int& return_length); + void CmtCmd_84(char* filename,char* file_md5,char* send_data,int& send_length); + void CmtCmd_85(char* filename,char* file_md5,char* send_data,int& send_length); + void CmtCmd_87(char* MeasurementID,char* send_data,int& send_length); + private : Json::FastWriter showValue; }; diff --git a/jsonparse/cmt_parse.cpp b/jsonparse/cmt_parse.cpp new file mode 100644 index 0000000..5befe7c --- /dev/null +++ b/jsonparse/cmt_parse.cpp @@ -0,0 +1,460 @@ +#include +#include "SH_JsonCmd.hpp" +#include "../localserver/SH_LocalServer.hpp" +#include "../common/SH_CommonFunc.hpp" +#include "../common/SH_global.h" +#include +#include "../dbaccess/SH_SqlDB.hpp" +#include "../localserver/cmt_server.hpp" + + +void JsonData::CmtCmd_80(char* send_data,int& send_length) +{ + GatewayVersion gateway_ver; + gateway_ver.version = 1; + memcpy(gateway_ver.mac,GlobalConfig::MacAddr_G.c_str(),sizeof(gateway_ver.mac)); + memcpy(gateway_ver.web_ver,ReadStrByOpt(SYSTEMINFOFILE, "Version", "WebVersion").c_str(),sizeof(gateway_ver.web_ver)); + memcpy(gateway_ver.system_ver,ReadStrByOpt(SYSTEMINFOFILE, "Version", "SystemVersion").c_str(),sizeof(gateway_ver.system_ver)); + memcpy(gateway_ver.gateway_ver,ReadStrByOpt(SYSTEMINFOFILE, "Version", "GateWayVersion").c_str(),sizeof(gateway_ver.gateway_ver)); + memcpy(gateway_ver.ip,GlobalConfig::IpAddr_G.c_str(),sizeof(gateway_ver.ip)); + memcpy(gateway_ver.gateway_type,ReadStrByOpt(SYSTEMINFOFILE, "Version", "GateWayProduct").c_str(),sizeof(gateway_ver.gateway_type)); + memcpy(gateway_ver.gateway_hw_ver,ReadStrByOpt(SYSTEMINFOFILE, "Version", "GateWayHwVesion").c_str(),sizeof(gateway_ver.gateway_hw_ver)); + memcpy(gateway_ver.comm_mode,"以太网",sizeof(gateway_ver.comm_mode)); +#ifdef NR5G_MODULE + memset(gateway_ver.comm_mode,0,sizeof(gateway_ver.comm_mode)); + memcpy(gateway_ver.comm_mode,"5G",sizeof(gateway_ver.comm_mode)); +#endif +#ifdef Q4G_MODULE + memset(gateway_ver.comm_mode,0,sizeof(gateway_ver.comm_mode)); + memcpy(gateway_ver.comm_mode,"4G",sizeof(gateway_ver.comm_mode)); +#endif +#ifdef WIFI_MODULE + memset(gateway_ver.comm_mode,0,sizeof(gateway_ver.comm_mode)); + memcpy(gateway_ver.comm_mode,"WiFi",sizeof(gateway_ver.comm_mode)); +#endif + + std::string gatewayLocation = sql_ctl->GetData(T_GATEWAY_INFO(TNAME), "gatewayLocation", NULL); + memcpy(gateway_ver.terminal_name,gatewayLocation.c_str(),sizeof(gateway_ver.terminal_name)); + GetSysStatusCMT(gateway_ver.cpu_use,gateway_ver.memory_use,gateway_ver.disk_remain,gateway_ver.temperature); + memcpy(send_data,&gateway_ver,sizeof(GatewayVersion)); + send_length = sizeof(GatewayVersion); +} + +void JsonData::CmtCmd_81(char* recv_body,int& count,char* send_data,int& send_length) +{ + int featureInterVal; + int featureInterTime; + int waveInterVal; + int waveInterTime; + int maxSensorNum; + array_t arrRes; + char whereCon[512]={0}; + if (recv_body != NULL) + { + printf("count = %d\n",count); + char short_addr_[256]={0}; + for (int i = 0; i < count; i++){ + char temp[5]={0}; + memcpy(temp,recv_body + i * 4,4); + printf("short_addr = %s\n",temp); + strcat(short_addr_,"'"); + strcat(short_addr_,temp); + strcat(short_addr_,"'"); + if (i + 1 != count){ + strcat(short_addr_ ,","); + } + } + sprintf(whereCon,"zigbeeShortAddr IN (%s)",short_addr_); + arrRes = sql_ctl->GetDataMultiLineTransaction(T_SENSOR_INFO(TNAME), "*", whereCon); + }else{ + arrRes = sql_ctl->GetDataMultiLineTransaction(T_SENSOR_INFO(TNAME), "*", NULL); + } + int iResult = arrRes.size(); + printf("result = %d\n",iResult); + int j = 0; + if (iResult > 0) { + SensorInfo sensor_info[iResult]; + for (; j < iResult; j++) + { + memcpy(sensor_info[j].sensor_name,arrRes[j][1].c_str(),sizeof(sensor_info[j].sensor_name)); + memcpy(sensor_info[j].measurement_id,arrRes[j][44].c_str(),sizeof(sensor_info[j].measurement_id)); + memcpy(sensor_info[j].short_addr , arrRes[j][30].c_str(),sizeof(sensor_info[j].short_addr)); + memcpy(sensor_info[j].hw_ver,arrRes[j][8].c_str(),sizeof(sensor_info[j].hw_ver)); + memcpy(sensor_info[j].soft_ver,arrRes[j][9].c_str(),sizeof(sensor_info[j].soft_ver)); + std::vector vParamRSSI; + boost::split(vParamRSSI, arrRes[j][40], boost::is_any_of(","), boost::token_compress_on); + if (vParamRSSI.size() > 1) { + sensor_info[j].gateway_rssi = (atof(vParamRSSI[0].c_str())/255) * 100; + sensor_info[j].sensor_rssi = (atof(vParamRSSI[1].c_str())/255) * 100; + } else { + sensor_info[j].gateway_rssi = (atof(vParamRSSI[0].c_str())/255) * 100; + sensor_info[j].sensor_rssi = 99; + } + std::vector vParambattery; + boost::split(vParambattery, arrRes[j][43], boost::is_any_of(","), boost::token_compress_on); + if (vParambattery.size() > 1) { + sensor_info[j].battry = (atof(vParambattery[1].c_str())/atof(vParambattery[0].c_str())) * 100; + } else { + sensor_info[j].battry = 99; + } + std::vector vParam; + boost::split(vParam, arrRes[j][42], boost::is_any_of(","), boost::token_compress_on); + if (vParam.size() > 1){ + if (vParam[1] != "0"){ + sensor_info[j].loose_status = 1; + }else{ + sensor_info[j].loose_status = 0; + } + } + char whereCon[256]={0x00}; + sprintf(whereCon,"dataNodeNo = '%s'",arrRes[j][44].c_str()); + vec_t vecRes = sql_ctl->GetDataSingleLine(T_DATASTATIC_INFO(TNAME), "temTop,temBot",whereCon); + if (vecRes.size() > 0) + { + sensor_info[j].temperature_top = atoi(vecRes[0].c_str()); + sensor_info[j].temperature_bot = atoi(vecRes[1].c_str()); + }else{ + sensor_info[j].temperature_top = 200; + sensor_info[j].temperature_bot = 200; + } + + memcpy(sensor_info[j].product,arrRes[j][17].c_str(),sizeof(sensor_info[j].product)); + if (arrRes[j][17] == "01"){ + memcpy(sensor_info[j].product,"DN101",sizeof(sensor_info[j].product)); + }else if (arrRes[j][17] == "02"){ + memcpy(sensor_info[j].product,"DN102",sizeof(sensor_info[j].product)); + } + sensor_info[j].status = atoi(arrRes[j][37].c_str()); + + char szTableName[100] = {0x00}; + memset(whereCon,0,sizeof(whereCon)); + sprintf(szTableName, " t_data_waveSend "); + const char *sql = + " timestamp >= strftime('%s', 'now', '-1 day', 'start of day','utc') " + "AND timestamp < strftime('%s', 'now', '-1 day','start of day','utc','+24 hours') "; + sprintf(whereCon," and channelID = '%s-X'",arrRes[j][44].c_str()); + std::string strsql = std::string(sql) + std::string(whereCon); + int waveX_Count = sql_ctl->GetTableRows(szTableName,strsql.c_str()); + + memset(whereCon,0,sizeof(whereCon)); + sprintf(whereCon," and channelID = '%s-Y'",arrRes[j][44].c_str()); + strsql = std::string(sql) + std::string(whereCon); + int waveY_Count = sql_ctl->GetTableRows(szTableName,strsql.c_str()); + + memset(whereCon,0,sizeof(whereCon)); + sprintf(whereCon," and channelID = '%s-Z'",arrRes[j][44].c_str()); + strsql = std::string(sql) + std::string(whereCon); + int waveZ_Count = sql_ctl->GetTableRows(szTableName,strsql.c_str()); + memset(whereCon,0,sizeof(whereCon)); + memset(szTableName,0,sizeof(szTableName)); + sprintf(szTableName, " t_dataStatic_%s ",arrRes[j][44].c_str()); + sprintf(whereCon," and channelID = '%s-S'",arrRes[j][44].c_str()); + strsql = std::string(sql) + std::string(whereCon); + int static_Count = sql_ctl->GetTableRows(szTableName,strsql.c_str()); + featureInterVal = atoi(arrRes[j][21].c_str()) * 60; + waveInterVal = atoi(arrRes[j][22].c_str()) * 60; + int day_count = 86400 / waveInterVal; + + sensor_info[j].wave_x_reporting_rate = (float( waveX_Count)/(86400/waveInterVal)) * 100; + sensor_info[j].wave_y_reporting_rate = (float(waveY_Count)/(86400/waveInterVal)) * 100; + sensor_info[j].wave_z_reporting_rate = (float(waveZ_Count)/(86400/waveInterVal)) * 100; + sensor_info[j].eigen_value_reporting_rate = (float(static_Count)/(86400/featureInterVal)) * 100; + day_count = 86400 / featureInterVal; + printf("static_Count = %d,day_count = %d,wave_x_reporting_rate = %d\n",static_Count,day_count,sensor_info[j].eigen_value_reporting_rate ); + + memset(whereCon,0,sizeof(whereCon)); + sprintf(whereCon,"channelID = '%s-Z'",arrRes[j][44].c_str()); + std::string integratRMS = sql_ctl->GetData(T_DATA_INFO(TNAME), "integratRMS",whereCon); + + sensor_info[j].velocity_rms = atof(integratRMS.c_str()); + sensor_info[j].upgrade_status = 0; + memcpy(sensor_info[j].upgrade_time,"0",sizeof(sensor_info[j].upgrade_time)); + sensor_info[j].version = 1; + } + memcpy(send_data ,(char*)&sensor_info[0],sizeof(SensorInfo) * j); + send_length = sizeof(SensorInfo) * j; + } + +} + +void JsonData::CmtCmd_82(char* MeasurementID,char* send_data,int& channel,int& send_length) +{ + FILE* pFile = NULL; + char* buffer = NULL; + int thisSize = 32; + WaveRes wave; + char whereCon[64]={0}; + sprintf(whereCon,"MeasurementID = '%s'",MeasurementID); + vec_t vecRes = sql_ctl->GetDataSingleLine(T_SENSOR_INFO(TNAME), "samplingRate,ACCSampleTime",whereCon); + std::string strChannel = ""; + + if (channel == 1){ + strChannel = "X"; + }else if(channel == 2){ + strChannel = "Y"; + }else if (channel == 3){ + strChannel = "Z"; + } + std::string data_file = "/opt/data/" + std::string(MeasurementID) + "-" + strChannel + ".dat"; + print_info( "strFileName = %s\n", data_file.c_str()); + + pFile = fopen(data_file.c_str(), "rb"); + if (pFile != NULL) { + while (fgetc(pFile) != EOF) { + ++thisSize; + } + rewind(pFile); + fseek(pFile, 32, SEEK_SET);//跳过32个字节的时间戳 + buffer = (char*)malloc(thisSize - 32); + fread(buffer, sizeof(char), thisSize - 32, pFile); + fclose(pFile); + + wave.sampling_rate = atoi(vecRes[0].c_str()); + wave.sampling_time = atoi(vecRes[1].c_str()); + wave.version = 1; + send_length = sizeof(WaveRes) + thisSize - 32; + memcpy(send_data,(char*)&wave,sizeof(WaveRes)); + memcpy(send_data + sizeof(WaveRes) ,buffer,thisSize - 32); + free(buffer); + } +} + +void JsonData::CmtCmd_83(char* recv_body,int& count,char* send_data,int& send_length) +{ + array_t arrRes; + std::string filename = ""; + char whereCon[128]={0}; + if (recv_body){ + printf("count = %d\n",count); + char MeasurementID_[256]={0}; + for (int i = 0; i < count; i++){ + char temp[21]={0}; + memcpy(temp,recv_body + i * 20,20); + printf("short_addr = %s\n",temp); + strcat(MeasurementID_,"'"); + strcat(MeasurementID_,temp); + strcat(MeasurementID_,"'"); + if (i + 1 != count){ + strcat(MeasurementID_ ,","); + } + } + sprintf(whereCon,"MeasurementID IN (%s)",MeasurementID_); + arrRes = sql_ctl->GetDataMultiLineTransaction(T_SENSOR_INFO(TNAME), "*", whereCon); + }else{ + arrRes = sql_ctl->GetDataMultiLineTransaction(T_SENSOR_INFO(TNAME), "*", NULL); + } + if (arrRes.size() > 0){ + std::string current_time = GetLocalTimeWithMs(); + filename = "/opt/DataNode/config_" + GlobalConfig::MacAddr_G + "_" + std::string(current_time)+ ".csv"; + std::ofstream csvFile(filename); + if (!csvFile.is_open()) { + std::cerr << "Error: Could not open file " << filename << std::endl; + return; + } + // 写入 CSV 标题行 + csvFile << "GW MAC,Product,IP,PanID,Signal Channel,Terminal Name,SN,Sensor MAC,Measurement ID," + "Short Addr,Sensor Name,Update Date,Gateway RSSI,Sensor RSSI,HW Ver,Soft Ver,Sampling Rate," + "Range,Sampling Time,VIFF,Power,Retry Time\n"; + for (int i = 0; i < count; i++) + { + DownloadConfig download_config; + memcpy(download_config.gw_mac,GlobalConfig::MacAddr_G.c_str(),sizeof(download_config.gw_mac)); + if (arrRes[i][17] == "01"){ + memcpy(download_config.product,"DN101",sizeof(download_config.product)); + }else if (arrRes[i][17] == "02"){ + memcpy(download_config.product,"DN102",sizeof(download_config.product)); + } + memcpy(download_config.ip,GlobalConfig::IpAddr_G.c_str(),sizeof(download_config.ip)); + download_config.panid = atoi(arrRes[i][28].c_str()); + download_config.signal_channle = atoi(arrRes[i][29].c_str()); + memcpy(download_config.terminal_name,"",sizeof(download_config.terminal_name)); + memcpy(download_config.sn,arrRes[i][11].c_str(),sizeof(download_config.sn)); + memcpy(download_config.sensor_mac,arrRes[i][0].c_str(),sizeof(download_config.sensor_mac)); + memcpy(download_config.measurement_id,arrRes[i][44].c_str(),sizeof(download_config.measurement_id)); + download_config.short_addr = atoi(arrRes[i][30].c_str()); + memcpy(download_config.sensor_name,arrRes[i][1].c_str(),sizeof(download_config.sensor_name)); + memcpy(download_config.update_date,arrRes[i][38].c_str(),sizeof(download_config.update_date)); + std::vector vParamRSSI; + boost::split(vParamRSSI, arrRes[i][40], boost::is_any_of(","), boost::token_compress_on); + if (vParamRSSI.size() > 1) { + download_config.gateway_rssi = (atof(vParamRSSI[0].c_str())/255) * 100; + download_config.sensor_rssi = (atof(vParamRSSI[1].c_str())/255) * 100; + } else { + download_config.gateway_rssi = (atof(vParamRSSI[0].c_str())/255) * 100; + download_config.sensor_rssi = 99; + } + memcpy(download_config.hw_ver,arrRes[i][8].c_str(),sizeof(download_config.hw_ver)); + memcpy(download_config.soft_ver,arrRes[i][9].c_str(),sizeof(download_config.soft_ver)); + download_config.sampling_rate = atoi(arrRes[i][23].c_str()); + download_config.range = atoi(arrRes[i][25].c_str()); + download_config.sampling_time = atoi(arrRes[i][36].c_str()); + download_config.viff = atoi(arrRes[i][39].c_str()); + download_config.power = atoi(arrRes[i][33].c_str()); + download_config.retry_time = atoi(arrRes[i][34].c_str()); + + csvFile << download_config.gw_mac << ',' << download_config.product << ','<< download_config.ip << ',' << download_config.panid << ',' + << download_config.signal_channle << ','<< download_config.terminal_name << ','<< download_config.sn << ','<< download_config.sensor_mac << ',' + << download_config.measurement_id << ','<< download_config.short_addr << ','<< download_config.sensor_name << ','<< download_config.update_date << ',' + << download_config.gateway_rssi << ','<< download_config.sensor_rssi << ','<< download_config.hw_ver << ','<< download_config.soft_ver << ',' + << download_config.sampling_rate << ','<< download_config.range << ','<< download_config.sampling_time << ','<< download_config.viff << ',' + << download_config.power << ','<< download_config.retry_time << '\n' ; + } + csvFile.close(); + std::cout << "CSV file written to " << filename << std::endl; + } + send_length = sizeof(DownloadConfigRes); + DownloadConfigRes download_condfig_res; + download_condfig_res.version = 1; + memcpy(download_condfig_res.filename,filename.c_str(),sizeof(download_condfig_res.filename)); + memcpy(send_data,(char*)&download_condfig_res,sizeof(DownloadConfigRes)); + print_info( "cmd 83 send_length = %d\n",send_length); + +} + +void JsonData::CmtCmd_84(char* filename,char* file_md5,char* send_data,int& send_length) +{ + std::vector vecDataNode; + UploadConfigRes upload_condfig_res; + upload_condfig_res.code = 0; + upload_condfig_res.version = 1; + sprintf(upload_condfig_res.message ,"%s",""); + send_length = sizeof(UploadConfigRes); + char file_path[64]={0}; + char cmd[128]={0}; + sprintf(cmd, "mv /opt/%s /opt/DataNode/",filename); + system(cmd); + sprintf(file_path, "/opt/DataNode/%s",filename); + if(get_file_md5(file_path) != std::string(file_md5)) + { + LOG_ERROR( "file md5 error = %s\n",file_path); + upload_condfig_res.code = 1; + sprintf(upload_condfig_res.message ,"%s",""); + memcpy(send_data,(char*)&upload_condfig_res,sizeof(UploadConfigRes)); + return ; + } + std::ifstream csv_data(file_path, std::ios::in); + int iRet = 0; + if (!csv_data.is_open()) { + LOG_ERROR( "UpdataDataNodeConfig fail to open:%s\n", file_path); + } + std::string line; + std::vector words; + std::string word; + + DataNodeInfo dataNode; + getline(csv_data, line); + + std::istringstream sin; + while (getline(csv_data, line)) { + words.clear(); + sin.clear(); + sin.str(line); + while (getline(sin, word, ',')) { + words.push_back(word); + } + std::string mac = words[0]; + if (mac != GlobalConfig::MacAddr_G) { + iRet = -2; + break; + } + dataNode.ZigbeeLongAddr = words[7]; + dataNode.ZigbeeShortAddr = words[9]; + dataNode.SamplingRate = atoi(words[16].c_str()); + dataNode.Range = atoi(words[17].c_str()); + dataNode.ACCSampleTime = atoi(words[18].c_str()); + dataNode.VIntegralFilterFrequency = atoi(words[19].c_str()); + dataNode.ZigbeePower = atoi(words[20].c_str()); + dataNode.ZigbeeRetry = atoi(words[21].c_str()); + vecDataNode.push_back(dataNode); + } + csv_data.close(); + if (vecDataNode.size() == 0) { + LOG_ERROR( "UpdataDataNodeConfig vecDataNode is 0\n"); + upload_condfig_res.code = 2; + sprintf(upload_condfig_res.message ,"%s","upgrade sensor is 0"); + memcpy(send_data,(char*)&upload_condfig_res,sizeof(UploadConfigRes)); + return ; + } + + char whereCon[1024] = {0}; + char updateSql[1024] = {0}; + for (size_t i = 0; i < vecDataNode.size(); i++) { + sprintf(updateSql, "range='%d',samplingRate='%d',AccSampleTime = '%d',viff ='%d' ,ZigbeePower = '%d',ZigbeeRetry = '%d',UpdateFlag = 0", vecDataNode[i].Range, + vecDataNode[i].SamplingRate, vecDataNode[i].ACCSampleTime, vecDataNode[i].VIntegralFilterFrequency, vecDataNode[i].ZigbeePower, vecDataNode[i].ZigbeeRetry); + sprintf(whereCon, "dataNodeNo='%s'", vecDataNode[i].ZigbeeLongAddr.c_str()); + + iRet = sql_ctl->UpdateTableData(T_SENSOR_INFO(TNAME), updateSql, whereCon); + if (iRet != 0) { + LOG_ERROR( "UpdataDataNodeConfig UpdateTableData fail\n"); + } + + memset(whereCon, 0x00, sizeof(whereCon)); + memset(updateSql, 0x00, sizeof(updateSql)); + } + + memcpy(send_data,(char*)&upload_condfig_res,sizeof(UploadConfigRes)); + print_info( "cmd 84 send_length = %d",send_length); +} + +void JsonData::CmtCmd_85(char* filename,char* file_md5,char* send_data,int& send_length) +{ + print_info("filename = %s,file_md5 = %s\n",filename,file_md5); + char file_path[64]={0}; + sprintf(file_path, "/opt/%s",filename); + if(get_file_md5(file_path) != std::string(file_md5)) + { + LOG_ERROR( "file md5 error = %s\n",file_path); + return ; + } + sleep(3); + int iRet = system("/opt/opt.sh"); + print_info( "iRet = %d", iRet); + if (iRet == -1) { + LOG_ERROR( "system() error\n"); + } +} + + +void JsonData::CmtCmd_87(char* MeasurementID,char* send_data,int& send_length) +{ + array_t arrRes; + char whereCon[128] = {}; + sprintf(whereCon, "channelID like '%%%s%%' ORDER BY timeStamp DESC LIMIT 0,3", MeasurementID); + arrRes = sql_ctl->GetDataMultiLineTransaction(T_DATA_INFO(TNAME), "*", whereCon); + int iResult = arrRes.size(); + if (iResult > 0) { + int j = 0; + GetEigenvalueRes get_eigenvalue_res[iResult]; + for (; j < iResult; j++) { + get_eigenvalue_res[j].version = 1; + if(arrRes[j][1] == (std::string(MeasurementID) +"-X")){ + get_eigenvalue_res[j].channel = 1; + }else if (arrRes[j][1] == (std::string(MeasurementID) +"-Y")){ + get_eigenvalue_res[j].channel = 2; + }else if (arrRes[j][1] == (std::string(MeasurementID) +"-Z")){ + get_eigenvalue_res[j].channel = 3; + } + printf("channle = %d\n",get_eigenvalue_res[j].channel); + get_eigenvalue_res[j].DiagnosisPk = atof(arrRes[j][2].c_str()); + get_eigenvalue_res[j].IntegratPk = atof(arrRes[j][3].c_str()); + get_eigenvalue_res[j].IntegratRMS = atof(arrRes[j][4].c_str()); + get_eigenvalue_res[j].RmsValues = atof(arrRes[j][5].c_str()); + get_eigenvalue_res[j].EnvelopEnergy = atof(arrRes[j][6].c_str()); + get_eigenvalue_res[j].Amp1 = atof(arrRes[j][7].c_str()); + get_eigenvalue_res[j].Amp2 = atof(arrRes[j][8].c_str()); + get_eigenvalue_res[j].Amp3 = atof(arrRes[j][9].c_str()); + get_eigenvalue_res[j].Amp4 = atof(arrRes[j][10].c_str()); + get_eigenvalue_res[j].Amp5 = atof(arrRes[j][11].c_str()); + get_eigenvalue_res[j].Phase1 = atof(arrRes[j][12].c_str()); + get_eigenvalue_res[j].Phase2 = atof(arrRes[j][13].c_str()); + get_eigenvalue_res[j].Phase3 = atof(arrRes[j][14].c_str()); + get_eigenvalue_res[j].Phase4 = atof(arrRes[j][15].c_str()); + get_eigenvalue_res[j].Time = atoi(arrRes[j][17].c_str()); + } + memcpy(send_data,(char*)&get_eigenvalue_res,sizeof(GetEigenvalueRes) * j); + send_length = sizeof(GetEigenvalueRes) * j; + } +} + + + diff --git a/localserver/SH_LocalServer.hpp b/localserver/SH_LocalServer.hpp index 3d1b517..a018904 100644 --- a/localserver/SH_LocalServer.hpp +++ b/localserver/SH_LocalServer.hpp @@ -13,7 +13,25 @@ #include "../secure/SH_Secure.hpp" #include "../jsonparse/SH_JsonCmd.hpp" +enum WebCommand { + //CMT TCP + kGateWayVersion = 80, + kSensorInfo = 81, + kSensorWave = 82, + KDownloadConfig = 83, + KUploadConfig = 84, + KUpgadeGateway = 85, + KUpgradeSensor = 86, + KEigenvalue = 87, + KUpgradeSensorStop = 88 +}; +enum GatewayType{ + kGWTDW2700 = 1, + + kGWTDG101 = 10, + kGWTDG102 = 11 +}; class LocalServer : public MySingleton { private: @@ -25,6 +43,7 @@ public: virtual ~LocalServer(); void HandleFromServer(const char *pData, int pLen, const char *topic); std::string HandleCgi_cmd(std::string &pData); + static void HandleTcp_cmd(const char* recvData,char* send_data,uint8_t& rescmd,int& reslength,int recvbody_length = 0); }; #endif \ No newline at end of file diff --git a/localserver/cmt_cmd.cpp b/localserver/cmt_cmd.cpp new file mode 100644 index 0000000..cedf9c9 --- /dev/null +++ b/localserver/cmt_cmd.cpp @@ -0,0 +1,90 @@ +#include +#include "cmt_server.hpp" +#include "SH_LocalServer.hpp" +#include "../jsonparse/SH_JsonCmd.hpp" +#include "../common/SH_global.h" + + +void LocalServer::HandleTcp_cmd(const char* recv_data,char* send_data,uint8_t& rescmd,int& send_length,int recvbody_length) +{ + PackageHead head; + memcpy(&head,recv_data,sizeof(PackageHead)); + uint8_t cmd = head.cmd; + rescmd = head.cmd; + printf("cmd = %d\n",cmd); + JsonData jd; + switch (cmd) + { + case 1:{ + Search search; + search.version = 1; + memcpy(search.mac,GlobalConfig::MacAddr_G.c_str(),sizeof(search.mac)); +#ifdef IMX6UL_GATEWAY + search.gw_type = kGWTDG101; +#endif +#ifdef G2UL_GATEWAY + search.gw_type = kGWTDG102; +#endif + send_length = sizeof(Search); + memcpy(send_data,&search,sizeof(Search)); + }break; + case kGateWayVersion: { + jd.CmtCmd_80(send_data,send_length); + }break; + case kSensorInfo:{ + char *recv_body = NULL; + if (recvbody_length > 0){ + recv_body = (char*)malloc(recvbody_length - 4); + memcpy(recv_body,recv_data + sizeof(PackageHead) + 4,recvbody_length - 4); + } + int count = 0; + memcpy((char*)&count,recv_data + sizeof(PackageHead),4); + jd.CmtCmd_81(recv_body,count,send_data,send_length); + if (recv_body){ + free(recv_body); + } + }break; + case kSensorWave:{ + WaveReq wave_req; + memcpy(&wave_req,recv_data + sizeof(PackageHead),sizeof(WaveReq)); + jd.CmtCmd_82(wave_req.measurement_id,send_data,wave_req.channel,send_length); + + }break; + case KDownloadConfig:{ + char *recv_body = NULL; + int count = 0; + if (recvbody_length > 0){ + recv_body = (char*)malloc(recvbody_length - 4); + memcpy((char*)&count,(char*)recv_data + sizeof(PackageHead),4); + memcpy(recv_body,recv_data + sizeof(PackageHead) + 4,recvbody_length - 4); + } + jd.CmtCmd_83(recv_body,count,send_data,send_length); + if (recv_body){ + free(recv_body); + } + }break; + case KUploadConfig:{ + UploadConfigReq upload_config; + memcpy(&upload_config,recv_data + sizeof(PackageHead),sizeof(UploadConfigReq)); + printf("filename = %s\n",upload_config.filename); + jd.CmtCmd_84(upload_config.filename,upload_config.md5,send_data,send_length); + + }break; + case KUpgadeGateway:{ + + UpgradeGwReq upgrade_gw; + memcpy(&upgrade_gw,recv_data + sizeof(PackageHead),sizeof(UpgradeGwReq)); + jd.CmtCmd_85(upgrade_gw.filename,upgrade_gw.md5,send_data,send_length); + }break; + + case KEigenvalue:{ + GetEigenvalueReq get_eigenvalue; + memcpy(&get_eigenvalue,recv_data + sizeof(PackageHead),sizeof(GetEigenvalueReq)); + jd.CmtCmd_87(get_eigenvalue.measurement_id,send_data,send_length); + } + break; + default: + break; + } + +} diff --git a/localserver/cmt_server.cpp b/localserver/cmt_server.cpp new file mode 100644 index 0000000..120274f --- /dev/null +++ b/localserver/cmt_server.cpp @@ -0,0 +1,93 @@ +#include "cmt_server.hpp" +#include +#include +#include +#include +#include + +#include "../localserver/SH_LocalServer.hpp" + + +void CMTSession::start() { + data_ = (char*)malloc(CMT_TCP_LEN); + memset(data_, 0, CMT_TCP_LEN); + sessionSet_.insert(shared_from_this()); // 将会话添加到会话集合中 + do_read(); +} +void CMTSession::set_data(char *data, int len) { + memcpy(data_, data, len); +} +void CMTSession::do_write(std::size_t length) { + auto self(shared_from_this()); + print_info( "[CMT] response len = %d\n", length); + boost::asio::async_write(socket_, boost::asio::buffer(data_, length), [this, self](boost::system::error_code ec, std::size_t /*length*/) { + if (ec) { + print_info("[CMT] fail to send data, %s, %d\n", ec.category().name(), ec.value()); + socket_.close(); + sessionSet_.erase(shared_from_this()); + } else { + print_info( "[CMT] waiting for next message...\n"); + do_read(); + // socket_.close(); + // sessionSet_.erase(shared_from_this()); + } + }); +} + +void CMTServer::do_accept() { + acceptor_.async_accept(socket_, [this](boost::system::error_code ec) { + print_info("[CMT] accept a socket\n"); + if (!ec) { + std::make_shared(std::move(socket_), sessionSet_)->start(); + } + + do_accept(); + }); +} +void CMTSession::do_read() { + auto self(shared_from_this()); + socket_.async_read_some(boost::asio::buffer(data_, CMT_TCP_LEN), [this, self](boost::system::error_code ec, std::size_t length) { + if (!ec) { + if (length == 0) { + print_error("[CMT] Client disconnected (length 0)\n"); + sessionSet_.erase(shared_from_this()); + return; + } + + if (length < 6 || data_[0] != 0xAA || data_[1] != 0x55 || data_[2] != 0xAA) { + print_info("[CMT] invalid data package, len:%d\n", length); + do_read(); + } + uint8_t cmd = data_[3]; + int payload_len = 0; + memcpy((char*)&payload_len, (char*)&data_[4], 4); + payload_len = htonl(payload_len); + print_info("[CMT] cmd: %d, message len: %d, payload len: %d, head:%2x-%2x-%2x\n", cmd, length, payload_len, data_[0], data_[1], data_[2]); + print_info( "[CMT] payload bytes %d, %d\n", data_[4], data_[5]); + int send_data_len = 0; + char send_data[96100] = {0}; + LocalServer::HandleTcp_cmd(data_,send_data,cmd,send_data_len,payload_len); + PackageHead pkg_head; + pkg_head.head[0] = 0xAA; + pkg_head.head[1] = 0x55; + pkg_head.head[2] = 0xAA; + pkg_head.cmd = cmd; + pkg_head.len = send_data_len; + memset(data_,0,CMT_TCP_LEN); + memcpy(data_, &pkg_head, head_len_); + memcpy(data_ + head_len_, &send_data, send_data_len); + do_write(head_len_ + send_data_len); + + } else if (ec == boost::asio::error::eof){ + print_info("[CMT] Client disconnect the connection\n"); + sessionSet_.erase(shared_from_this()); + } else if (ec == boost::asio::error::connection_reset){ + print_info("[CMT] Connection reset by client\n"); + sessionSet_.erase(shared_from_this()); + } else { + print_error("[CMT] Error message, reason: %s\n", ec.message().c_str()); + socket_.close(); + sessionSet_.erase(shared_from_this()); + } + }); +} diff --git a/localserver/cmt_server.hpp b/localserver/cmt_server.hpp new file mode 100644 index 0000000..f7769cd --- /dev/null +++ b/localserver/cmt_server.hpp @@ -0,0 +1,263 @@ +#ifndef CMT_PROTOCOL_HPP_ +#define CMT_PROTOCOL_HPP_ +#include +#include +#include +#include +#include +#include + +using boost::asio::ip::tcp; + +#define CMT_TCP_LEN 100000 + +//1 tcp server可以参考本安有线中的代码,侦听端口10000 +//2 定义无线网关与传感器用到的结构 +//3 包头为 + +#pragma pack(1) +struct PackageHead{ + uint8_t head[3]; // 固定值:0xAA55AA + uint8_t cmd; + int len; + char data[0]; +}; + +//网关版本和状态信息cmd 80 +struct GatewayVersion{ + int version; // 写1 + char web_ver[12]; + char system_ver[12]; + char gateway_ver[12]; + char ip[16]; + char gateway_type[12]; + char gateway_hw_ver[12]; + char terminal_name[32]; // 终端名称,如果为空,填写Default + int cpu_use; + int memory_use; + int disk_remain; + int temperature; + char comm_mode[10]; + char mac[20]; +}; +enum SensorStatus{ + OFFLINE = 0, + ONLINE = 1 +}; +enum SensorUpgradeStatus{ + UPGRADE_NORMAL = 0, + UPGRADING = 1, + UPGRADE_SUCCESS = 2, + UPGRADE_FALIED = 3 +}; +enum LooseStatus{ + NORMAL = 0, + LOOSE = 1 +}; +//传感器信息cmd 81 + +struct SensorInfoReq{ + char short_addr[4]; +}; +struct SensorInfo{ + int version; + char sensor_name[64]; + char measurement_id[20]; + char short_addr[5]; + char hw_ver[12]; + char soft_ver[12]; + int gateway_rssi; + int sensor_rssi; + int battry; + int loose_status; //参考 LooseStatus + int temperature_bot; + int temperature_top; + char product[6]; // DN101;DN102 + int status; // 参考 SensorStatus + int eigen_value_reporting_rate; + int wave_x_reporting_rate; + int wave_y_reporting_rate; + int wave_z_reporting_rate; + float velocity_rms; + int upgrade_status; // 参考 SensorUpgradeStatus + char upgrade_time[20]; +}; + +enum ChannelType{ + X = 1, + Y = 2, + Z = 3 +}; +//波形cmd 82 +struct WaveReq{ + char measurement_id[20]; + int channel;//参考 ChannelType +}; + +struct WaveRes{ + int version; + int sampling_rate; + int sampling_time; + char wave[0]; +}; + +//下载配置 cmd 83 +struct DownloadConfigReq{ + char measurement_id[20]; +}; +enum Range{ + RANGE_8G = 0, + RANGE_16G = 1, + RANGE_32G = 2, + RANGE_64G = 3, + RANGE_50G = 4 +}; +struct DownloadConfigRes{ + int version; + char filename[128]; +}; +struct DownloadConfig{ + char gw_mac[20]; + char product[6]; // DN101;DN102 + char ip[16]; + int panid; + int signal_channle; + char terminal_name[32]; + char sn[10]; + char sensor_mac[20]; + char measurement_id[20]; + int short_addr; + char sensor_name[64]; + char update_date[20]; + int gateway_rssi; + int sensor_rssi; + char hw_ver[12]; + char soft_ver[12]; + int sampling_rate; + int range; //量程 参考 Range + int sampling_time; + int viff; //速度积分起始频率 + int power; //zigbee发射功率 + int retry_time; //zigbee重发次数 +}; + +//上传配置 cmd 84 +struct UploadConfigReq{ + char filename[64]; + char md5[33]; +}; +struct UploadConfigRes{ + int version; + int code; + char message[64]; +}; +//网关更新 cmd 85 +struct UpgradeGwReq{ + char filename[64]; + char md5[33]; +}; + +struct UpgradeGwRes{ + int version; + int code; + char message[64]; +}; +//传感器更新 cmd 86 +struct UpgradeSensorReq{ + char filename[64]; + char md5[33]; + char upgrade_short_addr[0]; +}; +struct UpgradeSensorRes{ + int version; + int code; + char message[64]; +}; +//获取特征值 cmd 87 +struct GetEigenvalueReq{ + char measurement_id[20]; +}; +struct GetEigenvalueRes{ + int version; + int channel;//参考 ChannelType + float DiagnosisPk; + float IntegratPk; + float IntegratRMS; + float RmsValues; + float EnvelopEnergy; + float Amp1; + float Amp2; + float Amp3; + float Amp4; + float Amp5; + float Phase1; + float Phase2; + float Phase3; + float Phase4; + int Time; +}; + +//停止更新传感器 cmd 88 +struct UpgradeStopReq{ + int short_addr; +}; +struct UpgradeStopRes{ + int version; + int code; + char message[64]; +}; +// 搜索应答 cmd 1 +struct Search { + int version; + char mac[20]; + int gw_type; // GatewayType +}; + +class CMTSession : public std::enable_shared_from_this { +public: + CMTSession(tcp::socket socket, std::unordered_set>& sessionSet) : socket_(std::move(socket)), sessionSet_(sessionSet) { + web_version_ = "1.0.1"; + version_ = 1; + head_len_ = sizeof(PackageHead); + } + ~CMTSession() { + if (data_ != nullptr) { + free(data_); + } + } + + void start(); + void set_data(char *data, int len); + void do_write(std::size_t length); + +private: + void do_read(); + + tcp::socket socket_; + std::unordered_set>& sessionSet_; + char *data_; + std::string web_version_; + int version_; + int head_len_; +}; + +class CMTServer { +public: + CMTServer(boost::asio::io_service& io_service, short port) : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), socket_(io_service) { do_accept(); } + + // 向所有客户端发送消息 + void send_message_to_all(char *message, int len) { + for (auto& session : sessionSet_) { + session->set_data(message, len); + session->do_write(len); + } + } +private: + void do_accept(); + + tcp::acceptor acceptor_; + tcp::socket socket_; + std::unordered_set> sessionSet_; +}; + +#endif diff --git a/main.cpp b/main.cpp index 7dbf18a..952d929 100644 --- a/main.cpp +++ b/main.cpp @@ -117,7 +117,10 @@ int main(int argc, char *argv[]) boost::thread startTcpCgi(attrs,StartCgiServer); startTcpCgi.detach(); - + //启动CMT server + boost::thread startTcpCmt(attrs, StartCMTServer); + startTcpCmt.detach(); + sleep(5); pUart->ZigbeeInit(); sleep(1); diff --git a/platform/SH_PlatformInit.cpp b/platform/SH_PlatformInit.cpp index d80e1d6..2967b43 100644 --- a/platform/SH_PlatformInit.cpp +++ b/platform/SH_PlatformInit.cpp @@ -12,7 +12,7 @@ int GlobalConfig::LinkCount = 0; int GlobalConfig::net0Status = 1; -std::string GlobalConfig::Version = "3.2.5"; +std::string GlobalConfig::Version = "3.2.6"; std::string GlobalConfig::MacAddr_G = ""; std::string GlobalConfig::MacAddr_G2 = ""; std::string GlobalConfig::IpAddr_G = ""; diff --git a/threadfunc/SH_ThreadFunc.cpp b/threadfunc/SH_ThreadFunc.cpp index eab25ea..674ea86 100644 --- a/threadfunc/SH_ThreadFunc.cpp +++ b/threadfunc/SH_ThreadFunc.cpp @@ -13,6 +13,9 @@ #include "../dial5G/Dial.h" #include "../wifi/wpa_client.h" #include +#include "../localserver/cmt_server.hpp" + +std::unique_ptr g_mgr_server; namespace{ Uart *pUart = Uart::instance(); @@ -497,7 +500,12 @@ void RunLED() sleep(1); } } - +void StartCMTServer() { + sleep(2); + boost::asio::io_service io_service; + g_mgr_server = std::make_unique(io_service, 10000); + io_service.run(); +} void HeartRep() { int count = 0; diff --git a/threadfunc/SH_ThreadFunc.hpp b/threadfunc/SH_ThreadFunc.hpp index 8f35074..0853d53 100644 --- a/threadfunc/SH_ThreadFunc.hpp +++ b/threadfunc/SH_ThreadFunc.hpp @@ -25,6 +25,7 @@ extern void StartMqttClient(); //启动mqtt服务 extern void SearchThread(); //组播功能, 提供发现设备功能 extern void RecvUpdateFile(); //更新升级包 extern void StartCgiServer(); //启动cgi处理服务端 +extern void StartCMTServer(); extern void HeartRep(); extern void UartStart(); // extern void TestUart(); diff --git a/uart/SH_Uart.cpp b/uart/SH_Uart.cpp index 668e044..820d824 100644 --- a/uart/SH_Uart.cpp +++ b/uart/SH_Uart.cpp @@ -26,6 +26,7 @@ std::vector g_VecWaveDataX; std::vector g_VecWaveDataY; std::vector g_VecWaveDataZ; map g_mapCompress; +char mqttData[1024000] = {0}; // namespace{ // PlatformInit *platform = PlatformInit::instance(); // LocalServer *wlServer = LocalServer::instance(); @@ -3963,31 +3964,28 @@ void Uart::WriteDatFile(int sampleRate,string& strMeasurementID,int iChannel,std FILE *fp = fopen(strFileName.c_str(), "w"); - fwrite(localtimestamp,sizeof(localtimestamp),1,fp); - print_info("fopen FIle vecData.size : %d\n", vecData.size()); - float mean = pCalculation->mean(vecData); - float frTemp; - char buf[33]={0x00}; - std::string strWaveData = ""; - for (int i = 0; i < vecData.size(); i++) { - frTemp = vecData[i] - mean; - fwrite(&frTemp,sizeof(float),1,fp); - memset(buf,0x00,sizeof(buf)); - sprintf(buf, "%.2f", frTemp); - std::string waveTemp(buf); - if(i == 0) - strWaveData = waveTemp; - else - strWaveData = strWaveData + "," + waveTemp; - - if (i % 100 == 0) - { - mssleep(5000); + fwrite(localtimestamp,sizeof(localtimestamp),1,fp); + LOG_INFO( " vecData.size : %d,start \n", vecData.size()); + int id = 0; + char buf[33] = {0x00}; + float mean = pCalculation->mean(vecData); + float frTemp; + for (size_t i = 0; i < vecData.size(); i++) { + frTemp = vecData[i] - mean; + memset(buf, 0x00, sizeof(buf)); + sprintf(buf, "%.2f", frTemp); + fwrite(&frTemp,sizeof(float),1,fp); + if (i != vecData.size() -1){ + strncpy(mqttData + id ,buf,strlen(buf)); + id = id + strlen(buf); + strncpy(mqttData + id,",",1); + id = id + 1; + }else{ + strncpy(mqttData + id ,buf,strlen(buf)); } - } - + } + LOG_INFO( " vecData.size : %d,end \n", vecData.size()); fclose(fp); - // Json::Value valWaveData; int length = vecData.size(); valWaveData["number"] = sampleRate; @@ -3996,7 +3994,7 @@ void Uart::WriteDatFile(int sampleRate,string& strMeasurementID,int iChannel,std valWaveData["dataNodeGatewayNo"] = GlobalConfig::MacAddr_G; valWaveData["SensorEngineeringUnit"] = ""; valWaveData["timeStamp"] = nowTimetamp; - valWaveData["waveData"] = strWaveData; + valWaveData["waveData"] = mqttData; valWaveData["mean"] = mean; Json::FastWriter WaveValue; std::string WaveData = WaveValue.write(valWaveData);