4411 lines
194 KiB
C++
4411 lines
194 KiB
C++
|
||
#include <QtCore/QCoreApplication>
|
||
#include <iostream>
|
||
#include <fstream>
|
||
#include <qdebug.h>
|
||
|
||
#include <QFile>
|
||
#include <QtXml/QDomDocument>
|
||
#include <QtXml/QDomElement>
|
||
#include <QtXml/QDomNode>
|
||
#include <QtXml/QDomNodeList>
|
||
#include <QtCore/qglobal.h>
|
||
#include <list> //C++ STL的list
|
||
#include <map> //C++ STL的map
|
||
#include <QStringList>
|
||
|
||
#include <QDateTime>//zw修改 2023-08-22 存储数据合理性相关属性
|
||
#include <QMap>//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;
|
||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
using namespace std;
|
||
|
||
extern int parse_commerror_write(const std::vector<std::string>& codes);
|
||
extern int parse_commstatus_write(const std::vector<std::string>& codes);
|
||
extern int parse_match_write(const std::vector<std::string>& codes);
|
||
extern int parse_dataintegrity_write(const std::vector<std::string>& codes);
|
||
extern int parse_rationality_write(const std::vector<std::string>& 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<CDataValue*> DataValueList; //数据值链表
|
||
};
|
||
|
||
class CItem //数据项类
|
||
{
|
||
public:
|
||
QString strItemName; //数据项名
|
||
QString strItemValue; //数据项值
|
||
QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
|
||
list<CSequence*> SequenceList; //相别链表
|
||
};
|
||
|
||
class CMonitor //监测点类
|
||
{
|
||
public:
|
||
QString strMonitor; //监测点名
|
||
QString type; //参数等级type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
|
||
list<CItem*> 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<CMonitor*> MonitorList; //监测点链表
|
||
list<CEventData*> SOEList; //SOE事件链表
|
||
};
|
||
|
||
class CTopic //Kafka Producer发送主题类
|
||
{
|
||
public:
|
||
QString strTopic; //Kafka Producer发送主题值
|
||
list<CDataType*> 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<CEventData*> 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<long long> timespan;//时间戳队列
|
||
int msspan;
|
||
|
||
Mn_Timespan()
|
||
{
|
||
msspan = 0;
|
||
}
|
||
};
|
||
|
||
class Xmldata //zw修改 2023-08-30
|
||
{
|
||
public:
|
||
XmlDataBase xmlbase;//xml数据库数据
|
||
XmlConfig xmlcfg;//新増的xml节点解析数据
|
||
list<CTopic*> topicList; //Kafka发送主题链表
|
||
bool updataflag = true;
|
||
};
|
||
|
||
//-------------------------------------------------------------------------------------*/
|
||
//主程序已定义该变量
|
||
//extern QMutex kafka_data_list_mutex; //Kafka发送数据锁
|
||
//extern QList<kafka_data_t> kafka_data_list; //kafka发送数据链表
|
||
extern int FILE_FLAG;
|
||
|
||
QMutex kafka_data_list_mutex; //Kafka发送数据锁
|
||
QList<Ckafka_data_t> kafka_data_list; //kafka发送数据链表
|
||
|
||
QMutex oss_data_list_mutex; //oss发送数据锁 zw新增
|
||
QList<oss_data_t> oss_data_list; //oss发送数据链表 zw新增
|
||
//-------------------------------------------------------------------------------------*/
|
||
//////////////////////////////////////WW 2023-08-22 start
|
||
QMutex Sql_data_list_mutex; //Sql执行语句锁
|
||
QList<QString> Sql_data_list; //Sql执行语句链表
|
||
//////////////////////////////////////WW 2023-08-22 end
|
||
|
||
//QMap<int, QMap<QString, MP_RATIONALITY*> > error_data_list;//zw修改 2023 - 8 - 22 新増数据不合理性记录map
|
||
//QMap<int, QMap<QString, QDateTime> > error_datamatch_list;//zw修改 2023-8-28 数据匹配率缺少字段记录map
|
||
QMap<QString,Mn_Timespan*> data_timespan_list;//zw修改 2023 - 8 - 29 计算时间间隔
|
||
QMap<QString, Xmldata*> xmlinfo_list;//zw修改 保存所有型号对应的xml数据-数据库数据 新增的节点解析数据 kafka发送链表
|
||
|
||
XmlConfig xmlcfg;//zw修改 2023 - 8 - 14 新増xml节点解析的数据
|
||
list<CTopic *> topicList; //Kafka发送主题链表
|
||
int inited = false; //JiangSu_Config.xml是否初始化标识
|
||
|
||
XmlConfig xmlcfg2;//lnk2024 - 8 - 13 新増角型xml节点解析的数据
|
||
list<CTopic*> topicList2; //lnk2024-8-14角型Kafka发送主题链表
|
||
QMap<QString, Xmldata*> 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<QString, MP_RATIONALITY*> *map_list,long long time)
|
||
{
|
||
if(pDataValue == NULL)
|
||
{
|
||
cout << "Function errorlog_num Error!" <<endl;
|
||
return;
|
||
}
|
||
//cout << pDataValue->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<QString, MP_RATIONALITY*> map_list)
|
||
{
|
||
int count = 0;
|
||
QString log_json;//待生成的json字符串
|
||
QMap<QString, MP_RATIONALITY*> tmp = map_list;
|
||
for (QMap<QString, MP_RATIONALITY*>::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<QString, QDateTime> *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<QString, QDateTime> data_match_map_1, QMap<QString, QDateTime> data_match_map_2,long long time)
|
||
{
|
||
QString log_json,fullnamelist;//待生成的json字符串
|
||
if (data_match_map_1.count() != 0) {
|
||
for (QMap<QString, QDateTime>::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<QString, QDateTime>::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<CTopic*> *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() <<std::endl;//lnk20250208
|
||
return 0;
|
||
}
|
||
if (!doc.setContent(&file)) //将文件内容读到doc中
|
||
{
|
||
std::cout << "can't read config file" << tmppath.toStdString() <<std::endl;//lnk20250208
|
||
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 <DataType>
|
||
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 <Monitor>
|
||
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 <Item>
|
||
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 <Sequence>
|
||
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 <Value>
|
||
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 <Value>
|
||
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 <DataType>
|
||
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 <SOE>
|
||
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 <DataType>
|
||
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<<xmlcfg->LDevicePrefix.toAscii().data() <<endl;
|
||
}
|
||
}
|
||
} //判断n为元素 结束
|
||
|
||
n = n.nextSibling();//获取下一个兄弟节点(HISDATA —> RTDATA —> RTDATASOE)
|
||
} //while (!n.isNull) 结束
|
||
|
||
return true;
|
||
}
|
||
#endif
|
||
//lnk2024-8-16 适配角型接线
|
||
bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *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 <DataType>
|
||
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 <Monitor>
|
||
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 <Item>
|
||
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 <Sequence>
|
||
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 <Value>
|
||
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 (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 <Value>
|
||
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 <Value>
|
||
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 <DataType>
|
||
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 <SOE>
|
||
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 <DataType>
|
||
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<<xmlcfg->LDevicePrefix.toAscii().data() <<endl;
|
||
}
|
||
}
|
||
} //判断n为元素 结束
|
||
|
||
n = n.nextSibling();//获取下一个兄弟节点(HISDATA —> RTDATA —> RTDATASOE)
|
||
} //while (!n.isNull) 结束
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// czy 2023-11-23 测试json的装置间隔频,打印前台
|
||
/// </summary>
|
||
/// <param name="flag">1是,2是,3是填入计算的interval</param>
|
||
/// <param name="interval">1是,2是,3是填入计算的interval</param>
|
||
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;
|
||
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// czy kafka的json中将线电压转成相电压
|
||
/// </summary>
|
||
/// <param name="pSequence"></param>
|
||
/// <returns></returns>
|
||
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*> 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<CTopic*>* 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<QString, MP_RATIONALITY*> data_reason_map;//数据合理性map
|
||
QMap<QString, QDateTime> data_match_map_1;//数据匹配率map 基础数据
|
||
QMap<QString, QDateTime> 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<CTopic*>::iterator tp = ctopic_list.begin();
|
||
while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表
|
||
{
|
||
CTopic* pTopic = *tp++;
|
||
if ("HISDATA" == pTopic->strTopic) //Topic等于HISDATA
|
||
{
|
||
list<CDataType*>::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<CMonitor*>::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<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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<CMonitor*>::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<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
|
||
while (mt != pDataType->MonitorList.end())
|
||
{
|
||
CMonitor* pMonitor = *mt++;
|
||
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
|
||
|
||
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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);
|
||
}
|
||
else {
|
||
errorlog_datamatch(pDataValue->strFullName, &data_match_map_2);
|
||
}
|
||
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,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<QString, QDateTime>().swap(data_match_map_1);
|
||
QMap<QString, QDateTime>().swap(data_match_map_2);
|
||
QMap<QString, MP_RATIONALITY*>().swap(data_reason_map);
|
||
}
|
||
return 1; //结束该函数,停止后续代码执行
|
||
} //②-①历史稳态数据解析结束!--------------------------------
|
||
} //DataTypeList 结束
|
||
} //遍历 HISDATA 结束!
|
||
} //TopicList 结束
|
||
} //一、结束
|
||
|
||
if (200 == data->func_type) //二、3秒数据/实时数据 ——> MMS_Assist
|
||
{
|
||
list<CTopic*>::iterator tp = ctopic_list.begin();
|
||
while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表
|
||
{
|
||
CTopic* pTopic = *tp++;
|
||
if ("RTDATA" == pTopic->strTopic) //Topic等于RTDATA------------------------------------------------------------
|
||
{
|
||
list<CDataType*>::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<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
|
||
while (mt != pDataType->MonitorList.end())
|
||
{
|
||
CMonitor* pMonitor = *mt++;
|
||
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
|
||
|
||
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
|
||
while (mt != pDataType->MonitorList.end())
|
||
{
|
||
CMonitor* pMonitor = *mt++;
|
||
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
|
||
|
||
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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<CDataType*>::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<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
|
||
list<CEventData*>::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<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
|
||
list<CEventData*>::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<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
|
||
list<CEventData*>::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<CTopic*>::iterator tp = ctopic_list.begin();
|
||
while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表
|
||
{
|
||
CTopic* pTopic = *tp++;
|
||
if ("HISDATA" == pTopic->strTopic) //Topic等于HISDATA----------------------------------------------------------
|
||
{
|
||
list<CDataType*>::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<CMonitor*>::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<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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<CMonitor*>::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<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
|
||
while (mt != pDataType->MonitorList.end())
|
||
{
|
||
CMonitor* pMonitor = *mt++;
|
||
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
|
||
|
||
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
|
||
list<CItem*>::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<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
|
||
list<CSequence*>::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<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
|
||
CDataValue* pDataValueBegin = *dv;
|
||
list<CDataValue*>::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);
|
||
}
|
||
else {
|
||
errorlog_datamatch(pDataValue->strFullName, &data_match_map_2);
|
||
}
|
||
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<QString, QDateTime>().swap(data_match_map_1);
|
||
QMap<QString, QDateTime>().swap(data_match_map_2);
|
||
QMap<QString, MP_RATIONALITY*>().swap(data_reason_map);
|
||
}
|
||
return 1; //结束该函数,停止后续代码执行
|
||
} //②-①历史稳态数据解析结束!--------------------------------
|
||
} //DataTypeList 结束
|
||
} //遍历 HISDATA 结束!
|
||
|
||
if ("RTDATASOE" == pTopic->strTopic) //Topic等于RTDATASOE----------------------------------------------------------
|
||
{
|
||
list<CDataType*>::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<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
|
||
list<CEventData*>::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<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
|
||
list<CEventData*>::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<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
|
||
list<CEventData*>::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<CEventData*>::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() <<std::endl;
|
||
}
|
||
else{
|
||
std::cout << "??????????????????xmlinfo_list not contains" << type.toStdString() <<std::endl;
|
||
}
|
||
}
|
||
//zw修改 2023-9-4 读取装置类型对应的xml文件
|
||
void Set_xml_nodeinfo()
|
||
{
|
||
//配置无对应xml文件时的默认解析配置
|
||
if (!inited) //初始化 JiangSu_Config.xml
|
||
{
|
||
QString path;
|
||
path.append("not define");
|
||
ParseXMLConfig2(0, &xmlcfg, &topicList, path); //调用 ParseXMLConfig() 解析JiangSu_Config.xml配置文件
|
||
if (isdelta_flag) {
|
||
ParseXMLConfig2(1, &xmlcfg2, &topicList2, path); //lnk2024-8-13角型接线
|
||
}
|
||
inited = true;
|
||
}
|
||
|
||
if (xmlinfo_list.size() != 0)
|
||
{
|
||
cout << "!!!!!!!!!! xmlinfo_list.size() != 0 !!!!!!!!!!!" << endl;
|
||
for (QMap<QString, Xmldata*>::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<QString, Xmldata*>::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()];
|
||
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()];
|
||
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()];
|
||
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()];
|
||
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()];
|
||
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<std::string> 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);
|
||
|
||
//处理返回的数据
|
||
// 检查 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(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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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,
|
||
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) //监测点号,暂态报告名,设备类型
|
||
{
|
||
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 数据
|
||
//不需要数据类型,因为是http接口不是数据队列
|
||
cJSON_AddStringToObject(root, "monitorId", mp_id);
|
||
cJSON_AddNumberToObject(root, "amplitude", mag);
|
||
cJSON_AddNumberToObject(root, "duration", dur * 1000);
|
||
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); // 动态设置波形文件路径
|
||
//添加相别部分
|
||
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 integrity_test()
|
||
{
|
||
QString time = "2024-11-6";
|
||
QString datatime = "2024-11-6 13:13:13";
|
||
QString monitorId = "000cf2a27f3f13f330b9e8690641e7f2";
|
||
|
||
errorlog_dataintegrity_pgsql(time,datatime,monitorId,1);
|
||
}*/
|
||
|
||
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<CTopic*>::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-配置映射文件///////////////////////////////////
|