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"
2025-05-28 16:09:15 +08:00
# include "../log4cplus/log4.h" //lnk添加log4
2026-03-06 16:27:58 +08:00
///////////////////////////////////////////////////////////////////////lnk20260305数据追踪相关
# include <QHash>
# include <QMutex>
# include <QMutexLocker>
# include <QMapIterator>
# include <QStringList>
// ★MOD: 全局追踪表: mp_id -> remaining times
static QMutex g_trace_mutex ;
static QHash < QString , int > g_trace_map ;
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
2026-02-04 09:21:54 +08:00
//lnk20250115添加台账锁
extern pthread_mutex_t mtx ;
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事件触发指标名称
2026-02-04 09:21:54 +08:00
int nIndex ; //数据在每条线路LineInfo值数组中的位置
QString desc ; //soe事件描述
2025-05-09 16:53:07 +08:00
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 ; //相别值 例: 7: ABC三项, 8: T相
QString strSeq ; //相别 例: A、B、C、T
QString type ; //参数等级type类型: 0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件
list < CDataValue * > DataValueList ; //数据值链表
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 A, B, C配置成一样, 如果Flag=1, A, B, C根据实际配置
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
2026-03-06 16:27:58 +08:00
/////////////////////////////////////////////////////////////////////////////////////////////lnk20260305数据追踪
static QString escape_json_string ( const QString & s )
{
QString out = s ;
out . replace ( " \\ " , " \\ \\ " ) ;
out . replace ( " \" " , " \\ \" " ) ;
out . replace ( " \r " , " \\ r " ) ;
out . replace ( " \n " , " \\ n " ) ;
out . replace ( " \t " , " \\ t " ) ;
return out ;
}
// 打开追踪:次数 times( 比如 5)
void process_trace_command ( const std : : string & id , int times )
{
if ( times < = 0 ) return ;
QString qid = QString : : fromStdString ( id ) . trimmed ( ) ;
if ( qid . isEmpty ( ) ) return ;
QMutexLocker lk ( & g_trace_mutex ) ;
g_trace_map [ qid ] = times ; // 重新打开就覆盖/重置次数
}
// 查询是否要追踪
static bool trace_is_enabled ( const QString & mp_id )
{
QMutexLocker lk ( & g_trace_mutex ) ;
auto it = g_trace_map . constFind ( mp_id ) ;
return ( it ! = g_trace_map . constEnd ( ) & & it . value ( ) > 0 ) ;
}
// 命中一次并扣减;扣到 0 自动删
static void trace_hit_and_decrement ( const QString & mp_id )
{
QMutexLocker lk ( & g_trace_mutex ) ;
auto it = g_trace_map . find ( mp_id ) ;
if ( it = = g_trace_map . end ( ) ) return ;
int left = it . value ( ) ;
left - = 1 ;
if ( left < = 0 ) g_trace_map . erase ( it ) ;
else it . value ( ) = left ;
}
//追踪61850原始数据
static QString build_mms_multiline_text ( const json_block_data * data )
{
QStringList lines ;
QMapIterator < QString , double > it ( data - > mms_str_map ) ;
while ( it . hasNext ( ) ) {
it . next ( ) ;
lines < < QString ( " %1 = %2 " ) . arg ( it . key ( ) ) . arg ( it . value ( ) , 0 , ' g ' , 15 ) ;
}
return lines . join ( " \n " ) ;
}
static QString build_trace_json ( const json_block_data * data )
{
if ( ! data ) return " {} " ;
QString mms_text = build_mms_multiline_text ( data ) ;
QString json ;
json + = " { " ;
json + = QString ( " \" mp_id \" : \" %1 \" , " ) . arg ( escape_json_string ( data - > mp_id ) ) ;
json + = QString ( " \" func_type \" :%1, " ) . arg ( data - > func_type ) ;
json + = QString ( " \" data_time \" :%1, " ) . arg ( QString : : number ( ( qlonglong ) data - > time ) ) ;
json + = QString ( " \" voltage_level \" : \" %1 \" , " ) . arg ( QString : : number ( data - > voltage_level , ' f ' , 6 ) ) ;
json + = QString ( " \" dev_type \" : \" %1 \" , " ) . arg ( escape_json_string ( data - > dev_type ) ) ;
json + = QString ( " \" mms_text \" : \" %1 \" " ) . arg ( escape_json_string ( mms_text ) ) ;
json + = " } " ;
2025-05-20 16:31:12 +08:00
2026-03-06 16:27:58 +08:00
return json ;
}
static void send_trace_if_needed ( json_block_data * pdata )
{
const QString mp_id_q = pdata - > mp_id ;
if ( trace_is_enabled ( mp_id_q ) ) {
// 1) 组 json
QString jsonText = build_trace_json ( pdata ) ;
// 2) 组 KafkaData
Ckafka_data_t KafkaData ;
KafkaData . monitor_id = pdata - > monitorId ;
KafkaData . mp_id = pdata - > mp_id ;
KafkaData . strTopic = " DATA_TRACE_TOPIC " ;
KafkaData . strText = jsonText ;
kafka_data_list_mutex . lock ( ) ;
kafka_data_list . append ( KafkaData ) ;
kafka_data_list_mutex . unlock ( ) ;
// 3) 次数 -1
trace_hit_and_decrement ( mp_id_q ) ;
}
}
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 ) ) //①读取Topic, HISDATA、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 " ) ; //相别值(7: ABC三相、8: T相)
sq - > type = node4 . toElement ( ) . attribute ( " type " ) ; //参数等级
sq - > strSeq = strPhasic [ n ] ; //相别赋值 例: A、B、C
it - > SequenceList . push_back ( sq ) ; //添加 相别链表
QString strTag5 = node4 . toElement ( ) . tagName ( ) ; //Sequence节点
if ( " Sequence " = = strTag5 ) //⑤读取相别Sequence
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 " ) ; //相别值(7: ABC三相、112:线AB,BC,CA 8: T相)
sq - > type = node4 . toElement ( ) . attribute ( " type " ) ; //参数等级
sq - > strSeq = strLine [ n ] ; //相别赋值 例: AB、BC、CA
it - > SequenceList . push_back ( sq ) ; //添加 相别链表
QString strTag5 = node4 . toElement ( ) . tagName ( ) ; //Sequence节点
if ( " Sequence " = = strTag5 ) //⑤读取相别Sequence
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名称
2026-02-04 09:21:54 +08:00
ed - > desc = node . toElement ( ) . attribute ( " desc " ) ; //SOE描述
2025-05-09 16:53:07 +08:00
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 具体字段(如有定义)
}
*/
}
}
}
2026-02-02 10:39:27 +08:00
// ===== DEBUG 打印: mms_str_map (属性名 -> 值) =====
static void print_mms_str_map ( const json_block_data * data )
{
if ( ! data ) {
std : : cout < < " [DBG] json_block_data is NULL \n " ;
return ;
}
std : : cout < < " \n ========== [DBG] json_block_data.mms_str_map ========== \n " ;
std : : cout < < " [DBG] monitorId= " < < data - > monitorId
< < " func_type= " < < data - > func_type
< < " flag= " < < data - > flag
< < " time(ms)= " < < data - > time
< < " voltage_level= " < < data - > voltage_level
< < " \n " ;
std : : cout < < " [DBG] mp_id= " < < data - > mp_id . toStdString ( )
< < " dev_type= " < < data - > dev_type . toStdString ( )
< < " \n " ;
std : : cout < < " [DBG] mms_str_map size= " < < data - > mms_str_map . size ( ) < < " \n " ;
// Qt4/Qt5 都稳: QMapIterator
QMapIterator < QString , double > it ( data - > mms_str_map ) ;
while ( it . hasNext ( ) ) {
it . next ( ) ;
std : : cout < < " " < < it . key ( ) . toStdString ( ) < < " = " < < it . value ( ) < < " \n " ;
}
std : : cout < < " ====================================================== \n \n " ;
}
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
{
2026-02-02 10:39:27 +08:00
// 刚进函数就打印 mms_str_map
if ( DEBUGOPEN ) {
print_mms_str_map ( data ) ;
}
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
2026-02-02 10:39:27 +08:00
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-02-02 10:39:27 +08:00
if ( DEBUGOPEN ) printCTopicList ( ctopic_list ) ;
2026-01-27 16:58:15 +08:00
//lnk20260127 添加数据类型区分
bool typeofdata = false ;
2026-03-04 19:15:32 +08:00
bool data_have_static = data - > data_have_statistic ;
2026-01-27 16:58:15 +08:00
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
2026-03-04 19:15:32 +08:00
if ( typeofdata = = false | | data_have_static = = false ) { //不合并则处理完闪变就不处理其他数据,如果有统计数据或者数据类型区分了就继续处理其他数据
2026-01-27 16:58:15 +08:00
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 + + ;
2025-08-25 11:25:03 +08:00
//////////////////////////////////////////////////////////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 + + ;
2025-08-25 11:25:03 +08:00
//////////////////////////////////////////////////////////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 + + ;
2025-08-25 11:25:03 +08:00
//////////////////////////////////////////////////////////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-03-04 19:15:32 +08:00
if ( typeofdata = = false | | data_have_static = = false ) { //不合并则处理完闪变就不处理其他数据
2026-01-28 13:43:24 +08:00
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
2026-02-04 09:21:54 +08:00
static void format_time_ms ( long long ms , char * buf , size_t buf_len )
{
time_t sec = ms / 1000 ;
int milli = ms % 1000 ;
struct tm tm_time ;
localtime_r ( & sec , & tm_time ) ; // 线程安全
snprintf ( buf , buf_len ,
" %04d-%02d-%02d %02d:%02d:%02d.%03d " ,
tm_time . tm_year + 1900 ,
tm_time . tm_mon + 1 ,
tm_time . tm_mday ,
tm_time . tm_hour ,
tm_time . tm_min ,
tm_time . tm_sec ,
milli ) ;
}
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 )
{
2026-02-04 09:21:54 +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-01-16 16:17:01 +08:00
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 ) ) ;
2026-02-04 09:21:54 +08:00
//使用日志接口记录日志
char time_str [ 64 ] ;
format_time_ms ( time , time_str , sizeof ( time_str ) ) ;
QByteArray descBa = pEventData - > desc . toLocal8Bit ( ) ;
pthread_mutex_lock ( & mtx ) ; std : : cout < < " ggio hold lock !!!!!!!!!!! " < < std : : endl ;
const char * mp_name_raw = find_mp_name_from_mp_id ( mp_id ) ;
pthread_mutex_unlock ( & mtx ) ; std : : cout < < " ggio unlock lock !!!!!!!!!!! " < < std : : endl ;
char mp_name [ 128 ] ;
if ( mp_name_raw & & mp_name_raw [ 0 ] ! = ' \0 ' ) {
snprintf ( mp_name , sizeof ( mp_name ) , " %s " , mp_name_raw ) ;
} else {
snprintf ( mp_name , sizeof ( mp_name ) , " unknown " ) ;
}
DIY_WARNLOG_CODE ( full_key_m_d , LOG_CODE_REPORT ,
" 监测点:%s(%s),在%s发生事件:%s,事件值:%.2f " ,
mp_name , mp_id , time_str , descBa . constData ( ) , v ) ;
2025-01-16 16:17:01 +08:00
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 ( ) ; //解锁
2026-02-04 09:21:54 +08:00
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 ) ;
2026-03-12 15:28:17 +08:00
xmlinfo_list2 [ type ] - > updataflag = true ;
2025-02-14 16:44:38 +08:00
}
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 ) ;
2026-03-12 15:28:17 +08:00
snprintf ( file_name , sizeof ( file_name ) , " %s " , FILE_NAME ) ;
file_name [ sizeof ( file_name ) - 1 ] = ' \0 ' ;
2025-01-16 16:17:01 +08:00
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 ) ;
2026-03-12 15:28:17 +08:00
snprintf ( save_name , sizeof ( save_name ) , " %s " , Qsavename . toAscii ( ) . data ( ) ) ;
save_name [ sizeof ( save_name ) - 1 ] = ' \0 ' ;
2025-01-16 16:17:01 +08:00
cout < < file_name < < " !!!!!!!!!!!!!!!!!!!!!!!!!! " < < save_name < < endl ;
2025-05-28 16:09:15 +08:00
//mq日志
2025-08-19 16:36:45 +08:00
DIY_WARNLOG_CODE ( " process " , LOG_CODE_ICD_AND_DOWNLOAD , " 【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s " , TMNL_TYPE , FILE_PATH , save_name ) ;
2025-05-28 16:09:15 +08:00
2026-03-12 15:28:17 +08:00
2025-05-09 16:53:07 +08:00
// 调用web获取文件内容
2025-01-16 16:17:01 +08:00
char * fileContent = NULL ;
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 ) ;
2026-03-12 15:28:17 +08:00
if ( fileContent ! = NULL & & fileContent [ 0 ] ! = ' \0 ' ) {
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 ;
2025-05-28 16:09:15 +08:00
//mq日志
2025-08-19 16:36:45 +08:00
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 ;
2025-08-19 16:36:45 +08:00
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 ;
2025-08-19 16:36:45 +08:00
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 ) {
2025-08-19 16:36:45 +08:00
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 ) ;
2026-03-12 15:28:17 +08:00
if ( ptr ! = NULL & & ptr [ 0 ] ! = ' \0 ' ) {
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 ;
2026-03-12 15:28:17 +08:00
2025-05-29 16:36:34 +08:00
2025-08-19 16:36:45 +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 {
2026-03-12 15:28:17 +08:00
// 表示有响应,则可视为成功;根据项目需要可加更精细的判断
handleCommentResponse ( std : : string ( ptr ) ) ;
2025-05-29 16:36:34 +08:00
2025-08-19 16:36:45 +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 ( ) ) ;
2026-03-12 15:28:17 +08:00
cJSON_Delete ( j_r ) ;
2025-04-02 15:16:11 +08:00
}
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 ;
}
2026-03-12 15:28:17 +08:00
if ( NULL = = mp_id | | strlen ( mp_id ) = = 0 ) {
2025-04-02 11:48:18 +08:00
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 ) ;
2026-03-12 15:28:17 +08:00
if ( json_string = = NULL ) {
DIY_ERRORLOG_CODE ( full_key_m_d , LOG_CODE_TRANSIENT_COMM , " 【ERROR】监测点: %s暂态事件生成JSON字符串失败 " , mp_id ) ;
std : : cerr < < " Failed to print JSON object. " < < std : : endl ;
cJSON_Delete ( root ) ;
return 0 ;
}
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
// ================ 插入新功能 =========================
// ********** 新增功能开始 **********
2026-03-12 15:28:17 +08:00
if ( ptr ! = NULL & & ptr [ 0 ] ! = ' \0 ' )
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日志
2025-08-19 16:36:45 +08:00
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 ) ) {
2026-03-12 15:28:17 +08:00
DIY_ERRORLOG_CODE ( full_key_m_d , LOG_CODE_TRANSIENT_COMM , " 【ERROR】监测点: %s无法将暂态时间为%lld的暂态事件写入本地缓存 " , mp_id , start_tm ) ;
2025-09-04 16:26:00 +08:00
}
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 {
2026-03-12 15:28:17 +08:00
cJSON_Delete ( 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
// 下面继续原逻辑,不动,处理本次发送
2026-03-12 15:28:17 +08:00
if ( ptr ! = NULL & & ptr [ 0 ] ! = ' \0 ' ) {
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 ) ;
2026-03-12 15:28:17 +08:00
ptr = NULL ;
2025-04-02 11:48:18 +08:00
} 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日志
2025-08-19 16:36:45 +08:00
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 ) ) {
2026-03-12 15:28:17 +08:00
DIY_ERRORLOG_CODE ( full_key_m_d , LOG_CODE_TRANSIENT_COMM , " 【ERROR】监测点: %s无法将暂态时间为%lld的暂态事件写入本地缓存 " , mp_id , start_tm ) ;
2025-09-04 16:26:00 +08:00
}
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////////////////////////////////////////////////////////
2025-02-13 11:51:05 +08:00
void clearXmlConfigAndTopicList ( Xmldata * data ) {
2025-05-09 16:53:07 +08:00
// 清空 XmlConfig
data - > xmlcfg = XmlConfig ( ) ; // 通过重新赋值重置 xmlcfg
2025-02-13 11:51:05 +08:00
2025-05-09 16:53:07 +08:00
// 清空 topicList
2025-02-13 11:51:05 +08:00
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-02-13 11:51:05 +08:00
}
2025-05-09 16:53:07 +08:00
data - > topicList . clear ( ) ; // 清空链表
2025-02-13 11:51:05 +08:00
}
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-02-13 11:51:05 +08:00
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-02-13 11:51:05 +08:00
2025-05-09 16:53:07 +08:00
//将这个点的xmlcfg和topicList删除
2025-02-13 11:51:05 +08:00
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 ) ;
2025-02-13 11:51:05 +08:00
if ( ! ret )
{
std : : cout < < " !!!! this ledger xml config fail!!!! " < < std : : endl ;
}
2025-08-20 20:32:17 +08:00
//}
2025-02-13 11:51:05 +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