#include #include #include #include #include #include #include #include #include #include #include //C++ STL的list #include //C++ STL的map #include #include //zw修改 2023-08-22 存储数据合理性相关属性 #include //zw修改 2023-08-22 存储数据合理性相关属性 #include "mms_json_inter.h" //json头文件 #include "../mms/db_interface.h" //json头文件 #include "../mms/rdb_client.h" //台账更新引用接口 //lnk20241031用于上传和下载文件 #include "../json/cjson.h" ///////////////////////////////////////////////////lnk2024-10-21//////////////////////////////////////////////////////// extern void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr); extern std::string WEB_INTEGRITY; extern std::string WEB_COMFLAG; extern std::string WEB_EVENT; extern std::string WEB_FILEDOWNLOAD; extern std::string G_CONNECT_TOPIC; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// using namespace std; extern int parse_commerror_write(const std::vector& codes); extern int parse_commstatus_write(const std::vector& codes); extern int parse_match_write(const std::vector& codes); extern int parse_dataintegrity_write(const std::vector& codes); extern int parse_rationality_write(const std::vector& codes); extern std::string intToString(int number); QString JSON_CONFIG_FN = QString("JiangSu_Config.xml"); #define APR_SUCCESS 1 #define APR_EBADPATH 0 #define APR_EBADF 0 const string PhsSTR = "ABCT"; extern int FILE_FLAG; //lnk20250214 extern int isdelta_flag; //江苏Kafka发送数据类定义-------------------------------------------------------------/* class CEventData //SOE事件类 { public: int nDataType; //告警SOE事件类型 QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 QString triggerFlag; //告警SOE事件触发指标名称 int nIndex; //数据在每条线路LineInfo值数组中的位置 QString DO; //数据对象名 QString DA; //数据属性名 QString strFullName; //数据对象名 $ 数据属性名 }; class CDataValue //数据值类 { public: QString strName; //数据名 float fValue; //数据值 bool bIsValue; //数据是否赋值成功标识 int nIndex; //数据在每条线路LineInfo值数组中的位置 QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 QString DO; //数据对象名 QString DA; //数据属性名 QString strFullName; //数据对象名 $ 数据属性名 QString strCoefficient; //数据系数(字符型) float fCoefficient; //数据系数(浮点型) QString strOffset; //起始序号偏移量(字符型) int iOffset; //起始序号偏移量(整型) = 江苏电科院臻迪数据项起始序号 - 装置数据项实际起始序号 bool bIsAngle; //角度标志 WW 2018-06-28 bool bPlt; //长时闪变标识:true-长时闪变 false-短时闪变 QString BaseFlag; //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown QString LimitUp; //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown QString LimitDown; //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown CDataValue() { fCoefficient = 1.0f; //数据系数(浮点型) iOffset = 0; //起始序号偏移量(整型) bIsAngle = false; //非角度标志 bPlt = false; //短时闪变标识 } }; class CSequence //相别(A、B、C、T)类 { public: QString strSValue; //相别值 例:7:ABC三项,8:T相 QString strSeq; //相别 例:A、B、C、T QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 list DataValueList; //数据值链表 }; class CItem //数据项类 { public: QString strItemName; //数据项名 QString strItemValue; //数据项值 QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 list SequenceList; //相别链表 }; class CMonitor //监测点类 { public: QString strMonitor; //监测点名 QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 list ItemList; //数据项链表 }; class CDataType //数据类型类 { public: int iDataType; //数据类型值:1-稳态 2-闪变 3-暂态 QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 int BaseFlag1; //zw修改 2023-8-25 记录基础数据总个数 int BaseFlag0; //zw修改 2023-8-25 记录非基础数据个数 list MonitorList; //监测点链表 list SOEList; //SOE事件链表 }; class CTopic //Kafka Producer发送主题类 { public: QString strTopic; //Kafka Producer发送主题值 list DataTypeList; //数据类型链表 }; class XmlConfig //zw修改 2023 - 8 - 14 增加xml解析的配置类 { public: QString WavePhasicFlag; //是否分相 0-不分相 1-分相 如果Flag=0 A,B,C配置成一样,如果Flag=1,A,B,C根据实际配置 QString WavePhasicA; QString WavePhasicB; QString WavePhasicC; QString UnitOfTimeUnit; //暂态事件持续事件单位:0 - 毫秒 1 - 秒 QString ValueOfTimeUnit; //上送值的时间:UTC-UTC时间 beijing-北京时间 QString WaveTimeFlag; //录波文件的时间:UTC-UTC时间 beijing-北京时间 QString IEDname; //例:PQMonitor QString LDevicePrefix; //例:PQM list SOEList; //SOE告警事件链表 }; class XmlDataBase //zw修改 2023-8-30 增加解析数据库模型表数据类 { public: QString MODEL_ID;//模型编码 guid QString TMNL_TYPE;//终端型号 QString TMNL_FACTORY;//终端厂家 QString FILE_PATH;//远端模型文件路径 lnk2024-10-28 QString FILE_NAME;//oss文件存储路径 QDateTime datetime;//更新时间 时间戳 }; class MP_RATIONALITY //zw修改 2023 - 8 - 22 增加数据不合理性记录类 { public: double fValue;//zw修改 2023-08-22 第一次记录的不合理数值 QDateTime dtvalue;//zw修改 2023-08-22 第一次记录的不合理数值出现时间 int over_time;//zw修改 2023-08-22 该记录属性不合理数值出现次数 }; class Mn_Timespan //zw修改 2023-08-29 时间间隔保存类 { public: QList timespan;//时间戳队列 int msspan; Mn_Timespan() { msspan = 0; } }; class Xmldata //zw修改 2023-08-30 { public: XmlDataBase xmlbase;//xml数据库数据 XmlConfig xmlcfg;//新増的xml节点解析数据 list topicList; //Kafka发送主题链表 bool updataflag = true; }; //-------------------------------------------------------------------------------------*/ //主程序已定义该变量 //extern QMutex kafka_data_list_mutex; //Kafka发送数据锁 //extern QList kafka_data_list; //kafka发送数据链表 extern int FILE_FLAG; QMutex kafka_data_list_mutex; //Kafka发送数据锁 QList kafka_data_list; //kafka发送数据链表 QMutex oss_data_list_mutex; //oss发送数据锁 zw新增 QList oss_data_list; //oss发送数据链表 zw新增 //-------------------------------------------------------------------------------------*/ //////////////////////////////////////WW 2023-08-22 start QMutex Sql_data_list_mutex; //Sql执行语句锁 QList Sql_data_list; //Sql执行语句链表 //////////////////////////////////////WW 2023-08-22 end //QMap > error_data_list;//zw修改 2023 - 8 - 22 新増数据不合理性记录map //QMap > error_datamatch_list;//zw修改 2023-8-28 数据匹配率缺少字段记录map QMap data_timespan_list;//zw修改 2023 - 8 - 29 计算时间间隔 QMap xmlinfo_list;//zw修改 保存所有型号对应的xml数据-数据库数据 新增的节点解析数据 kafka发送链表 XmlConfig xmlcfg;//zw修改 2023 - 8 - 14 新増xml节点解析的数据 list topicList; //Kafka发送主题链表 int inited = false; //JiangSu_Config.xml是否初始化标识 XmlConfig xmlcfg2;//lnk2024 - 8 - 13 新増角型xml节点解析的数据 list topicList2; //lnk2024-8-14角型Kafka发送主题链表 QMap xmlinfo_list2;//lnk2024-8-14 保存角型所有型号对应的xml数据-数据库数据 新增的节点解析数据 kafka发送链表 extern int isdelta_flag;//lnk2024-8-16 角型接线标志 ///////////////////////////////////////////////lnk20241021替换web接口////////////////////////////////// void connectlog_pgsql(char* id,char* datetime,int status); void errorlog_pgsql(char* id, QString time, QString filename); void SoeRptSql(char* id, int state,char* rpt); QString errorlog_num_pgsql(QString monitorId, QString datatime, QString filename, int count); QString errorlog_dataintegrity_pgsql(QString time, QString datatime,QString monitorId,bool recallflag); QString errorlog_datamatch_pgsql(QString id, QString time, int BASE_MAT_NUM,int ADV_MAT_NUM,int BASE_ACT_NUM,int ADV_ACT_NUM,QString filename); #if 0 void connectlog_pgsql(char* id) { QString pgsql; pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_status_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',1) ").arg(id).arg(QDateTime::currentDateTime().toString("yyyyMMdd"))); pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\") do update set ")); pgsql.append(QString("\"comm_status\"= \"%1\".\"%2meas_pq_comm_status_tr\".\"comm_status\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 //cout << pgsql.toAscii().data() << endl; } //zw修改 2023 - 8 - 24 新增异常事件 pgsql组装函数 终端id 发生当日时间 存储文件路径 void errorlog_pgsql(char* id, QString time, QString filename) { QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',1,'%3') ").arg(id).arg(time).arg(filename)); pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\") do update set ")); pgsql.append(QString("\"comm_status\"= \"%1\".\"%2meas_pq_comm_error_tr\".\"comm_status\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << pgsql.toAscii().data() << endl; } //zw修改 20240115 新增暂降触发报告记录 void SoeRptSql(char* id, int state,char* rpt) { QDateTime savetime = QDateTime::currentDateTime(); QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(id).arg(savetime.toString("yyyyMMdd")).arg(state).arg(rpt)); pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\",\"file_name\") do update set ")); pgsql.append(QString("\"comm_status\"= %1;").arg(state)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 } #endif //zw修改 2023 - 8 - 18 新增异常事件 json组装函数 终端id 终端ip 终端端口 日志来源 异常类别 void errorlog_json(char* id,char* ip,int port,int type,char* error_type,char* ERROR_DES,char* ERROR_PARAM) { if (id == NULL || ip == NULL || port == NULL || type == NULL || error_type == NULL) { cout << "Function errorlog_json Error!" << endl; } QString json;//待组装的json日志 json.append("{"); json.append(QString("\"TERMINAL_ID\": \"%1\",").arg(id));//装置ID json.append(QString("\"COMM_TIME\": \"%1\",").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")));//发生时间 json.append(QString("\"TMNL_IP\": \"%1\",").arg(ip));//终端IP json.append(QString("\"TMNL_PORT\": \"%1\",").arg(port));//终端端口号 json.append(QString("\"COMM_TYPE\": \"%1\",").arg(type));//日志来源 json.append(QString("\"ERROR_TYPE\": \"%1\",").arg(error_type));//异常类别 json.append(QString("\"ERROR_DES\": \"%1\",").arg(ERROR_DES));//错误描述 json.append(QString("\"ERROR_PARAM\": \"%1\"").arg(ERROR_PARAM));//关键参数 json.append("}"); cout << json.toAscii().data() << endl; QDateTime savetime = QDateTime::currentDateTime(); QString Qfilename, Qsavename; Qfilename.append("comtrade/").append(id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_COMM.log"); Qsavename.append("/FeProject/dat/").append(id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_COMM.log"); char file_name[256]; memset(file_name, 0, 256); sprintf(file_name, "%s", Qfilename.toAscii().data()); char save_name[256]; memset(save_name, 0, 256); sprintf(save_name, "%s", Qsavename.toAscii().data()); //cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; oss_data_t OssData; OssData.filename = file_name; OssData.savename = save_name; OssData.data = json; OssData.id = QString(id); OssData.time = savetime.toString("yyyyMMdd"); //时间 OssData.log_name = "comm"; oss_data_list_mutex.lock(); //加锁 oss_data_list.append(OssData); //添加 kafka发送链表 oss_data_list_mutex.unlock(); //解锁 //std::ofstream file(save_name); // 创建一个输出文件流对象,打开文件 example.txt //if (file.is_open()) { // 判断文件是否成功打开 // file << json.toAscii().data() << "\n"; // file.close(); // 关闭文件 //} //else { // std::cerr << "Unable to open file\n"; //} //PutOSS(file_name, save_name); //std::remove(save_name); //errorlog_pgsql(id, savetime.toString("yyyyMMdd"), Qfilename); } //zw修改 2023 - 8 - 23 数值合理性判断函数 节点属性 实际值 电压等级 存储map void errorlog_num(CDataValue* pDataValue, double value, double UL, QMap *map_list,long long time) { if(pDataValue == NULL) { cout << "Function errorlog_num Error!" <LimitUp.toAscii().data() << pDataValue->LimitDown.toAscii().data() << endl; if (pDataValue->LimitUp != "not define" && pDataValue->LimitDown != "not define" && UL != 0)//zw修改 2023-8-23 数据合理性判断 { double limitup = 0, limitdown = 0; if (pDataValue->LimitUp.indexOf("*%UN") != -1) { QString tmp = pDataValue->LimitUp; float temp = tmp.replace("*%UN", "").toFloat(); limitup = temp * UL; } else if (pDataValue->LimitUp.indexOf("*%U") != -1) { QString tmp = pDataValue->LimitUp; float temp = tmp.replace("*%U", "").toFloat(); limitup = (temp * UL) / 1.732f; } else { limitup = pDataValue->LimitUp.toFloat(); } if (pDataValue->LimitDown.indexOf("*%UN") != -1) { QString tmp = pDataValue->LimitDown; float temp = tmp.replace("*%UN", "").toFloat(); limitdown = temp * UL; } else if (pDataValue->LimitDown.indexOf("*%U") != -1) { QString tmp = pDataValue->LimitDown; float temp = tmp.replace("*%U", "").toFloat(); limitdown = (temp * UL) / 1.732f; } else { limitdown = pDataValue->LimitDown.toFloat(); } //cout << limitdown << "||||" << limitup << "||||" << UL << endl; if (pDataValue->LimitUp != "0" || pDataValue->LimitDown != "0") { if (value < limitdown || value >limitup)//合理性判断 { if (!map_list->contains(pDataValue->strFullName)) { MP_RATIONALITY* tmp_data = new MP_RATIONALITY(); tmp_data->fValue = value; tmp_data->over_time = 0; tmp_data->dtvalue = QDateTime::fromTime_t(time / 1000); map_list->insert(pDataValue->strFullName, tmp_data); } map_list->value(pDataValue->strFullName)->over_time++; } } } } //zw修改 2023 - 8 - 23 数值合理性判断 异常数值转换json和pgsql QString errorlog_num_json(QString monitorId, QMap map_list) { int count = 0; QString log_json;//待生成的json字符串 QMap tmp = map_list; for (QMap::iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { count++; QString key2 = it2.key(); MP_RATIONALITY* value2 = it2.value(); log_json.append("{"); log_json.append(QString("\"strFullName\":\"%1\", ").arg(key2));//不合理值全称 log_json.append(QString("\"value\":\"%1\", ").arg(value2->fValue));//不合理值 log_json.append(QString("\"datetime\":\"%1\"").arg(value2->dtvalue.toString("yyyy-MM-dd hh:mm:ss")));//不合理值发生时间 log_json.append("}"); } return log_json; } ///////////////////////////////////////////////lnk20241021替换web接口////////////////////////////////// #if 0 //2023 9-18 合理性数据 pgsql语句生成 QString errorlog_num_pgsql(QString monitorId, QString datatime, QString filename, int count) { QString log_pqsql;//待生成的pgsql语句 log_pqsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_rationality_tr\"(\"monitor_id\",\"statistical_date\",\"irrat_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); log_pqsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(monitorId).arg(datatime).arg(count).arg(filename)); log_pqsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(log_pqsql); Sql_data_list_mutex.unlock(); //解锁 return log_pqsql; } //zw修改 2023 - 8 - 24 数值完整性判断 单条pgsql插入语句生成 终端id 插入天数2023-08-15 数据时间2023-08-15 19:15:00 QString errorlog_dataintegrity_pgsql(QString time, QString datatime,QString monitorId,bool recallflag) { int num = 480; if (data_timespan_list[monitorId]->msspan != 0) { num = 1440 / data_timespan_list[monitorId]->msspan; } QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_intact_tr\"(\"monitor_id\",\"statistical_date\",\"exp_num\",\"act_num\",\"value_time\",\"last_value_time\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',480,1,array[TIMESTAMP'%3'],'%4') ").arg(monitorId).arg(time).arg(datatime).arg(datatime)); pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do update set ")); //pgsql.append(QString("\"value_time\"=(array_cat(EXCLUDED.\"value_time\", \"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\"))[:1440] , \"exp_num\" = %3 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); if (recallflag == true) { if (data_timespan_list[monitorId]->msspan != 0) { pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); } else { pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); } } else { pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); } Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 return pgsql; } #endif //zw修改 2023-8-24 数值完整性判断 保存时间戳 void errorlog_dataintegrity_timespanlist(QString monitorId,long long time) { if (!data_timespan_list.contains(monitorId))//zw修改 计算时间间隔步骤 { Mn_Timespan* mn_tmp = new Mn_Timespan(); mn_tmp->timespan.append(time); data_timespan_list.insert(monitorId, mn_tmp); } else { if (data_timespan_list[monitorId]->timespan.count() <= 8) { data_timespan_list[monitorId]->timespan.append(time); } } } //zw修改 2023-8-24 数值完整性判断 计算时间间隔 void errorlog_dataintegrity_timespanlist_2(QString monitorId) { if (data_timespan_list[monitorId]->msspan == 0 && data_timespan_list[monitorId]->timespan.count() >= 8) //尝试计算完整性 { int count[10] = {0,0,0,0,0,0,0,0,0,0}; int tmp_sp = 0; qSort(data_timespan_list[monitorId]->timespan.begin(), data_timespan_list[monitorId]->timespan.end()); for (int i = 1; i < data_timespan_list[monitorId]->timespan.size(); i++) { int tmp_ms = data_timespan_list[monitorId]->timespan[i] - data_timespan_list[monitorId]->timespan[i - 1]; if (tmp_ms >= 30000 && tmp_ms <= 90000) { count[0]++; } else if (tmp_ms >= 90000 && tmp_ms <= 150000) { count[1]++; } else if (tmp_ms >= 150000 && tmp_ms <= 210000) { count[2]++; } else if (tmp_ms >= 210000 && tmp_ms <= 270000) { count[3]++; } else if (tmp_ms >= 270000 && tmp_ms <= 330000) { count[4]++; } else if (tmp_ms >= 330000 && tmp_ms <= 390000) { count[5]++; } else if (tmp_ms >= 390000 && tmp_ms <= 450000) { count[6]++; } else if (tmp_ms >= 450000 && tmp_ms <= 510000) { count[7]++; } else if (tmp_ms >= 510000 && tmp_ms <= 570000) { count[8]++; } else if (tmp_ms >= 570000 && tmp_ms <= 630000) { count[9]++; } } for (int i = 0; i < 10; i++) { if (count[i] != 0 && count[i] > tmp_sp) { tmp_sp = count[i]; data_timespan_list[monitorId]->msspan = i+1; } } } } //zw修改 2023 - 8 - 28 数据匹配率 map记录 数据全称 存储map void errorlog_datamatch(QString fullname, QMap *map_list) { if(!map_list->contains(fullname)) { map_list->insert(fullname, QDateTime::currentDateTime()); } } ///////////////////////////////////////////////lnk20241021替换web接口////////////////////////////////// #if 0 //zw修改 2023 - 8 - 25 数值匹配率判断 单条pgsql插入语句生成 终端id 插入天数2023-08-15 基础应有 完整应有 基础实际 完整实际 QString errorlog_datamatch_pgsql(QString id, QString time, int BASE_MAT_NUM,int ADV_MAT_NUM,int BASE_ACT_NUM,int ADV_ACT_NUM,QString filename) { QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_match_tr\"(\"monitor_id\",\"statistical_date\",\"base_mat_num\",\"adv_mat_num\",\"base_act_num\",\"adv_act_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',%3,%4,%5,%6,'%7') ").arg(id).arg(time).arg(BASE_MAT_NUM).arg(ADV_MAT_NUM).arg(BASE_ACT_NUM).arg(ADV_ACT_NUM).arg(filename)); pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); //pgsql.append(QString("\"BASE_ACT_NUM\"= %1 , \"ADV_ACT_NUM\"= %2;").arg(BASE_ACT_NUM).arg(ADV_ACT_NUM)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 return pgsql; } #endif //zw修改 2023-8-29 数值匹配率json格式生成 QString errorlog_datamatch_json(QMap data_match_map_1, QMap data_match_map_2,long long time) { QString log_json,fullnamelist;//待生成的json字符串 if (data_match_map_1.count() != 0) { for (QMap::iterator it2 = data_match_map_1.begin(); it2 != data_match_map_1.end(); ++it2) { QString key2 = it2.key(); QDateTime value2 = it2.value(); fullnamelist.append("\""); fullnamelist.append(key2);//不匹配的值全称 fullnamelist.append("\","); } } if (data_match_map_2.count() != 0) { for (QMap::iterator it2 = data_match_map_2.begin(); it2 != data_match_map_2.end(); ++it2) { QString key2 = it2.key(); QDateTime value2 = it2.value(); fullnamelist.append("\""); fullnamelist.append(key2);//不匹配的值全称 fullnamelist.append("\","); } } fullnamelist.chop(1); log_json.append(QString("{ \"datetime\": \"%1\",").arg(QDateTime::fromTime_t(time / 1000).toString("yyyy-MM-dd hh:mm:ss"))); log_json.append(QString(" \"LackDataName\": [%1] ").arg(fullnamelist)); log_json.append("}"); return log_json; } #if 0 bool ParseXMLConfig2(XmlConfig *cfg, list *ctopiclist,QString path) //解析JiangSu_Config.xml配置文件 { //cfg = new XmlConfig(); //注:①#7#代表通配符,用于通配数据类型 采用8421码,8-CP95 4-最小值 2-最大值 1-平均值 // ②%2,50%代表通配符,用于通配谐波数据,采用范围编码,第一个数字表示谐波起始号,第二个数字谐波结束号 // ③SEQ=后面的值采用8421码 8-T 4-C 2-B 1-A //注:type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 11-实时SOE事件 QString strPhasic[4] = { "A", "B", "C", "T" }; //数组枚举 相别(A-T) int nStart = 1, nEnd = 1; //谐波起、止次数 QString strValueTemp; //临时存放谐波次数字符串 例:%0,49% 或 %2,50% //加载JiangSu_Config.xml配置文件 //QString xml_dir = QString("D:/")+QString("PQD-9k/config/"); //相对路径读取xml失败,此处改用绝对路径! zl 2018-11-14 15:43:34 QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 if ("not define" == path) { QString xml_dir = QString("../") + QString("etc/"); //Linux下调试路径 QFile file(xml_dir + JSON_CONFIG_FN); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { std::cout << "can't open not define config file" << std::endl;//lnk20250208 return 0; } if (!doc.setContent(&file)) //将文件内容读到doc中 { std::cout << "can't read not define config file" << std::endl;//lnk20250208 file.close(); return 0; } file.close(); cout << "not define xml" << endl; } else { QString tmppath; tmppath.append("/FeProject/dat/").append(path).append(".xml"); QFile file(tmppath); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { std::cout << "can't open config file" << tmppath.toStdString() <strTopic = e.attribute("name"); //发送主题名 ctopiclist->push_back(topic); //添加 Kafka发送主题链表 //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if ("Topic" == strTag && ("HISDATA" == topic->strTopic || "RTDATA" == topic->strTopic)) //①读取Topic,HISDATA、RTDATA主题--------------------------------------------------- { QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { CDataType* dt = new CDataType(); //数据类型指针 dt->iDataType = node.toElement().attribute("value").toInt(); //数据类型值(1-实时/历史稳态、2-实时/历史闪变、3-实时/历史暂态、4-补招稳态、5-补招闪变、6-补招暂态) dt->type = node.toElement().attribute("type"); //参数等级 dt->BaseFlag0 = 0; dt->BaseFlag1 = 0; topic->DataTypeList.push_back(dt); //添加 数据类型链表 QString strTag2 = node.toElement().tagName(); //DataType节点 if ("DataType" == strTag2) //②读取数据类型DataType { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { CMonitor* mt = new CMonitor(); //监测点类型指针 mt->strMonitor = node2.toElement().attribute("name"); //监测点名称 注:该值需要从Rpt解析中获取监测点号 mt->type = node2.toElement().attribute("type"); //参数等级 dt->MonitorList.push_back(mt); //添加 监测点链表 QString strTag3 = node2.toElement().tagName(); //Monitor节点 if ("Monitor" == strTag3) //③读取监测点Monitor { QDomNodeList list3 = node2.childNodes(); //获得元素Monitor的所有子节点的列表 for (int i3 = 0; i3 < list3.count(); i3++) //遍历 Item列表 { QDomNode node3 = list3.at(i3); //node3 if (node3.isElement()) { CItem* it = new CItem(); //数据项类指针 it->strItemName = node3.toElement().attribute("name"); //FLAG、TIME、V、I、PQ it->type = node3.toElement().attribute("type"); //参数等级 if ("FLAG" == it->strItemName) //剔除标记(1:不剔除,0:剔除,默认剔除) it->strItemValue = node3.toElement().attribute("value"); //数据项值 mt->ItemList.push_back(it); //添加 数据项链表 QString strTag4 = node3.toElement().tagName(); //Item节点 if ("Item" == strTag4) //④读取数据项Item { QDomNodeList list4 = node3.childNodes(); //获得元素Item的所有子节点的列表 for (int i4 = 0; i4 < list4.count(); i4++) //遍历 Sequence列表 { QDomNode node4 = list4.at(i4); //node4 if (node4.isElement()) { QString strPhase = node4.toElement().attribute("value"); //相别 if ("7" == strPhase) //⑤-①读取ABC三相数据 { for (int n = 0; n < 3; n++) //遍历 相别(ABC三相) { CSequence* sq = new CSequence(); //ABC三相相别类指针 sq->strSValue = node4.toElement().attribute("value"); //相别值(7:ABC三相、8:T相) sq->type = node4.toElement().attribute("type"); //参数等级 sq->strSeq = strPhasic[n]; //相别赋值 例:A、B、C it->SequenceList.push_back(sq); //添加 相别链表 QString strTag5 = node4.toElement().tagName(); //Sequence节点 if ("Sequence" == strTag5) //⑤读取相别Sequence { QDomNodeList list5 = node4.childNodes(); //获得元素Sequence的所有子节点的列表 for (int i5 = 0; i5 < list5.count(); i5++) //遍历 ABC三相Value列表 { QDomNode node5 = list5.at(i5); //node5 if (node5.isElement()) { QDomElement e_Value = node5.toElement(); //将其转换为元素 QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点 if ("Value" == strTag6) //⑥读取ABC三相Value { QString strDVName = e_Value.attribute("name"); //数据名 QString strDAName = e_Value.attribute("DA"); //数据属性名 if (strDAName.indexOf("phs*") >= 0) //DA包含"phs*" strDAName = strDAName.replace("*", sq->strSeq); //将DA相别*替换为具体相别(A、B、C) 例:phsA$cVal$mag$f //⑥-①谐波数据读取(ABC三相)------------------------------------- if (strDVName.indexOf("%") >= 0 && strDAName.indexOf("%-") >= 0) //数据名包含% 且 DA包含%- 例:V_%0,49%_MAX { QStringList strHarm1 = strDVName.split('%'); if (strHarm1.count() >= 2) //例:V_ | 0,49 | _MAX { strValueTemp = "%" + strHarm1.at(1) + "%"; //例:%0,49% QStringList strHarm2 = strHarm1.at(1).split(','); //例:0,49 if (strHarm2.count() >= 2) { nStart = (strHarm2.at(0)).toInt(); //谐波起始次数 例:0 nEnd = (strHarm2.at(1)).toInt(); //谐波结束次数 例:49 } } QString substring = strDAName.mid(strDAName.indexOf("[") + 1, strDAName.indexOf("]") - strDAName.indexOf("[") - 1); QStringList strDAList1 = substring.split('-'); int strDAoffset = (strDAList1.at(1)).toInt(); for (int i = nStart; i <= nEnd; i++) //遍历 ABC三相谐波次数 { QString strDVNameTemp = strDVName; //临时 数据名 QString strDANameTemp = strDAName; //临时 数据属性名 CDataValue* dv1 = new CDataValue(); //ABC三相谐波数据值类指针 dv1->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv1->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv1->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv1->strOffset = e_Value.attribute("Offset"); //起始序号偏移量(字符型) dv1->iOffset = e_Value.attribute("Offset").toInt(); //起始序号偏移量(整型) = 江苏电科院臻迪数据项起始序号 - 装置数据项实际起始序号 dv1->DO = e_Value.attribute("DO"); //数据对象名 dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //将数据名中%0,49%替换为具体数字 例:SI_%0,49%变为SI_1 dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //将DA中%-2替换为具体数字 例:phs*Har[1]$mag$f //cout << dv1->strName.toAscii().data() << "--" << dv1->DA.toAscii().data() << " (" << dv1->iOffset << endl; //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv1->BaseFlag = e_Value.attribute("BaseFlag"); if (dv1->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv1->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv1->LimitUp = e_Value.attribute("LimitUp"); } else { dv1->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv1->LimitDown = e_Value.attribute("LimitDown"); } else { dv1->LimitDown = "not define"; } if (!dv1->DO.isEmpty() && !dv1->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv1->strFullName = dv1->DO + "$" + dv1->DA; else dv1->strFullName = "not define"; sq->DataValueList.push_back(dv1); //添加 数据链表(ABC三相) } //遍历ABC三相谐波次数 结束 //continue; //ABC三相谐波次数遍历完成后,继续读取下一节点 } else //⑥-②非谐波数据读取(ABC三相)------------------------------- { CDataValue* dv2 = new CDataValue(); //ABC三相非谐波数据值类指针 dv2->strName = e_Value.attribute("name"); //数据名 dv2->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv2->DO = e_Value.attribute("DO"); //数据对象名 dv2->DA = strDAName; //数据属性名 //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv2->BaseFlag = e_Value.attribute("BaseFlag"); if (dv2->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv2->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv2->LimitUp = e_Value.attribute("LimitUp"); } else { dv2->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv2->LimitDown = e_Value.attribute("LimitDown"); } else { dv2->LimitDown = "not define"; } if (!e_Value.attribute("PltFlag").isEmpty() && e_Value.attribute("PltFlag") == "True") //长时闪变标识 dv2->bPlt = true; //长时闪变标识 else dv2->bPlt = false; //短时闪变 或 其他数据 if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv2->strFullName = dv2->DO + "$" + dv2->DA; else dv2->strFullName = "not define"; sq->DataValueList.push_back(dv2); //添加 数据链表(ABC三相) } } //读取ABC三相Value 结束 } //判断node5为元素 结束 } //遍历ABC三相Value列表 结束 } //遍历 ABC三相 结束 } } //⑤-①读取ABC三相数据 结束 if ("8" == strPhase) //⑤-②读取T相数据 { CSequence* sq = new CSequence(); //T相相别类指针 sq->strSValue = node4.toElement().attribute("value"); //相别值 sq->type = node4.toElement().attribute("type"); //参数等级 sq->strSeq = strPhasic[3]; //相别赋值 it->SequenceList.push_back(sq); //添加 相别链表(T相) QDomNodeList list5 = node4.childNodes(); //获得元素Sequence的所有子节点的列表 for (int i5 = 0; i5 < list5.count(); i5++) //遍历 T相Value列表 { QDomNode node5 = list5.at(i5); //node5 if (node5.isElement()) { QDomElement e_Value = node5.toElement(); //将其转换为元素 QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点 if ("Value" == strTag6) //⑥读取T相Value { //⑥-①谐波数据读取(T相) 注:T相没有谐波数据 //⑥-②非谐波数据读取(T相) CDataValue* dv2 = new CDataValue(); //T相非谐波数据值类指针 dv2->strName = e_Value.attribute("name"); //数据名 dv2->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv2->DO = e_Value.attribute("DO"); //数据对象名 dv2->DA = e_Value.attribute("DA"); //数据属性名 //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv2->BaseFlag = e_Value.attribute("BaseFlag"); if (dv2->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv2->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv2->LimitUp = e_Value.attribute("LimitUp"); } else { dv2->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv2->LimitDown = e_Value.attribute("LimitDown"); } else { dv2->LimitDown = "not define"; } if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv2->strFullName = dv2->DO + "$" + dv2->DA; else dv2->strFullName = "not define"; sq->DataValueList.push_back(dv2); //添加 数据链表(ABC三相) } //读取T相Value 结束 } //判断node5为元素 结束 } //遍历T相Value列表 结束 } //⑤-②读取T相数据 结束 } //判断node4为元素 结束 } //遍历Sequence列表 结束 } //读取数据项Item 结束 } //判断node3为元素 结束 } //遍历Item列表 结束 } //读取Monitor节点 结束 } //判断node2为元素 结束 } //遍历Monitor列表 结束 } //读取数据类型DataType 结束 } //判断node为元素 结束 } //遍历DataType列表 结束 } //读取Topic节点HISDATA、RTDATA 结束 else if ("Topic" == strTag && "RTDATASOE" == topic->strTopic) //SOE事件------------------------------------------------------- { QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { CDataType* dt = new CDataType(); //数据类型类指针 dt->iDataType = node.toElement().attribute("value").toInt(); //数据类型值(1-稳态SOE、2-闪变SOE、3-暂态SOE) dt->type = node.toElement().attribute("type"); //参数等级 topic->DataTypeList.push_back(dt); //添加 数据类型链表 QString strTag2 = node.toElement().tagName(); //DataType节点 if ("DataType" == strTag2) //②读取数据类型DataType { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 SOE列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { CEventData* ed = new CEventData(); //SOE事件类指针 ed->triggerFlag = node2.toElement().attribute("TriggerFlag"); //SOE触发标识 ed->DO = node2.toElement().attribute("DO"); //数据对象名 ed->DA = node2.toElement().attribute("DA"); //数据属性名 ed->type = node2.toElement().attribute("type"); //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 if (!ed->DO.isEmpty() && !ed->DA.isEmpty()) //数据对象名和数据属性名均不为空 ed->strFullName = ed->DO + "$" + ed->DA; else ed->strFullName = "not define"; dt->SOEList.push_back(ed); //添加 SOE事件链表 } //判断node2为元素 结束 } //遍历SOE列表 结束 } //读取数据类型DataType节点 结束 } //判断node为元素 结束 } //遍历DataType列表 结束 } //Topic节点RTDATASOE 结束 else if ("Topic" == strTag && "SOEDATA" == topic->strTopic) { QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { CEventData* ed = new CEventData(); //SOE事件类指针 ed->triggerFlag = node.toElement().attribute("name"); //SOE名称 ed->DO = node.toElement().attribute("DO"); //数据对象名 ed->DA = node.toElement().attribute("DA"); //数据属性名 ed->type = node.toElement().attribute("type"); //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 if (!ed->DO.isEmpty() && !ed->DA.isEmpty()) //数据对象名和数据属性名均不为空 ed->strFullName = ed->DO + "$" + ed->DA; else ed->strFullName = "not define"; //cout << ed->triggerFlag.toAscii().data() << "=====" << ed->strFullName.toAscii().data() << endl; cfg->SOEList.push_back(ed); } } } } if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 { //cout << "ReportMap" << endl; } if ("Topic" != strTag && "ReportMap" != strTag)//zw修改 2023 - 8 - 14 增加判断 新增部分节点解析 { if ("WavePhasic" == strTag) { cfg->WavePhasicFlag.append(e.attribute("Flag")); if (cfg->WavePhasicFlag == "1") { cfg->WavePhasicA.append(e.attribute("A")); cfg->WavePhasicB.append(e.attribute("B")); cfg->WavePhasicC.append(e.attribute("C")); } } if ("UnitOfTime" == strTag) { cfg->UnitOfTimeUnit.append(e.attribute("Unit")); } if ("ValueOfTime" == strTag) { cfg->ValueOfTimeUnit.append(e.attribute("Unit")); } if ("ComtradeFile" == strTag) { cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag")); //cout << xmlcfg->WaveTimeFlag.toAscii().data() << endl; } if ("IED" == strTag) { cfg->IEDname.append(e.attribute("name")); //cout << xmlcfg->IEDname.toAscii().data() << endl; } if ("LDevice" == strTag) { cfg->LDevicePrefix.append(e.attribute("Prefix")); //cout<LDevicePrefix.toAscii().data() < RTDATA —> RTDATASOE) } //while (!n.isNull) 结束 return true; } #endif //lnk2024-8-16 适配角型接线 bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QString path) //解析JiangSu_Config.xml配置文件 { //cfg = new XmlConfig(); //注:①#7#代表通配符,用于通配数据类型 采用8421码,8-CP95 4-最小值 2-最大值 1-平均值 // ②%2,50%代表通配符,用于通配谐波数据,采用范围编码,第一个数字表示谐波起始号,第二个数字谐波结束号 // ③SEQ=后面的值采用8421码 8-T 4-C 2-B 1-A //注:type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 11-实时SOE事件 QString strPhasic[4] = { "A", "B", "C", "T" }; //数组枚举 相别(A-T) QString strLine[4] = { "AB", "BC", "CA", "T" }; //lnk2024-8-14数组枚举 角型相别(AB-T) int nStart = 1, nEnd = 1; //谐波起、止次数 QString strValueTemp; //临时存放谐波次数字符串 例:%0,49% 或 %2,50% //加载JiangSu_Config.xml配置文件 //QString xml_dir = QString("D:/")+QString("PQD-9k/config/"); //相对路径读取xml失败,此处改用绝对路径! zl 2018-11-14 15:43:34 QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 if ("not define" == path) { QString xml_dir = QString("../") + QString("etc/"); //Linux下调试路径 QFile file(xml_dir + JSON_CONFIG_FN); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { return 0; } if (!doc.setContent(&file)) //将文件内容读到doc中 { file.close(); return 0; } file.close(); cout << "not define xml" << endl; } else { QString tmppath; tmppath.append("/FeProject/dat/").append(path).append(".xml"); QFile file(tmppath); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { return 0; } if (!doc.setContent(&file)) //将文件内容读到doc中 { file.close(); return 0; } file.close(); cout << "define xml" << endl; } //将xml文件内容读到doc中 QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate" QDomElement docElem = doc.documentElement(); //返回根节点元素 QDomNode n = docElem.firstChild(); //获得doc的第一个节点,即"Topic" while (!n.isNull()) //如果Topic节点不为空 { if (n.isElement()) { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); //Topic节点 if ("Topic" == strTag)//zw修改 2023 - 8 - 14 增加判断 将topic节点和其他节点的解析分离 { CTopic* topic = new CTopic(); //发送主题类指针 topic->strTopic = e.attribute("name"); //发送主题名 ctopiclist->push_back(topic); //添加 Kafka发送主题链表 //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if ("Topic" == strTag && ("HISDATA" == topic->strTopic || "RTDATA" == topic->strTopic)) //①读取Topic,HISDATA、RTDATA主题--------------------------------------------------- { QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { CDataType* dt = new CDataType(); //数据类型指针 dt->iDataType = node.toElement().attribute("value").toInt(); //数据类型值(1-实时/历史稳态、2-实时/历史闪变、3-实时/历史暂态、4-补招稳态、5-补招闪变、6-补招暂态) dt->type = node.toElement().attribute("type"); //参数等级 dt->BaseFlag0 = 0; dt->BaseFlag1 = 0; topic->DataTypeList.push_back(dt); //添加 数据类型链表 QString strTag2 = node.toElement().tagName(); //DataType节点 if ("DataType" == strTag2) //②读取数据类型DataType { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { CMonitor* mt = new CMonitor(); //监测点类型指针 mt->strMonitor = node2.toElement().attribute("name"); //监测点名称 注:该值需要从Rpt解析中获取监测点号 mt->type = node2.toElement().attribute("type"); //参数等级 dt->MonitorList.push_back(mt); //添加 监测点链表 QString strTag3 = node2.toElement().tagName(); //Monitor节点 if ("Monitor" == strTag3) //③读取监测点Monitor { QDomNodeList list3 = node2.childNodes(); //获得元素Monitor的所有子节点的列表 for (int i3 = 0; i3 < list3.count(); i3++) //遍历 Item列表 { QDomNode node3 = list3.at(i3); //node3 if (node3.isElement()) { CItem* it = new CItem(); //数据项类指针 it->strItemName = node3.toElement().attribute("name"); //FLAG、TIME、V、I、PQ it->type = node3.toElement().attribute("type"); //参数等级 if ("FLAG" == it->strItemName) //剔除标记(1:不剔除,0:剔除,默认剔除) it->strItemValue = node3.toElement().attribute("value"); //数据项值 mt->ItemList.push_back(it); //添加 数据项链表 QString strTag4 = node3.toElement().tagName(); //Item节点 if ("Item" == strTag4) //④读取数据项Item { QDomNodeList list4 = node3.childNodes(); //获得元素Item的所有子节点的列表 for (int i4 = 0; i4 < list4.count(); i4++) //遍历 Sequence列表 { QDomNode node4 = list4.at(i4); //node4 if (node4.isElement()) { QString strPhase = node4.toElement().attribute("value"); //相别 if ((!xml_flag || "V" != it->strItemName) && "7" == strPhase) //⑤-①读取ABC三相数据 //lnk2024-8-14 角型判断 { for (int n = 0; n < 3; n++) //遍历 相别(ABC三相) { CSequence* sq = new CSequence(); //ABC三相相别类指针 sq->strSValue = node4.toElement().attribute("value"); //相别值(7:ABC三相、8:T相) sq->type = node4.toElement().attribute("type"); //参数等级 sq->strSeq = strPhasic[n]; //相别赋值 例:A、B、C it->SequenceList.push_back(sq); //添加 相别链表 QString strTag5 = node4.toElement().tagName(); //Sequence节点 if ("Sequence" == strTag5) //⑤读取相别Sequence { QDomNodeList list5 = node4.childNodes(); //获得元素Sequence的所有子节点的列表 for (int i5 = 0; i5 < list5.count(); i5++) //遍历 ABC三相Value列表 { QDomNode node5 = list5.at(i5); //node5 if (node5.isElement()) { QDomElement e_Value = node5.toElement(); //将其转换为元素 QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点 if ("Value" == strTag6) //⑥读取ABC三相Value { QString strDVName = e_Value.attribute("name"); //数据名 QString strDAName = e_Value.attribute("DA"); //数据属性名 if (strDAName.indexOf("l_phs*") >= 0){ //DA包含"l_phs*"//lnk20250221星形接线也可以接受PPV strDAName = strDAName.replace("l_phs", "phs"); strDAName = strDAName.replace("*", strLine[n]); //qDebug() << "strDAName:" << strDAName << endl;//调试用 } //将DA相别*替换为具体相别(AB、BC、CA) 例:phsAB$cVal$mag$f else if (strDAName.indexOf("phs*") >= 0) {//DA包含"phs*" strDAName = strDAName.replace("*", sq->strSeq);} //将DA相别*替换为具体相别(A、B、C) 例:phsA$cVal$mag$f //⑥-①谐波数据读取(ABC三相)------------------------------------- if (strDVName.indexOf("%") >= 0 && strDAName.indexOf("%-") >= 0) //数据名包含% 且 DA包含%- 例:V_%0,49%_MAX { QStringList strHarm1 = strDVName.split('%'); if (strHarm1.count() >= 2) //例:V_ | 0,49 | _MAX { strValueTemp = "%" + strHarm1.at(1) + "%"; //例:%0,49% QStringList strHarm2 = strHarm1.at(1).split(','); //例:0,49 if (strHarm2.count() >= 2) { nStart = (strHarm2.at(0)).toInt(); //谐波起始次数 例:0 nEnd = (strHarm2.at(1)).toInt(); //谐波结束次数 例:49 } } QString substring = strDAName.mid(strDAName.indexOf("[") + 1, strDAName.indexOf("]") - strDAName.indexOf("[") - 1); QStringList strDAList1 = substring.split('-'); int strDAoffset = (strDAList1.at(1)).toInt(); for (int i = nStart; i <= nEnd; i++) //遍历 ABC三相谐波次数 { QString strDVNameTemp = strDVName; //临时 数据名 QString strDANameTemp = strDAName; //临时 数据属性名 CDataValue* dv1 = new CDataValue(); //ABC三相谐波数据值类指针 dv1->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv1->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv1->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv1->strOffset = e_Value.attribute("Offset"); //起始序号偏移量(字符型) dv1->iOffset = e_Value.attribute("Offset").toInt(); //起始序号偏移量(整型) = 江苏电科院臻迪数据项起始序号 - 装置数据项实际起始序号 dv1->DO = e_Value.attribute("DO"); //数据对象名 dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //将数据名中%0,49%替换为具体数字 例:SI_%0,49%变为SI_1 dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //将DA中%-2替换为具体数字 例:phs*Har[1]$mag$f //cout << dv1->strName.toAscii().data() << "--" << dv1->DA.toAscii().data() << " (" << dv1->iOffset << endl; //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv1->BaseFlag = e_Value.attribute("BaseFlag"); if (dv1->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv1->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv1->LimitUp = e_Value.attribute("LimitUp"); } else { dv1->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv1->LimitDown = e_Value.attribute("LimitDown"); } else { dv1->LimitDown = "not define"; } if (!dv1->DO.isEmpty() && !dv1->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv1->strFullName = dv1->DO + "$" + dv1->DA; else dv1->strFullName = "not define"; sq->DataValueList.push_back(dv1); //添加 数据链表(ABC三相) } //遍历ABC三相谐波次数 结束 //continue; //ABC三相谐波次数遍历完成后,继续读取下一节点 } else //⑥-②非谐波数据读取(ABC三相)------------------------------- { CDataValue* dv2 = new CDataValue(); //ABC三相非谐波数据值类指针 dv2->strName = e_Value.attribute("name"); //数据名 dv2->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv2->DO = e_Value.attribute("DO"); //数据对象名 dv2->DA = strDAName; //数据属性名 //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv2->BaseFlag = e_Value.attribute("BaseFlag"); if (dv2->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv2->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv2->LimitUp = e_Value.attribute("LimitUp"); } else { dv2->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv2->LimitDown = e_Value.attribute("LimitDown"); } else { dv2->LimitDown = "not define"; } if (!e_Value.attribute("PltFlag").isEmpty() && e_Value.attribute("PltFlag") == "True") //长时闪变标识 dv2->bPlt = true; //长时闪变标识 else dv2->bPlt = false; //短时闪变 或 其他数据 if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv2->strFullName = dv2->DO + "$" + dv2->DA; else dv2->strFullName = "not define"; sq->DataValueList.push_back(dv2); //添加 数据链表(ABC三相) } } //读取ABC三相Value 结束 } //判断node5为元素 结束 } //遍历ABC三相Value列表 结束 } //遍历 ABC三相 结束 } } //⑤-①读取ABC三相数据 结束 if (xml_flag && "V" == it->strItemName && "112" == strPhase) //lnk2024-8-13角型 { for (int n = 0; n < 3; n++) //遍历 相别(AB、BC、CA三相) { CSequence* sq = new CSequence(); //AB、BC、CA三相别类指针 sq->strSValue = node4.toElement().attribute("value"); //相别值(7:ABC三相、112:线AB,BC,CA 8:T相) sq->type = node4.toElement().attribute("type"); //参数等级 sq->strSeq = strLine[n]; //相别赋值 例:AB、BC、CA it->SequenceList.push_back(sq); //添加 相别链表 QString strTag5 = node4.toElement().tagName(); //Sequence节点 if ("Sequence" == strTag5) //⑤读取相别Sequence { QDomNodeList list5 = node4.childNodes(); //获得元素Sequence的所有子节点的列表 for (int i5 = 0; i5 < list5.count(); i5++) //遍历 AB、BC、CA三相Value列表 { QDomNode node5 = list5.at(i5); //node5 if (node5.isElement()) { QDomElement e_Value = node5.toElement(); //将其转换为元素 QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点 if ("Value" == strTag6) //⑥读取AB、BC、CA三相Value { QString strDVName = e_Value.attribute("name"); //数据名 QString strDAName = e_Value.attribute("DA"); //数据属性名 if (strDAName.indexOf("phs*") >= 0) //DA包含"phs*" strDAName = strDAName.replace("*", sq->strSeq); //将DA相别*替换为具体相别(AB、BC、CA) 例:phsAB$cVal$mag$f //⑥-①谐波数据读取(AB、BC、CA三相)------------------------------------- if (strDVName.indexOf("%") >= 0 && strDAName.indexOf("%-") >= 0) //数据名包含% 且 DA包含%- 例:V_%0,49%_MAX { QStringList strHarm1 = strDVName.split('%'); if (strHarm1.count() >= 2) //例:%0,49% { strValueTemp = "%" + strHarm1.at(1) + "%"; //例:%0,49% QStringList strHarm2 = strHarm1.at(1).split(','); //例:0,49 if (strHarm2.count() >= 2) { nStart = (strHarm2.at(0)).toInt(); //谐波起始次数 例:0 nEnd = (strHarm2.at(1)).toInt(); //谐波结束次数 例:49 } } QString substring = strDAName.mid(strDAName.indexOf("[") + 1, strDAName.indexOf("]") - strDAName.indexOf("[") - 1); QStringList strDAList1 = substring.split('-'); int strDAoffset = (strDAList1.at(1)).toInt(); for (int i = nStart; i <= nEnd; i++) //遍历 AB、BC、CA三相谐波次数 { QString strDVNameTemp = strDVName; //临时 数据名 QString strDANameTemp = strDAName;//临时 数据属性名 CDataValue* dv1 = new CDataValue(); //AB、BC、CA三相谐波数据值类指针 dv1->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv1->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv1->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv1->strOffset = e_Value.attribute("Offset"); //起始序号偏移量(字符型) dv1->iOffset = e_Value.attribute("Offset").toInt(); //起始序号偏移量(整型) = 江苏电科院臻迪数据项起始序号 - 装置数据项实际起始序号 dv1->DO = e_Value.attribute("DO"); //数据对象名 std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl; std::cout << dv1->DO.toUtf8().constData() << std::endl; //lnk 输出ppv std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl; dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //将数据名中%0,49%替换为具体数字 例:SI_%0,49%变为SI_1 dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //将DA中%-2替换为具体数字 例:phs*Har[1]$mag$f //cout << dv1->strName.toAscii().data() << "--" << dv1->DA.toAscii().data() << " (" << dv1->iOffset << endl; //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv1->BaseFlag = e_Value.attribute("BaseFlag"); if (dv1->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv1->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv1->LimitUp = e_Value.attribute("LimitUp"); } else { dv1->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv1->LimitDown = e_Value.attribute("LimitDown"); } else { dv1->LimitDown = "not define"; } if (!dv1->DO.isEmpty() && !dv1->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv1->strFullName = dv1->DO + "$" + dv1->DA; else dv1->strFullName = "not define"; sq->DataValueList.push_back(dv1); //添加 数据链表(AB、BC、CA三相) } //遍历ABC三相谐波次数 结束 //continue; //AB、BC、CA三相谐波次数遍历完成后,继续读取下一节点 } else //⑥-②非谐波数据读取(AB、BC、CA三相)------------------------------- { CDataValue* dv2 = new CDataValue(); //ABC三相非谐波数据值类指针 dv2->strName = e_Value.attribute("name"); //数据名 dv2->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv2->DO = e_Value.attribute("DO"); //数据对象名 dv2->DA = strDAName; //数据属性名 //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv2->BaseFlag = e_Value.attribute("BaseFlag"); if (dv2->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv2->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv2->LimitUp = e_Value.attribute("LimitUp"); } else { dv2->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv2->LimitDown = e_Value.attribute("LimitDown"); } else { dv2->LimitDown = "not define"; } if (!e_Value.attribute("PltFlag").isEmpty() && e_Value.attribute("PltFlag") == "True") //长时闪变标识 dv2->bPlt = true; //长时闪变标识 else dv2->bPlt = false;//短时闪变 或 其他数据 if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv2->strFullName = dv2->DO + "$" + dv2->DA; else dv2->strFullName = "not define"; sq->DataValueList.push_back(dv2); //添加 数据链表(AB、BC、CA三相) } } //读取AB、BC、CA三相Value 结束 }//判断node5为元素 结束 } //遍历AB、BC、CA三相Value列表 结束 } //遍历 AB、BC、CA三相 结束 } }//⑤-①读取AB、BC、CA三相数据 结束 if ("8" == strPhase) //⑤-②读取T相数据 { CSequence* sq = new CSequence(); //T相相别类指针 sq->strSValue = node4.toElement().attribute("value"); //相别值 sq->type = node4.toElement().attribute("type"); //参数等级 sq->strSeq = strPhasic[3]; //相别赋值 it->SequenceList.push_back(sq); //添加 相别链表(T相) QDomNodeList list5 = node4.childNodes(); //获得元素Sequence的所有子节点的列表 for (int i5 = 0; i5 < list5.count(); i5++) //遍历 T相Value列表 { QDomNode node5 = list5.at(i5); //node5 if (node5.isElement()) { QDomElement e_Value = node5.toElement(); //将其转换为元素 QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点 if ("Value" == strTag6) //⑥读取T相Value { //⑥-①谐波数据读取(T相) 注:T相没有谐波数据 //⑥-②非谐波数据读取(T相) CDataValue* dv2 = new CDataValue(); //T相非谐波数据值类指针 dv2->strName = e_Value.attribute("name"); //数据名 dv2->type = e_Value.attribute("type"); //参数等级 if (e_Value.attributes().contains("Coefficient")) { dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型) dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型) } dv2->DO = e_Value.attribute("DO"); //数据对象名 dv2->DA = e_Value.attribute("DA"); //数据属性名 //zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { dv2->BaseFlag = e_Value.attribute("BaseFlag"); if (dv2->BaseFlag == "1") { dt->BaseFlag1++; } else { dt->BaseFlag0++; } } else { dt->BaseFlag0++; dv2->BaseFlag = "0"; } if (e_Value.attributes().contains("LimitUp")) { dv2->LimitUp = e_Value.attribute("LimitUp"); } else { dv2->LimitUp = "not define"; } if (e_Value.attributes().contains("LimitDown")) { dv2->LimitDown = e_Value.attribute("LimitDown"); } else { dv2->LimitDown = "not define"; } if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空 dv2->strFullName = dv2->DO + "$" + dv2->DA; else dv2->strFullName = "not define"; sq->DataValueList.push_back(dv2); //添加 数据链表(ABC三相) } //读取T相Value 结束 } //判断node5为元素 结束 } //遍历T相Value列表 结束 } //⑤-②读取T相数据 结束 } //判断node4为元素 结束 } //遍历Sequence列表 结束 } //读取数据项Item 结束 } //判断node3为元素 结束 } //遍历Item列表 结束 } //读取Monitor节点 结束 } //判断node2为元素 结束 } //遍历Monitor列表 结束 } //读取数据类型DataType 结束 } //判断node为元素 结束 } //遍历DataType列表 结束 } //读取Topic节点HISDATA、RTDATA 结束 else if ("Topic" == strTag && "RTDATASOE" == topic->strTopic) //SOE事件------------------------------------------------------- { QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { CDataType* dt = new CDataType(); //数据类型类指针 dt->iDataType = node.toElement().attribute("value").toInt(); //数据类型值(1-稳态SOE、2-闪变SOE、3-暂态SOE) dt->type = node.toElement().attribute("type"); //参数等级 topic->DataTypeList.push_back(dt); //添加 数据类型链表 QString strTag2 = node.toElement().tagName(); //DataType节点 if ("DataType" == strTag2) //②读取数据类型DataType { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 SOE列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { CEventData* ed = new CEventData(); //SOE事件类指针 ed->triggerFlag = node2.toElement().attribute("TriggerFlag"); //SOE触发标识 ed->DO = node2.toElement().attribute("DO"); //数据对象名 ed->DA = node2.toElement().attribute("DA"); //数据属性名 ed->type = node2.toElement().attribute("type"); //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 if (!ed->DO.isEmpty() && !ed->DA.isEmpty()) //数据对象名和数据属性名均不为空 ed->strFullName = ed->DO + "$" + ed->DA; else ed->strFullName = "not define"; dt->SOEList.push_back(ed); //添加 SOE事件链表 } //判断node2为元素 结束 } //遍历SOE列表 结束 } //读取数据类型DataType节点 结束 } //判断node为元素 结束 } //遍历DataType列表 结束 } //Topic节点RTDATASOE 结束 else if ("Topic" == strTag && "SOEDATA" == topic->strTopic) { QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { CEventData* ed = new CEventData(); //SOE事件类指针 ed->triggerFlag = node.toElement().attribute("name"); //SOE名称 ed->DO = node.toElement().attribute("DO"); //数据对象名 ed->DA = node.toElement().attribute("DA"); //数据属性名 ed->type = node.toElement().attribute("type"); //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件 if (!ed->DO.isEmpty() && !ed->DA.isEmpty()) //数据对象名和数据属性名均不为空 ed->strFullName = ed->DO + "$" + ed->DA; else ed->strFullName = "not define"; //cout << ed->triggerFlag.toAscii().data() << "=====" << ed->strFullName.toAscii().data() << endl; cfg->SOEList.push_back(ed); } } } } if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 { //cout << "ReportMap" << endl; } if ("Topic" != strTag && "ReportMap" != strTag)//zw修改 2023 - 8 - 14 增加判断 新增部分节点解析 { if ("WavePhasic" == strTag) { cfg->WavePhasicFlag.append(e.attribute("Flag")); if (cfg->WavePhasicFlag == "1") { cfg->WavePhasicA.append(e.attribute("A")); cfg->WavePhasicB.append(e.attribute("B")); cfg->WavePhasicC.append(e.attribute("C")); } } if ("UnitOfTime" == strTag) { cfg->UnitOfTimeUnit.append(e.attribute("Unit")); } if ("ValueOfTime" == strTag) { cfg->ValueOfTimeUnit.append(e.attribute("Unit")); } if ("ComtradeFile" == strTag) { cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag")); //cout << xmlcfg->WaveTimeFlag.toAscii().data() << endl; } if ("IED" == strTag) { cfg->IEDname.append(e.attribute("name")); //cout << xmlcfg->IEDname.toAscii().data() << endl; } if ("LDevice" == strTag) { cfg->LDevicePrefix.append(e.attribute("Prefix")); //cout<LDevicePrefix.toAscii().data() < RTDATA —> RTDATASOE) } //while (!n.isNull) 结束 return true; } /// /// czy 2023-11-23 测试json的装置间隔频,打印前台 /// /// 1是,2是,3是填入计算的interval /// 1是,2是,3是填入计算的interval void print_interval(int flag,int interval) { if (flag == 1) { cout << "interval!!dont't contain mp_id ,interval=1" << endl; } else if (flag == 2) { cout << "interval!!contain mp_id but interval=0, set interval=1" << endl; } else { cout << "interval!!contain mp_id , find interval=" << interval << endl; } } /// /// czy kafka的json中将线电压转成相电压 /// /// /// QString line_to_phasic(QString qstrSeq) { if (qstrSeq == "A" || qstrSeq == "AB") { return "A"; } else if (qstrSeq == "B" || qstrSeq == "BC") { return "B"; } else if (qstrSeq == "C" || qstrSeq == "CA") { return "C"; } else { return qstrSeq; } } //20250214添加角型接线处理 int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json生成函数 zw修改 2023-8-11 调整传送json结构 目前仅限历史稳态数据 { list ctopic_list; #if 0 if (xmlinfo_list.contains(data->dev_type)) { cout << "transfer_json_block_data contain data->dev_type" << endl; ctopic_list = xmlinfo_list[data->dev_type]->topicList; } else { cout << "transfer_json_block_data not contain data->dev_type" << endl; ctopic_list = topicList; } #endif ////lnk2024-8-15 区分星型,角型接线 if (strcmp(v_wiring_type, "1") == 0) //lnk2024-8-15 星型接线 { cout << "1 report v_wiring_type is" << v_wiring_type << endl; if (xmlinfo_list.contains(data->dev_type)) { cout << "transfer_json_block_data contain data->dev_type" << endl; ctopic_list = xmlinfo_list[data->dev_type]->topicList; } else { cout << "transfer_json_block_data not contain data->dev_type:" << data->dev_type.toStdString() << " !!!!"<< endl; ctopic_list = topicList; } } else //lnk2024-8-15 角型接线 { cout << "2 report v_wiring_type is" << v_wiring_type << endl; if (xmlinfo_list2.contains(data->dev_type)) { cout << "transfer_json_block_data contain data->dev_type" << endl; ctopic_list = xmlinfo_list2[data->dev_type]->topicList; } else { cout << "transfer_json_block_data not contain data->dev_type:" << data->dev_type.toStdString() << " !!!!"<< endl; ctopic_list = topicList; } } //list* tmp; bool shortjumpflag = false; bool longjumpflag = false; //zw修改 2023-8-28 新增日志启动判断 //bool data_match_flag = false, data_integrity_flag = true, data_reason_flag = false;//匹配率 完整性 合理性 日志记录标志 QMap data_reason_map;//数据合理性map QMap data_match_map_1;//数据匹配率map 基础数据 QMap data_match_map_2;//数据匹配率map 非基础数据 //zw修改 end if (!inited) //初始化 JiangSu_Config.xml { //ParseXMLConfig(); //调用 ParseXMLConfig() 解析JiangSu_Config.xml配置文件 inited = true; } if (NULL == data) //json拼接参数类指针为空 return 0; if (100 == data->func_type) //一、稳态/统计数据 ——> MMS_Client { list::iterator tp = ctopic_list.begin(); while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表 { CTopic* pTopic = *tp++; if ("HISDATA" == pTopic->strTopic) //Topic等于HISDATA { list::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList while (dt != pTopic->DataTypeList.end()) { bool isJump = false; //是否跳出(整个数据类型)循环 CDataType* pDataType = *dt++; if (2 == pDataType->iDataType) //②-②历史短闪变数据------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "PST"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 long long time_sec; //时间戳(秒) KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10, QChar('0'))); //拼接 json数据类型 例:历史闪变 "02" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList int countflag = 0, num = 0; while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; //////////////////////////////////////////////////////////lnk20250306为了数据入库,构造数据添加FLAG if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除 continue; } ////////////////////////////////////////////////////////// if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒 time_sec = data->time / 1000; //时间戳(秒) continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 num = num + pSequence->DataValueList.size(); while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 { countflag++; continue; } if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key { isJump = false; //跳出本层循环 countflag++; if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接 else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接 continue; } try { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\",").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) } catch (exception& e) { cout << "历史闪变数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (!KafkaData.strText.isEmpty()) { if (KafkaData.strText[KafkaData.strText.length() - 1] == ',') { KafkaData.strText = KafkaData.strText.remove(KafkaData.strText.size() - 1, 1); KafkaData.strText.append(" "); cout << "KafkaData.strText = KafkaData.strText.chopped(1) " << endl; } } if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 cout << countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"02\" " << num << endl; cout << KafkaData.strText.toAscii().data() << endl; if (countflag < num) { kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 shortjumpflag = true; } } //②-②历史闪变数据解析结束!-------------------------------- //20241204长闪变类型应该为3 if (3 == pDataType->iDataType) //②-②历史长闪变数据------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "PLT"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 long long time_sec; //时间戳(秒) KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10, QChar('0'))); //拼接 json数据类型 例:历史闪变 "02" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList int countflag = 0,num = 0; while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; //////////////////////////////////////////////////////////lnk20250306为了数据入库,构造数据添加FLAG if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除 continue; } ////////////////////////////////////////////////////////// if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒 time_sec = data->time / 1000; //时间戳(秒) continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 num = num + pSequence->DataValueList.size(); while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 { countflag++; continue; } if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key { isJump = false; //跳出本层循环 countflag++; if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接 else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接 continue; } try { if (0 == time_sec % 7200) //2小时间隔,长时闪变 { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) } } catch (exception& e) { cout << "历史闪变数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (!KafkaData.strText.isEmpty()) { if (KafkaData.strText[KafkaData.strText.length() - 1] == ',') { KafkaData.strText = KafkaData.strText.remove(KafkaData.strText.size() - 1, 1); KafkaData.strText.append(" "); cout << "KafkaData.strText = KafkaData.strText.chopped(1) " << endl; } } if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 cout<< countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"04\" " << num << endl; cout << KafkaData.strText.toAscii().data() << endl; if (countflag < num && 0 == time_sec % 7200) { kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 longjumpflag = true; } if (longjumpflag == true || shortjumpflag == true) { return 1; } //return 1; //结束该函数,停止后续代码执行 } //②-②历史闪变数据解析结束!-------------------------------- if (1 == pDataType->iDataType) //②-①历史稳态数据----------------------------------------------------------- { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "HISDATA"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10,QChar('0'))); //拼接 json数据类型 例:历史稳态 "01" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除 continue; } if ("TIME" == pItem->strItemName) //剔除"TIME",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":%1, ").arg(data->time)); //拼接 json发生时刻,毫秒 if (!data_timespan_list.contains(data->mp_id)) { KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻,毫秒 } else if (data_timespan_list[data->mp_id]->msspan == 0) { KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻,毫秒 } else { KafkaData.strText.append(QString("\"interval\":%1, ").arg(data_timespan_list[data->mp_id]->msspan)); //拼接 json发生时刻,毫秒 } continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 V、I、PQ list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C、T相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key { isJump = false; //跳出本层循环 //zw修改 2023-8-28 不匹配数据添加 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接 else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接 if (pDataValue->BaseFlag == "1") { //errorlog_datamatch(pDataValue->strFullName, &data_match_map_1);//lnk删除 } else { //errorlog_datamatch(pDataValue->strFullName, &data_match_map_2);//lnk删除 } continue; } try { if (pDataValue->strFullName.indexOf("$ang$f") != -1) //查找61850属性名中含有相角的定义 { double dAngleTemp = data->mms_str_map.value(pDataValue->strFullName); //角度值(-180度 ~ 180度) dAngleTemp = dAngleTemp > 180.0f ? dAngleTemp - 360.0f : dAngleTemp; if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值) //zw修改 2023 - 8 - 23 数值合理性判断函数 节点属性 实际值 监测点号 电压等级 //errorlog_num(pDataValue, dAngleTemp, data->voltage_level, &data_reason_map, data->time); } else { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) //zw修改 2023 - 8 - 23 数值合理性判断函数 节点属性 实际值 监测点号 电压等级 //(pDataValue, dTemp, data->voltage_level, &data_reason_map, data->time); } } catch (exception& e) { cout << "历史稳态数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (!KafkaData.strText.isEmpty()) { if (KafkaData.strText[KafkaData.strText.length() - 1] == ',') { KafkaData.strText = KafkaData.strText.remove(KafkaData.strText.size() - 1, 1); KafkaData.strText.append(" "); cout << "KafkaData.strText = KafkaData.strText.chopped(1) " << endl; } } if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 //lnk20241122不记录这些 if(false)//zw修改 2023-8-28 数据完整性 合理性 匹配率 日志记录执行判断逻辑 { cout << "!!!!!!!!!!!!!!!!!!!!!!===============" << data_match_map_1.count() << "--------" << data_match_map_2.count() << endl; cout << "!!!!!!!!!!!!!!!!!!!!!!---------------" << data_reason_map.count() << endl; if(data_match_map_1.count() + data_match_map_2.count() <= 1200)//完整性记录 默认为true 只要发送了kafka记录就执行 { errorlog_dataintegrity_timespanlist(data->mp_id,data->time); errorlog_dataintegrity_timespanlist_2(data->mp_id); QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time/1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); QString tmp_chr2 = dataintegrity_time.toString("yyyy-MM-dd hh:mm:ss"); //不再需要完整性记录lnk202411-6 //cout << errorlog_dataintegrity_pgsql(tmp_chr1, tmp_chr2, data->mp_id,false).toAscii().data() << endl; } if(data_reason_map.count() != 0)//合理性记录 只要map存在元素 记录不合理性日志 { QString reasonlog = errorlog_num_json(data->mp_id, data_reason_map); QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); QString Qfilename, Qsavename; Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); char file_name[256]; memset(file_name, 0, 256); sprintf(file_name, "%s", Qfilename.toAscii().data()); char save_name[256]; memset(save_name, 0, 256); sprintf(save_name, "%s", Qsavename.toAscii().data()); //cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; //cout << reasonlog.toAscii().data() << endl; oss_data_t OssData; OssData.filename = file_name; OssData.savename = save_name; OssData.data = reasonlog; QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); OssData.id = data->mp_id; OssData.time = tmp_chr1; //时间 OssData.list_num = data_reason_map.size(); OssData.log_name = "reason"; if (data->time % 3600000 == 0) { oss_data_list_mutex.lock(); //加锁 oss_data_list.append(OssData); //添加 kafka发送链表 oss_data_list_mutex.unlock(); //解锁 } //std::ofstream file(save_name); // 创建一个输出文件流对象,打开文件 example.txt //if (file.is_open()) { // 判断文件是否成功打开 // file << reasonlog.toAscii().data() << "\n"; // file.close(); // 关闭文件 //} //else { // cout << "Unable to open file\n" << endl; //} //PutOSS(file_name, save_name); //std::remove(save_name); /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); QString pgsql; pgsql.append(errorlog_num_pgsql(data->mp_id, tmp_chr1, Qfilename, data_reason_map.size())); cout << pgsql.toAscii().data() << endl;*/ } if(data_match_map_1.count() != 0 || data_match_map_2.count() != 0)//匹配率记录 只要map存在元素 记录不匹配的数值 { QString matchlog = errorlog_datamatch_json(data_match_map_1, data_match_map_2,data->time); //cout << matchlog.toAscii().data() << endl; QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); QString Qfilename,Qsavename; Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); char file_name[256]; memset(file_name,0,256); sprintf(file_name,"%s",Qfilename.toAscii().data()); char save_name[256]; memset(save_name, 0, 256); sprintf(save_name,"%s", Qsavename.toAscii().data()); cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; oss_data_t OssData; OssData.filename = file_name; OssData.savename = save_name; OssData.data = matchlog; QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); OssData.id = data->mp_id; OssData.time= tmp_chr1; //时间 //match_log OssData.base_mat_num= pDataType->BaseFlag1; OssData.adv_mat_num= pDataType->BaseFlag1 + pDataType->BaseFlag0; OssData.base_act_num= pDataType->BaseFlag1 - data_match_map_1.count(); OssData.adv_act_num= pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(); OssData.log_name = "match"; if (data->time % 3600000 == 0) { oss_data_list_mutex.lock(); //加锁 oss_data_list.append(OssData); //添加 kafka发送链表 oss_data_list_mutex.unlock(); //解锁 } //std::ofstream file(save_name); // 创建一个输出文件流对象,打开文件 example.txt //if (file.is_open()) { // 判断文件是否成功打开 // file << matchlog.toAscii().data() << "\n"; // file.close(); // 关闭文件 //} //else { // cout << "Unable to open file\n" << endl; //} //PutOSS(file_name, save_name); //std::remove(save_name); //GetOSS(file_name, savename); /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); QString pqsql; pqsql.append(errorlog_datamatch_pgsql(data->mp_id, tmp_chr1, pDataType->BaseFlag1, pDataType->BaseFlag1 + pDataType->BaseFlag0, pDataType->BaseFlag1 - data_match_map_1.count(), pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(), Qfilename)); cout << pqsql.toAscii().data() << endl;*/ } QMap().swap(data_match_map_1); QMap().swap(data_match_map_2); QMap().swap(data_reason_map); } return 1; //结束该函数,停止后续代码执行 } //②-①历史稳态数据解析结束!-------------------------------- } //DataTypeList 结束 } //遍历 HISDATA 结束! } //TopicList 结束 } //一、结束 if (200 == data->func_type) //二、3秒数据/实时数据 ——> MMS_Assist { list::iterator tp = ctopic_list.begin(); while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表 { CTopic* pTopic = *tp++; if ("RTDATA" == pTopic->strTopic) //Topic等于RTDATA------------------------------------------------------------ { list::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList while (dt != pTopic->DataTypeList.end()) { bool isJump = false; //是否跳出(整个数据类型)循环 CDataType* pDataType = *dt++; if (1 == pDataType->iDataType) //②-①实时3s数据-------------------------------------------------------------- { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATA"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10, QChar('0'))); //拼接 json数据类型 例:实时稳态 "01" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"FLAG\":\"%1\", ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除 continue; } if ("TIME" == pItem->strItemName) //剔除"TIME",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒 continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 V、I、PQ list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C、T相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pDataValue->strFullName) && pDataValueBegin->strName == pDataValue->strName)//确认字典里不含有该key { isJump = true; //跳出本层循环 break; } try { if (pDataValue->strFullName.indexOf("$ang$f") != -1) //查找61850属性名中含有相角的定义 { double dAngleTemp = data->mms_str_map.value(pDataValue->strFullName); //角度值(-180度 ~ 180度) dAngleTemp = dAngleTemp > 180.0f ? dAngleTemp - 360.0f : dAngleTemp; if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值) } else { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) } } catch (exception& e) { cout << "实时3s数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (!KafkaData.strText.isEmpty()) { if (KafkaData.strText[KafkaData.strText.length() - 1] == ',') { KafkaData.strText = KafkaData.strText.remove(KafkaData.strText.size() - 1, 1); KafkaData.strText.append(" "); cout << "KafkaData.strText = KafkaData.strText.chopped(1) " << endl; } } if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-①实时3s数据解析结束!---------------------------------- if (2 == pDataType->iDataType) //②-②实时闪变数据----------------------------------------------------------- { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATA"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 long long time_sec; //时间戳(秒) KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10, QChar('0'))); //拼接 json数据类型 例:实时闪变 "02" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒 time_sec = data->time / 1000; //时间戳(秒) continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pDataValue->strFullName) && pDataValueBegin->strName == pDataValue->strName)//确认字典里不含有该key { isJump = true; //跳出本层循环 break; } try { if (!pDataValue->bPlt) //短时闪变 { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) } else //长时闪变 { if (0 == time_sec % 7200) //2小时间隔,长时闪变 { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) } } } catch (exception& e) { cout << "实时闪变数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-②实时闪变数据解析结束!-------------------------------- } //DataTypeList 结束 } //遍历 RTDATA 结束! if ("RTDATASOE" == pTopic->strTopic) //Topic等于RTDATASOE---------------------------------------------------------- { list::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList while (dt != pTopic->DataTypeList.end()) { int triggerCount = 0; //SOE触发标识计数 CDataType* pDataType = *dt++; if (1 == pDataType->iDataType) //②-①SOE稳态事件------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATASOE"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\", ").arg(pDataType->iDataType)); //拼接 json数据类型 KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻(毫秒) KafkaData.strText.append(QString("\"%1\":[").arg(data->mp_id)); //拼接 json监测点号 list::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList list::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素 while (ed != pDataType->SOEList.end()) { CEventData* pEventData = *ed++; if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key continue; try { double dTemp = data->mms_str_map.value(pEventData->strFullName); if (dTemp >= 0.9) //SOE事件发生 { if (0 == triggerCount) //SOE触发标识计数 { KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 triggerCount++; //SOE触发标识计数 } else KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 } } catch (exception& e) { cout << "SOE稳态事件拼接json错误,原因: " << e.what() << endl; return false; } } //SOEList 结束 KafkaData.strText.append("]}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-①SOE稳态事件解析结束!--------------------------------- if (1 == pDataType->iDataType) //②-②SOE暂态事件------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATASOE"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\", ").arg(pDataType->iDataType)); //拼接 json数据类型 KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻(毫秒) KafkaData.strText.append(QString("\"%1\":[").arg(data->mp_id)); //拼接 json监测点号 list::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList list::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素 while (ed != pDataType->SOEList.end()) { CEventData* pEventData = *ed++; if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key continue; try { double dTemp = data->mms_str_map.value(pEventData->strFullName); if (dTemp >= 0.9) //SOE事件发生 { if (0 == triggerCount) //SOE触发标识计数 { KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 triggerCount++; //SOE触发标识计数 } else KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 } } catch (exception& e) { cout << "SOE暂态事件拼接json错误,原因: " << e.what() << endl; return false; } } //SOEList 结束 KafkaData.strText.append("]}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-②SOE暂态事件解析结束!--------------------------------- if (1 == pDataType->iDataType) //②-③SOE状态事件------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATASOE"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\", ").arg(pDataType->iDataType)); //拼接 json数据类型 KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻(毫秒) KafkaData.strText.append(QString("\"%1\":[").arg(data->mp_id)); //拼接 json监测点号 list::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList list::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素 while (ed != pDataType->SOEList.end()) { CEventData* pEventData = *ed++; if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key continue; try { double dTemp = data->mms_str_map.value(pEventData->strFullName); if (dTemp >= 0.9) //SOE事件发生 { if (0 == triggerCount) //SOE触发标识计数 { KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 triggerCount++; //SOE触发标识计数 } else KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 } } catch (exception& e) { cout << "SOE状态事件拼接json错误,原因: " << e.what() << endl; return false; } } //SOEList 结束 KafkaData.strText.append("]}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-③SOE状态事件解析结束!--------------------------------- } //DataTypeList 结束 } //遍历 RTDATASOE 结束! } //TopicList 结束 } //二、结束 if (400 == data->func_type || 500 == data->func_type || 600 == data->func_type || 700 == data->func_type) //三、补招历史数据 ——> MMS_Recall { list::iterator tp = ctopic_list.begin(); while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表 { CTopic* pTopic = *tp++; if ("HISDATA" == pTopic->strTopic) //Topic等于HISDATA---------------------------------------------------------- { list::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList while (dt != pTopic->DataTypeList.end()) { bool isJump = false; //是否跳出(整个数据类型)循环 CDataType* pDataType = *dt++; if (2 == pDataType->iDataType) //②-②历史短闪变数据------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "PST"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 long long time_sec; //时间戳(秒) KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10, QChar('0'))); //拼接 json数据类型 例:历史闪变 "02" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList int countflag = 0, num = 0; while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒 time_sec = data->time / 1000; //时间戳(秒) continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 num = num + pSequence->DataValueList.size(); while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 { countflag++; continue; } if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key { isJump = false; //跳出本层循环 countflag++; if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接 else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接 continue; } try { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\",").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) } catch (exception& e) { cout << "历史闪变数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (!KafkaData.strText.isEmpty()) { if (KafkaData.strText[KafkaData.strText.length() - 1] == ',') { KafkaData.strText = KafkaData.strText.remove(KafkaData.strText.size() - 1, 1); KafkaData.strText.append(" "); cout << "KafkaData.strText = KafkaData.strText.chopped(1) " << endl; } } if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 cout << countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"02\" " << num << endl; cout << KafkaData.strText.toAscii().data() << endl; if (countflag < num) { kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 shortjumpflag = true; } } //②-②历史闪变数据解析结束!-------------------------------- //20241204长闪变类型应该为3 if (3 == pDataType->iDataType) //②-②历史长闪变数据------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "PLT"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 long long time_sec; //时间戳(秒) KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10, QChar('0'))); //拼接 json数据类型 例:历史闪变 "02" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList int countflag = 0, num = 0; while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; if ("TIME" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻,毫秒 time_sec = data->time / 1000; //时间戳(秒) continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 num = num + pSequence->DataValueList.size(); while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 { countflag++; continue; } if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key { isJump = false; //跳出本层循环 countflag++; if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接 else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接 continue; } try { if (0 == time_sec % 7200) //2小时间隔,长时闪变 { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值) } } catch (exception& e) { cout << "历史闪变数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (!KafkaData.strText.isEmpty()) { if (KafkaData.strText[KafkaData.strText.length() - 1] == ',') { KafkaData.strText = KafkaData.strText.remove(KafkaData.strText.size() - 1, 1); KafkaData.strText.append(" "); cout << "KafkaData.strText = KafkaData.strText.chopped(1) " << endl; } } if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 cout << countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"04\" " << num << endl; cout << KafkaData.strText.toAscii().data() << endl; if (countflag < num && 0 == time_sec % 7200) { kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 longjumpflag = true; } if (longjumpflag == true || shortjumpflag == true) { return 1; } //return 1; //结束该函数,停止后续代码执行 } //②-②历史闪变数据解析结束!-------------------------------- if (1 == pDataType->iDataType) //②-①历史稳态数据----------------------------------------------------------- { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "HISDATA"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\" ").arg(pDataType->iDataType, 2, 10, QChar('0'))); //拼接 json数据类型 例:历史稳态 "01" KafkaData.strText.append(QString(", \"Monitor\":\"%1\" ").arg(data->mp_id));//例:监测点 "1100" list::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList while (mt != pDataType->MonitorList.end()) { CMonitor* pMonitor = *mt++; KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点 list::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList list::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素 while (it != pMonitor->ItemList.end()) { CItem* pItem = *it++; if ("FLAG" == pItem->strItemName) //剔除"FLAG",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记,1不剔除,0剔除,默认剔除 continue; } if ("TIME" == pItem->strItemName) //剔除"TIME",防止sq相别出现错误指针 { KafkaData.strText.append(QString("\"TIME\":%1, ").arg(data->time)); //拼接 json发生时刻,毫秒 if (!data_timespan_list.contains(data->mp_id)) { KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻,毫秒 } else if (data_timespan_list[data->mp_id]->msspan == 0) { KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻,毫秒 } else { KafkaData.strText.append(QString("\"interval\":%1, ").arg(data_timespan_list[data->mp_id]->msspan)); //拼接 json发生时刻,毫秒 } continue; } KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 V、I、PQ list::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList list::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素 while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //拼接 json相别 A、B、C、T相 KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相 list::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList CDataValue* pDataValueBegin = *dv; list::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素 while (dv != pSequence->DataValueList.end()) { CDataValue* pDataValue = *dv++; if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key { isJump = false; //跳出本层循环 //zw修改 2023-8-28 不匹配数据添加 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接 else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接 if (pDataValue->BaseFlag == "1") { //errorlog_datamatch(pDataValue->strFullName, &data_match_map_1);//lnk删除 } else { //errorlog_datamatch(pDataValue->strFullName, &data_match_map_2);//lnk删除 } continue; } try { if (pDataValue->strFullName.indexOf("$ang$f") != -1) //查找61850属性名中含有相角的定义 { double dAngleTemp = data->mms_str_map.value(pDataValue->strFullName); //角度值(-180度 ~ 180度) dAngleTemp = dAngleTemp > 180.0f ? dAngleTemp - 360.0f : dAngleTemp; if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值) //zw修改 2023 - 8 - 23 数值合理性判断函数 节点属性 实际值 监测点号 电压等级 //errorlog_num(pDataValue, dAngleTemp, data->voltage_level, &data_reason_map, data->time); } else { double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数 if (dv != dvEnd) //非单相最后一个数据值元素 KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值) //zw修改 2023 - 8 - 23 数值合理性判断函数 节点属性 实际值 监测点号 电压等级 //errorlog_num(pDataValue, dTemp, data->voltage_level, &data_reason_map, data->time); } } catch (exception& e) { cout << "历史稳态数据值拼接json错误,原因: " << e.what() << endl; return false; } } //DataValueList 结束 if (!KafkaData.strText.isEmpty()) { if (KafkaData.strText[KafkaData.strText.length() - 1] == ',') { KafkaData.strText = KafkaData.strText.remove(KafkaData.strText.size() - 1, 1); KafkaData.strText.append(" "); cout << "KafkaData.strText = KafkaData.strText.chopped(1) " << endl; } } if (isJump) break; //跳出循环 if (sq != sqEnd) //非A、B、C、T最后一个相别元素 KafkaData.strText.append("}, "); //拼接 json相别结尾 else KafkaData.strText.append("}"); //拼接 json相别结尾 } //SequenceList 结束 if (isJump) break; //跳出循环 if (it != itEnd) //非 V、I、PQ最后一个json数据项元素 KafkaData.strText.append("}, "); //拼接 json数据项结尾 else KafkaData.strText.append("}}"); //拼接 json数据项结尾 } //ItemList 结束 if (isJump) break; //跳出循环 } //MonitorList 结束 if (isJump) continue; //跳出本数据类型循环 KafkaData.strText.append("}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 //lnk20241122不记录这些 if (false)//zw修改 2023-8-28 数据完整性 合理性 匹配率 日志记录执行判断逻辑 { cout << "!!!!!!!!!!!!!!!!!!!!!!===============" << data_match_map_1.count() << "--------" << data_match_map_2.count() << endl; cout << "!!!!!!!!!!!!!!!!!!!!!!---------------" << data_reason_map.count() << endl; if (data_match_map_1.count() + data_match_map_2.count() <= 1200)//完整性记录 默认为true 只要发送了kafka记录就执行 { errorlog_dataintegrity_timespanlist(data->mp_id, data->time); errorlog_dataintegrity_timespanlist_2(data->mp_id); QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); QString tmp_chr2 = dataintegrity_time.toString("yyyy-MM-dd hh:mm:ss"); //不再需要完整性记录lnk202411-6 //cout << errorlog_dataintegrity_pgsql(tmp_chr1, tmp_chr2, data->mp_id,true).toAscii().data() << endl; } if (data_reason_map.count() != 0)//合理性记录 只要map存在元素 记录不合理性日志 { QString reasonlog = errorlog_num_json(data->mp_id, data_reason_map); QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); QString Qfilename, Qsavename; Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); char file_name[256]; memset(file_name, 0, 256); sprintf(file_name, "%s", Qfilename.toAscii().data()); char save_name[256]; memset(save_name, 0, 256); sprintf(save_name, "%s", Qsavename.toAscii().data()); cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; oss_data_t OssData; OssData.filename = file_name; OssData.savename = save_name; OssData.data = reasonlog; QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); OssData.id = data->mp_id; OssData.time = tmp_chr1; //时间 OssData.list_num = data_reason_map.size(); OssData.log_name = "reason"; if (data->time % 3600000 == 0) { oss_data_list_mutex.lock(); //加锁 oss_data_list.append(OssData); //添加 kafka发送链表 oss_data_list_mutex.unlock(); //解锁 } //std::ofstream file(save_name); // 创建一个输出文件流对象,打开文件 example.txt //if (file.is_open()) { // 判断文件是否成功打开 // file << reasonlog.toAscii().data() << "\n"; // file.close(); // 关闭文件 //} //else { // cout << "Unable to open file\n" << endl; //} //PutOSS(file_name, save_name); //std::remove(save_name); /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); QString pgsql; pgsql.append(errorlog_num_pgsql(data->mp_id, tmp_chr1, Qfilename, data_reason_map.size())); cout << pgsql.toAscii().data() << endl;*/ } if (data_match_map_1.count() != 0 || data_match_map_2.count() != 0)//匹配率记录 只要map存在元素 记录不匹配的数值 { QString matchlog = errorlog_datamatch_json(data_match_map_1, data_match_map_2, data->time); //cout << matchlog.toAscii().data() << endl; QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); QString Qfilename, Qsavename; Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); char file_name[256]; memset(file_name, 0, 256); sprintf(file_name, "%s", Qfilename.toAscii().data()); char save_name[256]; memset(save_name, 0, 256); sprintf(save_name, "%s", Qsavename.toAscii().data()); cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; oss_data_t OssData; OssData.filename = file_name; OssData.savename = save_name; OssData.data = matchlog; QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); OssData.id = data->mp_id; OssData.time = tmp_chr1; //时间 //match_log OssData.base_mat_num = pDataType->BaseFlag1; OssData.adv_mat_num = pDataType->BaseFlag1 + pDataType->BaseFlag0; OssData.base_act_num = pDataType->BaseFlag1 - data_match_map_1.count(); OssData.adv_act_num = pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(); OssData.log_name = "match"; if (data->time % 3600000 == 0) { oss_data_list_mutex.lock(); //加锁 oss_data_list.append(OssData); //添加 kafka发送链表 oss_data_list_mutex.unlock(); //解锁 } //std::ofstream file(save_name); // 创建一个输出文件流对象,打开文件 example.txt //if (file.is_open()) { // 判断文件是否成功打开 // file << matchlog.toAscii().data() << "\n"; // file.close(); // 关闭文件 //} //else { // cout << "Unable to open file\n" << endl; //} /*PutOSS(file_name, save_name); std::remove(save_name);*/ //GetOSS(file_name, savename); /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); QString pqsql; pqsql.append(errorlog_datamatch_pgsql(data->mp_id, tmp_chr1, pDataType->BaseFlag1, pDataType->BaseFlag1 + pDataType->BaseFlag0, pDataType->BaseFlag1 - data_match_map_1.count(), pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(), Qfilename)); cout << pqsql.toAscii().data() << endl;*/ } QMap().swap(data_match_map_1); QMap().swap(data_match_map_2); QMap().swap(data_reason_map); } return 1; //结束该函数,停止后续代码执行 } //②-①历史稳态数据解析结束!-------------------------------- } //DataTypeList 结束 } //遍历 HISDATA 结束! if ("RTDATASOE" == pTopic->strTopic) //Topic等于RTDATASOE---------------------------------------------------------- { list::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList while (dt != pTopic->DataTypeList.end()) { int triggerCount = 0; //SOE触发标识计数 CDataType* pDataType = *dt++; if (1 == pDataType->iDataType) //②-①SOE稳态事件------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATASOE"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\", ").arg(pDataType->iDataType)); //拼接 json数据类型 KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻(毫秒) KafkaData.strText.append(QString("\"%1\":[").arg(data->mp_id)); //拼接 json监测点号 list::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList list::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素 while (ed != pDataType->SOEList.end()) { CEventData* pEventData = *ed++; if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key continue; try { double dTemp = data->mms_str_map.value(pEventData->strFullName); if (dTemp >= 0.9) //SOE事件发生 { if (0 == triggerCount) //SOE触发标识计数 { KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 triggerCount++; //SOE触发标识计数 } else KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 } } catch (exception& e) { cout << "SOE稳态事件拼接json错误,原因: " << e.what() << endl; return false; } } //SOEList 结束 KafkaData.strText.append("]}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-①SOE稳态事件解析结束!--------------------------------- if (1 == pDataType->iDataType) //②-②SOE暂态事件------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATASOE"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\", ").arg(pDataType->iDataType)); //拼接 json数据类型 KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻(毫秒) KafkaData.strText.append(QString("\"%1\":[").arg(data->mp_id)); //拼接 json监测点号 list::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList list::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素 while (ed != pDataType->SOEList.end()) { CEventData* pEventData = *ed++; if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key continue; try { double dTemp = data->mms_str_map.value(pEventData->strFullName); if (dTemp >= 0.9) //SOE事件发生 { if (0 == triggerCount) //SOE触发标识计数 { KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 triggerCount++; //SOE触发标识计数 } else KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 } } catch (exception& e) { cout << "SOE暂态事件拼接json错误,原因: " << e.what() << endl; return false; } } //SOEList 结束 KafkaData.strText.append("]}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-②SOE暂态事件解析结束!--------------------------------- if (1 == pDataType->iDataType) //②-③SOE状态事件------------------------------------------------------------ { Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = data->monitorId; //监测点ID KafkaData.mp_id = data->mp_id; KafkaData.strTopic = "RTDATASOE"; //kafka发送主题 KafkaData.strText = ""; //kafka发送的json字符串 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append(QString("\"DATA_TYPE\":\"%1\", ").arg(pDataType->iDataType)); //拼接 json数据类型 KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻(毫秒) KafkaData.strText.append(QString("\"%1\":[").arg(data->mp_id)); //拼接 json监测点号 list::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList list::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素 while (ed != pDataType->SOEList.end()) { CEventData* pEventData = *ed++; if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空 continue; if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key continue; try { double dTemp = data->mms_str_map.value(pEventData->strFullName); if (dTemp >= 0.9) //SOE事件发生 { if (0 == triggerCount) //SOE触发标识计数 { KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 triggerCount++; //SOE触发标识计数 } else KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识 } } catch (exception& e) { cout << "SOE状态事件拼接json错误,原因: " << e.what() << endl; return false; } } //SOEList 结束 KafkaData.strText.append("]}"); //拼接 json稳态数据结尾 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 return 1; //结束该函数,停止后续代码执行 } //②-③SOE状态事件解析结束!--------------------------------- } //DataTypeList 结束 } //遍历 RTDATASOE 结束! } //TopicList 结束 } //三、结束 return 1; } /*//生成json暂态消息 zw修改 2023-8-25 调整json结构 int transfer_json_qvvr_data(unsigned int func_type, int monitor_id, float mag, float dur, long long start_tm, long long end_tm, int dis_kind, char* uuid_cfg,char* uuid_dat,char* mp_id,char* Qvvr_rptname,char* devtype) //生成json暂态消息 ——> MMS_Wave { XmlConfig c_xmlcfg; if (xmlinfo_list.contains(devtype)) { c_xmlcfg = xmlinfo_list[devtype]->xmlcfg; } else { c_xmlcfg = xmlcfg; } //if (0 == monitor_id) //json拼接监测点号为空 // return 0; if (strlen(mp_id) == 0) { return 0; } Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = monitor_id; KafkaData.mp_id = mp_id; // if (400 == func_type) //三、补招历史数据 ——> MMS_Recall // KafkaData.strTopic = "HISDATA"; //kafka发送主题 // else // KafkaData.strTopic = "RTDATA"; KafkaData.strTopic = "Event"; //kafka发送主题 KafkaData.strText.append("{"); //拼接 json起始 if (400 == func_type || 500 == func_type || 600 == func_type || 700 == func_type) //三、补招历史数据 ——> MMS_Recall KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //拼接 数据类型 else KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //拼接 数据类型 KafkaData.strText.append(QString("\"Monitor\":\"%1\", ").arg(mp_id)); //拼接 json监测点 KafkaData.strText.append(QString("\"Value\":{")); //拼接 json监测点 KafkaData.strText.append(QString("\"FLAG\":%1,").arg(1)); //拼接 剔除标记 KafkaData.strText.append(QString("\"TIME\":%1,").arg(start_tm)); //拼接 时间 KafkaData.strText.append("\"VOLTAGE\":{"); //拼接 数据项 例:VOLTAGE KafkaData.strText.append(QString("\"MAG\":%1").arg(mag)); //拼接 残余电压,即:特征幅值 KafkaData.strText.append(QString(", \"DUR\":%1").arg(dur * 1000)); //拼接 持续时间(毫秒) KafkaData.strText.append(QString(", \"STARTTIME\":%1").arg(start_tm )); //拼接 开始时间(毫秒) KafkaData.strText.append(QString(", \"ENDTIME\":%1").arg(end_tm)); //拼接 结束时间(毫秒) KafkaData.strText.append(QString(", \"DISKIND\":\"%1%2\"").arg("0").arg(dis_kind)); //拼接 暂降类型(1210001-暂升 1210002-暂降 1210004-中断 1210003-其他) KafkaData.strText.append(QString(", \"CFG_FILE\":\"%1\"").arg(uuid_cfg)); //拼接 cfg波形文件名称 KafkaData.strText.append(QString(", \"DAT_FILE\":\"%1\"").arg(uuid_dat)); //拼接 dat波形文件名称 if (c_xmlcfg.WavePhasicFlag == "1") { QString Qvvr_Rptname; Qvvr_Rptname.append(Qvvr_rptname); if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicA) != -1) { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("A")); //拼接 相别 } else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicB) != -1) { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("B")); //拼接 相别 } else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicC) != -1) { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("C")); //拼接 相别 } else { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //拼接 相别 } } else { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //拼接 相别 } KafkaData.strText.append("}"); //拼接 json结束 KafkaData.strText.append("}}"); //拼接 json结束 printf("transfer json qvvr data: %s==%s \n",KafkaData.strText.toStdString().c_str(), Qvvr_rptname); kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 //if (400 != func_type) { //非补招历史数据 // KafkaData.strTopic = "Event"; // kafka_data_list.append(KafkaData); //} kafka_data_list_mutex.unlock(); //解锁 return 1; }*/ void processGGIO_start_data_end(char* mp_id,char* fullname,double v,long long time,char* devtype,int monitor_id) { XmlConfig c_xmlcfg; if (xmlinfo_list.contains(devtype)) { c_xmlcfg = xmlinfo_list[devtype]->xmlcfg; } else { c_xmlcfg = xmlcfg; } QString Full_name; Full_name.append(fullname); Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = monitor_id; KafkaData.mp_id = mp_id; KafkaData.strTopic = "Alm"; //kafka发送主题 KafkaData.strText.append("{"); //拼接 json起始 KafkaData.strText.append("\"DATA_TYPE\":\"05\", "); //拼接 数据类型 KafkaData.strText.append(QString("\"Monitor\":\"%1\", ").arg(mp_id)); //拼接 json监测点 KafkaData.strText.append(QString("\"Value\":{")); //拼接 json监测点 KafkaData.strText.append(QString("\"FLAG\":%1,").arg(1)); //拼接 剔除标记 KafkaData.strText.append(QString("\"TIME\":%1,").arg(time)); //拼接 时间 KafkaData.strText.append(QString("\"SOE\":[")); //拼接 SOE list::iterator ed = c_xmlcfg.SOEList.begin(); //③遍历 SOEList while (ed != c_xmlcfg.SOEList.end()) { CEventData* pEventData = *ed++; if (pEventData->strFullName.indexOf(Full_name) != -1) { KafkaData.strText.append(QString("\"%1\"").arg(pEventData->triggerFlag)); break; } } KafkaData.strText.append(QString("]")); //拼接 SOE结束 KafkaData.strText.append("}"); //拼接 value结束 KafkaData.strText.append("}"); //拼接 json结束 printf("transfer json ggio data: %s==%s \n", KafkaData.strText.toStdString().c_str(), fullname); kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 } //zw修改 2023-8-31 新增或更新list队列 写入xml数据库信息 模型编码 终端型号 终端厂家 oss存储路径 时间 //lnk修改 2024-10-28 去掉终端厂家,换成远端模型文件路径 //void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* TMNL_FACTORY, char* FILE_NAME, int year, int month, int day, int hour, int minute, int second) void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char* FILE_NAME, int year, int month, int day, int hour, int minute, int second) { if (MODEL_ID == NULL || TMNL_TYPE == NULL || FILE_PATH == NULL || FILE_NAME == NULL) { cout << "Function Set_xml_databaseinfo Error!" << endl; return; } cout << "Function Set_xml_databaseinfo Start!" << endl; QString id, type, filepath, name; id.append(MODEL_ID); type.append(TMNL_TYPE); filepath.append(FILE_PATH); name.append(FILE_NAME); //调试用lnk20241125 cout << "setxmldatabase:" << TMNL_TYPE << endl; if (!xmlinfo_list.contains(type))//在终端类型列表中没查到 { Xmldata* config = new Xmldata(); //没找到就插个新的终端类型到列表中 xmlinfo_list.insert(type, config); //调试用lnk20241125 cout << "xmlinfo_list insert type:" << type.toStdString() << endl; } else//查到就更新覆盖 { //调试用lnk20241125 cout << "xmlinfo_list type contain:" << type.toStdString() << endl; QDateTime time(QDate(year, month, day), QTime(hour, minute, second)); if (xmlinfo_list[type]->xmlbase.datetime == time) { //终端型号更新标志,如果新增的型号错误,导致实际用的映射文件不一样,或者覆盖了原来的映射文件这里可能出问题。数据库在录入型号和映射文件时要注意 xmlinfo_list[type]->updataflag = false; //时间值一样说明是没有更新,当前业务中不包含时间值,所以每次都会更新 } else { xmlinfo_list[type]->updataflag = true; } //lnk20250208如果类型存在则不再往下执行 } //lnk20250208这里应该是覆盖而不是追加 //xmlinfo_list[type]->xmlbase.MODEL_ID.append(id); //xmlinfo_list[type]->xmlbase.TMNL_TYPE.append(type); //xmlinfo_list[type]->xmlbase.FILE_PATH.append(filepath); //xmlinfo_list[type]->xmlbase.FILE_NAME.append(name); xmlinfo_list[type]->xmlbase.MODEL_ID = id; xmlinfo_list[type]->xmlbase.TMNL_TYPE = type; xmlinfo_list[type]->xmlbase.FILE_PATH = filepath; xmlinfo_list[type]->xmlbase.FILE_NAME = name; QDateTime time(QDate(year, month, day), QTime(hour, minute, second)); xmlinfo_list[type]->xmlbase.datetime = time; cout << "##################################isdelta_flag is " << isdelta_flag << endl; /*lnk2024-8-14 根据isdelta_flag 选择xmllist*/ if (isdelta_flag) { cout << "xmllist2 create" << endl; if (!xmlinfo_list2.contains(type)) { Xmldata* config2 = new Xmldata(); xmlinfo_list2.insert(type, config2); } else { QDateTime time(QDate(year, month, day), QTime(hour, minute, second)); if (xmlinfo_list2[type]->xmlbase.datetime == time) { xmlinfo_list2[type]->updataflag = false; } else { xmlinfo_list2[type]->updataflag = true; } } xmlinfo_list2[type]->xmlbase.MODEL_ID = id; xmlinfo_list2[type]->xmlbase.TMNL_TYPE = type; xmlinfo_list2[type]->xmlbase.FILE_PATH = filepath; xmlinfo_list2[type]->xmlbase.FILE_NAME = name; xmlinfo_list2[type]->xmlbase.datetime = time; } /*lnk2024-8-14*/ char file_name[256]; memset(file_name, 0, 256); sprintf(file_name, "%s", FILE_NAME); QString Qsavename; Qsavename.append("/FeProject/dat/").append(id).append(".xml"); //本地保存路径 char save_name[256]; memset(save_name, 0, 256); sprintf(save_name, "%s", Qsavename.toAscii().data()); cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; //20241028 lnk 替换为文件下载web接口 //构造文件下载接口参数 //接口示例http://192.168.1.125:10215/file/download?filePath=/path/xxx.txt // 调用web获取文件内容 char* fileContent = NULL; //测试下载 //char downpath[128] = {"/home/pq/FeProject/src/pt61850netd_pqfe_lnk/download/123.txt"}; //char download[128] = {"{\"filename\":\"file_test.txt\"}"}; //SendJsonAPI_web("http://192.168.1.149:8091/file/download", "", download, &fileContent); std::string fullPath = std::string("filePath=") + std::string(FILE_PATH); //调试用 std::cout << "fullpath" << fullPath << std::endl; SendJsonAPI_web(WEB_FILEDOWNLOAD, fullPath.c_str(), "", &fileContent); if (fileContent != NULL) { // 创建并打开文件 //测试 //std::ofstream outFile(downpath, std::ios::binary);//二进制的方式打开 std::ofstream outFile(save_name, std::ios::out);//文本模式打开 if (outFile.is_open()) { // 将文件流写入文件 outFile.write(fileContent, strlen(fileContent)); outFile.close(); std::cout << "File saved successfully!" << std::endl; } else { std::cerr << "Error: Unable to open file for writing." << std::endl; } // 释放分配的内存 free(fileContent); } else { std::cerr << "Error: Unable to download file." << std::endl; } /*if (FILE_FLAG == 1) { GetOSS(file_name, save_name); } else if (FILE_FLAG == 2) { OBSFile(save_name, file_name, "getObject"); } else if (FILE_FLAG == 3) { //OBSFile(save_name, file_name, "getObject"); } else { }*/ //调试用 if (xmlinfo_list.contains(type)) { std::cout << "xmlinfo_list.contains" << type.toStdString() <::iterator it2 = xmlinfo_list.begin(); it2 != xmlinfo_list.end(); ++it2) { QString key2 = it2.key(); Xmldata* value2 = it2.value(); if (value2->updataflag == true) { ParseXMLConfig2(0,&(value2->xmlcfg), &(value2->topicList), value2->xmlbase.MODEL_ID); } } //lnk2024-8-14 选择角型接线 if (isdelta_flag) { for (QMap::iterator it3 = xmlinfo_list2.begin(); it3 != xmlinfo_list2.end(); ++it3) { QString key3 = it3.key(); Xmldata* value3 = it3.value(); // if (value3->updataflag == true) { ParseXMLConfig2(1, &(value3->xmlcfg), &(value3->topicList), value3->xmlbase.MODEL_ID); } } } } else { cout << "!!!!!!!!!! xmlinfo_list.size() == 0 !!!!!!!!!!!" << endl; } } //zw修改 2023-9-4 获取xml路径 char* Get_xmlpath(char* devtype) { QString type; type.append(devtype); //调试用lnk20241125 std::cout << type.toStdString() << std::endl; if (xmlinfo_list.contains(type)) { cout << "!!!!!!!!!! xmlinfo_list.contains(devtype) == 1 !!!!!!!!!!!" << endl; QByteArray byteArray = xmlinfo_list[devtype]->xmlbase.MODEL_ID.toLocal8Bit(); char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; } else { cout << "!!!!!!!!!! xmlinfo_list.contains(devtype) == 0 !!!!!!!!!!!" << endl; return NULL; } } //zw修改 2023-9-5 获取IED模型 char* Get_IED(char* devtype) { QString type; type.append(devtype); if (xmlinfo_list.contains(type)) { cout << "!!!!!!!!!! Get_IED xmlinfo_list.contains(devtype) == 1 !!!!!!!!!!!" << endl; QString ied; ied.append(xmlinfo_list[devtype]->xmlcfg.IEDname);//PQMonitor ied.append(xmlinfo_list[devtype]->xmlcfg.LDevicePrefix); ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; } else { cout << "!!!!!!!!!! Get_IED xmlinfo_list.contains(devtype) == 0 !!!!!!!!!!!" << endl; //cout << "ttttttttttttttt" << topicList.size() << endl; //cout << "ttttttttttttttt" << xmlcfg.IEDname.toAscii().data() << endl; QString ied; ied.append(xmlcfg.IEDname); ied.append(xmlcfg.LDevicePrefix); ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; } } char* Get_LDevice(char* devtype) { QString type; type.append(devtype); if (xmlinfo_list.contains(type)) {//解析列表中包含终端类型 QString ied; ied.append(xmlinfo_list[devtype]->xmlcfg.LDevicePrefix);//使用解析列表的终端前缀 ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; } else { //cout << "ttttttttttttttt" << topicList.size() << endl; //cout << "ttttttttttttttt" << xmlcfg.IEDname.toAscii().data() << endl; QString ied; ied.append(xmlcfg.LDevicePrefix);//使用默认解析配置的终端前缀 ied.append("%d"); QByteArray byteArray = ied.toLocal8Bit(); char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305 memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; } } ///////////////////////////////////////////////////lnk2024-10-21//////////////////////////////////////////////////////// void handleCommentResponse(const std::string& response) { // 解析 JSON 响应 cJSON* json_data = cJSON_Parse(response.c_str()); if (json_data == NULL) { std::cerr << "Error parsing response: " << cJSON_GetErrorPtr() << std::endl; return; } // 提取字段 cJSON* codeItem = cJSON_GetObjectItem(json_data, "code"); cJSON* msgItem = cJSON_GetObjectItem(json_data, "msg"); cJSON* dataItem = cJSON_GetObjectItem(json_data, "data"); if (codeItem) { std::string code = codeItem->valuestring; // 输出信息 std::cout << "Response Code: " << code << std::endl; std::string msg = (msgItem != NULL) ? msgItem->valuestring : "not found"; std::cout << "Message: " << msg << std::endl; } else { std::cerr << "Error: Missing expected fields in JSON response." << std::endl; } // 释放 JSON 对象 cJSON_Delete(json_data); } std::string boolToString(bool value) { return value ? "1" : "0"; } //添加入参、时间和状态lnk202411-4 void connectlog_pgsql(char* id,char* datetime,int status) { /*QString pgsql; pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_status_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',1) ").arg(id).arg(QDateTime::currentDateTime().toString("yyyyMMdd"))); pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\") do update set ")); pgsql.append(QString("\"comm_status\"= \"%1\".\"%2meas_pq_comm_status_tr\".\"comm_status\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 //cout << pgsql.toAscii().data() << endl;*/ /*std::vector codes; codes.push_back("log"); codes.push_back(std::string(id)); codes.push_back(QDateTime::currentDateTime().toString("yyyyMMdd").toStdString()); parse_commstatus_write(codes); codes.clear();*/ //采用状态更新的方式 //创建响应接收 char* ptr=NULL; // 创建 JSON 对象 cJSON* jsonObject = cJSON_CreateObject(); if (jsonObject == NULL) { std::cerr << "Failed to create JSON object." << std::endl; return; } // 添加字段到 JSON 对象 cJSON* id_item = cJSON_CreateString(id); if (!id_item) { std::cerr << "Failed to create 'id' string." << std::endl; cJSON_Delete(jsonObject); return; } cJSON_AddItemToObject(jsonObject, "id", id_item); cJSON* datetime_item = cJSON_CreateString(datetime); if (!datetime_item) { std::cerr << "Failed to create 'Datetime' string." << std::endl; cJSON_Delete(jsonObject); return; } cJSON_AddItemToObject(jsonObject, "Datetime", datetime_item); char statusStr[12]; // 足够容纳一个整数(包括负号和 '\0') sprintf(statusStr, "%d", status);// 使用 sprintf 将 int 转换为字符串 cJSON* status_item = cJSON_CreateString(statusStr); if (!status_item) { std::cerr << "Failed to create 'status' string." << std::endl; cJSON_Delete(jsonObject); return; } cJSON_AddItemToObject(jsonObject, "status", status_item); // 将对象添加到数组 //cJSON_AddItemToArray(jsonArray, jsonObject); // 将数组转换为字符串 //char* jsonString = cJSON_PrintUnformatted(jsonArray); char* jsonString = cJSON_Print(jsonObject); if (jsonString == NULL) { std::cerr << "Failed to print JSON object." << std::endl; cJSON_Delete(jsonObject); return; } //std::cout << "jsonString: " << jsonString << std::endl;////减少多余的打印 //发送数据到远端 /*SendJsonAPI_web(WEB_COMFLAG, "", jsonString,&ptr);//不使用接口lnk20250310 //处理返回的数据 // 检查 ptr 是否为 NULL,避免 std::string 初始化失败 if (ptr != NULL) { //handleCommentResponse(std::string(ptr));//减少多余的打印 free(ptr); // 如果 SendJsonAPI_web 分配了内存,记得释放 } else { // 处理 ptr 为 NULL 的情况,例如日志记录或错误处理 std::cout << "Error: Received NULL response" << std::endl; }*/ //使用mq Ckafka_data_t connect_info; connect_info.strTopic = QString::fromStdString(G_CONNECT_TOPIC); connect_info.strText = QString::fromStdString(std::string(jsonString)); if(g_node_id == STAT_DATA_BASE_NODE_ID){//稳态才上传 kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(connect_info); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁 } // 释放内存 cJSON_Delete(jsonObject); free(jsonString); // cJSON_PrintUnformatted使用malloc分配内存 } //新增异常事件 pgsql组装函数 终端id 发生当日时间 存储文件路径 void errorlog_pgsql(char* id, QString time, QString filename) { /*QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',1,'%3') ").arg(id).arg(time).arg(filename)); pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\") do update set ")); pgsql.append(QString("\"comm_status\"= \"%1\".\"%2meas_pq_comm_error_tr\".\"comm_status\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << pgsql.toAscii().data() << endl;*/ /*std::vector codes; codes.push_back("log"); codes.push_back(std::string(id)); codes.push_back(time.toStdString()); codes.push_back(filename.toStdString()); parse_commerror_write(codes); codes.clear();*/ } //新增暂降触发报告记录 void SoeRptSql(char* id, int state,char* rpt) { /*QDateTime savetime = QDateTime::currentDateTime(); QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(id).arg(savetime.toString("yyyyMMdd")).arg(state).arg(rpt)); pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\",\"file_name\") do update set ")); pgsql.append(QString("\"comm_status\"= %1;").arg(state)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁*/ /*std::vector codes; codes.push_back("soe"); codes.push_back(std::string(id)); codes.push_back(QDateTime::currentDateTime().toString("yyyyMMdd").toStdString()); codes.push_back(intToString(state)); codes.push_back(std::string(rpt)); parse_commerror_write(codes); codes.clear();*/ } //lnk 20241210删除不需要的代码 #if 0 //合理性数据 pgsql语句生成 QString errorlog_num_pgsql(QString monitorId, QString datatime, QString filename, int count) { /*QString log_pqsql;//待生成的pgsql语句 log_pqsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_rationality_tr\"(\"monitor_id\",\"statistical_date\",\"irrat_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); log_pqsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(monitorId).arg(datatime).arg(count).arg(filename)); log_pqsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(log_pqsql); Sql_data_list_mutex.unlock(); //解锁 return log_pqsql;*/ /*std::vector codes; codes.push_back("log"); codes.push_back(monitorId.toStdString()); codes.push_back(datatime.toStdString()); codes.push_back(intToString(count)); codes.push_back(filename.toStdString()); parse_rationality_write(codes); codes.clear();*/ } //数值完整性判断 单条pgsql插入语句生成 终端id 插入天数 QString errorlog_dataintegrity_pgsql(QString time, QString datatime,QString monitorId,bool recallflag) { /*int num = 480; if (data_timespan_list[monitorId]->msspan != 0) { num = 1440 / data_timespan_list[monitorId]->msspan; } QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_intact_tr\"(\"monitor_id\",\"statistical_date\",\"exp_num\",\"act_num\",\"value_time\",\"last_value_time\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',480,1,array[TIMESTAMP'%3'],'%4') ").arg(monitorId).arg(time).arg(datatime).arg(datatime)); pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do update set ")); //pgsql.append(QString("\"value_time\"=(array_cat(EXCLUDED.\"value_time\", \"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\"))[:1440] , \"exp_num\" = %3 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); if (recallflag == true) { if (data_timespan_list[monitorId]->msspan != 0) { pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); } else { pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); } } else { pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); } Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 return pgsql;*/ //不再需要这么多入参202411-1lnk,只需要id和时间点,不区分补招和稳态,不需要时间间隔 /*std::vector codes; codes.push_back("log"); codes.push_back(time.toStdString()); codes.push_back(datatime.toStdString()); codes.push_back(monitorId.toStdString()); codes.push_back(boolToString(recallflag)); codes.push_back(intToString(data_timespan_list[monitorId]->msspan)); parse_dataintegrity_write(codes); codes.clear();*/ //创建响应接收 char* ptr=NULL; // 创建 cJSON 对象 cJSON* jsonArray = cJSON_CreateArray(); // 创建 JSON 对象 cJSON* jsonObject = cJSON_CreateObject(); cJSON_AddStringToObject(jsonObject, "id", monitorId.toStdString().c_str()); cJSON_AddStringToObject(jsonObject, "date", datatime.toStdString().c_str()); // 将对象添加到数组 cJSON_AddItemToArray(jsonArray, jsonObject); // 将数组转换为字符串 char* jsonString = cJSON_PrintUnformatted(jsonArray); //发送数据到远端 SendJsonAPI_web(WEB_INTEGRITY,"", jsonString,&ptr); //处理返回的数据 // 检查 ptr 是否为 NULL,避免 std::string 初始化失败 if (ptr != NULL) { handleCommentResponse(std::string(ptr)); free(ptr); // 如果 SendJsonAPI_web 分配了内存,记得释放 } else { // 处理 ptr 为 NULL 的情况,例如日志记录或错误处理 std::cout << "Error: Received NULL response" << std::endl; } // 转换为 QString QString result = QString::fromStdString(jsonString); // 释放内存 cJSON_Delete(jsonArray); free(jsonString); // cJSON_PrintUnformatted使用malloc分配内存 return result; //返回json打印用 } //数值匹配率判断 单条pgsql插入语句生成 终端id 插入天数 基础应有 完整应有 基础实际 完整实际 QString errorlog_datamatch_pgsql(QString id, QString time, int BASE_MAT_NUM,int ADV_MAT_NUM,int BASE_ACT_NUM,int ADV_ACT_NUM,QString filename) { /*QString pgsql;//待组装的pgsql语句 pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_match_tr\"(\"monitor_id\",\"statistical_date\",\"base_mat_num\",\"adv_mat_num\",\"base_act_num\",\"adv_act_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); pgsql.append(QString("values('%1',date'%2',%3,%4,%5,%6,'%7') ").arg(id).arg(time).arg(BASE_MAT_NUM).arg(ADV_MAT_NUM).arg(BASE_ACT_NUM).arg(ADV_ACT_NUM).arg(filename)); pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); //pgsql.append(QString("\"BASE_ACT_NUM\"= %1 , \"ADV_ACT_NUM\"= %2;").arg(BASE_ACT_NUM).arg(ADV_ACT_NUM)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql); Sql_data_list_mutex.unlock(); //解锁 return pgsql;*/ /*std::vector codes; codes.push_back("log"); codes.push_back(id.toStdString()); codes.push_back(time.toStdString()); codes.push_back(intToString(BASE_MAT_NUM)); codes.push_back(intToString(ADV_MAT_NUM)); codes.push_back(intToString(BASE_ACT_NUM)); codes.push_back(intToString(ADV_ACT_NUM)); codes.push_back(filename.toStdString()); parse_match_write(codes); codes.clear();*/ } #endif //lnk202411-5 暂态数据不再使用kafka发送,改成http接口 int transfer_json_qvvr_data(unsigned int func_type, int monitor_id, double mag, double dur, long long start_tm, long long end_tm, int dis_kind, //伏值,持续时间,开始时间,结束时间,暂态类型 char* uuid_cfg,char* uuid_dat, //两个录波文件 char* mp_id,char* Qvvr_rptname,char* devtype) //监测点号,暂态报告名,设备类型 { XmlConfig c_xmlcfg; if (xmlinfo_list.contains(devtype)) { c_xmlcfg = xmlinfo_list[devtype]->xmlcfg;//查找映射 } else { c_xmlcfg = xmlcfg; } if (strlen(mp_id) == 0) { std::cout << "mp_id is null" << std::endl; return 0; } // 存储 uuid_cfg 和 uuid_dat 测试用 //const char wave_paths[] = {"/comtrade/"}; // 初始化 cJSON 根对象 cJSON* root = cJSON_CreateObject(); // 拼接 JSON 数据 //调试用 //printf("Inside function: &mag = %p, &dur = %p\n", &mag, &dur); //printf("~~~~~~~send QVVR_PerTime after record is %f~~~~~~~~~~ \n",dur); //printf("~~~~~~~send QVVR_Amg after record is %f~~~~~~~~~~ \n",mag); //不需要数据类型,因为是http接口不是数据队列 cJSON_AddStringToObject(root, "monitorId", mp_id); cJSON_AddNumberToObject(root, "amplitude", mag); cJSON_AddNumberToObject(root, "duration", dur); cJSON_AddNumberToObject(root, "eventType", dis_kind); // 格式化时间戳为日期字符串(假设时间戳为毫秒) char start_time_str[25]; time_t start_sec = start_tm / 1000; struct tm* time_info = localtime(&start_sec); strftime(start_time_str, sizeof(start_time_str), "%Y-%m-%d %H:%M:%S", time_info); // 添加毫秒部分 snprintf(start_time_str + strlen(start_time_str), sizeof(start_time_str) - strlen(start_time_str), ".%03lld", start_tm % 1000); cJSON_AddStringToObject(root, "startTime", start_time_str); //cJSON_AddStringToObject(root, "wavePathcfg", uuid_cfg); // 动态设置波形文件路径不需要传具体文件名 //cJSON_AddStringToObject(root, "wavePathdat", uuid_dat); // 动态设置波形文件路径 cJSON_AddStringToObject(root, "wavePath", uuid_dat); //添加相别部分 if (c_xmlcfg.WavePhasicFlag == "1") { QString Qvvr_Rptname;//转换为qstring格式 Qvvr_Rptname.append(Qvvr_rptname); if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicA) != -1) { //查找映射配置是否在报告名中出现 cJSON_AddStringToObject(root, "phase", "A"); //拼接 相别 } else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicB) != -1) { cJSON_AddStringToObject(root, "phase", "B"); //拼接 相别 } else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicC) != -1) { cJSON_AddStringToObject(root, "phase", "C"); //拼接 相别 } else { cJSON_AddStringToObject(root, "phase", "unknow"); //拼接 相别 } } else { cJSON_AddStringToObject(root, "phase", "unknow"); //拼接 相别 } // 将 cJSON 对象转换为字符串 char* json_string = cJSON_Print(root); printf("%s\n", json_string); // 输出 JSON 字符串 // 发送到暂态接口 char* ptr = NULL; SendJsonAPI_web(WEB_EVENT, "", json_string, &ptr); // 处理返回的数据 // 检查 ptr 是否为 NULL,避免 std::string 初始化失败 if (ptr != NULL) { handleCommentResponse(std::string(ptr)); free(ptr); // 如果 SendJsonAPI_web 分配了内存,记得释放 } else { // 处理 ptr 为 NULL 的情况,例如日志记录或错误处理 std::cout << "Error: Received NULL response" << std::endl; // 释放内存 cJSON_Delete(root); free(json_string); return 0; } // 释放内存 cJSON_Delete(root); free(json_string); /*Ckafka_data_t KafkaData; //kafka发送数据结构类对象 KafkaData.monitor_id = monitor_id; KafkaData.mp_id = mp_id; KafkaData.strTopic = "Event"; //kafka发送主题 KafkaData.strText.append("{"); //拼接 json起始 if (400 == func_type || 500 == func_type || 600 == func_type || 700 == func_type) //三、补招历史数据 ——> MMS_Recall KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //拼接 数据类型 else KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //拼接 数据类型 KafkaData.strText.append(QString("\"Monitor\":\"%1\", ").arg(mp_id)); //拼接 json监测点 KafkaData.strText.append(QString("\"Value\":{")); //拼接 json监测点 KafkaData.strText.append(QString("\"FLAG\":%1,").arg(1)); //拼接 剔除标记 KafkaData.strText.append(QString("\"TIME\":%1,").arg(start_tm)); //拼接 时间 KafkaData.strText.append("\"VOLTAGE\":{"); //拼接 数据项 例:VOLTAGE KafkaData.strText.append(QString("\"MAG\":%1").arg(mag)); //拼接 残余电压,即:特征幅值 KafkaData.strText.append(QString(", \"DUR\":%1").arg(dur * 1000)); //拼接 持续时间(毫秒) KafkaData.strText.append(QString(", \"STARTTIME\":%1").arg(start_tm )); //拼接 开始时间(毫秒) KafkaData.strText.append(QString(", \"ENDTIME\":%1").arg(end_tm)); //拼接 结束时间(毫秒) KafkaData.strText.append(QString(", \"DISKIND\":\"%1%2\"").arg("0").arg(dis_kind)); //拼接 暂降类型(1210001-暂升 1210002-暂降 1210004-中断 1210003-其他) KafkaData.strText.append(QString(", \"CFG_FILE\":\"%1\"").arg(uuid_cfg)); //拼接 cfg波形文件名称 KafkaData.strText.append(QString(", \"DAT_FILE\":\"%1\"").arg(uuid_dat)); //拼接 dat波形文件名称 if (c_xmlcfg.WavePhasicFlag == "1") { QString Qvvr_Rptname; Qvvr_Rptname.append(Qvvr_rptname); if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicA) != -1) { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("A")); //拼接 相别 } else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicB) != -1) { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("B")); //拼接 相别 } else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicC) != -1) { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("C")); //拼接 相别 } else { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //拼接 相别 } } else { KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //拼接 相别 } KafkaData.strText.append("}"); //拼接 json结束 KafkaData.strText.append("}}"); //拼接 json结束 printf("transfer json qvvr data: %s==%s \n",KafkaData.strText.toStdString().c_str(), Qvvr_rptname); kafka_data_list_mutex.lock(); //加锁 kafka_data_list.append(KafkaData); //添加 kafka发送链表 kafka_data_list_mutex.unlock(); //解锁*/ return 1; } void qvvr_test() { char uuid_cfg[] = {"/comtrade/"}; char uuid_dat[] = {"/comtrade/"}; char mp_id[] = {"000cf2a27f3f13f330b9e8690641e7f2"}; char Qvvr_rptname[] = {"unknow"}; char devtype[] = {"01"}; transfer_json_qvvr_data(1, 123456789, 220, 180, 1730894400.123, 1730894580, 1210001,uuid_cfg,uuid_dat,mp_id,Qvvr_rptname,devtype); } void comflag_test() { char id[] = {"000cf2a27f3f13f330b9e8690641e7f2"}; char datetime[] = {"2024-11-6 15:15:15"}; connectlog_pgsql(id,datetime,1); } ///////////////////////////////////////////////////lnk2024-10-21//////////////////////////////////////////////////////// void clearXmlConfigAndTopicList(Xmldata* data) { // 清空 XmlConfig data->xmlcfg = XmlConfig(); // 通过重新赋值重置 xmlcfg // 清空 topicList list::iterator it; for (it = data->topicList.begin(); it != data->topicList.end(); ++it) { delete *it; // 释放内存 } data->topicList.clear(); // 清空链表 } //4-配置映射文件////////////////////////////// void Set_xml_nodeinfo_one(char* dev_type) { bool ret = false; //如果是新增台账不是初始化,不需要再解析一次默认配置 /* //配置无对应xml文件时的默认解析配置 if (!inited) //初始化 JiangSu_Config.xml { QString path; path.append("not define"); ParseXMLConfig2(&xmlcfg, &topicList, path); //调用 ParseXMLConfig() 解析JiangSu_Config.xml配置文件 inited = true; } */ if(xmlinfo_list[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点 if(xmlinfo_list[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新 //将这个点的xmlcfg和topicList删除 clearXmlConfigAndTopicList(xmlinfo_list[QString::fromUtf8(dev_type)]); ret = ParseXMLConfig2(0,&(xmlinfo_list[QString::fromUtf8(dev_type)]->xmlcfg), &(xmlinfo_list[QString::fromUtf8(dev_type)]->topicList), xmlinfo_list[QString::fromUtf8(dev_type)]->xmlbase.MODEL_ID); if(!ret) { std::cout << "!!!! this ledger xml config fail!!!!" << std::endl; } } } else{ std::cout << "xmlinfo_list not contain this devtype" << std::endl; } //添加角形 if(isdelta_flag){ if(xmlinfo_list2[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点 if(xmlinfo_list2[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新 //将这个点的xmlcfg和topicList删除 clearXmlConfigAndTopicList(xmlinfo_list2[QString::fromUtf8(dev_type)]); ret = ParseXMLConfig2(1,&(xmlinfo_list2[QString::fromUtf8(dev_type)]->xmlcfg), &(xmlinfo_list2[QString::fromUtf8(dev_type)]->topicList), xmlinfo_list2[QString::fromUtf8(dev_type)]->xmlbase.MODEL_ID); if(!ret) { std::cout << "!!!! this ledger xml config fail!!!!" << std::endl; } } } else{ std::cout << "xmlinfo_list2 not contain this devtype" << std::endl; } } } //4-配置映射文件///////////////////////////////////