Files
microser/json/create_json.cpp

3540 lines
158 KiB
C++
Raw Normal View History

2025-01-16 16:17:01 +08:00
#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>
2025-05-09 16:53:07 +08:00
#include <list> //C++ STL的list
#include <map> //C++ STL的map
2025-01-16 16:17:01 +08:00
#include <QStringList>
2025-05-09 16:53:07 +08:00
#include <QDateTime>//zw修改 2023-08-22 存储数据合理性相关属性
#include <QMap>//zw修改 2023-08-22 存储数据合理性相关属性
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
#include "mms_json_inter.h" //json头文件
#include "../mms/db_interface.h" //json头文件
#include "../mms/rdb_client.h" //台账更新引用接口
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//lnk20241031用于上传和下载文件
2025-01-16 16:17:01 +08:00
#include "../json/cjson.h"
#include "../log4cplus/log4.h"//lnk添加log4
2025-01-16 16:17:01 +08:00
///////////////////////////////////////////////////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;
2025-03-11 21:07:17 +08:00
extern std::string G_CONNECT_TOPIC;
2025-07-10 18:05:18 +08:00
2025-07-30 16:30:10 +08:00
bool DEBUGOPEN = 0;
2025-01-16 16:17:01 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using namespace std;
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;
2025-02-14 16:44:38 +08:00
//lnk20250214
extern int isdelta_flag;
2025-05-09 16:53:07 +08:00
//江苏Kafka发送数据类定义-------------------------------------------------------------/*
class CEventData //SOE事件类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
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; //数据对象名 $ 数据属性名
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class CDataValue //数据值类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
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
2025-01-16 16:17:01 +08:00
CDataValue()
{
2025-05-09 16:53:07 +08:00
fCoefficient = 1.0f; //数据系数(浮点型)
iOffset = 0; //起始序号偏移量(整型)
bIsAngle = false; //非角度标志
bPlt = false; //短时闪变标识
2025-01-16 16:17:01 +08:00
}
};
2025-05-09 16:53:07 +08:00
class CSequence //相别(A、B、C、T)类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString strSValue; //相别值 例7ABC三项8T相
QString strSeq; //相别 例A、B、C、T
QString type; //参数等级type类型0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
list<CDataValue*> DataValueList; //数据值链表
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class CItem //数据项类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString strItemName; //数据项名
QString strItemValue; //数据项值
QString type; //参数等级type类型0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
list<CSequence*> SequenceList; //相别链表
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class CMonitor //监测点类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString strMonitor; //监测点名
QString type; //参数等级type类型0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
list<CItem*> ItemList; //数据项链表
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class CDataType //数据类型类
2025-01-16 16:17:01 +08:00
{
public:
2025-07-29 18:10:03 +08:00
int iDataType; //数据类型值1-稳态 2-闪变 3-长闪
2025-05-09 16:53:07 +08:00
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事件链表
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class CTopic //Kafka Producer发送主题类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString strTopic; //Kafka Producer发送主题值
list<CDataType*> DataTypeList; //数据类型链表
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class XmlConfig //zw修改 2023 - 8 - 14 增加xml解析的配置类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString WavePhasicFlag; //是否分相 0-不分相 1-分相 如果Flag=0 ABC配置成一样如果Flag=1ABC根据实际配置
2025-01-16 16:17:01 +08:00
QString WavePhasicA;
QString WavePhasicB;
QString WavePhasicC;
2026-01-27 16:58:15 +08:00
QString TypeOfData; //闪变和统计是否合并 0-分开 1-合并
QString UnitOfTimeUnit; //暂态事件持续事件单位0 - 毫秒 1 - 秒 lnk20260127
2025-05-09 16:53:07 +08:00
QString ValueOfTimeUnit; //上送值的时间UTC-UTC时间 beijing-北京时间
QString WaveTimeFlag; //录波文件的时间UTC-UTC时间 beijing-北京时间
QString IEDname; //例PQMonitor
QString LDevicePrefix; //例PQM
list<CEventData*> SOEList; //SOE告警事件链表
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class XmlDataBase //zw修改 2023-8-30 增加解析数据库模型表数据类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString MODEL_ID;//模型编码 guid
QString TMNL_TYPE;//终端型号
QString TMNL_FACTORY;//终端厂家
QString FILE_PATH;//远端模型文件路径 lnk2024-10-28
QString FILE_NAME;//oss文件存储路径
QDateTime datetime;//更新时间 时间戳
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class MP_RATIONALITY //zw修改 2023 - 8 - 22 增加数据不合理性记录类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
double fValue;//zw修改 2023-08-22 第一次记录的不合理数值
QDateTime dtvalue;//zw修改 2023-08-22 第一次记录的不合理数值出现时间
int over_time;//zw修改 2023-08-22 该记录属性不合理数值出现次数
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class Mn_Timespan //zw修改 2023-08-29 时间间隔保存类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QList<long long> timespan;//时间戳队列
2025-01-16 16:17:01 +08:00
int msspan;
Mn_Timespan()
{
msspan = 0;
}
};
2025-05-09 16:53:07 +08:00
class Xmldata //zw修改 2023-08-30
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
XmlDataBase xmlbase;//xml数据库数据
XmlConfig xmlcfg;//新増的xml节点解析数据
list<CTopic*> topicList; //Kafka发送主题链表
2025-01-16 16:17:01 +08:00
bool updataflag = true;
};
//-------------------------------------------------------------------------------------*/
2025-05-09 16:53:07 +08:00
//主程序已定义该变量
2025-02-14 16:44:38 +08:00
2025-04-29 15:05:36 +08:00
extern int FILE_FLAG;
2025-05-09 16:53:07 +08:00
QMutex kafka_data_list_mutex; //Kafka发送数据锁
QList<Ckafka_data_t> kafka_data_list; //kafka发送数据链表
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
QMutex oss_data_list_mutex; //oss发送数据锁 zw新增
QList<oss_data_t> oss_data_list; //oss发送数据链表 zw新增
2025-04-29 15:05:36 +08:00
//-------------------------------------------------------------------------------------*/
2025-05-09 16:53:07 +08:00
QMap<QString,Mn_Timespan*> data_timespan_list;//zw修改 2023 - 8 - 29 计算时间间隔
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
QMap<QString, Xmldata*> xmlinfo_list;//zw修改 保存所有型号对应的xml数据-数据库数据 新增的节点解析数据 kafka发送链表
XmlConfig xmlcfg;//zw修改 2023 - 8 - 14 新増xml节点解析的数据
list<CTopic *> topicList; //Kafka发送主题链表
2025-04-30 10:22:57 +08:00
2025-05-09 16:53:07 +08:00
int inited = false; //JiangSu_Config.xml是否初始化标识
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
XmlConfig xmlcfg2;//lnk2024 - 8 - 13 新増角型xml节点解析的数据
list<CTopic*> topicList2; //lnk2024-8-14角型Kafka发送主题链表
QMap<QString, Xmldata*> xmlinfo_list2;//lnk2024-8-14 保存角型所有型号对应的xml数据-数据库数据 新增的节点解析数据 kafka发送链表
2025-04-30 10:22:57 +08:00
2025-05-09 16:53:07 +08:00
extern int isdelta_flag;//lnk2024-8-16 角型接线标志
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
///////////////////////////////////////////////lnk20241021替换web接口//////////////////////////////////
2025-04-29 15:05:36 +08:00
void connectlog_pgsql(char* id,char* datetime,int status);
2025-05-09 16:53:07 +08:00
///////////////////////////////////////////////lnk20241021替换web接口//////////////////////////////////
2025-01-16 16:17:01 +08:00
2025-05-20 16:31:12 +08:00
2025-07-10 18:05:18 +08:00
////////////////////////////////////////////////////////////////////////////////////////////lnk20250710添加频率值存储
struct mp_freq_save {
double G_FREQ;
double FREQ;
double MAX_FREQ;
double MIN_FREQ;
mp_freq_save()
: G_FREQ(0.0), FREQ(0.0), MAX_FREQ(0.0), MIN_FREQ(0.0) {}
};
std::map<std::string,mp_freq_save> mp_freq_save_map;
//lnk20250520 获取映射文件中的一些数据/////////////////////////////////////////////////////////////////
2025-05-20 16:31:12 +08:00
bool get_xml_config_by_dev_type(const char* dev_type, XmlConfigC* out_cfg) {
if (!dev_type || !out_cfg)
{
printf("null dev_type");
return false;
}
2026-01-27 16:58:15 +08:00
memset(out_cfg, 0, sizeof(*out_cfg));
2025-05-20 16:31:12 +08:00
QString dev_type_q = QString::fromUtf8(dev_type);
QMap<QString, Xmldata*>::iterator it = xmlinfo_list.find(dev_type_q);
if (it == xmlinfo_list.end() || it.value() == nullptr) {
printf("this dev_type not contain");
return false;
}
const XmlConfig& cfg = it.value()->xmlcfg;
// 将 QString 复制到结构体中的 char[],确保不越界
strncpy(out_cfg->WavePhasicFlag, cfg.WavePhasicFlag.toUtf8().constData(), sizeof(out_cfg->WavePhasicFlag) - 1);
strncpy(out_cfg->WavePhasicA, cfg.WavePhasicA.toUtf8().constData(), sizeof(out_cfg->WavePhasicA) - 1);
strncpy(out_cfg->WavePhasicB, cfg.WavePhasicB.toUtf8().constData(), sizeof(out_cfg->WavePhasicB) - 1);
strncpy(out_cfg->WavePhasicC, cfg.WavePhasicC.toUtf8().constData(), sizeof(out_cfg->WavePhasicC) - 1);
strncpy(out_cfg->UnitOfTimeUnit, cfg.UnitOfTimeUnit.toUtf8().constData(), sizeof(out_cfg->UnitOfTimeUnit) - 1);
2026-01-27 16:58:15 +08:00
strncpy(out_cfg->TypeOfData, cfg.TypeOfData.toUtf8().constData(), sizeof(out_cfg->TypeOfData) - 1); out_cfg->TypeOfData[sizeof(out_cfg->TypeOfData) - 1] = '\0';//lnk20260127
2025-05-20 16:31:12 +08:00
strncpy(out_cfg->ValueOfTimeUnit, cfg.ValueOfTimeUnit.toUtf8().constData(),sizeof(out_cfg->ValueOfTimeUnit) - 1);
strncpy(out_cfg->WaveTimeFlag, cfg.WaveTimeFlag.toUtf8().constData(), sizeof(out_cfg->WaveTimeFlag) - 1);
strncpy(out_cfg->IEDname, cfg.IEDname.toUtf8().constData(), sizeof(out_cfg->IEDname) - 1);
strncpy(out_cfg->LDevicePrefix, cfg.LDevicePrefix.toUtf8().constData(), sizeof(out_cfg->LDevicePrefix) - 1);
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//lnk2024-8-16 适配角型接线
bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list<CTopic*> *ctopiclist,QString path) //解析JiangSu_Config.xml配置文件
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
//注:①#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文档
2025-01-16 16:17:01 +08:00
if ("not define" == path) {
2025-05-09 16:53:07 +08:00
QString xml_dir = QString("../") + QString("etc/"); //Linux下调试路径
2025-01-16 16:17:01 +08:00
QFile file(xml_dir + JSON_CONFIG_FN);
2025-05-09 16:53:07 +08:00
if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml
2025-01-16 16:17:01 +08:00
{
return 0;
}
2025-05-09 16:53:07 +08:00
if (!doc.setContent(&file)) //将文件内容读到doc中
2025-01-16 16:17:01 +08:00
{
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);
2025-05-09 16:53:07 +08:00
if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml
2025-01-16 16:17:01 +08:00
{
return 0;
}
2025-05-09 16:53:07 +08:00
if (!doc.setContent(&file)) //将文件内容读到doc中
2025-01-16 16:17:01 +08:00
{
file.close();
return 0;
}
file.close();
cout << "define xml" << endl;
}
2025-05-09 16:53:07 +08:00
//将xml文件内容读到doc中
QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate"
QDomElement docElem = doc.documentElement(); //返回根节点元素
QDomNode n = docElem.firstChild(); //获得doc的第一个节点即"Topic"
while (!n.isNull()) //如果Topic节点不为空
2025-01-16 16:17:01 +08:00
{
if (n.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e = n.toElement(); //将其转换为元素
QString strTag = e.tagName(); //Topic节点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if ("Topic" == strTag)//zw修改 2023 - 8 - 14 增加判断 将topic节点和其他节点的解析分离
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
CTopic* topic = new CTopic(); //发送主题类指针
topic->strTopic = e.attribute("name"); //发送主题名
ctopiclist->push_back(topic); //添加 Kafka发送主题链表
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
if ("Topic" == strTag && ("HISDATA" == topic->strTopic || "RTDATA" == topic->strTopic)) //①读取TopicHISDATA、RTDATA主题---------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-01-16 16:17:01 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
CDataType* dt = new CDataType(); //数据类型指针
dt->iDataType = node.toElement().attribute("value").toInt(); //数据类型值(1-实时/历史稳态、2-实时/历史闪变、3-实时/历史暂态、4-补招稳态、5-补招闪变、6-补招暂态)
dt->type = node.toElement().attribute("type"); //参数等级
2025-01-16 16:17:01 +08:00
dt->BaseFlag0 = 0;
dt->BaseFlag1 = 0;
2025-05-09 16:53:07 +08:00
topic->DataTypeList.push_back(dt); //添加 数据类型链表
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QString strTag2 = node.toElement().tagName(); //DataType节点
if ("DataType" == strTag2) //②读取数据类型DataType
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表
for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表
2025-01-16 16:17:01 +08:00
{
QDomNode node2 = list2.at(i2); //node2 <Monitor>
if (node2.isElement())
{
2025-05-09 16:53:07 +08:00
CMonitor* mt = new CMonitor(); //监测点类型指针
mt->strMonitor = node2.toElement().attribute("name"); //监测点名称 注该值需要从Rpt解析中获取监测点号
mt->type = node2.toElement().attribute("type"); //参数等级
dt->MonitorList.push_back(mt); //添加 监测点链表
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QString strTag3 = node2.toElement().tagName(); //Monitor节点
if ("Monitor" == strTag3) //③读取监测点Monitor
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list3 = node2.childNodes(); //获得元素Monitor的所有子节点的列表
for (int i3 = 0; i3 < list3.count(); i3++) //遍历 Item列表
2025-01-16 16:17:01 +08:00
{
QDomNode node3 = list3.at(i3); //node3 <Item>
if (node3.isElement())
{
2025-05-09 16:53:07 +08:00
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
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list4 = node3.childNodes(); //获得元素Item的所有子节点的列表
for (int i4 = 0; i4 < list4.count(); i4++) //遍历 Sequence列表
2025-01-16 16:17:01 +08:00
{
QDomNode node4 = list4.at(i4); //node4 <Sequence>
if (node4.isElement())
{
2025-05-09 16:53:07 +08:00
QString strPhase = node4.toElement().attribute("value"); //相别
2025-07-29 18:10:03 +08:00
if ((!xml_flag || ("V" != it->strItemName && "F_S" != it->strItemName && "F_L" != it->strItemName)) && "7" == strPhase) //⑤-①读取ABC三相数据 //lnk2024-8-14 角型判断
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
for (int n = 0; n < 3; n++) //遍历 相别(ABC三相)
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
CSequence* sq = new CSequence(); //ABC三相相别类指针
sq->strSValue = node4.toElement().attribute("value"); //相别值(7ABC三相、8T相)
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
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list5 = node4.childNodes(); //获得元素Sequence的所有子节点的列表
for (int i5 = 0; i5 < list5.count(); i5++) //遍历 ABC三相Value列表
2025-01-16 16:17:01 +08:00
{
QDomNode node5 = list5.at(i5); //node5 <Value>
if (node5.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e_Value = node5.toElement(); //将其转换为元素
QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点
if ("Value" == strTag6) //⑥读取ABC三相Value
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QString strDVName = e_Value.attribute("name"); //数据名
QString strDAName = e_Value.attribute("DA"); //数据属性名
2025-02-21 16:24:41 +08:00
2025-05-09 16:53:07 +08:00
if (strDAName.indexOf("l_phs*") >= 0){ //DA包含"l_phs*"//lnk20250221星形接线也可以接受PPV
2025-02-21 16:24:41 +08:00
strDAName = strDAName.replace("l_phs", "phs");
strDAName = strDAName.replace("*", strLine[n]);
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
} //将DA相别*替换为具体相别(AB、BC、CA) 例phsAB$cVal$mag$f
2025-02-21 16:24:41 +08:00
2025-05-09 16:53:07 +08:00
else if (strDAName.indexOf("phs*") >= 0) {//DA包含"phs*"
strDAName = strDAName.replace("*", sq->strSeq);} //将DA相别*替换为具体相别(A、B、C) 例phsA$cVal$mag$f
2025-02-21 16:24:41 +08:00
2025-05-09 16:53:07 +08:00
//⑥-①谐波数据读取(ABC三相)-------------------------------------
if (strDVName.indexOf("%") >= 0 && strDAName.indexOf("%-") >= 0) //数据名包含% 且 DA包含%- 例V_%0,49%_MAX
2025-01-16 16:17:01 +08:00
{
QStringList strHarm1 = strDVName.split('%');
2025-05-09 16:53:07 +08:00
if (strHarm1.count() >= 2) //例V_ | 0,49 | _MAX
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
strValueTemp = "%" + strHarm1.at(1) + "%"; //例:%0,49%
QStringList strHarm2 = strHarm1.at(1).split(','); //例0,49
2025-01-16 16:17:01 +08:00
if (strHarm2.count() >= 2)
{
2025-05-09 16:53:07 +08:00
nStart = (strHarm2.at(0)).toInt(); //谐波起始次数 例0
nEnd = (strHarm2.at(1)).toInt(); //谐波结束次数 例49
2025-01-16 16:17:01 +08:00
}
}
QString substring = strDAName.mid(strDAName.indexOf("[") + 1, strDAName.indexOf("]") - strDAName.indexOf("[") - 1);
QStringList strDAList1 = substring.split('-');
int strDAoffset = (strDAList1.at(1)).toInt();
2025-05-09 16:53:07 +08:00
for (int i = nStart; i <= nEnd; i++) //遍历 ABC三相谐波次数
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QString strDVNameTemp = strDVName; //临时 数据名
QString strDANameTemp = strDAName; //临时 数据属性名
CDataValue* dv1 = new CDataValue(); //ABC三相谐波数据值类指针
dv1->type = e_Value.attribute("type"); //参数等级
2025-01-16 16:17:01 +08:00
if (e_Value.attributes().contains("Coefficient")) {
2025-05-09 16:53:07 +08:00
dv1->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型)
dv1->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型)
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
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
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
2025-01-16 16:17:01 +08:00
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";
}
2025-05-09 16:53:07 +08:00
if (!dv1->DO.isEmpty() && !dv1->DA.isEmpty()) //数据对象名和数据属性名均不为空
2025-01-16 16:17:01 +08:00
dv1->strFullName = dv1->DO + "$" + dv1->DA;
else
dv1->strFullName = "not define";
2025-05-09 16:53:07 +08:00
sq->DataValueList.push_back(dv1); //添加 数据链表(ABC三相)
} //遍历ABC三相谐波次数 结束
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
else //⑥-②非谐波数据读取(ABC三相)-------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
CDataValue* dv2 = new CDataValue(); //ABC三相非谐波数据值类指针
dv2->strName = e_Value.attribute("name"); //数据名
dv2->type = e_Value.attribute("type"); //参数等级
2025-01-16 16:17:01 +08:00
if (e_Value.attributes().contains("Coefficient")) {
2025-05-09 16:53:07 +08:00
dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型)
dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型)
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
dv2->DO = e_Value.attribute("DO"); //数据对象名
dv2->DA = strDAName; //数据属性名
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
2025-01-16 16:17:01 +08:00
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";
}
2025-05-09 16:53:07 +08:00
if (!e_Value.attribute("PltFlag").isEmpty() && e_Value.attribute("PltFlag") == "True") //长时闪变标识
dv2->bPlt = true; //长时闪变标识
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
dv2->bPlt = false; //短时闪变 或 其他数据
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空
2025-01-16 16:17:01 +08:00
dv2->strFullName = dv2->DO + "$" + dv2->DA;
else
dv2->strFullName = "not define";
2025-05-09 16:53:07 +08:00
sq->DataValueList.push_back(dv2); //添加 数据链表(ABC三相)
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
} //读取ABC三相Value 结束
} //判断node5为元素 结束
} //遍历ABC三相Value列表 结束
} //遍历 ABC三相 结束
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
} //⑤-①读取ABC三相数据 结束
2025-01-16 16:17:01 +08:00
2025-07-29 18:10:03 +08:00
if (xml_flag && ("V" == it->strItemName || "F_S" == it->strItemName || "F_L" == it->strItemName) && "112" == strPhase) //lnk2024-8-13角型//lnk20250729闪变也要加上角形
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
for (int n = 0; n < 3; n++) //遍历 相别(AB、BC、CA三相)
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
CSequence* sq = new CSequence(); //AB、BC、CA三相别类指针
sq->strSValue = node4.toElement().attribute("value"); //相别值(7ABC三相、112:线AB,BC,CA 8T相)
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
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list5 = node4.childNodes(); //获得元素Sequence的所有子节点的列表
for (int i5 = 0; i5 < list5.count(); i5++) //遍历 AB、BC、CA三相Value列表
2025-02-14 16:44:38 +08:00
{
QDomNode node5 = list5.at(i5); //node5 <Value>
if (node5.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e_Value = node5.toElement(); //将其转换为元素
QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点
if ("Value" == strTag6) //⑥读取AB、BC、CA三相Value
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
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
2025-02-14 16:44:38 +08:00
{
QStringList strHarm1 = strDVName.split('%');
2025-05-09 16:53:07 +08:00
if (strHarm1.count() >= 2) //例:%0,49%
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
strValueTemp = "%" + strHarm1.at(1) + "%"; //例:%0,49%
QStringList strHarm2 = strHarm1.at(1).split(','); //例0,49
2025-02-14 16:44:38 +08:00
if (strHarm2.count() >= 2)
{
2025-05-09 16:53:07 +08:00
nStart = (strHarm2.at(0)).toInt(); //谐波起始次数 例0
nEnd = (strHarm2.at(1)).toInt(); //谐波结束次数 例49
2025-02-14 16:44:38 +08:00
}
}
QString substring = strDAName.mid(strDAName.indexOf("[") + 1, strDAName.indexOf("]") - strDAName.indexOf("[") - 1);
QStringList strDAList1 = substring.split('-');
int strDAoffset = (strDAList1.at(1)).toInt();
2025-05-09 16:53:07 +08:00
for (int i = nStart; i <= nEnd; i++) //遍历 AB、BC、CA三相谐波次数
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
QString strDVNameTemp = strDVName; //临时 数据名
QString strDANameTemp = strDAName;//临时 数据属性名
CDataValue* dv1 = new CDataValue(); //AB、BC、CA三相谐波数据值类指针
dv1->type = e_Value.attribute("type"); //参数等级
2025-02-14 16:44:38 +08:00
if (e_Value.attributes().contains("Coefficient")) {
2025-05-09 16:53:07 +08:00
dv1->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型)
dv1->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型)
2025-02-14 16:44:38 +08:00
}
2025-05-09 16:53:07 +08:00
dv1->strOffset = e_Value.attribute("Offset"); //起始序号偏移量(字符型)
dv1->iOffset = e_Value.attribute("Offset").toInt(); //起始序号偏移量(整型) = 江苏电科院臻迪数据项起始序号 - 装置数据项实际起始序号
dv1->DO = e_Value.attribute("DO"); //数据对象名
2025-02-14 16:44:38 +08:00
2025-08-25 16:39:43 +08:00
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
if(DEBUGOPEN)std::cout << dv1->DO.toUtf8().constData() << std::endl; //lnk 输出ppv
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2025-02-14 16:44:38 +08:00
2025-05-09 16:53:07 +08:00
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
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
2025-02-14 16:44:38 +08:00
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";
}
2025-05-09 16:53:07 +08:00
if (!dv1->DO.isEmpty() && !dv1->DA.isEmpty()) //数据对象名和数据属性名均不为空
2025-02-14 16:44:38 +08:00
dv1->strFullName = dv1->DO + "$" + dv1->DA;
else
dv1->strFullName = "not define";
2025-05-09 16:53:07 +08:00
sq->DataValueList.push_back(dv1); //添加 数据链表(AB、BC、CA三相)
} //遍历ABC三相谐波次数 结束
2025-04-29 15:05:36 +08:00
2025-02-14 16:44:38 +08:00
}
2025-05-09 16:53:07 +08:00
else //⑥-②非谐波数据读取(AB、BC、CA三相)-------------------------------
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
CDataValue* dv2 = new CDataValue(); //ABC三相非谐波数据值类指针
dv2->strName = e_Value.attribute("name"); //数据名
dv2->type = e_Value.attribute("type"); //参数等级
2025-02-14 16:44:38 +08:00
if (e_Value.attributes().contains("Coefficient")) {
2025-05-09 16:53:07 +08:00
dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型)
dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型)
2025-02-14 16:44:38 +08:00
}
2025-05-09 16:53:07 +08:00
dv2->DO = e_Value.attribute("DO"); //数据对象名
dv2->DA = strDAName; //数据属性名
2025-02-14 16:44:38 +08:00
2025-08-25 16:39:43 +08:00
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
if(DEBUGOPEN)std::cout << dv2->DO.toUtf8().constData() << std::endl; //lnk 输出ppv
//std::cout << "!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!!!!!ppv!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
2025-03-18 11:25:20 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
2025-02-14 16:44:38 +08:00
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";
}
2025-05-09 16:53:07 +08:00
if (!e_Value.attribute("PltFlag").isEmpty() && e_Value.attribute("PltFlag") == "True") //长时闪变标识
dv2->bPlt = true; //长时闪变标识
2025-02-14 16:44:38 +08:00
else
2025-05-09 16:53:07 +08:00
dv2->bPlt = false;//短时闪变 或 其他数据
2025-02-14 16:44:38 +08:00
2025-05-09 16:53:07 +08:00
if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空
2025-02-14 16:44:38 +08:00
dv2->strFullName = dv2->DO + "$" + dv2->DA;
else
dv2->strFullName = "not define";
2025-05-09 16:53:07 +08:00
sq->DataValueList.push_back(dv2); //添加 数据链表(AB、BC、CA三相)
2025-02-14 16:44:38 +08:00
}
2025-05-09 16:53:07 +08:00
} //读取AB、BC、CA三相Value 结束
}//判断node5为元素 结束
} //遍历AB、BC、CA三相Value列表 结束
} //遍历 AB、BC、CA三相 结束
2025-02-14 16:44:38 +08:00
}
2025-05-09 16:53:07 +08:00
}//⑤-①读取AB、BC、CA三相数据 结束
2025-02-14 16:44:38 +08:00
2025-05-09 16:53:07 +08:00
if ("8" == strPhase) //⑤-②读取T相数据
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
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列表
2025-01-16 16:17:01 +08:00
{
QDomNode node5 = list5.at(i5); //node5 <Value>
if (node5.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e_Value = node5.toElement(); //将其转换为元素
QString strTag6 = e_Value.tagName(); //相别Sequence下 所有DataValue子节点
if ("Value" == strTag6) //⑥读取T相Value
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
//⑥-①谐波数据读取(T相) 注T相没有谐波数据
//⑥-②非谐波数据读取(T相)
CDataValue* dv2 = new CDataValue(); //T相非谐波数据值类指针
dv2->strName = e_Value.attribute("name"); //数据名
dv2->type = e_Value.attribute("type"); //参数等级
2025-01-16 16:17:01 +08:00
if (e_Value.attributes().contains("Coefficient")) {
2025-05-09 16:53:07 +08:00
dv2->strCoefficient = e_Value.attribute("Coefficient"); //数据系数(字符型)
dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //数据系数(浮点型)
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
dv2->DO = e_Value.attribute("DO"); //数据对象名
dv2->DA = e_Value.attribute("DA"); //数据属性名
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 2023 - 8 - 14 为历史数据部分 Value节点新增指标-BaseFlag LimitUp LimitDown
2025-01-16 16:17:01 +08:00
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";
}
2025-05-09 16:53:07 +08:00
if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //数据对象名和数据属性名均不为空
2025-01-16 16:17:01 +08:00
dv2->strFullName = dv2->DO + "$" + dv2->DA;
else
dv2->strFullName = "not define";
2025-05-09 16:53:07 +08:00
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事件-------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-01-16 16:17:01 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
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); //添加 数据类型链表
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QString strTag2 = node.toElement().tagName(); //DataType节点
if ("DataType" == strTag2) //②读取数据类型DataType
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表
for (int i2 = 0; i2 < list2.count(); i2++) //遍历 SOE列表
2025-01-16 16:17:01 +08:00
{
QDomNode node2 = list2.at(i2); //node2 <SOE>
if (node2.isElement())
{
2025-05-09 16:53:07 +08:00
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()) //数据对象名和数据属性名均不为空
2025-01-16 16:17:01 +08:00
ed->strFullName = ed->DO + "$" + ed->DA;
else
ed->strFullName = "not define";
2025-05-09 16:53:07 +08:00
dt->SOEList.push_back(ed); //添加 SOE事件链表
} //判断node2为元素 结束
} //遍历SOE列表 结束
} //读取数据类型DataType节点 结束
} //判断node为元素 结束
} //遍历DataType列表 结束
} //Topic节点RTDATASOE 结束
2025-01-16 16:17:01 +08:00
else if ("Topic" == strTag && "SOEDATA" == topic->strTopic)
{
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素Topic的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-01-16 16:17:01 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
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()) //数据对象名和数据属性名均不为空
2025-01-16 16:17:01 +08:00
ed->strFullName = ed->DO + "$" + ed->DA;
else
ed->strFullName = "not define";
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
cfg->SOEList.push_back(ed);
}
}
}
}
2025-05-09 16:53:07 +08:00
if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if ("Topic" != strTag && "ReportMap" != strTag)//zw修改 2023 - 8 - 14 增加判断 新增部分节点解析
2025-01-16 16:17:01 +08:00
{
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"));
}
2026-01-27 16:58:15 +08:00
//lnk 20260127
if ("TypeOfData" == strTag)
{
cfg->TypeOfData.append(e.attribute("Unit"));
}
2025-01-16 16:17:01 +08:00
if ("ValueOfTime" == strTag)
{
cfg->ValueOfTimeUnit.append(e.attribute("Unit"));
}
if ("ComtradeFile" == strTag)
{
cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag"));
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
if ("IED" == strTag)
{
cfg->IEDname.append(e.attribute("name"));
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
if ("LDevice" == strTag)
{
cfg->LDevicePrefix.append(e.attribute("Prefix"));
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
}
2025-05-09 16:53:07 +08:00
} //判断n为元素 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
n = n.nextSibling();//获取下一个兄弟节点(HISDATA —> RTDATA —> RTDATASOE)
} //while (!n.isNull) 结束
2025-01-16 16:17:01 +08:00
return true;
}
/// <summary>
2025-05-09 16:53:07 +08:00
/// czy 2023-11-23 测试json的装置间隔频,打印前台
2025-01-16 16:17:01 +08:00
/// </summary>
2025-05-09 16:53:07 +08:00
/// <param name="flag">1是,2是,3是填入计算的interval</param>
/// <param name="interval">1是,2是,3是填入计算的interval</param>
2025-01-16 16:17:01 +08:00
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;
}
}
2025-02-14 16:44:38 +08:00
/// <summary>
2025-05-09 16:53:07 +08:00
/// czy kafka的json中将线电压转成相电压
2025-02-14 16:44:38 +08:00
/// </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;
}
}
2025-07-29 18:10:03 +08:00
//调试用
void printCTopicList(const std::list<CTopic*>& ctopic_list) {
int topicIndex = 0;
for (const auto& topic : ctopic_list) {
printf("==== Topic[%d] ====\n", topicIndex++);
printf("Topic name: %s\n", topic->strTopic.toStdString().c_str());
int dtypeIndex = 0;
for (const auto& dtype : topic->DataTypeList) {
printf(" -- DataType[%d] --\n", dtypeIndex++);
printf(" iDataType: %d, type: %s, BaseFlag1: %d, BaseFlag0: %d\n",
dtype->iDataType,
dtype->type.toStdString().c_str(),
dtype->BaseFlag1,
dtype->BaseFlag0);
int monitorIndex = 0;
for (const auto& monitor : dtype->MonitorList) {
printf(" >> Monitor[%d] name: %s, type: %s\n",
monitorIndex++,
monitor->strMonitor.toStdString().c_str(),
monitor->type.toStdString().c_str());
int itemIndex = 0;
for (const auto& item : monitor->ItemList) {
printf(" >> Item[%d] name: %s, value: %s, type: %s\n",
itemIndex++,
item->strItemName.toStdString().c_str(),
item->strItemValue.toStdString().c_str(),
item->type.toStdString().c_str());
int seqIndex = 0;
for (const auto& seq : item->SequenceList) {
printf(" >> Sequence[%d] strSeq: %s, strSValue: %s, type: %s\n",
seqIndex++,
seq->strSeq.toStdString().c_str(),
seq->strSValue.toStdString().c_str(),
seq->type.toStdString().c_str());
int valIndex = 0;
for (const auto& val : seq->DataValueList) {
printf(" >> DataValue[%d] name: %s, value: %f\n",
valIndex++,
val->strName.toStdString().c_str(),
val->fValue);
}
}
}
}
// 如果需要打印 SOEList可加以下
/*
int soeIndex = 0;
for (const auto& soe : dtype->SOEList) {
printf(" >> SOE[%d] ... \n", soeIndex++);
// 打印 SOE 具体字段(如有定义)
}
*/
}
}
}
2025-05-09 16:53:07 +08:00
//20250214添加角型接线处理
int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json生成函数 zw修改 2023-8-11 调整传送json结构 目前仅限历史稳态数据
2025-01-16 16:17:01 +08:00
{
list<CTopic*> ctopic_list;
2025-02-14 16:44:38 +08:00
2025-05-09 16:53:07 +08:00
////lnk2024-8-15 区分星型,角型接线
if (strcmp(v_wiring_type, "0") == 0) //lnk2024-8-15 星型接线
2025-02-14 16:44:38 +08:00
{
2025-02-17 16:58:14 +08:00
cout << "1 report v_wiring_type is" << v_wiring_type << endl;
2025-02-14 16:44:38 +08:00
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 {
2025-02-17 16:58:14 +08:00
cout << "transfer_json_block_data not contain data->dev_type:" << data->dev_type.toStdString() << " !!!!"<< endl;
2025-02-14 16:44:38 +08:00
ctopic_list = topicList;
}
}
2025-05-09 16:53:07 +08:00
else //lnk2024-8-15 角型接线
2025-02-14 16:44:38 +08:00
{
2025-02-17 16:58:14 +08:00
cout << "2 report v_wiring_type is" << v_wiring_type << endl;
2025-02-14 16:44:38 +08:00
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;
2025-07-29 18:10:03 +08:00
2025-07-30 16:30:10 +08:00
if(DEBUGOPEN)printCTopicList(ctopic_list);
2025-02-14 16:44:38 +08:00
}
else {
2025-02-17 16:58:14 +08:00
cout << "transfer_json_block_data not contain data->dev_type:" << data->dev_type.toStdString() << " !!!!"<< endl;
2025-03-18 11:25:20 +08:00
ctopic_list = topicList2;
2025-07-29 18:10:03 +08:00
2025-02-14 16:44:38 +08:00
}
}
2026-01-27 16:58:15 +08:00
//lnk20260127 添加数据类型区分
bool typeofdata = false;
QString devType = data->dev_type;
QByteArray devTypeBytes = devType.toUtf8();
const char* dev_type_cstr = devTypeBytes.constData();
qDebug() << "[DBG] devType (QString) =" << devType;
qDebug() << "[DBG] devType length =" << devType.length();
qDebug() << "[DBG] devTypeBytes =" << devTypeBytes;
qDebug() << "[DBG] devTypeBytes size =" << devTypeBytes.size();
printf("[DBG] dev_type_cstr = '%s'\n", dev_type_cstr);
XmlConfigC cfg1;
if (get_xml_config_by_dev_type(dev_type_cstr, &cfg1)) {
printf("========== XmlConfigC dump ==========\n");
printf("WavePhasicFlag = '%s'\n", cfg1.WavePhasicFlag);
printf("WavePhasicA = '%s'\n", cfg1.WavePhasicA);
printf("WavePhasicB = '%s'\n", cfg1.WavePhasicB);
printf("WavePhasicC = '%s'\n", cfg1.WavePhasicC);
printf("UnitOfTimeUnit = '%s'\n", cfg1.UnitOfTimeUnit);
printf("TypeOfData = '%s'\n", cfg1.TypeOfData);
printf("ValueOfTimeUnit = '%s'\n", cfg1.ValueOfTimeUnit);
printf("WaveTimeFlag = '%s'\n", cfg1.WaveTimeFlag);
printf("IEDname = '%s'\n", cfg1.IEDname);
printf("LDevicePrefix = '%s'\n", cfg1.LDevicePrefix);
printf("=====================================\n");
// 如果 TypeOfData == "1",则置 true
if (strcmp(cfg1.TypeOfData, "1") == 0) {
typeofdata = true;
}
} else {
printf("not find this dev_type\n");
}
2025-01-16 16:17:01 +08:00
bool shortjumpflag = false;
bool longjumpflag = false;
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 end
if (!inited) //初始化 JiangSu_Config.xml
2025-01-16 16:17:01 +08:00
{
inited = true;
}
2025-05-09 16:53:07 +08:00
if (NULL == data) //json拼接参数类指针为空
2025-01-16 16:17:01 +08:00
return 0;
2025-05-09 16:53:07 +08:00
if (100 == data->func_type) //一、稳态/统计数据 ——> MMS_Client
2025-01-16 16:17:01 +08:00
{
list<CTopic*>::iterator tp = ctopic_list.begin();
2025-05-09 16:53:07 +08:00
while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表
2025-01-16 16:17:01 +08:00
{
CTopic* pTopic = *tp++;
2025-05-09 16:53:07 +08:00
if ("HISDATA" == pTopic->strTopic) //Topic等于HISDATA
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
list<CDataType*>::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList
2025-01-16 16:17:01 +08:00
while (dt != pTopic->DataTypeList.end())
{
2025-05-09 16:53:07 +08:00
bool isJump = false; //是否跳出(整个数据类型)循环
2025-01-16 16:17:01 +08:00
CDataType* pDataType = *dt++;
2025-05-09 16:53:07 +08:00
if (2 == pDataType->iDataType) //②-②历史短闪变数据------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "PST"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
int countflag = 0, num = 0;
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
2025-05-09 16:53:07 +08:00
//////////////////////////////////////////////////////////lnk20250306为了数据入库构造数据添加FLAG
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-03-06 15:24:49 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
2025-03-06 15:24:49 +08:00
continue;
}
//////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻毫秒
time_sec = data->time / 1000; //时间戳(秒)
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
num = num + pSequence->DataValueList.size();
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
{
countflag++;
continue;
}
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = false; //跳出本层循环
2025-01-16 16:17:01 +08:00
countflag++;
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
continue;
}
try
{
2025-05-09 16:53:07 +08:00
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数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "历史闪变数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}}"); //拼接 json数据项结尾
} //ItemList 结束
if (isJump) break; //跳出循环
} //MonitorList 结束
if (isJump) continue; //跳出本数据类型循环
KafkaData.strText.append("}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
cout << countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"02\" " << num << endl;
cout << KafkaData.strText.toAscii().data() << endl;
if (countflag < num) {
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
shortjumpflag = true;
}
2025-05-09 16:53:07 +08:00
} //②-②历史闪变数据解析结束!--------------------------------
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//20241204长闪变类型应该为3
if (3 == pDataType->iDataType) //②-②历史长闪变数据------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "PLT"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
int countflag = 0,num = 0;
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
2025-05-09 16:53:07 +08:00
//////////////////////////////////////////////////////////lnk20250306为了数据入库构造数据添加FLAG
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-03-06 15:24:49 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
2025-03-06 15:24:49 +08:00
continue;
}
//////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻毫秒
time_sec = data->time / 1000; //时间戳(秒)
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-05-09 16:53:07 +08:00
//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相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
num = num + pSequence->DataValueList.size();
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
{
countflag++;
continue;
}
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = false; //跳出本层循环
2025-01-16 16:17:01 +08:00
countflag++;
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
continue;
}
try
{
2025-05-09 16:53:07 +08:00
if (0 == time_sec % 7200) //2小时间隔长时闪变
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
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数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "历史闪变数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}}"); //拼接 json数据项结尾
} //ItemList 结束
if (isJump) break; //跳出循环
} //MonitorList 结束
if (isJump) continue; //跳出本数据类型循环
KafkaData.strText.append("}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-07-29 18:10:03 +08:00
cout<< countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"03\" " << num << endl;
2025-01-16 16:17:01 +08:00
cout << KafkaData.strText.toAscii().data() << endl;
if (countflag < num && 0 == time_sec % 7200) {
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
longjumpflag = true;
}
2026-01-27 16:58:15 +08:00
//lnk20260127
if (typeofdata == false) {//不合并则处理完闪变就不处理其他数据
if (longjumpflag == true || shortjumpflag == true) {
return 1;
}
}
2025-05-09 16:53:07 +08:00
} //②-②历史闪变数据解析结束!--------------------------------
2025-01-16 16:17:01 +08:00
2026-01-27 16:58:15 +08:00
//合并则继续处理其他数据
2025-05-09 16:53:07 +08:00
if (1 == pDataType->iDataType) //②-①历史稳态数据-----------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "HISDATA"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
2025-05-09 16:53:07 +08:00
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"TIME"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":%1, ").arg(data->time)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
if (!data_timespan_list.contains(data->mp_id)) {
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
}
else if (data_timespan_list[data->mp_id]->msspan == 0)
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
}
else {
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"interval\":%1, ").arg(data_timespan_list[data->mp_id]->msspan)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
}
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 V、I、PQ
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = false; //跳出本层循环
//zw修改 2023-8-28 不匹配数据添加
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
continue;
}
try
{
2025-05-09 16:53:07 +08:00
if (pDataValue->strFullName.indexOf("$ang$f") != -1) //查找61850属性名中含有相角的定义
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
double dAngleTemp = data->mms_str_map.value(pDataValue->strFullName); //角度值(-180度 ~ 180度)
2025-01-16 16:17:01 +08:00
dAngleTemp = dAngleTemp > 180.0f ? dAngleTemp - 360.0f : dAngleTemp;
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值)
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
else
{
2025-05-09 16:53:07 +08:00
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数据值(非角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值)
2025-07-10 18:05:18 +08:00
//lnk20250710添加频率存储
if(dTemp > 0.99){
//printf("pDataValue->strName==========================%s",pDataValue->strName.toStdString().c_str());
if(pDataValue->strName == "G_FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].G_FREQ = dTemp; //保存95值
}
else if(pDataValue->strName == "FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].FREQ = dTemp; //保存平均值
}
else if(pDataValue->strName == "MAX_FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].MAX_FREQ = dTemp; //保存最大值
}
else if(pDataValue->strName == "MIN_FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].MIN_FREQ = dTemp; //保存最小值
}
}
else{
if(pDataValue->strName == "G_FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].G_FREQ; //保存95值
}
else if(pDataValue->strName == "FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].FREQ; //保存平均值
}
else if(pDataValue->strName == "MAX_FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].MAX_FREQ; //保存最大值
}
else if(pDataValue->strName == "MIN_FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].MIN_FREQ; //保存最小值
}
}
//lnk20250710添加频率存储
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "历史稳态数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}}"); //拼接 json数据项结尾
} //ItemList 结束
if (isJump) break; //跳出循环
} //MonitorList 结束
if (isJump) continue; //跳出本数据类型循环
KafkaData.strText.append("}"); //拼接 json稳态数据结尾
2025-07-29 18:10:03 +08:00
//调试用
2025-07-30 16:30:10 +08:00
if(DEBUGOPEN)cout << KafkaData.strText.toAscii().data() << endl;
2025-07-29 18:10:03 +08:00
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
return 1; //结束该函数,停止后续代码执行
} //②-①历史稳态数据解析结束!--------------------------------
} //DataTypeList 结束
} //遍历 HISDATA 结束!
} //TopicList 结束
} //一、结束
if (200 == data->func_type) //二、3秒数据/实时数据 ——> MMS_Assist
2025-01-16 16:17:01 +08:00
{
list<CTopic*>::iterator tp = ctopic_list.begin();
2025-05-09 16:53:07 +08:00
while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表
2025-01-16 16:17:01 +08:00
{
CTopic* pTopic = *tp++;
2025-05-09 16:53:07 +08:00
if ("RTDATA" == pTopic->strTopic) //Topic等于RTDATA------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
list<CDataType*>::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList
2025-01-16 16:17:01 +08:00
while (dt != pTopic->DataTypeList.end())
{
2025-05-09 16:53:07 +08:00
bool isJump = false; //是否跳出(整个数据类型)循环
2025-01-16 16:17:01 +08:00
CDataType* pDataType = *dt++;
2025-05-09 16:53:07 +08:00
if (1 == pDataType->iDataType) //②-①实时3s数据--------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATA"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
2025-05-09 16:53:07 +08:00
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"FLAG\":\"%1\", ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"TIME"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 V、I、PQ
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName) && pDataValueBegin->strName == pDataValue->strName)//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = true; //跳出本层循环
2025-01-16 16:17:01 +08:00
break;
}
try
{
2025-05-09 16:53:07 +08:00
if (pDataValue->strFullName.indexOf("$ang$f") != -1) //查找61850属性名中含有相角的定义
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
double dAngleTemp = data->mms_str_map.value(pDataValue->strFullName); //角度值(-180度 ~ 180度)
2025-01-16 16:17:01 +08:00
dAngleTemp = dAngleTemp > 180.0f ? dAngleTemp - 360.0f : dAngleTemp;
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
}
else
{
2025-05-09 16:53:07 +08:00
double dTemp = data->mms_str_map.value(pDataValue->strFullName) * pDataValue->fCoefficient; //接口数据 * 系数
2025-07-10 18:05:18 +08:00
//lnk20250710添加频率存储
if(dTemp > 0.99){
//printf("pDataValue->strName==========================%s",pDataValue->strName.toStdString().c_str());
if(pDataValue->strName == "G_FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].G_FREQ = dTemp; //保存95值
}
else if(pDataValue->strName == "FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].FREQ = dTemp; //保存平均值
}
else if(pDataValue->strName == "MAX_FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].MAX_FREQ = dTemp; //保存最大值
}
else if(pDataValue->strName == "MIN_FREQ") {
mp_freq_save_map[data->mp_id.toStdString()].MIN_FREQ = dTemp; //保存最小值
}
}
else{
if(pDataValue->strName == "G_FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].G_FREQ; //保存95值
}
else if(pDataValue->strName == "FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].FREQ; //保存平均值
}
else if(pDataValue->strName == "MAX_FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].MAX_FREQ; //保存最大值
}
else if(pDataValue->strName == "MIN_FREQ") {
dTemp = mp_freq_save_map[data->mp_id.toStdString()].MIN_FREQ; //保存最小值
}
}
//lnk20250710添加频率存储
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值)
2025-07-10 18:05:18 +08:00
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "实时3s数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
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(); //解锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 1; //结束该函数,停止后续代码执行
} //②-①实时3s数据解析结束----------------------------------
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (2 == pDataType->iDataType) //②-②实时闪变数据-----------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATA"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
//////////////////////////////////////////////////////////lnk20250306为了数据入库构造数据添加FLAG
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
{
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
continue;
}
//////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻毫秒
time_sec = data->time / 1000; //时间戳(秒)
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //拼接 json相别 A、B、C、T相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName) && pDataValueBegin->strName == pDataValue->strName)//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = true; //跳出本层循环
2025-01-16 16:17:01 +08:00
break;
}
try
{
2025-05-09 16:53:07 +08:00
if (!pDataValue->bPlt) //短时闪变
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
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数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
else //长时闪变
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
if (0 == time_sec % 7200) //2小时间隔长时闪变
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
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数据值(非角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值)
2025-01-16 16:17:01 +08:00
}
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "实时闪变数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}}"); //拼接 json数据项结尾
} //ItemList 结束
if (isJump) break; //跳出循环
} //MonitorList 结束
if (isJump) continue; //跳出本数据类型循环
KafkaData.strText.append("}"); //拼接 json稳态数据结尾
2025-07-30 16:30:10 +08:00
//调试用
if(DEBUGOPEN)cout << KafkaData.strText.toAscii().data() << endl;
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-07-30 16:30:10 +08:00
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 1; //结束该函数,停止后续代码执行
} //②-②实时闪变数据解析结束!--------------------------------
} //DataTypeList 结束
} //遍历 RTDATA 结束!
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if ("RTDATASOE" == pTopic->strTopic) //Topic等于RTDATASOE----------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
list<CDataType*>::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList
2025-01-16 16:17:01 +08:00
while (dt != pTopic->DataTypeList.end())
{
2025-05-09 16:53:07 +08:00
int triggerCount = 0; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
CDataType* pDataType = *dt++;
2025-05-09 16:53:07 +08:00
if (1 == pDataType->iDataType) //②-①SOE稳态事件------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATASOE"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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监测点号
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
list<CEventData*>::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素
2025-01-16 16:17:01 +08:00
while (ed != pDataType->SOEList.end())
{
CEventData* pEventData = *ed++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
continue;
try
{
double dTemp = data->mms_str_map.value(pEventData->strFullName);
2025-05-09 16:53:07 +08:00
if (dTemp >= 0.9) //SOE事件发生
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
if (0 == triggerCount) //SOE触发标识计数
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
triggerCount++; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
}
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "SOE稳态事件拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //SOEList 结束
KafkaData.strText.append("]}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 1; //结束该函数,停止后续代码执行
} //②-①SOE稳态事件解析结束---------------------------------
2025-01-16 16:17:01 +08:00
2025-07-30 16:30:10 +08:00
if (2 == pDataType->iDataType) //②-②SOE暂态事件------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATASOE"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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监测点号
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
list<CEventData*>::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素
2025-01-16 16:17:01 +08:00
while (ed != pDataType->SOEList.end())
{
CEventData* pEventData = *ed++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
continue;
try
{
double dTemp = data->mms_str_map.value(pEventData->strFullName);
2025-05-09 16:53:07 +08:00
if (dTemp >= 0.9) //SOE事件发生
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
if (0 == triggerCount) //SOE触发标识计数
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
triggerCount++; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
}
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "SOE暂态事件拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //SOEList 结束
KafkaData.strText.append("]}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 1; //结束该函数,停止后续代码执行
} //②-②SOE暂态事件解析结束---------------------------------
2025-01-16 16:17:01 +08:00
2025-07-30 16:30:10 +08:00
if (3 == pDataType->iDataType) //②-③SOE状态事件------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATASOE"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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监测点号
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
list<CEventData*>::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素
2025-01-16 16:17:01 +08:00
while (ed != pDataType->SOEList.end())
{
CEventData* pEventData = *ed++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
continue;
try
{
double dTemp = data->mms_str_map.value(pEventData->strFullName);
2025-05-09 16:53:07 +08:00
if (dTemp >= 0.9) //SOE事件发生
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
if (0 == triggerCount) //SOE触发标识计数
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
triggerCount++; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
}
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "SOE状态事件拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //SOEList 结束
KafkaData.strText.append("]}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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
2025-01-16 16:17:01 +08:00
{
list<CTopic*>::iterator tp = ctopic_list.begin();
2025-05-09 16:53:07 +08:00
while (tp != ctopic_list.end()) //①遍历 Kafka发送主题链表
2025-01-16 16:17:01 +08:00
{
CTopic* pTopic = *tp++;
2025-05-09 16:53:07 +08:00
if ("HISDATA" == pTopic->strTopic) //Topic等于HISDATA----------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
list<CDataType*>::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList
2025-01-16 16:17:01 +08:00
while (dt != pTopic->DataTypeList.end())
{
2025-05-09 16:53:07 +08:00
bool isJump = false; //是否跳出(整个数据类型)循环
2025-01-16 16:17:01 +08:00
CDataType* pDataType = *dt++;
2025-05-09 16:53:07 +08:00
if (2 == pDataType->iDataType) //②-②历史短闪变数据------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "PST"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
int countflag = 0, num = 0;
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
//////////////////////////////////////////////////////////lnk20250306为了数据入库构造数据添加FLAG
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
{
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
continue;
}
//////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻毫秒
time_sec = data->time / 1000; //时间戳(秒)
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-05-09 16:53:07 +08:00
//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相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
num = num + pSequence->DataValueList.size();
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
{
countflag++;
continue;
}
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = false; //跳出本层循环
2025-01-16 16:17:01 +08:00
countflag++;
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
continue;
}
try
{
2025-05-09 16:53:07 +08:00
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数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "历史闪变数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}}"); //拼接 json数据项结尾
} //ItemList 结束
if (isJump) break; //跳出循环
} //MonitorList 结束
if (isJump) continue; //跳出本数据类型循环
KafkaData.strText.append("}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
cout << countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"02\" " << num << endl;
cout << KafkaData.strText.toAscii().data() << endl;
if (countflag < num) {
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
shortjumpflag = true;
}
2025-05-09 16:53:07 +08:00
} //②-②历史闪变数据解析结束!--------------------------------
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//20241204长闪变类型应该为3
if (3 == pDataType->iDataType) //②-②历史长闪变数据------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "PLT"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
int countflag = 0, num = 0;
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
//////////////////////////////////////////////////////////lnk20250306为了数据入库构造数据添加FLAG
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
{
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
continue;
}
//////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":\"%1\", ").arg(data->time)); //拼接 json发生时刻毫秒
time_sec = data->time / 1000; //时间戳(秒)
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 F
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-05-09 16:53:07 +08:00
//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相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
num = num + pSequence->DataValueList.size();
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
{
countflag++;
continue;
}
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = false; //跳出本层循环
2025-01-16 16:17:01 +08:00
countflag++;
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
continue;
}
try
{
2025-05-09 16:53:07 +08:00
if (0 == time_sec % 7200) //2小时间隔长时闪变
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
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数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "历史闪变数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}}"); //拼接 json数据项结尾
} //ItemList 结束
if (isJump) break; //跳出循环
} //MonitorList 结束
if (isJump) continue; //跳出本数据类型循环
KafkaData.strText.append("}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-07-29 18:10:03 +08:00
cout << countflag << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!send name=\"DATA_TYPE\" value=\"03\" " << num << endl;
2025-01-16 16:17:01 +08:00
cout << KafkaData.strText.toAscii().data() << endl;
if (countflag < num && 0 == time_sec % 7200) {
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
longjumpflag = true;
}
2026-01-28 13:43:24 +08:00
if (typeofdata == false) {//不合并则处理完闪变就不处理其他数据
if (longjumpflag == true || shortjumpflag == true) {
return 1;
}
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//return 1; //结束该函数,停止后续代码执行
} //②-②历史闪变数据解析结束!--------------------------------
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (1 == pDataType->iDataType) //②-①历史稳态数据-----------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "HISDATA"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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"
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CMonitor*>::iterator mt = pDataType->MonitorList.begin(); //③遍历 MonitorList
2025-01-16 16:17:01 +08:00
while (mt != pDataType->MonitorList.end())
{
CMonitor* pMonitor = *mt++;
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\":{").arg("Value")); //拼接 json监测点
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CItem*>::iterator it = pMonitor->ItemList.begin(); //④遍历 ItemList
list<CItem*>::iterator itEnd = pMonitor->ItemList.end(); //ItemList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (it != pMonitor->ItemList.end())
{
CItem* pItem = *it++;
2025-05-09 16:53:07 +08:00
if ("FLAG" == pItem->strItemName) //剔除"FLAG"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"FLAG\":%1, ").arg(data->flag)); //拼接 json剔除标记1不剔除0剔除默认剔除
2025-01-16 16:17:01 +08:00
continue;
}
2025-05-09 16:53:07 +08:00
if ("TIME" == pItem->strItemName) //剔除"TIME"防止sq相别出现错误指针
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"TIME\":%1, ").arg(data->time)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
if (!data_timespan_list.contains(data->mp_id)) {
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
}
else if (data_timespan_list[data->mp_id]->msspan == 0)
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"interval\":%1, ").arg(3)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
}
else {
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"interval\":%1, ").arg(data_timespan_list[data->mp_id]->msspan)); //拼接 json发生时刻毫秒
2025-01-16 16:17:01 +08:00
}
continue;
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":{").arg(pItem->strItemName)); //拼接 json数据项 V、I、PQ
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CSequence*>::iterator sq = pItem->SequenceList.begin(); //⑤遍历 SequenceList
list<CSequence*>::iterator sqEnd = pItem->SequenceList.end(); //SequenceList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (sq != pItem->SequenceList.end())
{
CSequence* pSequence = *sq++;
2025-05-09 16:53:07 +08:00
//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相
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dv = pSequence->DataValueList.begin(); //⑥遍历 DataValueList
2025-01-16 16:17:01 +08:00
CDataValue* pDataValueBegin = *dv;
2025-05-09 16:53:07 +08:00
list<CDataValue*>::iterator dvEnd = pSequence->DataValueList.end(); //DataValueList链表最后一个数据值元素
2025-01-16 16:17:01 +08:00
while (dv != pSequence->DataValueList.end())
{
CDataValue* pDataValue = *dv++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pDataValue->strFullName || "not define" == pDataValue->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pDataValue->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
isJump = false; //跳出本层循环
//zw修改 2023-8-28 不匹配数据添加
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":%2, ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //拼接
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
continue;
}
try
{
2025-05-09 16:53:07 +08:00
if (pDataValue->strFullName.indexOf("$ang$f") != -1) //查找61850属性名中含有相角的定义
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
double dAngleTemp = data->mms_str_map.value(pDataValue->strFullName); //角度值(-180度 ~ 180度)
2025-01-16 16:17:01 +08:00
dAngleTemp = dAngleTemp > 180.0f ? dAngleTemp - 360.0f : dAngleTemp;
2025-05-09 16:53:07 +08:00
if (dv != dvEnd) //非单相最后一个数据值元素
KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //拼接 json数据值(角度值)
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
else
{
2025-05-09 16:53:07 +08:00
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数据值(非角度值)
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //拼接 json数据值(非角度值)
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "历史稳态数据值拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //DataValueList 结束
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (sq != sqEnd) //非A、B、C、T最后一个相别元素
KafkaData.strText.append("}, "); //拼接 json相别结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}"); //拼接 json相别结尾
} //SequenceList 结束
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (isJump) break; //跳出循环
if (it != itEnd) //非 V、I、PQ最后一个json数据项元素
KafkaData.strText.append("}, "); //拼接 json数据项结尾
2025-01-16 16:17:01 +08:00
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append("}}"); //拼接 json数据项结尾
} //ItemList 结束
if (isJump) break; //跳出循环
} //MonitorList 结束
if (isJump) continue; //跳出本数据类型循环
KafkaData.strText.append("}"); //拼接 json稳态数据结尾
2025-07-30 16:30:10 +08:00
//调试用
if(DEBUGOPEN)cout << KafkaData.strText.toAscii().data() << endl;
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
return 1; //结束该函数,停止后续代码执行
} //②-①历史稳态数据解析结束!--------------------------------
} //DataTypeList 结束
} //遍历 HISDATA 结束!
if ("RTDATASOE" == pTopic->strTopic) //Topic等于RTDATASOE----------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
list<CDataType*>::iterator dt = pTopic->DataTypeList.begin(); //②遍历 DataTypeList
2025-01-16 16:17:01 +08:00
while (dt != pTopic->DataTypeList.end())
{
2025-05-09 16:53:07 +08:00
int triggerCount = 0; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
CDataType* pDataType = *dt++;
2025-05-09 16:53:07 +08:00
if (1 == pDataType->iDataType) //②-①SOE稳态事件------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATASOE"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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监测点号
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
list<CEventData*>::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素
2025-01-16 16:17:01 +08:00
while (ed != pDataType->SOEList.end())
{
CEventData* pEventData = *ed++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
continue;
try
{
double dTemp = data->mms_str_map.value(pEventData->strFullName);
2025-05-09 16:53:07 +08:00
if (dTemp >= 0.9) //SOE事件发生
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
if (0 == triggerCount) //SOE触发标识计数
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
triggerCount++; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
}
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "SOE稳态事件拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //SOEList 结束
KafkaData.strText.append("]}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 1; //结束该函数,停止后续代码执行
} //②-①SOE稳态事件解析结束---------------------------------
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (1 == pDataType->iDataType) //②-②SOE暂态事件------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATASOE"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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监测点号
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
list<CEventData*>::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素
2025-01-16 16:17:01 +08:00
while (ed != pDataType->SOEList.end())
{
CEventData* pEventData = *ed++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
continue;
try
{
double dTemp = data->mms_str_map.value(pEventData->strFullName);
2025-05-09 16:53:07 +08:00
if (dTemp >= 0.9) //SOE事件发生
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
if (0 == triggerCount) //SOE触发标识计数
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
triggerCount++; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
}
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "SOE暂态事件拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //SOEList 结束
KafkaData.strText.append("]}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 1; //结束该函数,停止后续代码执行
} //②-②SOE暂态事件解析结束---------------------------------
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (1 == pDataType->iDataType) //②-③SOE状态事件------------------------------------------------------------
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
KafkaData.monitor_id = data->monitorId; //监测点ID
2025-01-16 16:17:01 +08:00
KafkaData.mp_id = data->mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "RTDATASOE"; //kafka发送主题
KafkaData.strText = ""; //kafka发送的json字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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监测点号
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CEventData*>::iterator ed = pDataType->SOEList.begin(); //③遍历 SOEList
list<CEventData*>::iterator edEnd = pDataType->SOEList.end(); //SOEList尾元素
2025-01-16 16:17:01 +08:00
while (ed != pDataType->SOEList.end())
{
CEventData* pEventData = *ed++;
2025-05-09 16:53:07 +08:00
if ("NOT DEFINE" == pEventData->strFullName || "not define" == pEventData->strFullName) //数据对象名 $ 数据属性名 即:拼接名为空
2025-01-16 16:17:01 +08:00
continue;
2025-05-09 16:53:07 +08:00
if (!data->mms_str_map.contains(pEventData->strFullName))//确认字典里不含有该key
2025-01-16 16:17:01 +08:00
continue;
try
{
double dTemp = data->mms_str_map.value(pEventData->strFullName);
2025-05-09 16:53:07 +08:00
if (dTemp >= 0.9) //SOE事件发生
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
if (0 == triggerCount) //SOE触发标识计数
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("\"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
triggerCount++; //SOE触发标识计数
2025-01-16 16:17:01 +08:00
}
else
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString(", \"%1\" ").arg(pEventData->triggerFlag)); //拼接 json SOE触发标识
2025-01-16 16:17:01 +08:00
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
cout << "SOE状态事件拼接json错误原因: " << e.what() << endl;
2025-01-16 16:17:01 +08:00
return false;
}
2025-05-09 16:53:07 +08:00
} //SOEList 结束
KafkaData.strText.append("]}"); //拼接 json稳态数据结尾
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 1; //结束该函数,停止后续代码执行
} //②-③SOE状态事件解析结束---------------------------------
} //DataTypeList 结束
} //遍历 RTDATASOE 结束!
} //TopicList 结束
} //三、结束
2025-01-16 16:17:01 +08:00
return 1;
}
2025-02-14 16:44:38 +08:00
2025-01-16 16:17:01 +08:00
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);
2025-05-09 16:53:07 +08:00
Ckafka_data_t KafkaData; //kafka发送数据结构类对象
2025-01-16 16:17:01 +08:00
KafkaData.monitor_id = monitor_id;
KafkaData.mp_id = mp_id;
2025-05-09 16:53:07 +08:00
KafkaData.strTopic = "Alm"; //kafka发送主题
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
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
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
list<CEventData*>::iterator ed = c_xmlcfg.SOEList.begin(); //③遍历 SOEList
2025-01-16 16:17:01 +08:00
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;
}
}
2025-05-09 16:53:07 +08:00
KafkaData.strText.append(QString("]")); //拼接 SOE结束
KafkaData.strText.append("}"); //拼接 value结束
KafkaData.strText.append("}"); //拼接 json结束
2025-01-16 16:17:01 +08:00
printf("transfer json ggio data: %s==%s \n", KafkaData.strText.toStdString().c_str(), fullname);
2025-05-09 16:53:07 +08:00
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(KafkaData); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//zw修改 2023-8-31 新增或更新list队列 写入xml数据库信息 模型编码 终端型号 终端厂家 oss存储路径 时间
//lnk修改 2024-10-28 去掉终端厂家,换成远端模型文件路径
2025-01-16 16:17:01 +08:00
//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);
2025-05-09 16:53:07 +08:00
//调试用lnk20241125
2025-01-16 16:17:01 +08:00
cout << "setxmldatabase:" << TMNL_TYPE << endl;
2025-05-09 16:53:07 +08:00
if (!xmlinfo_list.contains(type))//在终端类型列表中没查到
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
Xmldata* config = new Xmldata(); //没找到就插个新的终端类型到列表中
2025-01-16 16:17:01 +08:00
xmlinfo_list.insert(type, config);
2025-08-20 20:32:17 +08:00
xmlinfo_list[type]->updataflag = true;//lnk20250820
2025-05-09 16:53:07 +08:00
//调试用lnk20241125
2025-01-16 16:17:01 +08:00
cout << "xmlinfo_list insert type:" << type.toStdString() << endl;
}
2025-05-09 16:53:07 +08:00
else//查到就更新覆盖
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
//调试用lnk20241125
2025-01-16 16:17:01 +08:00
cout << "xmlinfo_list type contain:" << type.toStdString() << endl;
QDateTime time(QDate(year, month, day), QTime(hour, minute, second));
2025-05-09 16:53:07 +08:00
if (xmlinfo_list[type]->xmlbase.datetime == time) { //终端型号更新标志,如果新增的型号错误,导致实际用的映射文件不一样,或者覆盖了原来的映射文件这里可能出问题。数据库在录入型号和映射文件时要注意
xmlinfo_list[type]->updataflag = false; //时间值一样说明是没有更新,当前业务中不包含时间值,所以每次都会更新
2025-01-16 16:17:01 +08:00
}
else {
xmlinfo_list[type]->updataflag = true;
}
2025-05-09 16:53:07 +08:00
//lnk20250208如果类型存在则不再往下执行
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//lnk20250208这里应该是覆盖而不是追加
2025-02-08 17:04:39 +08:00
//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;
2025-01-16 16:17:01 +08:00
QDateTime time(QDate(year, month, day), QTime(hour, minute, second));
xmlinfo_list[type]->xmlbase.datetime = time;
2025-02-14 16:44:38 +08:00
cout << "##################################isdelta_flag is " << isdelta_flag << endl;
2025-05-09 16:53:07 +08:00
/*lnk2024-8-14 根据isdelta_flag 选择xmllist*/
2025-02-14 16:44:38 +08:00
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*/
2025-01-16 16:17:01 +08:00
char file_name[256];
memset(file_name, 0, 256);
sprintf(file_name, "%s", FILE_NAME);
QString Qsavename;
2025-05-09 16:53:07 +08:00
Qsavename.append("/FeProject/dat/").append(id).append(".xml"); //本地保存路径
2025-01-16 16:17:01 +08:00
char save_name[256];
memset(save_name, 0, 256);
sprintf(save_name, "%s", Qsavename.toAscii().data());
cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl;
//mq日志
DIY_WARNLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE,FILE_PATH,save_name);
2025-05-09 16:53:07 +08:00
//20241028 lnk 替换为文件下载web接口
//构造文件下载接口参数
//接口示例http://192.168.1.125:10215/file/download?filePath=/path/xxx.txt
// 调用web获取文件内容
2025-01-16 16:17:01 +08:00
char* fileContent = NULL;
2025-05-09 16:53:07 +08:00
//测试下载
2025-01-16 16:17:01 +08:00
//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);
2025-05-09 16:53:07 +08:00
//调试用
2025-01-16 16:17:01 +08:00
std::cout << "fullpath" << fullPath << std::endl;
SendJsonAPI_web(WEB_FILEDOWNLOAD, fullPath.c_str(), "", &fileContent);
if (fileContent != NULL) {
2025-05-09 16:53:07 +08:00
// 创建并打开文件
2025-01-16 16:17:01 +08:00
2025-08-19 20:56:35 +08:00
//判断返回的是不是错误json响应
bool isErrorJson = false;
cJSON* root = cJSON_Parse(fileContent);
if (root != NULL) {
cJSON* codeItem = cJSON_GetObjectItem(root, "code");
cJSON* dataItem = cJSON_GetObjectItem(root, "data");
if (codeItem && codeItem->valuestring &&
strcmp(codeItem->valuestring, "A00555") == 0 &&
(dataItem == NULL || (dataItem->type == cJSON_NULL))) {
isErrorJson = true;
std::cerr << "Error: Server returned empty file stream, code=A00555." << std::endl;
DIY_ERRORLOG_CODE("process", LOG_CODE_ICD_AND_DOWNLOAD,
"【ERROR】前置下载文件失败服务端返回A00555(文件流为空),文件=%s",
save_name);
}
cJSON_Delete(root);
}
2025-05-09 16:53:07 +08:00
//测试
//std::ofstream outFile(downpath, std::ios::binary);//二进制的方式打开
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
std::ofstream outFile(save_name, std::ios::out);//文本模式打开
2025-01-16 16:17:01 +08:00
if (outFile.is_open()) {
2025-05-09 16:53:07 +08:00
// 将文件流写入文件
2025-01-16 16:17:01 +08:00
outFile.write(fileContent, strlen(fileContent));
outFile.close();
std::cout << "File saved successfully!" << std::endl;
//mq日志
DIY_INFOLOG("process","【NORMAL】前置下载映射文件%s成功",save_name);
2025-01-16 16:17:01 +08:00
} else {
std::cerr << "Error: Unable to open file for writing." << std::endl;
DIY_ERRORLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置写入本地映射文件%s失败",save_name);
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
// 释放分配的内存
2025-01-16 16:17:01 +08:00
free(fileContent);
} else {
std::cerr << "Error: Unable to download file." << std::endl;
DIY_ERRORLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH);
2025-01-16 16:17:01 +08:00
}
}
2025-05-09 16:53:07 +08:00
//zw修改 2023-9-4 读取装置类型对应的xml文件
2025-01-16 16:17:01 +08:00
void Set_xml_nodeinfo()
{
2025-05-09 16:53:07 +08:00
//配置无对应xml文件时的默认解析配置
if (!inited) //初始化 JiangSu_Config.xml
2025-01-16 16:17:01 +08:00
{
QString path;
path.append("not define");
2025-05-09 16:53:07 +08:00
ParseXMLConfig2(0, &xmlcfg, &topicList, path); //调用 ParseXMLConfig() 解析JiangSu_Config.xml配置文件
2025-02-14 16:44:38 +08:00
if (isdelta_flag) {
2025-05-09 16:53:07 +08:00
ParseXMLConfig2(1, &xmlcfg2, &topicList2, path); //lnk2024-8-13角型接线
2025-02-14 16:44:38 +08:00
}
2025-01-16 16:17:01 +08:00
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) {
2025-02-14 16:44:38 +08:00
ParseXMLConfig2(0,&(value2->xmlcfg), &(value2->topicList), value2->xmlbase.MODEL_ID);
}
}
2025-05-09 16:53:07 +08:00
//lnk2024-8-14 选择角型接线
2025-02-14 16:44:38 +08:00
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);
}
2025-01-16 16:17:01 +08:00
}
}
}
else {
cout << "!!!!!!!!!! xmlinfo_list.size() == 0 !!!!!!!!!!!" << endl;
}
}
2025-05-09 16:53:07 +08:00
//zw修改 2023-9-4 获取xml路径
2025-01-16 16:17:01 +08:00
char* Get_xmlpath(char* devtype)
{
QString type;
type.append(devtype);
2025-05-09 16:53:07 +08:00
//调试用lnk20241125
2025-01-16 16:17:01 +08:00
std::cout << type.toStdString() << std::endl;
2025-03-13 16:35:19 +08:00
if (xmlinfo_list.contains(devtype) &&
2025-05-09 16:53:07 +08:00
xmlinfo_list[devtype] != NULL && // 先检查指针是否为空
!xmlinfo_list[devtype]->xmlbase.MODEL_ID.isNull() && // 确保 QString 不是 NULL
!xmlinfo_list[devtype]->xmlbase.MODEL_ID.isEmpty() && // 确保字符串不为空
xmlinfo_list[devtype]->xmlbase.MODEL_ID.trimmed().length() >= 4) { //确保modelid存在lnk20250313
2025-01-16 16:17:01 +08:00
cout << "!!!!!!!!!! xmlinfo_list.contains(devtype) == 1 !!!!!!!!!!!" << endl;
2025-05-09 16:53:07 +08:00
QByteArray byteArray = xmlinfo_list[devtype]->xmlbase.MODEL_ID.toLocal8Bit();//易崩溃点,一定要确保modelid存在lnk20250313
char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305
2025-01-16 16:17:01 +08:00
memcpy(charArray, byteArray.data(), byteArray.size());
charArray[byteArray.size()] = '\0';
return charArray;
}
else {
cout << "!!!!!!!!!! xmlinfo_list.contains(devtype) == 0 !!!!!!!!!!!" << endl;
return NULL;
}
}
2025-05-09 16:53:07 +08:00
//zw修改 2023-9-5 获取IED模型
2025-01-16 16:17:01 +08:00
char* Get_IED(char* devtype)
{
QString type;
type.append(devtype);
2025-03-13 16:35:19 +08:00
if (xmlinfo_list.contains(type) && xmlinfo_list[type] != NULL) {
2025-02-08 17:04:39 +08:00
cout << "!!!!!!!!!! Get_IED xmlinfo_list.contains(devtype) == 1 !!!!!!!!!!!" << endl;
2025-03-13 16:35:19 +08:00
2025-05-09 16:53:07 +08:00
// 确保 xmlcfg 及其成员非空
2025-03-13 16:35:19 +08:00
if (xmlinfo_list[type]->xmlcfg.IEDname.isNull() || xmlinfo_list[type]->xmlcfg.LDevicePrefix.isNull()) {
cout << "Error: IEDname or LDevicePrefix is NULL in Get_IED!" << endl;
return NULL;
}
2025-01-16 16:17:01 +08:00
QString ied;
2025-05-20 16:31:12 +08:00
ied.append(xmlinfo_list[type]->xmlcfg.IEDname); // 从配置文件读取的终端名
ied.append(xmlinfo_list[type]->xmlcfg.LDevicePrefix); //// 从配置文件读取的监测点名
2025-01-16 16:17:01 +08:00
ied.append("%d");
2025-03-13 16:35:19 +08:00
2025-01-16 16:17:01 +08:00
QByteArray byteArray = ied.toLocal8Bit();
2025-03-13 16:35:19 +08:00
if (byteArray.isEmpty()) {
cout << "Error: Generated QByteArray is empty!" << endl;
return NULL;
}
2025-05-09 16:53:07 +08:00
// 分配内存,确保足够大小并安全拷贝
2025-03-13 16:35:19 +08:00
char* charArray = new char[byteArray.size() + 1];
if (!charArray) {
cout << "Error: Memory allocation failed!" << endl;
return NULL;
}
2025-01-16 16:17:01 +08:00
memcpy(charArray, byteArray.data(), byteArray.size());
2025-05-09 16:53:07 +08:00
charArray[byteArray.size()] = '\0'; // 确保字符串以 '\0' 结尾
2025-03-13 16:35:19 +08:00
2025-01-16 16:17:01 +08:00
return charArray;
2025-03-13 16:35:19 +08:00
}
2025-01-16 16:17:01 +08:00
else {
2025-02-08 17:04:39 +08:00
cout << "!!!!!!!!!! Get_IED xmlinfo_list.contains(devtype) == 0 !!!!!!!!!!!" << endl;
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
QString ied;
ied.append(xmlcfg.IEDname);
ied.append(xmlcfg.LDevicePrefix);
ied.append("%d");
QByteArray byteArray = ied.toLocal8Bit();
2025-05-09 16:53:07 +08:00
char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305
2025-01-16 16:17:01 +08:00
memcpy(charArray, byteArray.data(), byteArray.size());
charArray[byteArray.size()] = '\0';
return charArray;
}
}
char* Get_LDevice(char* devtype)
{
QString type;
type.append(devtype);
2025-05-09 16:53:07 +08:00
if (xmlinfo_list.contains(type) && xmlinfo_list[type] != NULL) { // 确保类型存在且不为空
2025-03-13 16:35:19 +08:00
if (xmlinfo_list[type]->xmlcfg.LDevicePrefix.isNull() || xmlinfo_list[type]->xmlcfg.LDevicePrefix.isEmpty()) {
cout << "Error: LDevicePrefix is NULL or empty in Get_IED!" << endl;
return NULL;
}
2025-01-16 16:17:01 +08:00
QString ied;
2025-05-09 16:53:07 +08:00
ied.append(xmlinfo_list[type]->xmlcfg.LDevicePrefix); // 使用解析列表的终端前缀
2025-01-16 16:17:01 +08:00
ied.append("%d");
2025-03-13 16:35:19 +08:00
2025-01-16 16:17:01 +08:00
QByteArray byteArray = ied.toLocal8Bit();
2025-03-13 16:35:19 +08:00
if (byteArray.isEmpty()) {
cout << "Error: Generated QByteArray is empty!" << endl;
return NULL;
}
2025-05-09 16:53:07 +08:00
// 分配内存,确保足够大小
2025-03-13 16:35:19 +08:00
char* charArray = new char[byteArray.size() + 1];
if (!charArray) {
cout << "Error: Memory allocation failed!" << endl;
return NULL;
}
2025-01-16 16:17:01 +08:00
memcpy(charArray, byteArray.data(), byteArray.size());
2025-05-09 16:53:07 +08:00
charArray[byteArray.size()] = '\0'; // 确保字符串以 '\0' 结尾
2025-03-13 16:35:19 +08:00
2025-01-16 16:17:01 +08:00
return charArray;
}
else {
2025-04-29 15:05:36 +08:00
2025-01-16 16:17:01 +08:00
QString ied;
2025-05-09 16:53:07 +08:00
ied.append(xmlcfg.LDevicePrefix);//使用默认解析配置的终端前缀
2025-01-16 16:17:01 +08:00
ied.append("%d");
QByteArray byteArray = ied.toLocal8Bit();
2025-05-09 16:53:07 +08:00
char* charArray = new char[byteArray.size()+1];//分配内存时+1防止内存泄漏lnk20250305
2025-01-16 16:17:01 +08:00
memcpy(charArray, byteArray.data(), byteArray.size());
charArray[byteArray.size()] = '\0';
return charArray;
}
}
///////////////////////////////////////////////////lnk2024-10-21////////////////////////////////////////////////////////
void handleCommentResponse(const std::string& response) {
2025-05-09 16:53:07 +08:00
// 解析 JSON 响应
2025-01-16 16:17:01 +08:00
cJSON* json_data = cJSON_Parse(response.c_str());
if (json_data == NULL) {
std::cerr << "Error parsing response: " << cJSON_GetErrorPtr() << std::endl;
return;
}
2025-05-09 16:53:07 +08:00
// 提取字段
2025-01-16 16:17:01 +08:00
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;
2025-05-09 16:53:07 +08:00
// 输出信息
2025-01-16 16:17:01 +08:00
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;
}
2025-05-09 16:53:07 +08:00
// 释放 JSON 对象
2025-01-16 16:17:01 +08:00
cJSON_Delete(json_data);
}
std::string boolToString(bool value) {
return value ? "1" : "0";
}
2025-05-09 16:53:07 +08:00
//添加入参、时间和状态lnk202411-4
2025-01-16 16:17:01 +08:00
void connectlog_pgsql(char* id,char* datetime,int status)
{
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
//创建响应接收
2025-01-16 16:17:01 +08:00
char* ptr=NULL;
2025-05-09 16:53:07 +08:00
// 创建 JSON 对象
2025-01-16 16:17:01 +08:00
cJSON* jsonObject = cJSON_CreateObject();
if (jsonObject == NULL) {
std::cerr << "Failed to create JSON object." << std::endl;
return;
}
2025-05-09 16:53:07 +08:00
// 添加字段到 JSON 对象
2025-01-16 16:17:01 +08:00
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;
}
2025-03-12 14:33:55 +08:00
cJSON_AddItemToObject(jsonObject, "date", datetime_item);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
char statusStr[12]; // 足够容纳一个整数(包括负号和 '\0'
sprintf(statusStr, "%d", status);// 使用 sprintf 将 int 转换为字符串
2025-01-16 16:17:01 +08:00
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);
char* jsonString = cJSON_Print(jsonObject);
if (jsonString == NULL) {
std::cerr << "Failed to print JSON object." << std::endl;
cJSON_Delete(jsonObject);
return;
}
2025-03-12 11:45:53 +08:00
2025-05-09 16:53:07 +08:00
//使用mq
2025-03-12 11:45:53 +08:00
Ckafka_data_t connect_info;
connect_info.strTopic = QString::fromStdString(G_CONNECT_TOPIC);
connect_info.strText = QString::fromStdString(std::string(jsonString));
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if(g_node_id == STAT_DATA_BASE_NODE_ID){//稳态才上传
kafka_data_list_mutex.lock(); //加锁
kafka_data_list.append(connect_info); //添加 kafka发送链表
kafka_data_list_mutex.unlock(); //解锁
2025-03-12 11:45:53 +08:00
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 释放内存
2025-01-16 16:17:01 +08:00
cJSON_Delete(jsonObject);
2025-05-09 16:53:07 +08:00
free(jsonString); // cJSON_PrintUnformatted使用malloc分配内存
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//lnk202411-5 暂态数据不再使用kafka发送改成http接口
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////暂态事件放入文件
// 下面这部分是你要在原函数中“插入的新增功能”所需的辅助函数
2025-04-02 11:48:18 +08:00
// *****************************************************************************************
2025-05-09 16:53:07 +08:00
// 获取指定目录下所有文件的信息(文件名、修改时间、大小),以便后续做删除或判断文件总大小
2025-04-02 11:48:18 +08:00
struct FileInfo {
std::string fileName;
2025-05-09 16:53:07 +08:00
time_t modTime; // 上次修改时间
long long fileSize; // 文件大小
2025-04-02 11:48:18 +08:00
};
2025-05-09 16:53:07 +08:00
// 扫描目录,获取该目录下所有普通文件的信息
2025-04-02 11:48:18 +08:00
static void getDirectoryFilesInfo(const std::string &dirPath, std::vector<FileInfo> &fileList)
{
DIR* dp = opendir(dirPath.c_str());
if (!dp) {
std::cerr << "Failed to get info from : " << dirPath << std::endl;
2025-05-09 16:53:07 +08:00
return; // 打开失败则直接返回
2025-04-02 11:48:18 +08:00
}
struct dirent* entry = NULL;
while ((entry = readdir(dp)) != NULL) {
2025-05-09 16:53:07 +08:00
// 跳过 . 和 ..
2025-04-02 11:48:18 +08:00
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
2025-05-09 16:53:07 +08:00
// 拼出完整路径
2025-04-02 11:48:18 +08:00
std::string fullPath = dirPath + entry->d_name;
2025-05-09 16:53:07 +08:00
// 获取文件信息
2025-04-02 11:48:18 +08:00
struct stat st;
if (stat(fullPath.c_str(), &st) == 0) {
if (S_ISREG(st.st_mode)) {
FileInfo fi;
2025-05-09 16:53:07 +08:00
fi.fileName = fullPath; // 包含路径
fi.modTime = st.st_mtime; // 修改时间
fi.fileSize = (long long)st.st_size; // 文件大小
2025-04-02 11:48:18 +08:00
fileList.push_back(fi);
}
}
}
closedir(dp);
}
2025-05-09 16:53:07 +08:00
// 将 JSON 字符串写入指定文件
2025-09-04 16:26:00 +08:00
static bool writeJsonToFile(const char* filePath, const char* jsonString)
2025-04-02 11:48:18 +08:00
{
FILE* fp = fopen(filePath, "w");
if (!fp) {
2025-09-04 16:26:00 +08:00
//DIY_ERRORLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【ERROR】无法将暂态事件写入本地缓存");
2025-04-02 11:48:18 +08:00
std::cerr << "Failed to write in file : " << filePath << std::endl;
2025-09-04 16:26:00 +08:00
return false;
2025-04-02 11:48:18 +08:00
}
fprintf(fp, "%s", jsonString);
fclose(fp);
2025-09-04 16:26:00 +08:00
return true;
2025-04-02 11:48:18 +08:00
}
2025-05-09 16:53:07 +08:00
// 检查 qvvr 目录下文件总大小,若超过 10M 则删除最老的一个文件
// 注意该逻辑严格按照你需求“只删一个最老的文件”来实现而不是循环删到小于10M
2025-04-02 11:48:18 +08:00
static void checkAndRemoveOldestIfNeeded(const std::string &dirPath, long long maxBytes)
{
2025-05-09 16:53:07 +08:00
// 1) 判断目录是否存在,不存在则尝试创建
2025-04-02 11:48:18 +08:00
{
struct stat st;
2025-05-09 16:53:07 +08:00
// 调用 stat() 判断是否存在
2025-04-02 11:48:18 +08:00
if (stat(dirPath.c_str(), &st) == -1) {
if (errno == ENOENT) {
2025-05-09 16:53:07 +08:00
// 目录不存在,尝试创建
// 注意mkdir 只会创建最后一级目录,若需要递归创建父目录,请自行扩展
2025-04-02 11:48:18 +08:00
if (mkdir(dirPath.c_str(), 0777) != 0) {
2025-05-09 16:53:07 +08:00
// 若 mkdir 失败,可根据实际需求进行日志输出或错误处理
2025-04-02 11:48:18 +08:00
std::cerr << "Failed to create directory: " << dirPath << std::endl;
2025-05-09 16:53:07 +08:00
return; // 创建失败则直接返回,避免后续操作报错
2025-04-02 11:48:18 +08:00
}
} else {
2025-05-09 16:53:07 +08:00
// stat() 调用出错,但并非 ENOENT可根据需求处理
2025-04-02 11:48:18 +08:00
std::cerr << "stat error: " << strerror(errno) << std::endl;
return;
}
}
else {
2025-05-09 16:53:07 +08:00
// 如果能 stat 到 dirPath需要再判断是否真的是个“目录”而非普通文件
2025-04-02 11:48:18 +08:00
if (!S_ISDIR(st.st_mode)) {
2025-05-09 16:53:07 +08:00
// 存在同名的非目录文件,无法作为目录使用
2025-04-02 11:48:18 +08:00
std::cerr << dirPath << " exists but is not a directory." << std::endl;
return;
}
}
}
2025-05-09 16:53:07 +08:00
// ============== 以下是原有的逻辑 ==============
// 获取目录下所有文件信息
2025-04-02 11:48:18 +08:00
std::vector<FileInfo> fileList;
getDirectoryFilesInfo(dirPath, fileList);
2025-05-09 16:53:07 +08:00
// 计算总大小
2025-04-02 11:48:18 +08:00
long long totalSize = 0;
for (size_t i = 0; i < fileList.size(); ++i) {
totalSize += fileList[i].fileSize;
}
2025-05-09 16:53:07 +08:00
// 如果超过阈值,则删除最老的那个
2025-04-02 11:48:18 +08:00
if (totalSize > maxBytes && !fileList.empty()) {
2025-05-09 16:53:07 +08:00
// 按修改时间升序排序,最老(修改时间最早)的排在最前面
2025-04-02 11:48:18 +08:00
std::sort(fileList.begin(), fileList.end(),
2025-05-09 16:53:07 +08:00
// C++98 的比较写法
2025-04-02 11:48:18 +08:00
static_cast<bool(*)(const FileInfo&, const FileInfo&)>(
2025-05-09 16:53:07 +08:00
// 不能使用lambda用函数指针
// 比较函数
2025-04-02 11:48:18 +08:00
(bool (*)(const FileInfo&, const FileInfo&))[] (const FileInfo &a, const FileInfo &b) {
return a.modTime < b.modTime;
}
)
);
2025-05-09 16:53:07 +08:00
// 删掉第一个(最老的文件)
2025-04-02 11:48:18 +08:00
remove(fileList[0].fileName.c_str());
}
}
2025-05-09 16:53:07 +08:00
// 扫描目录下的离线文件,依次读取并发送;若发送成功则删除该文件,发送不成功则保留
2025-04-02 11:48:18 +08:00
static void scanAndResendOfflineFiles(const std::string &dirPath)
{
2025-05-09 16:53:07 +08:00
// 获取目录下所有文件信息
2025-04-02 11:48:18 +08:00
std::vector<FileInfo> fileList;
2025-04-02 15:16:11 +08:00
std::cout << "getDirectoryFilesInfo" << std::endl;
2025-04-02 11:48:18 +08:00
getDirectoryFilesInfo(dirPath, fileList);
2025-04-02 15:16:11 +08:00
std::cout << "send every file" << std::endl;
2025-05-09 16:53:07 +08:00
// 逐个文件尝试重发
2025-04-02 11:48:18 +08:00
for (size_t i = 0; i < fileList.size(); ++i) {
2025-05-09 16:53:07 +08:00
// 读取文件内容(即之前存的 JSON)
2025-04-02 11:48:18 +08:00
FILE* fp = fopen(fileList[i].fileName.c_str(), "r");
if (!fp) {
DIY_ERRORLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【ERROR】无法打开本地缓存的暂态事件");
2025-04-02 11:48:18 +08:00
std::cerr << " fail to open exsist file " << fileList[i].fileName << std::endl;
continue;
}
2025-05-09 16:53:07 +08:00
// 读取到内存
2025-04-02 11:48:18 +08:00
std::string jsonContent;
char buf[1024];
while (!feof(fp)) {
if (fgets(buf, sizeof(buf), fp)) {
jsonContent += buf;
}
}
fclose(fp);
2025-04-02 15:16:11 +08:00
std::cout << "send jsonContent" << jsonContent << std::endl;
2025-05-09 16:53:07 +08:00
// 尝试发送
char* ptr = NULL; // 接收返回
2025-04-02 15:16:11 +08:00
SendJsonAPI_web(WEB_EVENT, "", jsonContent.c_str(), &ptr);
2025-04-02 11:48:18 +08:00
if (ptr != NULL) {
2025-04-02 15:16:11 +08:00
cJSON* j_r = cJSON_Parse(ptr);
if (j_r == NULL) {
std::cout << "old file send fail" << std::endl;
2025-05-09 16:53:07 +08:00
// 表示有响应,则可视为成功;根据项目需要可加更精细的判断
2025-04-02 15:16:11 +08:00
handleCommentResponse(std::string(ptr));
2025-05-29 16:36:34 +08:00
DIY_WARNLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【WARN】前置重发暂态事件失败");
2025-05-29 16:36:34 +08:00
2025-04-02 15:16:11 +08:00
}
else{
2025-05-29 16:36:34 +08:00
DIY_WARNLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【WARN】前置重发暂态事件成功");
2025-05-29 16:36:34 +08:00
2025-04-02 15:16:11 +08:00
std::cout << "old file send success,remove it" << std::endl;
2025-05-09 16:53:07 +08:00
// 删除文件
2025-04-02 15:16:11 +08:00
remove(fileList[i].fileName.c_str());
free(j_r);
}
2025-04-02 11:48:18 +08:00
}
else {
2025-05-09 16:53:07 +08:00
// 发送失败,保留文件,以便下次重试
2025-04-02 15:16:11 +08:00
std::cout << "old file send fail" << std::endl;
2025-04-02 11:48:18 +08:00
}
2025-04-02 15:16:11 +08:00
free(ptr);
2025-04-02 11:48:18 +08:00
}
}
// *****************************************************************************************
2025-04-02 15:16:11 +08:00
std::string FormatTimeForFilename(const std::string& timeStr) {
std::string result;
for (char c : timeStr) {
if (isdigit(c)) {
result += c;
}
}
return result;
}
2025-05-09 16:53:07 +08:00
// ======================== 原先的函数 ========================
2025-04-02 11:48:18 +08:00
int transfer_json_qvvr_data(unsigned int func_type, int monitor_id,
double mag, double dur, long long start_tm, long long end_tm, int dis_kind,
char* uuid_cfg,char* uuid_dat,
char* mp_id,char* Qvvr_rptname,char* devtype)
{
2025-05-29 16:36:34 +08:00
//监测点日志的key,lnk20250526
char full_key_m_c[256]; // 分配足够空间
char full_key_m_d[256]; // 分配足够空间
snprintf(full_key_m_c, sizeof(full_key_m_c), "monitor.%s.COM", mp_id);
snprintf(full_key_m_d, sizeof(full_key_m_d), "monitor.%s.DATA", mp_id);
//监测点日志的key,lnk20250526
2025-05-09 16:53:07 +08:00
// 原本的逻辑,不做任何改动
2025-04-02 11:48:18 +08:00
// ---------------------------------------------------------------
XmlConfig c_xmlcfg;
if (xmlinfo_list.contains(devtype)) {
2025-05-09 16:53:07 +08:00
c_xmlcfg = xmlinfo_list[devtype]->xmlcfg;//查找映射
2025-04-02 11:48:18 +08:00
}
else {
c_xmlcfg = xmlcfg;
}
if (strlen(mp_id) == 0) {
std::cout << "mp_id is null" << std::endl;
return 0;
}
cJSON* root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "monitorId", mp_id);
cJSON_AddNumberToObject(root, "amplitude", mag);
cJSON_AddNumberToObject(root, "duration", dur);
cJSON_AddNumberToObject(root, "eventType", dis_kind);
char start_time_str[25];
time_t start_sec = start_tm / 1000;
struct tm* time_info = localtime(&start_sec);
strftime(start_time_str, sizeof(start_time_str), "%Y-%m-%d %H:%M:%S", time_info);
snprintf(start_time_str + strlen(start_time_str), sizeof(start_time_str) - strlen(start_time_str), ".%03lld", start_tm % 1000);
cJSON_AddStringToObject(root, "startTime", start_time_str);
// cJSON_AddStringToObject(root, "wavePathcfg", uuid_cfg);
// cJSON_AddStringToObject(root, "wavePathdat", uuid_dat);
cJSON_AddStringToObject(root, "wavePath", uuid_dat);
if (c_xmlcfg.WavePhasicFlag == "1") {
QString Qvvr_Rptname;
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");
}
char* json_string = cJSON_Print(root);
2025-05-09 16:53:07 +08:00
printf("%s\n", json_string); // 输出 JSON 字符串
2025-04-02 11:48:18 +08:00
2025-05-09 16:53:07 +08:00
// 发送到暂态接口
2025-04-02 11:48:18 +08:00
char* ptr = NULL;
SendJsonAPI_web(WEB_EVENT, "", json_string, &ptr);
2025-05-09 16:53:07 +08:00
// ================ 插入新功能 =========================
// ********** 新增功能开始 **********
2025-04-02 15:16:11 +08:00
if(ptr != NULL)
2025-04-02 11:48:18 +08:00
{
2025-04-02 15:16:11 +08:00
cJSON* j_r = cJSON_Parse(ptr);
2025-05-09 16:53:07 +08:00
// 如果发送失败(j_r == NULL),则把当前 json 存入指定目录(/FeProject/dat/qvvr/)
2025-04-02 15:16:11 +08:00
if (j_r == NULL) {
2025-05-29 16:36:34 +08:00
//mq日志
DIY_ERRORLOG_CODE(full_key_m_d,LOG_CODE_TRANSIENT_COMM,"【ERROR】暂态接口响应异常,无法上送监测点%s的暂态事件",mp_id);
2025-05-29 16:36:34 +08:00
2025-04-02 15:16:11 +08:00
std::cout << "qvvr send fail ,store in local" << std::endl;
2025-05-09 16:53:07 +08:00
// 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M若超过则删除最老的一个文件
2025-04-02 11:48:18 +08:00
std::string qvvrDir = "/FeProject/dat/qvvr/";
2025-05-30 15:40:20 +08:00
2025-04-02 11:48:18 +08:00
2025-05-09 16:53:07 +08:00
// 2) 将此条 json 存为文件,文件名: mp_id-start_time_str-dis_kind.txt
// 例如: 502-2025-04-02 15:25:30.123-3.txt (仅示例)
2025-04-02 11:48:18 +08:00
std::string fileName = qvvrDir;
fileName += mp_id;
fileName += "-";
2025-04-02 15:16:11 +08:00
fileName += FormatTimeForFilename(start_time_str);
2025-04-02 11:48:18 +08:00
fileName += "-";
char buf[64];
sprintf(buf, "%d", dis_kind);
fileName += buf;
fileName += ".txt";
2025-05-09 16:53:07 +08:00
// 把 json_string 写入文件
2025-09-04 16:26:00 +08:00
if(!writeJsonToFile(fileName.c_str(), json_string)){
DIY_ERRORLOG_CODE(full_key_m_d,LOG_CODE_TRANSIENT_COMM,"【ERROR】监测点%s无法将暂态时间为%lld的暂态事件写入本地缓存",start_tm,mp_id);
}
2025-05-30 15:40:20 +08:00
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
2025-04-02 11:48:18 +08:00
}
2025-04-02 15:16:11 +08:00
else{
free(j_r);
2025-05-09 16:53:07 +08:00
//后续处理
2025-04-02 15:16:11 +08:00
}
2025-04-02 11:48:18 +08:00
}
2025-05-09 16:53:07 +08:00
// 无论此次发送成功或失败,都要扫描/FeProject/dat/qvvr/目录下的文件并尝试依次重发
2025-04-02 15:16:11 +08:00
if(1)
{
std::string qvvrDir = "/FeProject/dat/qvvr/";
scanAndResendOfflineFiles(qvvrDir);
}
2025-05-09 16:53:07 +08:00
// ********** 新增功能结束 **********
2025-04-02 11:48:18 +08:00
2025-05-09 16:53:07 +08:00
// 下面继续原逻辑,不动,处理本次发送
2025-04-02 11:48:18 +08:00
if (ptr != NULL) {
2025-04-02 15:16:11 +08:00
std::cout << "current qvvr handle response" << std::endl;
2025-04-02 11:48:18 +08:00
handleCommentResponse(std::string(ptr));
free(ptr);
} else {
2025-05-09 16:53:07 +08:00
// 处理 ptr 为 NULL 的情况,例如日志记录或错误处理
2025-04-02 11:48:18 +08:00
std::cout << "Error: Received NULL response" << std::endl;
2025-05-29 16:36:34 +08:00
//mq日志
DIY_ERRORLOG_CODE(full_key_m_d,LOG_CODE_TRANSIENT_COMM,"【ERROR】暂态接口无响应,无法上送监测点%s的暂态事件",mp_id);
2025-05-29 16:36:34 +08:00
std::cout << "qvvr send fail ,store in local" << std::endl;
// 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M若超过则删除最老的一个文件
std::string qvvrDir = "/FeProject/dat/qvvr/";
2025-05-30 15:40:20 +08:00
2025-05-29 16:36:34 +08:00
// 2) 将此条 json 存为文件,文件名: mp_id-start_time_str-dis_kind.txt
// 例如: 502-2025-04-02 15:25:30.123-3.txt (仅示例)
std::string fileName = qvvrDir;
fileName += mp_id;
fileName += "-";
fileName += FormatTimeForFilename(start_time_str);
fileName += "-";
char buf[64];
sprintf(buf, "%d", dis_kind);
fileName += buf;
fileName += ".txt";
// 把 json_string 写入文件
2025-09-04 16:26:00 +08:00
if(!writeJsonToFile(fileName.c_str(), json_string)){
DIY_ERRORLOG_CODE(full_key_m_d,LOG_CODE_TRANSIENT_COMM,"【ERROR】监测点%s无法将暂态时间为%lld的暂态事件写入本地缓存",start_tm,mp_id);
}
2025-05-29 16:36:34 +08:00
2025-05-30 15:40:20 +08:00
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
2025-05-09 16:53:07 +08:00
// 释放内存
2025-04-02 15:16:11 +08:00
cJSON_Delete(root);
free(json_string);
2025-04-02 11:48:18 +08:00
return 0;
}
2025-05-09 16:53:07 +08:00
// 释放内存
2025-04-02 11:48:18 +08:00
cJSON_Delete(root);
free(json_string);
return 1;
}
2025-05-09 16:53:07 +08:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////暂态事件放入文件
2025-01-16 16:17:01 +08:00
void qvvr_test()
{
char uuid_cfg[] = {"/comtrade/"};
char uuid_dat[] = {"/comtrade/"};
char mp_id[] = {"000cf2a27f3f13f330b9e8690641e7f2"};
char Qvvr_rptname[] = {"unknow"};
char devtype[] = {"01"};
transfer_json_qvvr_data(1, 123456789, 220, 180, 1730894400.123, 1730894580, 1210001,uuid_cfg,uuid_dat,mp_id,Qvvr_rptname,devtype);
}
void comflag_test()
{
char id[] = {"000cf2a27f3f13f330b9e8690641e7f2"};
char datetime[] = {"2024-11-6 15:15:15"};
connectlog_pgsql(id,datetime,1);
}
///////////////////////////////////////////////////lnk2024-10-21////////////////////////////////////////////////////////
void clearXmlConfigAndTopicList(Xmldata* data) {
2025-05-09 16:53:07 +08:00
// 清空 XmlConfig
data->xmlcfg = XmlConfig(); // 通过重新赋值重置 xmlcfg
2025-05-09 16:53:07 +08:00
// 清空 topicList
list<CTopic*>::iterator it;
for (it = data->topicList.begin(); it != data->topicList.end(); ++it) {
2025-05-09 16:53:07 +08:00
delete *it; // 释放内存
}
2025-05-09 16:53:07 +08:00
data->topicList.clear(); // 清空链表
}
2025-05-09 16:53:07 +08:00
//4-配置映射文件//////////////////////////////
2025-01-17 17:10:18 +08:00
void Set_xml_nodeinfo_one(char* dev_type)
{
bool ret = false;
2025-05-09 16:53:07 +08:00
if(xmlinfo_list[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点
2025-08-20 20:32:17 +08:00
//if(xmlinfo_list[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新
2025-05-09 16:53:07 +08:00
//将这个点的xmlcfg和topicList删除
clearXmlConfigAndTopicList(xmlinfo_list[QString::fromUtf8(dev_type)]);
2025-02-14 16:44:38 +08:00
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;
}
2025-08-20 20:32:17 +08:00
//}
2025-01-17 17:10:18 +08:00
}
else{
std::cout << "xmlinfo_list not contain this devtype" << std::endl;
}
2025-05-09 16:53:07 +08:00
//添加角形
2025-02-14 16:44:38 +08:00
if(isdelta_flag){
2025-05-09 16:53:07 +08:00
if(xmlinfo_list2[QString::fromUtf8(dev_type)] != NULL){ //原来已存在这个类型的节点
2025-08-20 20:32:17 +08:00
//if(xmlinfo_list2[QString::fromUtf8(dev_type)]->updataflag == true){ //需要更新
2025-01-17 17:10:18 +08:00
2025-05-09 16:53:07 +08:00
//将这个点的xmlcfg和topicList删除
2025-02-14 16:44:38 +08:00
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;
}
2025-08-20 20:32:17 +08:00
//}
2025-02-14 16:44:38 +08:00
}
else{
std::cout << "xmlinfo_list2 not contain this devtype" << std::endl;
}
}
2025-01-17 17:10:18 +08:00
}
2025-04-29 15:05:36 +08:00