Files
microser/cfg_parse/cfg_parser.cpp

6389 lines
242 KiB
C++
Raw Normal View History

2025-01-16 16:17:01 +08:00
using namespace std;
#include <QFile>
#include <QXmlStreamWriter>
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
#include <QtXml/QDomNode>
#include <QtXml/QDomNodeList>
#include <QtCore/qglobal.h>
#include <QStringList>
#include <QSettings>
#include <QDateTime>
#include <QDir>
#include <QFileInfo>
#include <QDebug>
#include <QMutex>
#include <QMap>
#include <ctime>
#define OTL_ODBC_ODBC
#define OTL_ODBC_UNIX
#include <unistd.h>
#include "otlv4.h"
#include <stdio.h>
#include <sstream> //lnk 2024-10-16
2025-05-09 16:53:07 +08:00
#include <set> //写去重的设备类型
#include <fstream>//上传文件
2025-01-16 16:17:01 +08:00
#include "../mms/db_interface.h"
#include "../json/save2json.h"
#include "../json/mms_json_inter.h"
#include "../mms/rdb_client.h"
#include "../mms/interface.h"
2025-05-09 16:53:07 +08:00
#include "../json/cjson.h"//WW 2023-08-27新增json解析函数
2025-01-16 16:17:01 +08:00
#include "../include/curl/curl.h"
2025-05-09 16:53:07 +08:00
#include "../log4cplus/log4.h"//lnk添加log4
#include <cstring>
2025-01-16 16:17:01 +08:00
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
2025-04-30 10:22:57 +08:00
extern pt61850app_t* g_pt61850app;
extern node_t* g_node;
extern apr_pool_t* g_cfg_pool;
extern apr_pool_t* g_init_pool;
extern apr_pool_t* g_temp_dev_pool;
extern char subdir[128];
extern int g_front_seg_index;
extern unsigned int g_no_auth;
2025-05-09 16:53:07 +08:00
extern char g_onlyIP[255]; //直连某个IP仅仅为方便测试
2025-01-16 16:17:01 +08:00
2025-04-30 10:22:57 +08:00
int g_DevFlag = 0;
2025-01-16 16:17:01 +08:00
#ifdef __cplusplus
}
#endif
2025-05-09 16:53:07 +08:00
///////////////////////////////lnk20250118台账变更使用的内存池动态内存池的方式每个内存池放一个ied的所有相关内容这个方案暂不使用只保留相关实现函数
// 用于存储终端 ID 和对应的子池
2025-01-21 17:48:37 +08:00
std::list<std::pair<std::string, apr_pool_t*> > pool_list;
///////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//ZW 2023-10-10 单条补招结构
2025-01-16 16:17:01 +08:00
class RecallInfo
{
public:
long long starttime;
long long endtime;
};
2025-05-09 16:53:07 +08:00
//CZY 2023-09-17 控制命令解析
2025-04-30 10:22:57 +08:00
class ProgramParam
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QList<QString> terminal_list;//终端id列表
QString file_name;//程序下装可用下装程序在oss中的位置
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
//CZY 2023-09-17 控制命令解析
2025-04-30 10:22:57 +08:00
class RecallParam
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString mp_id;//监测点id
QString start;//补招数据起始时间
QString end;//补招数据结束时间
int voltage;//暂态数据标志
int stat;//稳态数据标志
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
//CZY 2023-10-12 装置识别码与密钥
2025-01-16 16:17:01 +08:00
class terminal_ext //
{
public:
2025-05-09 16:53:07 +08:00
char terminal_identify_code[100];//终端识别码
char terminal_key[100];//终端密钥
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class CJournalRecall //日志补招结构类
2025-01-16 16:17:01 +08:00
{
public:
2025-05-09 16:53:07 +08:00
QString MonitorID; //线路监测点号
QString StartTime; //数据补招起始时间
QString EndTime; //数据补招结束时间
QString STEADY; //补招历史统计数据标识 0-不补招1-补招
QString VOLTAGE; //补招暂态事件标识 0-不补招1-补招
2025-01-16 16:17:01 +08:00
};
/*lnk 2024-10-15 */
2025-05-09 16:53:07 +08:00
class ledger_monitor //监测点台账
2025-01-16 16:17:01 +08:00
{
public:
char monitor_id[64];
char terminal_code[64];
char monitor_name[64];
char logical_device_seq[64];
char voltage_level[64];
char terminal_connect[64];
char timestamp[64];
char status[255];
2025-05-09 16:53:07 +08:00
char count_cfg[64]; //不是台账的一部分,用来记录数据库或业务中台的台账数量
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class terminal_dev //终端台账
2025-01-16 16:17:01 +08:00
{
public:
char terminal_id[64];
char terminal_code[64];
char org_name[64];
char maint_name[64];
char station_name[64];
char tmnl_factory[64];
char tmnl_status[64];
char dev_type[64];
char dev_key[255];
char dev_series[255];
char addr_str[64];
char port[64];
char timestamp[64];
2025-05-09 16:53:07 +08:00
//lnk20250210添加进程号
2025-02-10 17:03:15 +08:00
char processNo[64];
2025-01-16 16:17:01 +08:00
ledger_monitor line[10];
2025-05-09 16:53:07 +08:00
char count_cfg[64]; //不是台账的一部分,用来记录数据库或业务中台的台账数量
2025-01-16 16:17:01 +08:00
};
2025-05-09 16:53:07 +08:00
class icd_model //icd模型
2025-01-16 16:17:01 +08:00
{
public:
char model_id[64];
char tmnl_type[64];
2025-05-09 16:53:07 +08:00
char tmnl_type_id[64]; //不使用
char tmnl_factory[64]; //不使用
2025-01-16 16:17:01 +08:00
char file_name[128];
char file_path[128];
char timestamp[64];
};
/*lnk 2024-10-15 */
2025-05-09 16:53:07 +08:00
list<CJournalRecall> g_StatisticLackList; //日志补招结构类链表
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QMutex g_StatisticLackList_list_mutex; //recall队列数据锁
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QString DEVIE_CONFIG_FN = QString("Device_Config.xml");//不用
QString LINE_CONFIG_FN = QString("Line_Config.xml");//不用
QString JSON_CONFIG_FN_old = QString("JiangSu_Config.xml");//默认映射文件
QString THREE_SECS_CONFIG_FN = QString("Trigger3S.xml");//实时数据用
QString RECALL_CONFIG_FN = QString("Recall.xml");//不用
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//lnk20241220创建一个用来台账更新的文件保证数据完整的情况下更新台账
2025-01-17 17:10:18 +08:00
std::string LEDGER_UPDATE_FN = "LedgerUpdate.log";
2025-01-16 16:17:01 +08:00
const int MAX_CPUNO = 10;
2025-05-09 16:53:07 +08:00
//lnk20250121终端台账数量配置
int IED_COUNT = 300; //默认300
2025-03-07 18:27:03 +08:00
2025-03-04 17:29:04 +08:00
extern int INITFLAG;
2025-01-21 17:48:37 +08:00
2025-05-09 16:53:07 +08:00
//lnk2024-8-14添加角型接线标志,0不存在角形接线1存在角形接线
2025-02-14 16:44:38 +08:00
int isdelta_flag = 0;
2025-01-16 16:17:01 +08:00
//////CZY 2023-09-06 config
2025-05-09 16:53:07 +08:00
//多前置flag:1为开启,0为关闭
2025-01-16 16:17:01 +08:00
int MULTIPLE_NODE_FLAG = 1;
extern const char* PROGRAM_VERSION;
extern int FRONT_MP_NUM;
int ACCOUNT_UPDATE_INTERVAL;
char* ACCOUNT_UPDATE_LAST_TIME;
int MULIT_NODE_INTERVAL;
int COMMUNICATION_LOG_STATUS_TIME;
int COMMUNICATION_LOG_ABNORMAL_TIME;
2025-05-09 16:53:07 +08:00
char* POSTGRES_DATABASE;//数据库库名
char* POSTGRES_USERNAME;//数据库用户名
char* POSTGRES_PASSWORD;//数据库密码
char* POSTGRES_SCHEMA;//数据库模式名
char* POSTGRES_DNSNAME;//取postgres/guass库
char* POSTGRES_TABLEPREFIX;//表名前缀
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
char* CLIENT_ID;//中台CLIENT_ID
char* CLIENT_SECRET;//中台CLIENT_SECRET
char* TOKEN_URL;//中台取token接口
char* DEVICE_URL;//中台取终端接口
char* GRANT_TYPE;//中台GRANT_TYPE
2025-01-16 16:17:01 +08:00
char* UDS_UPLOAD_URL;
char* UDS_DOWNLOAD_URL;
char* UDS_DELETE_URL;
int FILE_FLAG;
int SEND_FLAG;
int FRONT_INST;
char* FRONT_IP;
int CITY_FLAG;
int recall_len;
int recall_sta;
int recall_daily;
char* BROKER_LIST;
char* TOPIC_STAT;
char* TOPIC_PST;
char* TOPIC_PLT;
char* TOPIC_EVENT;
char* TOPIC_ALARM;
char* TOPIC_SNG;
//lnk20241220
char* TOPIC_RTDATA;
char* PROTOCOL;
char* MECHANISMS;
char* KEYTAB_FILE;
char* SERVICE_NAME;
char* PRINCIPAL;
char* DOMAIN_NAME;
extern int g_front_seg_index;
extern int g_front_seg_num;
2025-05-09 16:53:07 +08:00
/*移植配置变量lnk10-9*/
//生产者
2025-01-16 16:17:01 +08:00
std::string G_ROCKETMQ_PRODUCER = "";//rocketmq producer
std::string G_ROCKETMQ_IPPORT = "";//rocketmq ip+port
std::string G_ROCKETMQ_TOPIC = "";//topie
std::string G_ROCKETMQ_TAG = "";//tag
std::string G_ROCKETMQ_KEY = "";//key
int QUEUENUM = 0;
std::string BROKERNAME = "";
2025-05-09 16:53:07 +08:00
//消费者
2025-01-16 16:17:01 +08:00
std::string G_ROCKETMQ_CONSUMER = "";//rocketmq consumer
std::string G_MQCONSUMER_IPPORT = "";//consumer ip+port
std::string G_MQCONSUMER_TOPIC_RT = "";//consumer topie
std::string G_MQCONSUMER_TAG_RT = "";//consumer tag
std::string G_MQCONSUMER_KEY_RT = "";//consumer key
std::string G_MQCONSUMER_ACCESSKEY = "";
std::string G_MQCONSUMER_SECRETKEY = "";
std::string G_MQCONSUMER_CHANNEL = "";
std::string G_MQCONSUMER_TOPIC_UD = "";//consumer topie
std::string G_MQCONSUMER_TAG_UD = "";//consumer tag
std::string G_MQCONSUMER_KEY_UD = "";//consumer key
std::string G_MQCONSUMER_TOPIC_RC = "";//consumer topie
std::string G_MQCONSUMER_TAG_RC = "";//consumer tag
std::string G_MQCONSUMER_KEY_RC = "";//consumer key
std::string G_MQCONSUMER_TOPIC_SET = "";//consumer topie
std::string G_MQCONSUMER_TAG_SET = "";//consumer tag
std::string G_MQCONSUMER_KEY_SET = "";//consumer key
2025-02-25 16:33:11 +08:00
std::string G_LOG_TOPIC = "";//topie
std::string G_LOG_TAG = "";//tag
std::string G_LOG_KEY = "";//key
std::string G_MQCONSUMER_TOPIC_LOG = "";//consumer topie
std::string G_MQCONSUMER_TAG_LOG = "";//consumer tag
std::string G_MQCONSUMER_KEY_LOG = "";//consumer key
2025-03-11 21:07:17 +08:00
std::string G_CONNECT_TOPIC = "";//consumer topie
std::string G_CONNECT_TAG = "";//consumer tag
std::string G_CONNECT_KEY = "";//consumer key
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//心跳
std::string Heart_Beat_Topic = "";
std::string Heart_Beat_Tag = "";
std::string Heart_Beat_Key = "";
//消息响应
std::string Topic_Reply_Topic = "";
std::string Topic_Reply_Tag = "";
std::string Topic_Reply_Key = "";
2025-01-16 16:17:01 +08:00
int G_TEST_FLAG = 0;
int G_TEST_NUM = 0;
2025-05-09 16:53:07 +08:00
int TEST_PORT = 11000;//用于当前进程登录测试shell的端口
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
std::string G_TEST_LIST = "";//测试用的发送实际数据的终端列表
std::vector<std::string> TESTARRAY;//解析的列表数组
2025-03-28 13:43:55 +08:00
2025-05-09 16:53:07 +08:00
//终端和监测点的状态筛选
2025-01-16 16:17:01 +08:00
std::string TERMINAL_STATUS = "";
std::string MONITOR_STATUS = "";
std::string ICD_FLAG = "";
2025-05-09 16:53:07 +08:00
//保留socket连接设置开关
2025-01-16 16:17:01 +08:00
int SOCKET_PORT = 13000;
int SOCKETENABLE = 0;
2025-05-09 16:53:07 +08:00
//添加http配置和台账配置lnk20241031
2025-01-16 16:17:01 +08:00
int HTTPENABLE = 0;
std::string HTTP_IP = "";
int HTTP_PORT = 12000;
2025-05-09 16:53:07 +08:00
/*添加web接口lnk202411-6*/
2025-01-16 16:17:01 +08:00
std::string WEB_DEVICE = "";
std::string WEB_ICD = "";
2025-05-09 16:53:07 +08:00
std::string WEB_INTEGRITY = ""; //暂不使用
2025-01-16 16:17:01 +08:00
std::string WEB_COMFLAG = "";
std::string WEB_EVENT = "";
std::string WEB_FILEUPLOAD = "";
std::string WEB_FILEDOWNLOAD = "";
2025-05-09 16:53:07 +08:00
//lnk20250115添加台账锁
2025-01-16 16:17:01 +08:00
extern pthread_mutex_t mtx;
/*lnk 2024-10-21 */
2025-03-06 18:41:48 +08:00
std::string intToString(int number);
2025-01-16 16:17:01 +08:00
//////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
extern int server_socket; //Web Socket服务端实例
extern unsigned int g_node_id; //前置程序类型(100-500)
2025-01-16 16:17:01 +08:00
//WW 2023-08-20 end
////////////////////////////////////////////////////////////////////////////////////////////////////
void parse_log_switch_ini(unsigned int* error, unsigned int* warn, unsigned int* info)
{
QString pt61850netd_pqfe_IniFilename = QString("../etc/pt61850netd_pqfe.ini");
QSettings settings(pt61850netd_pqfe_IniFilename, QSettings::IniFormat);
settings.beginGroup("Log");
*error = settings.value("error", 0).toUInt();
*warn = settings.value("warn", 0).toUInt();
*info = settings.value("info", 0).toUInt();
g_no_auth = settings.value("no_auth", 0).toUInt();
g_DevFlag = settings.value("DevFlag", 0).toUInt();
settings.endGroup();
}
2025-05-09 16:53:07 +08:00
//lnk20250328添加测试列表用的函数
2025-03-28 13:43:55 +08:00
void parseTestList(const std::string& input) {
2025-05-09 16:53:07 +08:00
TESTARRAY.clear(); // 清空旧数据
2025-03-28 13:43:55 +08:00
size_t start = 0;
size_t end = 0;
while ((end = input.find(',', start)) != std::string::npos) {
std::string id = input.substr(start, end - start);
if (!id.empty()) {
TESTARRAY.push_back(id);
std::cout << "use realdata device id:" << id << std::endl;
}
start = end + 1;
}
2025-05-09 16:53:07 +08:00
// 添加最后一个 ID如果没有逗号结尾
2025-03-28 13:43:55 +08:00
if (start < input.length()) {
std::string lastId = input.substr(start);
if (!lastId.empty()) {
TESTARRAY.push_back(lastId);
std::cout << "use realdata device id:" << lastId << std::endl;
}
}
}
2025-01-16 16:17:01 +08:00
//CZY 2023-09-06 config
void init_config() {
QByteArray ba;
2025-03-28 13:43:55 +08:00
QString MyKafkaIniFilename = QString("../etc/config/") + QString("mykafka.ini"); //+QString::fromAscii(subdir)
2025-01-16 16:17:01 +08:00
QSettings settings(MyKafkaIniFilename, QSettings::IniFormat);
ACCOUNT_UPDATE_INTERVAL = settings.value("AccountUpdate/Interval", 0).toInt();
qDebug() << "Read ACCOUNT_UPDATE_INTERVAL:" << ACCOUNT_UPDATE_INTERVAL << endl;
ba = settings.value("AccountUpdate/LastUpdateTime", "").toString().toLatin1();
ACCOUNT_UPDATE_LAST_TIME = strdup(ba.data());
qDebug() << "Read ACCOUNT_UPDATE_LAST_TIME:" << ACCOUNT_UPDATE_LAST_TIME << endl;
MULIT_NODE_INTERVAL = settings.value("MultiNode/Interval", 0).toInt();
qDebug() << "Read MULIT_NODE_INTERVAL:" << MULIT_NODE_INTERVAL << endl;
SEND_FLAG = settings.value("Flag/SendFlag", 0).toInt();
qDebug() << "Read SEND_FLAG:" << SEND_FLAG << endl;
FILE_FLAG = settings.value("Flag/FileFlag", 0).toInt();
qDebug() << "Read FILE_FLAG:" << FILE_FLAG << endl;
FRONT_INST = settings.value("Flag/FrontInst", 0).toInt();
qDebug() << "Read FRONT_INST:" << FRONT_INST << endl;
ba = settings.value("Flag/FrontIP", "").toString().toLatin1();
FRONT_IP = strdup(ba.data());
qDebug() << "Read FRONT_IP:" << FRONT_IP << endl;
CITY_FLAG = settings.value("Flag/CityFlag", 0).toInt();
qDebug() << "Read CITY_FLAG:" << CITY_FLAG << endl;
2025-05-09 16:53:07 +08:00
//台账配置lnk20241031//////////////////////////////////////////////////////////////
2025-01-16 16:17:01 +08:00
TERMINAL_STATUS = settings.value("Ledger/TerminalStatus", 0).toString().toStdString();
std::cout << "Read TERMINAL_STATUS:" << TERMINAL_STATUS << std::endl;
MONITOR_STATUS = settings.value("Ledger/MonitorStatus", 0).toString().toStdString();
std::cout << "Read MONITOR_STATUS:" << MONITOR_STATUS << std::endl;
ICD_FLAG = settings.value("Ledger/IcdFlag", 0).toString().toStdString();
std::cout << "Read ICD_FLAG:" << ICD_FLAG << std::endl;
2025-01-21 17:48:37 +08:00
IED_COUNT = settings.value("Ledger/IedCount", 0).toInt();
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//////////////////////////////////////////////////添加socket开关///////////////////
2025-01-16 16:17:01 +08:00
SOCKETENABLE = settings.value("Socket/SocketEnable", 0).toInt();
SOCKET_PORT = settings.value("Socket/SocketPort", 0).toInt();
2025-05-09 16:53:07 +08:00
//////添加http配置//////////////////////////////////////////////////////////////////
2025-01-16 16:17:01 +08:00
HTTPENABLE = settings.value("Http/HttpEnable", 0).toInt();
ba = settings.value("Http/HttpIp", "").toString().toLatin1();
HTTP_IP = strdup(ba.data());
std::cout << "Read HTTP_IP:" << HTTP_IP << std::endl;
HTTP_PORT = settings.value("Http/HttpPort", 0).toInt();
std::cout << "Read HTTP_PORT:" << HTTP_PORT << std::endl;
ba = settings.value("Http/WebDevice", "").toString().toLatin1();
WEB_DEVICE = strdup(ba.data());
std::cout << "Read WEB_DEVICE:" << WEB_DEVICE << std::endl;
ba = settings.value("Http/WebIcd", "").toString().toLatin1();
WEB_ICD = strdup(ba.data());
std::cout << "Read WEB_ICD:" << WEB_ICD << std::endl;
ba = settings.value("Http/WebIntegrity", "").toString().toLatin1();
WEB_INTEGRITY = strdup(ba.data());
std::cout << "Read WEB_INTEGRITY:" << WEB_INTEGRITY << std::endl;
ba = settings.value("Http/WebComflag", "").toString().toLatin1();
WEB_COMFLAG = strdup(ba.data());
std::cout << "Read WEB_COMFLAG:" << WEB_COMFLAG << std::endl;
ba = settings.value("Http/WebEvent", "").toString().toLatin1();
WEB_EVENT = strdup(ba.data());
std::cout << "Read WEB_EVENT:" << WEB_EVENT << std::endl;
ba = settings.value("Http/WebFileupload", "").toString().toLatin1();
WEB_FILEUPLOAD = strdup(ba.data());
std::cout << "Read WEB_FILEUPLOAD:" << WEB_FILEUPLOAD << std::endl;
ba = settings.value("Http/WebFiledownload", "").toString().toLatin1();
WEB_FILEDOWNLOAD = strdup(ba.data());
std::cout << "Read WEB_FILEDOWNLOAD:" << WEB_FILEDOWNLOAD << std::endl;
///////////////////////////////////////////////////////////////////////////////////////////////////////
recall_len = settings.value("Recall/recall_lenth", 0).toInt();
qDebug() << "Read recall_lenth:" << recall_len << endl;
recall_sta = settings.value("Recall/recall_start", 0).toInt();
qDebug() << "Read recall_start:" << recall_sta << endl;
recall_daily = settings.value("Recall/recall_dailytime", 0).toInt();
qDebug() << "Read recall_dailytime:" << recall_daily << endl;
COMMUNICATION_LOG_STATUS_TIME = settings.value("CommunicationLog/StatusRecordDuration", 0).toInt();
qDebug() << "Read COMMUNICATION_LOG_STATUS_TIME:" << COMMUNICATION_LOG_STATUS_TIME << endl;
COMMUNICATION_LOG_ABNORMAL_TIME = settings.value("CommunicationLog/AbnormalRecordDuration", 0).toInt();
qDebug() << "Read COMMUNICATION_LOG_ABNORMAL_TIME:" << COMMUNICATION_LOG_ABNORMAL_TIME << endl;
ba = settings.value("Postgres/Database", "").toString().toLatin1();
POSTGRES_DATABASE = strdup(ba.data());
ba = settings.value("Postgres/Username", "").toString().toLatin1();
POSTGRES_USERNAME = strdup(ba.data());
ba = settings.value("Postgres/Password", "").toString().toLatin1();
POSTGRES_PASSWORD = strdup(ba.data());
ba = settings.value("Postgres/Schema", "").toString().toLatin1();
POSTGRES_SCHEMA = strdup(ba.data());
ba = settings.value("Postgres/Dnsname", "").toString().toLatin1();
POSTGRES_DNSNAME = strdup(ba.data());
ba = settings.value("Postgres/TablePrefix", "").toString().toLatin1();
POSTGRES_TABLEPREFIX = strdup(ba.data());
qDebug() << "Read POSTGRES_DATABASE:" << POSTGRES_DATABASE << endl;
qDebug() << "Read POSTGRES_USERNAME:" << POSTGRES_USERNAME << endl;
qDebug() << "Read POSTGRES_PASSWORD:" << POSTGRES_PASSWORD << endl;
qDebug() << "Read POSTGRES_SCHEMA:" << POSTGRES_SCHEMA << endl;
qDebug() << "Read POSTGRES_DNSNAME:" << POSTGRES_DNSNAME << endl;
qDebug() << "Read POSTGRES_TABLEPREFIX:" << POSTGRES_TABLEPREFIX << endl;
ba = settings.value("Oss/OssEndpoint", "").toString().toLatin1();
OSS_ENDPOINT = strdup(ba.data());
ba = settings.value("Oss/AccessKeyID", "").toString().toLatin1();
ACCESS_KEY_ID = strdup(ba.data());
ba = settings.value("Oss/AccessKeySecret", "").toString().toLatin1();
ACCESS_KEY_SECRET = strdup(ba.data());
ba = settings.value("Oss/BucketName", "").toString().toLatin1();
BUCKET_NAME = strdup(ba.data());
qDebug() << "Read OSS_ENDPOINT:" << OSS_ENDPOINT << endl;
qDebug() << "Read ACCESS_KEY_ID:" << ACCESS_KEY_ID << endl;
qDebug() << "Read ACCESS_KEY_SECRET:" << ACCESS_KEY_SECRET << endl;
qDebug() << "Read BUCKET_NAME:" << BUCKET_NAME << endl;
ba = settings.value("Kafka/brokerlist", "").toString().toLatin1();
BROKER_LIST = strdup(ba.data());
ba = settings.value("Kafka/HisTopic", "").toString().toLatin1();
TOPIC_STAT = strdup(ba.data());
ba = settings.value("Kafka/PSTTopic", "").toString().toLatin1();
TOPIC_PST = strdup(ba.data());
ba = settings.value("Kafka/PLTTopic", "").toString().toLatin1();
TOPIC_PLT = strdup(ba.data());
ba = settings.value("Kafka/EventTopic", "").toString().toLatin1();
TOPIC_EVENT = strdup(ba.data());
ba = settings.value("Kafka/AlmTopic", "").toString().toLatin1();
TOPIC_ALARM = strdup(ba.data());
ba = settings.value("Kafka/SngTopic", "").toString().toLatin1();
TOPIC_SNG = strdup(ba.data());
ba = settings.value("Kafka/RTDataTopic", "").toString().toLatin1();
TOPIC_RTDATA = strdup(ba.data());
qDebug() << "Read BROKER_LIST:" << BROKER_LIST << endl;
qDebug() << "Read TOPIC_STAT:" << TOPIC_STAT << endl;
qDebug() << "Read TOPIC_PST:" << TOPIC_PST << endl;
qDebug() << "Read TOPIC_PLT:" << TOPIC_PLT << endl;
qDebug() << "Read TOPIC_EVENT:" << TOPIC_EVENT << endl;
qDebug() << "Read TOPIC_ALARM:" << TOPIC_ALARM << endl;
qDebug() << "Read TOPIC_SNG:" << TOPIC_SNG << endl;
qDebug() << "Read TOPIC_RTDATA:" << TOPIC_RTDATA << endl;
ba = settings.value("Kafka/Protocol", "").toString().toLatin1();
PROTOCOL = strdup(ba.data());
ba = settings.value("Kafka/Mechanisms", "").toString().toLatin1();
MECHANISMS = strdup(ba.data());
ba = settings.value("Kafka/KeytabFile", "").toString().toLatin1();
KEYTAB_FILE = strdup(ba.data());
ba = settings.value("Kafka/ServiceName", "").toString().toLatin1();
SERVICE_NAME = strdup(ba.data());
ba = settings.value("Kafka/Principal", "").toString().toLatin1();
PRINCIPAL = strdup(ba.data());
ba = settings.value("Kafka/DomainName", "").toString().toLatin1();
DOMAIN_NAME = strdup(ba.data());
qDebug() << "Read PROTOCOL:" << PROTOCOL << endl;
qDebug() << "Read MECHANISMS:" << MECHANISMS << endl;
qDebug() << "Read KEYTAB_FILE:" << KEYTAB_FILE << endl;
qDebug() << "Read SERVICE_NAME:" << SERVICE_NAME << endl;
qDebug() << "Read PRINCIPAL:" << PRINCIPAL << endl;
qDebug() << "Read DOMAIN_NAME:" << DOMAIN_NAME << endl;
ba = settings.value("Web/ClientId", "").toString().toLatin1();
CLIENT_ID = strdup(ba.data());
ba = settings.value("Web/ClientSecret", "").toString().toLatin1();
CLIENT_SECRET = strdup(ba.data());
ba = settings.value("Web/TokenUrl", "").toString().toLatin1();
TOKEN_URL = strdup(ba.data());
ba = settings.value("Web/DeviceUrl", "").toString().toLatin1();
DEVICE_URL = strdup(ba.data());
ba = settings.value("Web/GrantType", "").toString().toLatin1();
GRANT_TYPE = strdup(ba.data());
qDebug() << "Read CLIENT_ID:" << CLIENT_ID << endl;
qDebug() << "Read CLIENT_SECRET:" << CLIENT_SECRET << endl;
qDebug() << "Read TOKEN_URL:" << TOKEN_URL << endl;
qDebug() << "Read DEVICE_URL:" << DEVICE_URL << endl;
qDebug() << "Read GRANT_TYPE:" << GRANT_TYPE << endl;
ba = settings.value("Uds/UdsUploadUrl", "").toString().toLatin1();
UDS_UPLOAD_URL = strdup(ba.data());
ba = settings.value("Uds/UdsDownloadUrl", "").toString().toLatin1();
UDS_DOWNLOAD_URL = strdup(ba.data());
qDebug() << "Read UDS_UPLOAD_URL:" << UDS_UPLOAD_URL << endl;
qDebug() << "Read UDS_DOWNLOAD_URL:" << UDS_DOWNLOAD_URL << endl;
2025-05-09 16:53:07 +08:00
/*添加rocketmq的解析10-9 */////////////////////////////////////////////////////////////////
//生产者
2025-01-16 16:17:01 +08:00
ba = settings.value("RocketMq/producer", "").toString().toLatin1();
G_ROCKETMQ_PRODUCER = strdup(ba.data());
ba = settings.value("RocketMq/Ipport", "").toString().toLatin1();
G_ROCKETMQ_IPPORT = strdup(ba.data());
ba = settings.value("RocketMq/Topic", "").toString().toLatin1();
G_ROCKETMQ_TOPIC = strdup(ba.data());
ba = settings.value("RocketMq/Tag", "").toString().toLatin1();
G_ROCKETMQ_TAG = strdup(ba.data());
ba = settings.value("RocketMq/Key", "").toString().toLatin1();
G_ROCKETMQ_KEY = strdup(ba.data());
QUEUENUM = settings.value("RocketMq/Queuenum", 0).toInt();
2025-05-09 16:53:07 +08:00
//心跳
ba = settings.value("RocketMq/Heart_Beat_Topic", "").toString().toLatin1();
Heart_Beat_Topic = strdup(ba.data());
ba = settings.value("RocketMq/Heart_Beat_Tag", "").toString().toLatin1();
Heart_Beat_Tag = strdup(ba.data());
ba = settings.value("RocketMq/Heart_Beat_Key", "").toString().toLatin1();
Heart_Beat_Key = strdup(ba.data());
//消息响应
ba = settings.value("RocketMq/Topic_Reply_Topic", "").toString().toLatin1();
Topic_Reply_Topic = strdup(ba.data());
ba = settings.value("RocketMq/Topic_Reply_Tag", "").toString().toLatin1();
Topic_Reply_Tag = strdup(ba.data());
ba = settings.value("RocketMq/Topic_Reply_Key", "").toString().toLatin1();
Topic_Reply_Key = strdup(ba.data());
//消费者
2025-01-16 16:17:01 +08:00
ba = settings.value("RocketMq/consumer", "").toString().toLatin1();
G_ROCKETMQ_CONSUMER = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerIpport", "").toString().toLatin1();
G_MQCONSUMER_IPPORT = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTopicRT", "").toString().toLatin1();
G_MQCONSUMER_TOPIC_RT = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTagRT", "").toString().toLatin1();
G_MQCONSUMER_TAG_RT = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerKeyRT", "").toString().toLatin1();
G_MQCONSUMER_KEY_RT = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerAccessKey", "").toString().toLatin1();
G_MQCONSUMER_ACCESSKEY = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerSecretKey", "").toString().toLatin1();
G_MQCONSUMER_SECRETKEY = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerChannel", "").toString().toLatin1();
G_MQCONSUMER_CHANNEL = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTopicUD", "").toString().toLatin1();
G_MQCONSUMER_TOPIC_UD = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTagUD", "").toString().toLatin1();
G_MQCONSUMER_TAG_UD = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerKeyUD", "").toString().toLatin1();
G_MQCONSUMER_KEY_UD = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTopicRC", "").toString().toLatin1();
G_MQCONSUMER_TOPIC_RC = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTagRC", "").toString().toLatin1();
G_MQCONSUMER_TAG_RC = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerKeyRC", "").toString().toLatin1();
G_MQCONSUMER_KEY_RC = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTopicSET", "").toString().toLatin1();
G_MQCONSUMER_TOPIC_SET = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTagSET", "").toString().toLatin1();
G_MQCONSUMER_TAG_SET = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerKeySET", "").toString().toLatin1();
G_MQCONSUMER_KEY_SET = strdup(ba.data());
2025-02-25 16:33:11 +08:00
ba = settings.value("RocketMq/ConsumerTopicLOG", "").toString().toLatin1();
G_MQCONSUMER_TOPIC_LOG = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerTagLOG", "").toString().toLatin1();
G_MQCONSUMER_TAG_LOG = strdup(ba.data());
ba = settings.value("RocketMq/ConsumerKeyLOG", "").toString().toLatin1();
G_MQCONSUMER_KEY_LOG = strdup(ba.data());
ba = settings.value("RocketMq/LOGTopic", "").toString().toLatin1();
G_LOG_TOPIC = strdup(ba.data());
ba = settings.value("RocketMq/LOGTag", "").toString().toLatin1();
G_LOG_TAG = strdup(ba.data());
ba = settings.value("RocketMq/LOGKey", "").toString().toLatin1();
G_LOG_KEY = strdup(ba.data());
2025-03-11 21:07:17 +08:00
ba = settings.value("RocketMq/CONNECTTopic", "").toString().toLatin1();
G_CONNECT_TOPIC = strdup(ba.data());
ba = settings.value("RocketMq/CONNECTTag", "").toString().toLatin1();
G_CONNECT_TAG = strdup(ba.data());
ba = settings.value("RocketMq/CONNECTKey", "").toString().toLatin1();
G_CONNECT_KEY = strdup(ba.data());
2025-05-09 16:53:07 +08:00
//MQ测试
2025-01-16 16:17:01 +08:00
G_TEST_FLAG = settings.value("RocketMq/Testflag", 0).toInt();
G_TEST_NUM = settings.value("RocketMq/Testnum", 0).toInt();
2025-03-28 13:43:55 +08:00
ba = settings.value("RocketMq/TestList", 0).toString().toLatin1();
G_TEST_LIST = strdup(ba.data());
2025-05-09 16:53:07 +08:00
parseTestList(G_TEST_LIST);//解析测试用的终端列表
2025-03-28 13:43:55 +08:00
2025-05-09 16:53:07 +08:00
//测试shell
2025-01-16 16:17:01 +08:00
TEST_PORT = settings.value("RocketMq/TestPort", 0).toInt();
2025-05-09 16:53:07 +08:00
//生产者相关打印
2025-01-16 16:17:01 +08:00
std::cout << "Read G_ROCKETMQ_PRODUCER:" << G_ROCKETMQ_PRODUCER << std::endl;
std::cout << "Read G_ROCKETMQ_IPPORT:" << G_ROCKETMQ_IPPORT << std::endl;
std::cout << "Read G_ROCKETMQ_TOPIC:" << G_ROCKETMQ_TOPIC << std::endl;
std::cout << "Read G_ROCKETMQ_TAG:" << G_ROCKETMQ_TAG << std::endl;
std::cout << "Read G_ROCKETMQ_KEY:" << G_ROCKETMQ_KEY << std::endl;
std::cout << "Read QUEUENUM:" << QUEUENUM << std::endl;
2025-02-25 16:33:11 +08:00
std::cout << "Read G_LOG_TOPIC:" << G_LOG_TOPIC << std::endl;
std::cout << "Read G_LOG_TAG:" << G_LOG_TAG << std::endl;
std::cout << "Read G_LOG_KEY:" << G_LOG_KEY << std::endl;
2025-03-11 21:07:17 +08:00
std::cout << "Read G_CONNECT_TOPIC:" << G_CONNECT_TOPIC << std::endl;
std::cout << "Read G_CONNECT_TAG:" << G_CONNECT_TAG << std::endl;
std::cout << "Read G_CONNECT_KEY:" << G_CONNECT_KEY << std::endl;
2025-05-09 16:53:07 +08:00
//消费者相关打印
2025-01-16 16:17:01 +08:00
std::cout << "Read G_ROCKETMQ_CONSUMER:" << G_ROCKETMQ_CONSUMER << std::endl;
std::cout << "Read G_MQCONSUMER_IPPORT:" << G_MQCONSUMER_IPPORT << std::endl;
std::cout << "Read G_MQCONSUMER_TOPIC_RT:" << G_MQCONSUMER_TOPIC_RT << std::endl;
std::cout << "Read G_MQCONSUMER_TAG_RT:" << G_MQCONSUMER_TAG_RT << std::endl;
std::cout << "Read G_MQCONSUMER_KEY_RT:" << G_MQCONSUMER_KEY_RT << std::endl;
std::cout << "Read G_MQCONSUMER_ACCESSKEY:" << G_MQCONSUMER_ACCESSKEY << std::endl;
std::cout << "Read G_MQCONSUMER_SECRETKEY:" << G_MQCONSUMER_SECRETKEY << std::endl;
std::cout << "Read G_MQCONSUMER_CHANNEL:" << G_MQCONSUMER_CHANNEL << std::endl;
std::cout << "Read G_MQCONSUMER_TOPIC_UD:" << G_MQCONSUMER_TOPIC_UD << std::endl;
std::cout << "Read G_MQCONSUMER_TAG_UD:" << G_MQCONSUMER_TAG_UD << std::endl;
std::cout << "Read G_MQCONSUMER_KEY_UD:" << G_MQCONSUMER_KEY_UD << std::endl;
std::cout << "Read G_MQCONSUMER_TOPIC_RC:" << G_MQCONSUMER_TOPIC_RC << std::endl;
std::cout << "Read G_MQCONSUMER_TAG_RC:" << G_MQCONSUMER_TAG_RC << std::endl;
std::cout << "Read G_MQCONSUMER_KEY_RC:" << G_MQCONSUMER_KEY_RC << std::endl;
std::cout << "Read G_MQCONSUMER_TOPIC_SET:" << G_MQCONSUMER_TOPIC_SET << std::endl;
std::cout << "Read G_MQCONSUMER_TAG_SET:" << G_MQCONSUMER_TAG_SET << std::endl;
std::cout << "Read G_MQCONSUMER_KEY_SET:" << G_MQCONSUMER_KEY_SET << std::endl;
2025-02-25 16:33:11 +08:00
std::cout << "Read G_MQCONSUMER_TOPIC_LOG:" << G_MQCONSUMER_TOPIC_LOG << std::endl;
std::cout << "Read G_MQCONSUMER_TAG_LOG:" << G_MQCONSUMER_TAG_LOG << std::endl;
std::cout << "Read G_MQCONSUMER_KEY_LOG:" << G_MQCONSUMER_KEY_LOG << std::endl;
2025-05-09 16:53:07 +08:00
//Mq测试相关打印
2025-01-16 16:17:01 +08:00
std::cout << "Read G_TEST_FLAG:" << G_TEST_FLAG << std::endl;
std::cout << "Read G_TEST_NUM:" << G_TEST_NUM << std::endl;
2025-05-09 16:53:07 +08:00
//20241212lnk添加多前置
2025-01-16 16:17:01 +08:00
if (g_front_seg_index != 0 && g_front_seg_num != 0) {
MULTIPLE_NODE_FLAG = 1;
2025-03-05 17:47:47 +08:00
std::cout << "this is multiple process of index:" << g_front_seg_index << std::endl;
2025-01-16 16:17:01 +08:00
}
else{
MULTIPLE_NODE_FLAG = 0;
2025-03-05 17:47:47 +08:00
std::cout << "this is single process" << std::endl;
2025-01-16 16:17:01 +08:00
}
2025-02-26 16:39:10 +08:00
2025-05-09 16:53:07 +08:00
//20250109lnk添加进程测试打印端口
if (g_node_id == STAT_DATA_BASE_NODE_ID)//统计采集
2025-01-16 16:17:01 +08:00
TEST_PORT = TEST_PORT + STAT_DATA_BASE_NODE_ID + g_front_seg_index;
2025-05-09 16:53:07 +08:00
else if (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) {//补召
2025-01-16 16:17:01 +08:00
TEST_PORT = TEST_PORT + RECALL_HIS_DATA_BASE_NODE_ID + g_front_seg_index;
}
2025-05-09 16:53:07 +08:00
else if (g_node_id == THREE_SECS_DATA_BASE_NODE_ID) {//3秒采集
2025-01-16 16:17:01 +08:00
TEST_PORT = TEST_PORT + THREE_SECS_DATA_BASE_NODE_ID + g_front_seg_index;
}
2025-05-09 16:53:07 +08:00
else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波
2025-01-16 16:17:01 +08:00
TEST_PORT = TEST_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index;
}
2025-02-26 16:39:10 +08:00
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
// CZY 测试 ping IP
// 执行命令并获取输出结果
2025-01-16 16:17:01 +08:00
std::string executeCommand(const std::string& command) {
std::string result = "";
FILE* pipe = popen(command.c_str(), "r");
if (!pipe) {
std::cerr << "Error executing command." << std::endl;
return result;
}
char buffer[128];
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
bool telnet_port_socket(const char* ip, int port) {
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
inet_pton(AF_INET, ip, &server_addr.sin_addr);
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
return false;
}
2025-05-09 16:53:07 +08:00
// 设置连接超时时间为5秒
2025-01-16 16:17:01 +08:00
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
perror("setsockopt");
close(sockfd);
return false;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
perror("setsockopt");
close(sockfd);
return false;
}
if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
if (errno == EINPROGRESS) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(sockfd, &fds);
int ret = select(sockfd + 1, NULL, &fds, NULL, &timeout);
if (ret == -1) {
perror("select");
close(sockfd);
return false;
}
else if (ret == 0) {
2025-05-09 16:53:07 +08:00
// 连接超时
2025-01-16 16:17:01 +08:00
close(sockfd);
return false;
}
else {
int error;
socklen_t len = sizeof(error);
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
if (error == 0) {
2025-05-09 16:53:07 +08:00
// 连接成功
2025-01-16 16:17:01 +08:00
close(sockfd);
return true;
}
else {
2025-05-09 16:53:07 +08:00
// 连接失败
2025-01-16 16:17:01 +08:00
close(sockfd);
return false;
}
}
}
else {
2025-05-09 16:53:07 +08:00
// 连接失败
2025-01-16 16:17:01 +08:00
close(sockfd);
return false;
}
}
2025-05-09 16:53:07 +08:00
// 连接成功
2025-01-16 16:17:01 +08:00
close(sockfd);
return true;
}
// ping IP
bool ping_ip(const std::string& ip) {
std::string command = "ping -c 1 -w 2.5 " + ip;
std::string result = executeCommand(command);
2025-05-09 16:53:07 +08:00
// 判断输出结果是否包含 "1 packets transmitted, 1 received" 字符串
2025-01-16 16:17:01 +08:00
if (result.find("1 packets transmitted, 1 received") != std::string::npos) {
return true;
}
else {
return false;
}
}
2025-03-06 18:41:48 +08:00
void pingPrint(QTcpSocket* clientSocket, const std::string &msg) {
2025-05-09 16:53:07 +08:00
// 输出到标准输出
2025-03-06 18:41:48 +08:00
std::cout << msg << std::endl;
2025-05-09 16:53:07 +08:00
// 记录到日志文件
2025-03-06 18:41:48 +08:00
add_comm_log(const_cast<char*>(msg.c_str()));
2025-05-09 16:53:07 +08:00
// 如果 clientSocket 不为空,则发送到 shell
2025-03-06 18:41:48 +08:00
if (clientSocket != nullptr) {
clientSocket->write((msg + "\r\n").c_str());
clientSocket->flush();
}
}
2025-03-07 18:27:03 +08:00
int Worker::init_ping_telnet(QTcpSocket* clientSocket, int& ip_count, int& telnet_count) {
2025-03-06 18:41:48 +08:00
pingPrint(clientSocket, "start test ping telnet");
ied_t* ied = NULL;
int iedno;
2025-05-09 16:53:07 +08:00
// 遍历所有设备
2025-03-07 18:27:03 +08:00
for (iedno = 0; iedno < g_node->n_clients && !g_stopTelnetTest; iedno++) {
2025-05-09 16:53:07 +08:00
// **1. 监听输入,用户输入 ``` 退出**
if (clientSocket->waitForReadyRead(100)) { // ? 监听输入
2025-03-07 18:27:03 +08:00
QByteArray input = clientSocket->readAll().trimmed();
2025-05-09 16:53:07 +08:00
if (input == "`") { // ? 用户输入 ```,退出日志模式
2025-03-07 18:27:03 +08:00
std::cout << "Received '`' from shell socket! Exiting viewlog...\n";
g_stopTelnetTest = true;
break;
}
2025-03-06 18:41:48 +08:00
}
2025-03-07 18:27:03 +08:00
2025-03-06 18:41:48 +08:00
ied = g_node->clients[iedno];
if (ied) {
if (g_onlyIP[0] != 0 && (strcmp(g_onlyIP, ied->channel[0].addr_str) != 0)) {
continue;
}
bool pingResult = ping_ip(ied->channel[0].addr_str);
bool telnetResult = telnet_port_socket(ied->channel[0].addr_str, ied->channel[0].port);
std::string logMsg;
logMsg.append("Ping to IP ");
logMsg.append(ied->channel[0].addr_str);
if (pingResult) {
ip_count++;
logMsg.append(" is successful.");
} else {
logMsg.append(" is unsuccessful.");
}
pingPrint(clientSocket, logMsg);
add_comm_log(const_cast<char*>(logMsg.c_str()));
logMsg = "";
logMsg.append("Telnet port ");
logMsg.append(QString::number(ied->channel[0].port).toStdString());
if (telnetResult) {
telnet_count++;
logMsg.append(" is open on IP ");
} else {
logMsg.append(" is closed on IP ");
}
logMsg.append(ied->channel[0].addr_str);
add_comm_log(const_cast<char*>(logMsg.c_str()));
pingPrint(clientSocket, logMsg);
std::string countMsg = "iedno:" + intToString(iedno) +
" ip_count:" + intToString(ip_count) +
" telnet_count:" + intToString(telnet_count);
pingPrint(clientSocket, countMsg);
2025-05-09 16:53:07 +08:00
// 更新配置文件
2025-03-06 18:41:48 +08:00
QString MyKafkaIniFilename = QString("../etc/") + QString("testping.ini");
QSettings settings(MyKafkaIniFilename, QSettings::IniFormat);
settings.setValue("test/IpCount", ip_count);
settings.setValue("test/TelnetCount", telnet_count);
settings.setValue("test/IedCount", iedno);
}
}
pingPrint(clientSocket, "end test ping telnet");
return 1;
2025-01-16 16:17:01 +08:00
}
//CZY 2023-08-30 chat* null or emptry
bool isCharPtrEmpty(const char* str) {
return str == nullptr || str[0] == '\0' || str == "";
}
2025-05-09 16:53:07 +08:00
// CZY 2024-07-24 函数:检查字符串是否全为数字
2025-01-16 16:17:01 +08:00
int isAllDigits(const char* str) {
while (*str) {
if (!isdigit((unsigned char)*str)) {
2025-05-09 16:53:07 +08:00
return 0; // 发现非数字字符
2025-01-16 16:17:01 +08:00
}
str++;
}
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
// CZY 2024-07-24函数将字符串转换为int如果可能
2025-01-16 16:17:01 +08:00
int stringToInt(const char* str, int* result) {
if (isAllDigits(str)) {
2025-05-09 16:53:07 +08:00
*result = atoi(str); // 使用atoi进行转换注意atoi不会检查溢出
return 1; // 转换成功
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
return 0; // 转换失败
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
int GetServerIndexFromDB() //获取前置服务器序号
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
register int fd, interface;
const int MAXINTERFACES = 100;
struct ifreq buf[MAXINTERFACES];
struct arpreq arp;
struct ifconf ifc;
char mac[32] = "";
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
ifc.ifc_len = sizeof buf;
ifc.ifc_buf = (caddr_t)buf;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (!ioctl(fd, SIOCGIFCONF, (char*)&ifc)) {
interface = ifc.ifc_len / sizeof(struct ifreq);
printf("\ninterface num is interface= %d\n", interface);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
while (interface-- > 0) {
printf("net device %s\n", buf[interface].ifr_name);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
/*确保网卡是否支持混杂模式 Jugde whether the net card status is promisc */
2025-04-29 15:05:36 +08:00
if (!(ioctl(fd, SIOCGIFFLAGS, (char*)&buf[interface]))) {
if (buf[interface].ifr_flags & IFF_PROMISC) {
printf("the interface is PROMISC \n");
}
}
else {
char str[256] = "";
sprintf(str, "cpm: ioctl device %s", buf[interface].ifr_name);
perror(str);
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
/*判断网卡状态是否打开 Judge whether the net card status is up */
2025-04-29 15:05:36 +08:00
if (buf[interface].ifr_flags & IFF_UP) {
printf("the interface status is UP\n");
}
else {
printf("the interface status is DOWN\n");
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
/*获取网卡IP地址 Get IP of the net card */
2025-04-29 15:05:36 +08:00
if (!(ioctl(fd, SIOCGIFADDR, (char*)&buf[interface]))) {
printf("IP address is: %s\n", inet_ntoa(((struct sockaddr_in*)(&buf[interface].ifr_addr))->sin_addr));
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
}
else {
char str[256] = "";
sprintf(str, "cpm: ioctl device %s", buf[interface].ifr_name);
perror(str);
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
/*获取网卡的HW地址 Get HW ADDRESS of the net card */
2025-04-29 15:05:36 +08:00
if (!(ioctl(fd, SIOCGIFHWADDR, (char*)&buf[interface]))) {
printf("HW address is: ");
sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)buf[interface].ifr_hwaddr.sa_data[0],
(unsigned char)buf[interface].ifr_hwaddr.sa_data[1],
(unsigned char)buf[interface].ifr_hwaddr.sa_data[2],
(unsigned char)buf[interface].ifr_hwaddr.sa_data[3],
(unsigned char)buf[interface].ifr_hwaddr.sa_data[4],
(unsigned char)buf[interface].ifr_hwaddr.sa_data[5]);
printf("%s\n\n", mac);
}
else {
char str[256];
sprintf(str, "cpm: ioctl device %s", buf[interface].ifr_name);
perror(str);
}
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
}
else
perror("cpm: ioctl");
}
else
perror("cpm: socket");
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
close(fd);
return 0;
}
/////////////////////////////////////////////////////////CZY
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
void parse_one_rpt_log_ini(int idx, QStringList* rpt_cfg_strlist, QStringList* log_cfg_strlist, char* type)
{
char* tmp;
2025-05-09 16:53:07 +08:00
tmp = Get_xmlpath(type);//获取模型id号
if (tmp == NULL) {//找不到模型编号使用默认的型号和配置文件
//zw修改 2023 - 8 - 15 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-04-29 15:05:36 +08:00
if (strcmp(subdir, "cfg_stat_data") == 0)
{
QString devtype;
devtype.append(type);
QString devtype2;
2025-05-09 16:53:07 +08:00
devtype2.append("HL-6810");//稳态默认型号HL-6810
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
qDebug() << "cfg_stat_data";
2025-05-09 16:53:07 +08:00
QString xml_dir = QString("../") + QString("etc/"); //Linux下调试路径
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QDomDocument doc; //新建QDomDocument类对象它代表一个XML文档
QFile file(xml_dir + QString("JiangSu_Config.xml"));//默认配置文件JiangSu_Config.xml
if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error1";
return;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if (!doc.setContent(&file)) //将文件内容读到doc中
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error2";
file.close();
return;
}
file.close();
2025-05-09 16:53:07 +08:00
QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate"
QDomElement docElem = doc.documentElement(); //返回根节点元素
QDomNode n = docElem.firstChild(); //获得doc的第一个节点即"Topic"
while (!n.isNull()) //如果Topic节点不为空
2025-04-29 15:05:36 +08:00
{
if (n.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e = n.toElement(); //将其转换为元素
2025-04-29 15:05:36 +08:00
QString strTag = e.tagName(); //
2025-05-09 16:53:07 +08:00
if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-04-29 15:05:36 +08:00
{
qDebug() << "ReportStat";
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-04-29 15:05:36 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
QString strTag2 = node.toElement().tagName(); //DataType节点
2025-04-29 15:05:36 +08:00
if ("ReportStat" == strTag2)
{
2025-05-09 16:53:07 +08:00
QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表
for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表
2025-04-29 15:05:36 +08:00
{
QDomNode node2 = list2.at(i2); //node2 <Monitor>
if (node2.isElement())
{
rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl"));
qDebug() << "devtype:" << devtype << node2.toElement().attribute("ReportControl").toAscii().data();
}
}
}
}
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-04-29 15:05:36 +08:00
n = n.nextSibling();
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";
log_cfg_strlist->append(log_cfg_str);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
if (strcmp(subdir, "cfg_soe_comtrade") == 0)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
qDebug() << "cfg_soe_comtrade";
2025-05-09 16:53:07 +08:00
QString xml_dir = QString("../") + QString("etc/"); //Linux下调试路径
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QDomDocument doc; //新建QDomDocument类对象它代表一个XML文档
2025-04-29 15:05:36 +08:00
QFile file(xml_dir + QString("JiangSu_Config.xml"));
2025-05-09 16:53:07 +08:00
if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error1";
return;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if (!doc.setContent(&file)) //将文件内容读到doc中
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error2";
file.close();
return;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
file.close();
2025-05-09 16:53:07 +08:00
QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate"
QDomElement docElem = doc.documentElement(); //返回根节点元素
QDomNode n = docElem.firstChild(); //获得doc的第一个节点即"Topic"
while (!n.isNull()) //如果Topic节点不为空
2025-04-29 15:05:36 +08:00
{
if (n.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e = n.toElement(); //将其转换为元素
2025-04-29 15:05:36 +08:00
QString strTag = e.tagName(); //
2025-05-09 16:53:07 +08:00
if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-04-29 15:05:36 +08:00
{
qDebug() << "ReportEvent";
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-04-29 15:05:36 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
QString strTag2 = node.toElement().tagName(); //DataType节点
2025-04-29 15:05:36 +08:00
if ("ReportEvent" == strTag2)
{
2025-05-09 16:53:07 +08:00
QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表
for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表
2025-04-29 15:05:36 +08:00
{
QDomNode node2 = list2.at(i2); //node2 <Monitor>
if (node2.isElement())
{
rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl"));
qDebug() << node2.toElement().attribute("ReportControl").toAscii().data();
}
}
}
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
}
}
}
n = n.nextSibling();
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";
log_cfg_strlist->append(log_cfg_str);
}
if (strcmp(subdir, "cfg_his_data") == 0 || strcmp(subdir, "cfg_newhis_data") == 0 || strcmp(subdir, "cfg_recallhis_data") == 0 || strcmp(subdir, "cfg_recallall_data") == 0)
{
QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";
log_cfg_strlist->append(log_cfg_str);
}
}
2025-05-09 16:53:07 +08:00
else//型号不为空读取指定的配置文件
2025-04-29 15:05:36 +08:00
{
QString tmppath;
tmppath.append("/FeProject/dat/").append(tmp).append(".xml");
qDebug() << tmppath;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//lnk20241126调试用
2025-04-29 15:05:36 +08:00
std::cout << "rptcfgfile:" << tmppath.toStdString() << std::endl;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//zw修改 2023 - 8 - 15 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-04-29 15:05:36 +08:00
if (strcmp(subdir, "cfg_stat_data") == 0)
{
qDebug() << "cfg_stat_data";
2025-05-09 16:53:07 +08:00
QDomDocument doc; //新建QDomDocument类对象它代表一个XML文档
2025-04-29 15:05:36 +08:00
QFile file(tmppath);
2025-05-09 16:53:07 +08:00
if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error1";
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//lnk20241126调试用
2025-04-29 15:05:36 +08:00
std::cout << "Read RPT Error1" << std::endl;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
return;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if (!doc.setContent(&file)) //将文件内容读到doc中
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error2";
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//lnk20241126调试用
2025-04-29 15:05:36 +08:00
std::cout << "Read RPT Error2" << std::endl;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
file.close();
return;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
file.close();
2025-05-09 16:53:07 +08:00
QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate"
QDomElement docElem = doc.documentElement(); //返回根节点元素
QDomNode n = docElem.firstChild(); //获得doc的第一个节点即"Topic"
while (!n.isNull()) //如果Topic节点不为空
2025-04-29 15:05:36 +08:00
{
if (n.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e = n.toElement(); //将其转换为元素
2025-04-29 15:05:36 +08:00
QString strTag = e.tagName(); //
2025-05-09 16:53:07 +08:00
if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-04-29 15:05:36 +08:00
{
qDebug() << "ReportStat";
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-04-29 15:05:36 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
QString strTag2 = node.toElement().tagName(); //DataType节点
2025-04-29 15:05:36 +08:00
if ("ReportStat" == strTag2)
{
2025-05-09 16:53:07 +08:00
QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表
for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表
2025-04-29 15:05:36 +08:00
{
QDomNode node2 = list2.at(i2); //node2 <Monitor>
if (node2.isElement())
{
rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl"));
2025-05-09 16:53:07 +08:00
qDebug() << node2.toElement().attribute("ReportControl").toAscii().data();//读取各个报告配置
2025-04-29 15:05:36 +08:00
}
}
}
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
}
}
}
n = n.nextSibling();
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";//日志的配置是写死的
2025-04-29 15:05:36 +08:00
log_cfg_strlist->append(log_cfg_str);
}
2025-05-09 16:53:07 +08:00
//lnk添加实时数据20241125
2025-04-29 15:05:36 +08:00
if (strcmp(subdir, "cfg_3s_data") == 0)
{
qDebug() << "cfg_3s_data";
2025-05-09 16:53:07 +08:00
QDomDocument doc; //新建QDomDocument类对象它代表一个XML文档
2025-04-29 15:05:36 +08:00
QFile file(tmppath);
2025-05-09 16:53:07 +08:00
if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error1";
return;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if (!doc.setContent(&file)) //将文件内容读到doc中
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error2";
file.close();
return;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
file.close();
2025-05-09 16:53:07 +08:00
QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate"
QDomElement docElem = doc.documentElement(); //返回根节点元素
QDomNode n = docElem.firstChild(); //获得doc的第一个节点即"Topic"
while (!n.isNull()) //如果Topic节点不为空
2025-04-29 15:05:36 +08:00
{
if (n.isElement())
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
QDomElement e = n.toElement(); //将其转换为元素
2025-04-29 15:05:36 +08:00
QString strTag = e.tagName(); //
2025-05-09 16:53:07 +08:00
if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-04-29 15:05:36 +08:00
{
qDebug() << "ReportReal";
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-04-29 15:05:36 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
QString strTag2 = node.toElement().tagName(); //DataType节点
2025-04-29 15:05:36 +08:00
if ("ReportReal" == strTag2)
{
2025-05-09 16:53:07 +08:00
QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表
for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表
2025-04-29 15:05:36 +08:00
{
QDomNode node2 = list2.at(i2); //node2 <Monitor>
if (node2.isElement())
{
rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl"));
qDebug() << node2.toElement().attribute("ReportControl").toAscii().data();
}
}
}
}
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-04-29 15:05:36 +08:00
n = n.nextSibling();
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//实时数据没有日志
2025-04-29 15:05:36 +08:00
//QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";
//log_cfg_strlist->append(log_cfg_str);
}
if (strcmp(subdir, "cfg_soe_comtrade") == 0)
{
qDebug() << "cfg_soe_comtrade";
2025-05-09 16:53:07 +08:00
QDomDocument doc; //新建QDomDocument类对象它代表一个XML文档
2025-04-29 15:05:36 +08:00
QFile file(tmppath);
2025-05-09 16:53:07 +08:00
if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error1";
return;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if (!doc.setContent(&file)) //将文件内容读到doc中
2025-04-29 15:05:36 +08:00
{
qDebug() << "Read RPT Error2";
file.close();
return;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
file.close();
2025-05-09 16:53:07 +08:00
QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate"
QDomElement docElem = doc.documentElement(); //返回根节点元素
QDomNode n = docElem.firstChild(); //获得doc的第一个节点即"Topic"
while (!n.isNull()) //如果Topic节点不为空
2025-04-29 15:05:36 +08:00
{
if (n.isElement())
{
2025-05-09 16:53:07 +08:00
QDomElement e = n.toElement(); //将其转换为元素
2025-04-29 15:05:36 +08:00
QString strTag = e.tagName(); //
2025-05-09 16:53:07 +08:00
if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消
2025-04-29 15:05:36 +08:00
{
qDebug() << "ReportEvent";
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表
for (int i = 0; i < list.count(); i++) //遍历 DataType列表
2025-04-29 15:05:36 +08:00
{
QDomNode node = list.at(i); //node1 <DataType>
if (node.isElement())
{
2025-05-09 16:53:07 +08:00
QString strTag2 = node.toElement().tagName(); //DataType节点
if ("ReportEvent" == strTag2)//区分点
2025-04-29 15:05:36 +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-04-29 15:05:36 +08:00
{
QDomNode node2 = list2.at(i2); //node2 <Monitor>
if (node2.isElement())
{
rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl"));
qDebug() << node2.toElement().attribute("ReportControl").toAscii().data();
}
}
}
}
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-04-29 15:05:36 +08:00
n = n.nextSibling();
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";
log_cfg_strlist->append(log_cfg_str);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
if (strcmp(subdir, "cfg_his_data") == 0 || strcmp(subdir, "cfg_newhis_data") == 0 || strcmp(subdir, "cfg_recallhis_data") == 0 || strcmp(subdir, "cfg_recallall_data") == 0)
{
QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";
log_cfg_strlist->append(log_cfg_str);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
delete[] tmp;
2025-01-16 16:17:01 +08:00
}
}
2025-04-29 15:05:36 +08:00
int parse_rpt_log_ini()
{
const int MAX_DEV_FLAG = 10;
bool not_loaded[MAX_DEV_FLAG];
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QMap<QString, QStringList*> rpt_cfg_strlists;
QMap<QString, QStringList*> log_cfg_strlists;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
int iedno, cpuno;
2025-01-16 16:17:01 +08:00
ied_t* ied;
ied_usr_t* ied_usr;
2025-04-29 15:05:36 +08:00
LD_info_t* LD_info;
char buf[256];
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
for (iedno = 0; iedno < g_node->n_clients; iedno++) {
ied = g_node->clients[iedno];
ied_usr = GET_IEDEXT_ADDR(ied);
QString type;
type.append(ied_usr->dev_type);
if (!rpt_cfg_strlists.contains(type))
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
QStringList* rpt_temp = new QStringList();
QStringList* log_temp = new QStringList();
rpt_cfg_strlists.insert(type, rpt_temp);
log_cfg_strlists.insert(type, log_temp);
2025-05-09 16:53:07 +08:00
//g_DevFlag没有使用
2025-04-29 15:05:36 +08:00
parse_one_rpt_log_ini(g_DevFlag, rpt_cfg_strlists[type], log_cfg_strlists[type], ied_usr->dev_type);
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-04-29 15:05:36 +08:00
for (cpuno = 0; cpuno < ied->cpucount; cpuno++) {
LD_info = &(ied_usr->LD_info[cpuno]);
2025-05-09 16:53:07 +08:00
char str[256]; //256大小
2025-04-29 15:05:36 +08:00
char* tmp = Get_IED(ied_usr->dev_type);
if(tmp == NULL){std::cerr << "front read ied config error!" << std::endl;continue;}
qDebug() << tmp << endl;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
apr_snprintf(str, sizeof(str), tmp, cpuno + 1);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
delete[] tmp;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
init_rptctrl_by_count(LD_info, rpt_cfg_strlists[type]->size());
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
for (int i = 0; i < rpt_cfg_strlists[type]->size(); ++i) {
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
apr_snprintf(buf, sizeof(buf), "%s", rpt_cfg_strlists[type]->at(i).toAscii().constData());
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
fill_rptctrl_by_cfg(LD_info, i, buf);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
init_logctrl_by_count(LD_info, log_cfg_strlists[type]->size());
for (int i = 0; i < log_cfg_strlists[type]->size(); ++i) {
apr_snprintf(buf, sizeof(buf), "%s", log_cfg_strlists[type]->at(i).toAscii().constData());
char* tmp = Get_LDevice(ied_usr->dev_type);
if(tmp == NULL){std::cerr << "front read monitor config error!" << std::endl;continue;}
fill_logctrl_by_cfg(LD_info, i, buf, tmp);
delete[] tmp;
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
//报告控制块和日志控制块处理结束后清理容器
2025-04-29 15:05:36 +08:00
for (QMap<QString, QStringList*>::iterator it1 = log_cfg_strlists.begin(); it1 != log_cfg_strlists.end(); ++it1)
{
delete it1.value();
}
for (QMap<QString, QStringList*>::iterator it2 = rpt_cfg_strlists.begin(); it2 != rpt_cfg_strlists.end(); ++it2)
{
delete it2.value();
}
rpt_cfg_strlists.clear();
log_cfg_strlists.clear();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
return APR_SUCCESS;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//台账更新部分///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-04-29 15:05:36 +08:00
std::string LEDGER_UPDATE_DIR = "../etc/ledgerupdate/";
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::list<std::string> find_xml_belong_to_this_process()
{
2025-05-09 16:53:07 +08:00
char prefix[20]; // 假设最多需要20个字符根据实际需要调整
sprintf(prefix, "%d_%d", g_node_id, g_front_seg_index); // 将g_node_id和g_front_seg_index格式化为字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
DIR *dir = opendir(LEDGER_UPDATE_DIR.c_str()); // 打开目录
2025-04-29 15:05:36 +08:00
struct dirent *entry;
2025-05-09 16:53:07 +08:00
std::list<std::string> found_files; // 用于存储找到的所有匹配文件名
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (dir == NULL) {
std::cout << "Failed to open directory: " << LEDGER_UPDATE_DIR << std::endl;
2025-05-09 16:53:07 +08:00
return found_files; // 返回空的list
2025-04-29 15:05:36 +08:00
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 遍历目录中的所有文件
2025-04-29 15:05:36 +08:00
while ((entry = readdir(dir)) != NULL) {
std::string filename = entry->d_name;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 排除 "." 和 ".." 目录
2025-04-29 15:05:36 +08:00
if (filename == "." || filename == "..") {
continue;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::cout << "find" << filename << "in" << LEDGER_UPDATE_DIR << std::endl;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 判断文件名是否以 prefix 开头且扩展名是 .xml
2025-04-29 15:05:36 +08:00
if (filename.find(prefix) == 0 && filename.substr(filename.find_last_of('.') + 1) == "xml") {
std::string full_path = LEDGER_UPDATE_DIR + filename;
2025-05-09 16:53:07 +08:00
found_files.push_back(full_path); // 将完整路径加入容器
2025-04-29 15:05:36 +08:00
}
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
closedir(dir); // 关闭目录
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return found_files; // 返回所有找到的文件名
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
// 提取标签中的值的通用函数
2025-04-29 15:05:36 +08:00
std::string extract_value(const std::string& data, const std::string& tag) {
size_t start_pos = data.find("<" + tag + ">");
if (start_pos == std::string::npos) return "";
size_t end_pos = data.find("</" + tag + ">", start_pos);
if (end_pos == std::string::npos) return "";
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
return data.substr(start_pos + tag.length() + 2, end_pos - start_pos - tag.length() - 2);
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 根据 str_tag 将 terminal 添加到对应的数组
2025-04-29 15:05:36 +08:00
void add_terminal_to_trigger_update(trigger_update_xml_t* trigger_update_xml, const std::string& str_tag, const terminal& work_terminal) {
if (str_tag == "add") {
std::cout << "new ledger!!!!"<<std::endl;
if (trigger_update_xml->new_update_num < MAX_UPDATEA_NUM) {
trigger_update_xml->new_updates[trigger_update_xml->new_update_num] = work_terminal;
2025-05-09 16:53:07 +08:00
trigger_update_xml->new_update_num+= 1; // 更新新终端的数量
2025-04-29 15:05:36 +08:00
} else {
std::cerr << "Exceeded MAX_UPDATEA_NUM limit for new updates!" << std::endl;
}
}
else if (str_tag == "modify") {
std::cout << "modify ledger!!!"<<std::endl;
if (trigger_update_xml->modify_update_num < MAX_UPDATEA_NUM) {
trigger_update_xml->modify_updates[trigger_update_xml->modify_update_num] = work_terminal;
2025-05-09 16:53:07 +08:00
trigger_update_xml->modify_update_num+= 1; // 更新修改终端的数量
2025-04-29 15:05:36 +08:00
} else {
std::cerr << "Exceeded MAX_UPDATEA_NUM limit for modify updates!" << std::endl;
}
}
else {
std::cerr << "Unknown tag: " << str_tag << std::endl;
}
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 解析 XML 数据并提取 terminal 信息
void parse_terminal_from_data(trigger_update_xml_t* trigger_update_xml, const std::string& str_tag, const std::string& data,const std::string& guid_value) {
terminal work_terminal = {}; // 创建新的 terminal 对象
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 提取各个字段
2025-04-29 15:05:36 +08:00
strcpy(work_terminal.terminal_id, extract_value(data, "id").c_str());
strcpy(work_terminal.terminal_code, extract_value(data, "terminalCode").c_str());
strcpy(work_terminal.org_name, extract_value(data, "orgName").c_str());
strcpy(work_terminal.maint_name, extract_value(data, "maintName").c_str());
strcpy(work_terminal.station_name, extract_value(data, "stationName").c_str());
strcpy(work_terminal.tmnl_factory, extract_value(data, "manufacturer").c_str());
strcpy(work_terminal.tmnl_status, extract_value(data, "status").c_str());
strcpy(work_terminal.dev_type, extract_value(data, "devType").c_str());
strcpy(work_terminal.dev_key, extract_value(data, "devKey").c_str());
strcpy(work_terminal.dev_series, extract_value(data, "series").c_str());
strcpy(work_terminal.processNo, extract_value(data, "processNo").c_str());
strcpy(work_terminal.addr_str, extract_value(data, "ip").c_str());
strcpy(work_terminal.port, extract_value(data, "port").c_str());
strcpy(work_terminal.timestamp, extract_value(data, "updateTime").c_str());
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//添加guid20250506
strncpy(work_terminal.guid, guid_value.c_str(), sizeof(work_terminal.guid) - 1);
work_terminal.guid[sizeof(work_terminal.guid) - 1] = '\0';
2025-04-29 15:05:36 +08:00
size_t monitor_pos = 0;
size_t monitor_count = 0;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 查找每个 monitorData最多处理 10 个
2025-04-29 15:05:36 +08:00
while ((monitor_pos = data.find("<monitorData", monitor_pos)) != std::string::npos && monitor_count < 10) {
2025-05-09 16:53:07 +08:00
monitor work_monitor = {}; // 创建新的 monitor 对象
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 找到当前 monitorData 的结束位置
2025-04-29 15:05:36 +08:00
size_t monitor_end_pos = data.find("</monitorData", monitor_pos);
std::string monitor_data = data.substr(monitor_pos, monitor_end_pos - monitor_pos);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 提取各个字段并填充到 work_monitor 中
2025-04-29 15:05:36 +08:00
std::string monitor_id = extract_value(monitor_data, "id");
std::string monitor_name = extract_value(monitor_data, "name");
std::string voltage_level = extract_value(monitor_data, "voltageLevel");
std::string terminal_connect = extract_value(monitor_data, "ptType");
std::string line_no = extract_value(monitor_data, "lineNo");
std::string timestamp = extract_value(monitor_data, "timestamp");
std::string terminal_code = extract_value(monitor_data, "terminal_code");
std::string status = extract_value(monitor_data, "status");
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 将提取的数据复制到 work_monitor 中,若没有数据则复制 "N/A"
2025-04-29 15:05:36 +08:00
strcpy(work_monitor.monitor_id, monitor_id.empty() ? "N/A" : monitor_id.c_str());
strcpy(work_monitor.monitor_name, monitor_name.empty() ? "N/A" : monitor_name.c_str());
strcpy(work_monitor.voltage_level, voltage_level.empty() ? "N/A" : voltage_level.c_str());
strcpy(work_monitor.terminal_connect, terminal_connect.empty() ? "N/A" : terminal_connect.c_str());
strcpy(work_monitor.logical_device_seq, line_no.empty() ? "N/A" : line_no.c_str());
strcpy(work_monitor.timestamp, timestamp.empty() ? "N/A" : timestamp.c_str());
strcpy(work_monitor.terminal_code, terminal_code.empty() ? "N/A" : terminal_code.c_str());
strcpy(work_monitor.status, status.empty() ? "N/A" : status.c_str());
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 将提取的 monitor 数据存入 work_terminal.line[monitor_count]
2025-04-29 15:05:36 +08:00
work_terminal.line[monitor_count] = work_monitor;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
monitor_count++; // 增加 monitor 的计数
monitor_pos = monitor_end_pos; // 移动 monitor_pos 到下一个 <monitorData> 的位置
2025-04-29 15:05:36 +08:00
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 根据 str_tag 将 terminal 添加到相应的数组
2025-04-29 15:05:36 +08:00
add_terminal_to_trigger_update(trigger_update_xml, str_tag, work_terminal);
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
void parse_ledger_update(trigger_update_xml_t* trigger_update_xml, const std::string& strTag, const std::string& data,const std::string& guid_value)
2025-04-29 15:05:36 +08:00
{
std::cout << "record one xml.."<<std::endl;
2025-05-09 16:53:07 +08:00
// 根据 strTag 做不同处理
2025-04-29 15:05:36 +08:00
if (strTag == "add" || strTag == "modify") {
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 填充终端信息
parse_terminal_from_data(trigger_update_xml, strTag, data,guid_value);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
}else if (strTag == "delete") {
terminal delete_terminal;
memset(&delete_terminal, 0, sizeof(delete_terminal));
if (strTag == "delete") {
2025-05-09 16:53:07 +08:00
// 填充终端信息
2025-04-29 15:05:36 +08:00
strcpy(delete_terminal.terminal_id, extract_value(data, "id").c_str());
2025-05-09 16:53:07 +08:00
//添加guid20250506
strncpy(delete_terminal.guid, guid_value.c_str(), sizeof(delete_terminal.guid) - 1);
delete_terminal.guid[sizeof(delete_terminal.guid) - 1] = '\0';
// 将删除信息写入 delete_updates
2025-04-29 15:05:36 +08:00
std::cout << "delete ledger!!!!!"<<std::endl;
if (trigger_update_xml->delete_update_num < MAX_UPDATEA_NUM) {
trigger_update_xml->delete_updates[trigger_update_xml->delete_update_num] = delete_terminal;
2025-05-09 16:53:07 +08:00
trigger_update_xml->delete_update_num += 1; // 增加计数
2025-04-29 15:05:36 +08:00
}
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
} else {
std::cerr << "Unsupported strTag: " << strTag << std::endl;
}
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
int load_ledger_update_from_xml(trigger_update_xml_t* trigger_update_xml, const std::string& xml_fn)
{
std::cout << "start to load one xml.."<<std::endl;
2025-05-09 16:53:07 +08:00
std::ifstream file(xml_fn.c_str()); // 打开XML文件
2025-04-29 15:05:36 +08:00
if (!file.is_open()) {
std::cerr << "Failed to open file: " << xml_fn << std::endl;
return -1;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::string line;
std::stringstream file_content;
2025-05-09 16:53:07 +08:00
// 读取文件内容
2025-04-29 15:05:36 +08:00
while (std::getline(file, line)) {
file_content << line << "\n";
}
file.close();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::string content = file_content.str();
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 查找 <ledger_update> 标签
2025-04-29 15:05:36 +08:00
size_t ledger_pos = content.find("<ledger_update>");
if (ledger_pos == std::string::npos) {
std::cerr << "ledger_update tag not found!" << std::endl;
return -1;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// === 新增:查找 <guid> 标签 ===
std::string guid_value;
size_t guid_start = content.find("<guid>", ledger_pos);
size_t guid_end = content.find("</guid>", ledger_pos);
if (guid_start != std::string::npos && guid_end != std::string::npos && guid_end > guid_start) {
size_t guid_value_start = guid_start + std::string("<guid>").length();
guid_value = content.substr(guid_value_start, guid_end - guid_value_start);
std::cout << "Found guid: " << guid_value << std::endl;
} else {
std::cout << "No guid found in xml." << std::endl;
}
// 查找 <add>, <delete>, <modify> 标签
2025-04-29 15:05:36 +08:00
size_t add_pos = content.find("<add>", ledger_pos);
size_t delete_pos = content.find("<delete>", ledger_pos);
size_t modify_pos = content.find("<modify>", ledger_pos);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 确定哪个标签存在,并获取相应的位置
2025-04-29 15:05:36 +08:00
size_t target_pos = std::string::npos;
std::string target_tag;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (add_pos != std::string::npos) {
target_pos = add_pos;
target_tag = "add";
} else if (delete_pos != std::string::npos) {
target_pos = delete_pos;
target_tag = "delete";
} else if (modify_pos != std::string::npos) {
target_pos = modify_pos;
target_tag = "modify";
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//没找到正确的标签退出处理
2025-04-29 15:05:36 +08:00
if (target_pos == std::string::npos) {
std::cerr << "No <add>, <delete>, or <modify> tag found!" << std::endl;
return -1;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 查找目标标签的结束位置
2025-04-29 15:05:36 +08:00
size_t end_pos = content.find("</" + target_tag + ">", target_pos);
if (end_pos == std::string::npos) {
std::cerr << "Closing </" + target_tag + "> tag not found!" << std::endl;
return -1;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 提取目标标签的内容
2025-04-29 15:05:36 +08:00
std::string target_content = content.substr(target_pos + target_tag.length() + 2, end_pos - (target_pos + target_tag.length() + 2));
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 解析 <data> 和其中的内容
2025-04-29 15:05:36 +08:00
size_t data_pos = 0;
while ((data_pos = target_content.find("<terminalData>", data_pos)) != std::string::npos) {
size_t data_end_pos = target_content.find("</terminalData>", data_pos);
if (data_end_pos == std::string::npos) {
std::cerr << "Closing </terminalData> tag not found!" << std::endl;
return -1;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::string data_content = target_content.substr(data_pos + 14, data_end_pos - (data_pos + 14));
std::cout << "ledger data_content is " << data_content <<std::endl;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 调用parse_ledger_update处理台账的内容
parse_ledger_update(trigger_update_xml, target_tag, data_content,guid_value);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 移动到下一个<terminalData>标签,目前每个文件只有一个台账
2025-04-29 15:05:36 +08:00
data_pos = data_end_pos + 15;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::cout << "load one xml finish"<<std::endl;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 0; // 成功返回
2025-04-29 15:05:36 +08:00
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
int parse_ledger_update_xml(trigger_update_xml_t* trigger_update_xml)
{
//printf("begin ledger update xml...\n");
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::list<std::string> result = find_xml_belong_to_this_process();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (!result.empty()) {
std::cout << "Found XML files:" << std::endl;
for (std::list<std::string>::iterator it = result.begin(); it != result.end(); ++it) {
const std::string& filename = *it;
std::cout << filename << std::endl;
2025-05-09 16:53:07 +08:00
//解析每个文件,提取终端,判断终端是否满足更新条件
2025-04-29 15:05:36 +08:00
apr_sleep(apr_time_from_sec(1) / 10);
2025-05-09 16:53:07 +08:00
//加载一个文件的内容到数据结构
2025-04-29 15:05:36 +08:00
if (!load_ledger_update_from_xml(trigger_update_xml, filename)) {
std::cout << "read /etc/ledgerupdate/" << filename << " success..." << std::endl;
}
2025-05-09 16:53:07 +08:00
//处理过的文件删除掉
2025-04-29 15:05:36 +08:00
if (std::remove(filename.c_str()) != 0) {
std::cerr << "Failed to remove file: " << filename << " Error: " << strerror(errno) << std::endl;
return APR_EGENERAL;
}
else{
std::cout << "remove file: " << filename << " success..." << std::endl;
}
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
}
else {
2025-05-09 16:53:07 +08:00
//std::cout << "No matching XML files found." << std::endl;//减少不必要的打印
2025-04-29 15:05:36 +08:00
return APR_EGENERAL;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//有数据返回成功,后续进行处理
2025-04-29 15:05:36 +08:00
//printf("Modify Update Count: %d\n", trigger_update_xml->modify_update_num);
//printf("Delete Update Count: %d\n", trigger_update_xml->delete_update_num);
//printf("New Update Count: %d\n", trigger_update_xml->new_update_num);
if(trigger_update_xml->modify_update_num || trigger_update_xml->delete_update_num || trigger_update_xml->new_update_num){
printf("ledger update xml have data...\n");
2025-01-16 16:17:01 +08:00
return APR_SUCCESS;
}
2025-05-09 16:53:07 +08:00
else{//无数据返回失败,后续不处理
2025-04-29 15:05:36 +08:00
printf("ledger update xml no data...\n");
return APR_EGENERAL;
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-04-29 15:05:36 +08:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//实时触发部分/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-04-29 15:05:36 +08:00
QString THREE_SECS_WEBSERVICE_DIR = QString("../etc/trigger3s/");
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QString get_3s_trig_fn()
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
QDir directory(THREE_SECS_WEBSERVICE_DIR);
QStringList filters = QStringList() << "*.xml";
QStringList fileNames = directory.entryList(filters, QDir::Files, QDir::Time/*|QDir::Reversed*/);
if (fileNames.size() > 0)
return fileNames.at(0);
else
return "";
}
///////////////////////////////////////////////////////////////
int getValueFromElemAttrStr(QString str)
{
if (str == "true")
return 1;
else if (str == "false")
return 0;
else
return -1;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//lnk20241125添加打印调试用/////////////////////////////////////////////////////////////////////////////////////////////////
// 打印 trigger_t 结构体的函数
2025-04-29 15:05:36 +08:00
void print_trigger(const trigger_t& trigger) {
printf(" dev_idx: %d, line_id: %d, real_data: %d, soe_data: %d, limit: %d, count: %d\n",
trigger.dev_idx, trigger.line_id, trigger.real_data, trigger.soe_data, trigger.limit, trigger.count);
}
2025-05-09 16:53:07 +08:00
// 打印 trigger_3s_xml_t 结构体的函数
2025-04-29 15:05:36 +08:00
void print_trigger_3s_xml(const trigger_3s_xml_t& trigger_3s_xml) {
printf("Work Trigger Count: %d\n", trigger_3s_xml.work_trigger_num);
for (int i = 0; i < trigger_3s_xml.work_trigger_num; ++i) {
printf(" Work Trigger [%d]:\n", i + 1);
print_trigger(trigger_3s_xml.work_triggers[i]);
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
printf("New Trigger Count: %d\n", trigger_3s_xml.new_trigger_num);
for (int i = 0; i < trigger_3s_xml.new_trigger_num; ++i) {
printf(" New Trigger [%d]:\n", i + 1);
print_trigger(trigger_3s_xml.new_triggers[i]);
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
printf("Delete Trigger Count: %d\n", trigger_3s_xml.delete_trigger_num);
for (int i = 0; i < trigger_3s_xml.delete_trigger_num; ++i) {
printf(" Delete Trigger [%d]:\n", i + 1);
print_trigger(trigger_3s_xml.delete_triggers[i]);
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
printf("Modify Trigger Count: %d\n", trigger_3s_xml.modify_trigger_num);
for (int i = 0; i < trigger_3s_xml.modify_trigger_num; ++i) {
printf(" Modify Trigger [%d]:\n", i + 1);
print_trigger(trigger_3s_xml.modify_triggers[i]);
}
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//实时触发文件处理部分//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-04-29 15:05:36 +08:00
void parse_3s_trigger(trigger_3s_xml_t* trigger_3s_xml, QString parentTag, QDomElement& trigger_e)
{
QString e_atr("");
trigger_t trigger;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
trigger.dev_idx = trigger_e.attribute("DevSeries").toInt();
trigger.line_id = trigger_e.attribute("Line").toInt();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
e_atr = trigger_e.attribute("RealData").toLower();
trigger.real_data = getValueFromElemAttrStr(e_atr);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
e_atr = trigger_e.attribute("SOEData").toLower();
trigger.soe_data = getValueFromElemAttrStr(e_atr);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
trigger.limit = trigger_e.attribute("Limit").toInt();
trigger.count = trigger_e.attribute("Count").toInt();
//qDebug()<<parentTag << "-> " << dev_idx<<" "<<line_id<<" "<<real_data<<" "<<soe_data <<" " << limit<<" " << count;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (parentTag == "Work") {
trigger_3s_xml->work_triggers[trigger_3s_xml->work_trigger_num++] = trigger;
}
else if (parentTag == "New") {
trigger_3s_xml->new_triggers[trigger_3s_xml->new_trigger_num++] = trigger;
}
else if (parentTag == "Delete") {
trigger_3s_xml->delete_triggers[trigger_3s_xml->delete_trigger_num++] = trigger;
}
else if (parentTag == "Modify") {
trigger_3s_xml->modify_triggers[trigger_3s_xml->modify_trigger_num++] = trigger;
}
2025-05-09 16:53:07 +08:00
//调试用lnk20241125
2025-04-29 15:05:36 +08:00
print_trigger_3s_xml(*trigger_3s_xml);
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-04-29 15:05:36 +08:00
int load_3s_data_from_xml(trigger_3s_xml_t* trigger_3s_xml, QString xml_fn)
{
2025-05-09 16:53:07 +08:00
QDomDocument doc; //新建QDomDocument类对象它代表一个XML文档
2025-04-29 15:05:36 +08:00
QFile file(xml_fn);
if (!file.open(QIODevice::ReadOnly))
2025-05-09 16:53:07 +08:00
return APR_EBADPATH; //以只读方式打开
2025-04-29 15:05:36 +08:00
bool ret = doc.setContent(&file);
file.close();
if (!ret)
return APR_EBADF;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//将文件内容读到doc中
QDomElement docElem = doc.documentElement(); //返回根元素
QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点
while (!n.isNull()) { //如果节点不为空
if (n.isElement()) { //如果节点是元素
QDomElement e = n.toElement(); //将其转换为元素
2025-04-29 15:05:36 +08:00
QString strTag = e.tagName();
if (strTag == "Work" || strTag == "New" || strTag == "Delete" || strTag == "Modify") {
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表
for (int i = 0; i < list.count(); i++) { //遍历该列表
2025-04-29 15:05:36 +08:00
QDomNode node = list.at(i);
if (node.isElement()) {
QDomElement trigger_e = node.toElement();
QString strTag2 = trigger_e.tagName();
if (strTag2 == "Trigger") {
parse_3s_trigger(trigger_3s_xml, strTag, trigger_e);
} //else if ( strTag == "Trigger" )
}
}
2025-01-16 16:17:01 +08:00
}
}
2025-05-09 16:53:07 +08:00
n = n.nextSibling(); //下一个兄弟节点
2025-04-29 15:05:36 +08:00
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
return APR_SUCCESS;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QString BAK_WEBSERVICE_3S_TRIG_COMMAND_XML_FN = THREE_SECS_WEBSERVICE_DIR + "bak_3s_trig_command.txt";
int parse_3s_xml(trigger_3s_xml_t* trigger_3s_xml)
{
printf("begin 3s xml...\n");
memset(trigger_3s_xml, 0, sizeof(trigger_3s_xml_t));
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//这个文件是用来记录正在进行中的实时触发
2025-04-29 15:05:36 +08:00
QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/");
2025-05-09 16:53:07 +08:00
load_3s_data_from_xml(trigger_3s_xml, (cfg_dir + THREE_SECS_CONFIG_FN)); //加载/Feproject/etc/Trigger3S.xml
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QString the_webservice_xml_fn = get_3s_trig_fn();// ../etc/trigger3s/目录下的最新的xml文件这个文件是用来打开实时触发的开关
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
printf("the_webservice_xml_fn.size():%d\n",the_webservice_xml_fn.size());
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if (the_webservice_xml_fn.size() > 4) {//文件名大于4说明找到文件
2025-04-29 15:05:36 +08:00
apr_sleep(apr_time_from_sec(1) / 10);
the_webservice_xml_fn = THREE_SECS_WEBSERVICE_DIR + the_webservice_xml_fn;
load_3s_data_from_xml(trigger_3s_xml, the_webservice_xml_fn);
QFile::remove(BAK_WEBSERVICE_3S_TRIG_COMMAND_XML_FN);
QFile::rename(the_webservice_xml_fn, BAK_WEBSERVICE_3S_TRIG_COMMAND_XML_FN);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
printf("/etc/trigger3s/*.xml success...\n");
2025-01-16 16:17:01 +08:00
return APR_SUCCESS;
}
2025-04-29 15:05:36 +08:00
printf("3s xml fail...\n");
return APR_EGENERAL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//3s触发记录写入文件
2025-04-29 15:05:36 +08:00
void append_triggers(QDomDocument& doc, QDomElement& root, QString parentTag, trigger_t* trigger, int trigger_num)
{
QString str;
QDomElement funcItem = doc.createElement(parentTag);
root.appendChild(funcItem);
for (int i = 0; i < trigger_num; i++) {
if (trigger[i].dev_idx == INVALID_DEV_IDX)
continue;
if (trigger[i].real_data == 0 && trigger[i].soe_data == 0)
continue;
QDomElement triggerItem = doc.createElement("Trigger");
triggerItem.setAttribute("DevSeries", trigger[i].dev_idx);
triggerItem.setAttribute("Line", trigger[i].line_id);
str = trigger[i].real_data ? "true" : "false";
triggerItem.setAttribute("RealData", str);
str = trigger[i].soe_data ? "true" : "false";
triggerItem.setAttribute("SOEData", str);
triggerItem.setAttribute("Limit", trigger[i].limit);
triggerItem.setAttribute("Count", trigger[i].count);
funcItem.appendChild(triggerItem);
2025-01-16 16:17:01 +08:00
}
}
2025-04-29 15:05:36 +08:00
int create_3s_xml(trigger_3s_xml_t* trigger_3s_xml)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
QDomDocument doc;
doc.appendChild(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"gb2312\""));
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QDomElement root = doc.createElement("Trigger3S");
doc.appendChild(root);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
append_triggers(doc, root, "Work", trigger_3s_xml->work_triggers, trigger_3s_xml->work_trigger_num);
append_triggers(doc, root, "New", trigger_3s_xml->new_triggers, 0);
append_triggers(doc, root, "Delete", trigger_3s_xml->delete_triggers, 0);
append_triggers(doc, root, "Modify", trigger_3s_xml->modify_triggers, 0);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/");
QFile file(cfg_dir + THREE_SECS_CONFIG_FN /*+".bak.xml"*/);
if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)) {
return -1;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
QTextStream out(&file);
out.setCodec("gb2312");
doc.save(out, 4);
file.close();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
return APR_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
// 函数功能:从指定的 .cfg 配置文件中提取起始时间和触发时间,并将其转化为毫秒级时间戳。
// 输入参数:
// - comtrade_fn输入的文件名作为参考用于定位对应的 .cfg 配置文件。
// 输出参数:
// - start_tm返回的起始时间戳单位毫秒
// - trig_tm返回的触发时间戳单位毫秒
// 返回值:
// - 返回 APR_SUCCESS 表示成功,返回 APR_EBADF 表示文件错误。
2025-04-29 15:05:36 +08:00
int extract_timestamp_from_cfg_file(char* comtrade_fn, long long* start_tm, long long* trig_tm)
{
2025-05-09 16:53:07 +08:00
// 获取文件名信息,路径和文件名提取
2025-04-29 15:05:36 +08:00
QFileInfo fi(QString::fromAscii(comtrade_fn));
QString fn = fi.fileName();
2025-05-09 16:53:07 +08:00
QString cfgFileName_temp = QString("../comtrade/") + fn; // 拼接.cfg文件的路径
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 检查文件是否以 ".cfg" 或 ".CFG" 结尾
2025-04-29 15:05:36 +08:00
if (!cfgFileName_temp.endsWith(".cfg", Qt::CaseInsensitive) && !cfgFileName_temp.endsWith(".CFG", Qt::CaseInsensitive))
2025-05-09 16:53:07 +08:00
return APR_EBADF; // 如果文件名不符合要求,返回文件错误
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 打开配置文件
2025-04-29 15:05:36 +08:00
QFile cfgFile_temp(cfgFileName_temp);
2025-05-09 16:53:07 +08:00
if (!cfgFile_temp.exists()) { // 如果文件不存在
2025-04-29 15:05:36 +08:00
qDebug() << QString("Cannot find corresponding .cfg file: %1").arg(cfgFileName_temp);
cfgFile_temp.close();
return APR_EBADF;
}
2025-05-09 16:53:07 +08:00
else if (!cfgFile_temp.open(QFile::ReadOnly | QFile::Text)) { // 如果文件无法打开
2025-04-29 15:05:36 +08:00
qDebug() << QString("Cannot open file %1:\n%2.").arg(cfgFileName_temp).arg(cfgFile_temp.errorString());
return APR_EBADF;
}
else {
QStringList datContentList_temp;
2025-05-09 16:53:07 +08:00
QTextStream in_temp(&cfgFile_temp); // 创建文本流读取文件
// 忽略 GBK 编码相关的代码(被注释掉了)
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QString start_time_str(""); // 用于存储起始时间字符串
QString trigger_time_str(""); // 用于存储触发时间字符串
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 按行读取配置文件内容
2025-04-29 15:05:36 +08:00
while (!in_temp.atEnd()) {
2025-05-09 16:53:07 +08:00
QString line_temp = in_temp.readLine().trimmed(); // 读取并去除空白字符
QString upper_line_temp = line_temp.toUpper(); // 转换为大写字符
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 如果读取到 "ASCII" 或 "BINARY" 字符串,则停止处理
2025-04-29 15:05:36 +08:00
if ((upper_line_temp == QString("ASCII")) || (upper_line_temp == QString("BINARY")))
break;
else {
2025-05-09 16:53:07 +08:00
// 如果没有,更新起始时间和触发时间
2025-04-29 15:05:36 +08:00
start_time_str = trigger_time_str;
trigger_time_str = line_temp;
}
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 如果提取到的 start_time_str 长度大于3则去掉最后3个字符通常是毫秒部分
2025-04-29 15:05:36 +08:00
if (start_time_str.size() > 3)
start_time_str = start_time_str.left(start_time_str.size() - 3);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 将 start_time_str 转换为 QDateTime 对象,并转换为自纪元以来的毫秒数
2025-04-29 15:05:36 +08:00
QDateTime start_time_dt = QDateTime::fromString(start_time_str, "dd/MM/yyyy,hh:mm:ss.zzz");
2025-05-09 16:53:07 +08:00
*start_tm = start_time_dt.toMSecsSinceEpoch(); // 转换为毫秒时间戳并赋值给 start_tm
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 同样处理触发时间去掉最后3个字符并转换为时间戳
2025-04-29 15:05:36 +08:00
if (trigger_time_str.size() > 3)
trigger_time_str = trigger_time_str.left(trigger_time_str.size() - 3);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QDateTime trigger_time_dt = QDateTime::fromString(trigger_time_str, "dd/MM/yyyy,hh:mm:ss.zzz");
2025-05-09 16:53:07 +08:00
*trig_tm = trigger_time_dt.toMSecsSinceEpoch(); // 转换为毫秒时间戳并赋值给 trig_tm
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
cfgFile_temp.close(); // 关闭文件
2025-04-29 15:05:36 +08:00
}
2025-05-09 16:53:07 +08:00
return APR_SUCCESS; // 成功返回
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//录波部分///////////////////////////////////////////////////////////////////////////////
//WW 2023-11-01 增加录波段号采用int类型匹配
2025-04-29 15:05:36 +08:00
int parse_file_names_by_fltnum(int fltnum, char* domname, char** filenames, int filenum, int* cfg_idx, int* dat_idx, char* file_base_name, char* file_yyyymm)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
int j;
printf(">>>>>>>>>>>>>>>>>>pares_file_names file list match fltnum=%d", fltnum);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
*cfg_idx = -1;
*dat_idx = -1;
for (j = 0; j < filenum; ++j) {
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
char fileNameTemp[64];
2025-05-09 16:53:07 +08:00
strcpy(fileNameTemp, filenames[j]); //临时存放 装置录波文件名
2025-04-29 15:05:36 +08:00
printf(" %s ", fileNameTemp);
2025-05-09 16:53:07 +08:00
if (strstr(fileNameTemp, domname) == NULL) //例:域名:"PQMonitor_PQM1" 不是 装置录波文件名:"PQMonitor_PQM1_000001_20191121_154534_689.CFG/.DAT/.HDR"的子串
2025-04-29 15:05:36 +08:00
continue;
char* p = strtok(fileNameTemp, "_"); //PQMonitor
p = strtok(NULL, "_"); //PQM1
p = strtok(NULL, "_"); //000001
2025-05-09 16:53:07 +08:00
int nFltNum = atoi(p); //将字符转换成整型
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (nFltNum == fltnum) {
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QString fn_str = QString::fromAscii(filenames[j]);
if (fn_str.endsWith(".cfg", Qt::CaseInsensitive) || fn_str.endsWith(".CFG", Qt::CaseInsensitive)) {
//PQMonitor_PQM4_000349_20180531_113701_618.CFG
*cfg_idx = j;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QFileInfo fi(fn_str);
QString fn = fi.baseName();
strcpy(file_base_name, fn.toAscii().data());
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QString remain_str = fn_str.split(QString::fromAscii(p)).at(1);
QString yyyymm_str = remain_str.mid(1, 6);
strcpy(file_yyyymm, yyyymm_str.toAscii().data());
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
else if (fn_str.endsWith(".dat", Qt::CaseInsensitive) || fn_str.endsWith(".DAT", Qt::CaseInsensitive))
*dat_idx = j;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if (*cfg_idx != -1 && *dat_idx != -1)//两个文件都已经找到
2025-04-29 15:05:36 +08:00
break;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
printf("\n<<<<<<<<<<<<<<<<<<<<<pares_file_names file list match end cfg_inx=%d dat_idx=%d \n", *cfg_idx, *dat_idx);
if ((*cfg_idx) >= 0 && (*dat_idx) >= 0)
return APR_SUCCESS;
else
return APR_EBADF;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
//WW2023-11-01 end
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//补招部分////////////////////////////////////////////////////////////////////////////////
2025-04-29 15:05:36 +08:00
void parse_recall(recall_xml_t* recall_xml, QString parentTag, QDomElement& recall_e, char* id)
{
recall_t recall;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
recall.line_id = id;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QDateTime start_dt = QDateTime::fromString(recall_e.attribute("StartTime"), "yyyy-MM-dd hh:mm:ss");
recall.start_time = start_dt.toMSecsSinceEpoch() / 1000;
QDateTime end_dt = QDateTime::fromString(recall_e.attribute("EndTime"), "yyyy-MM-dd hh:mm:ss");
recall.end_time = end_dt.toMSecsSinceEpoch() / 1000;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
recall.need_steady = recall_e.attribute("STEADY").toInt();
recall.need_voltage = recall_e.attribute("VOLTAGE").toInt();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
qDebug() << parentTag << "-> " << " " << recall.line_id << " " << recall.need_steady << " " << recall.need_voltage
<< " " << recall.start_time << " " << recall.end_time;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (parentTag == "Work") {
recall_xml->work_recalls[recall_xml->work_recall_num++] = recall;
}
else if (parentTag == "New") {
recall_xml->new_recalls[recall_xml->new_recall_num++] = recall;
}
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
int delete_recall_xml(char* id)
{
QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/recall");
QString file_name = QString(subdir) + QString("_") + QString(QString::number(g_front_seg_index, 10)) + QString("_") + QString(id) + QString("_") + QString("*") + QString("_Recall.xml");
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//指定文件夹名
2025-04-29 15:05:36 +08:00
QDir dir(cfg_dir);
if (!dir.exists()) {
qDebug() << "folder does not exist!";
return false;
}
2025-05-09 16:53:07 +08:00
//指定文件后缀名,可指定多种类型
2025-04-29 15:05:36 +08:00
QStringList filter(file_name);
2025-05-09 16:53:07 +08:00
//指定查找类型和排序,按最新的修改时间获取
2025-04-29 15:05:36 +08:00
QStringList files = dir.entryList(filter, QDir::Files | QDir::Readable | QDir::NoDotAndDotDot, QDir::Name | QDir::Time);
2025-05-09 16:53:07 +08:00
for (int i = 0; i < files.size(); i++) {//清空读取文件
2025-04-29 15:05:36 +08:00
QString qstrRecallPath = cfg_dir + QString("/") + files[i];
QFile::remove(qstrRecallPath);
}
return APR_SUCCESS;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
int parse_recall_xml(recall_xml_t* recall_xml, char* id)
{
2025-04-30 10:22:57 +08:00
2025-04-29 15:05:36 +08:00
QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/recall");
QString file_name = QString(subdir) + QString("_") + QString(QString::number(g_front_seg_index, 10)) + QString("_") + QString(id) + QString("_") + QString("*") + QString("_Recall.xml");
2025-05-09 16:53:07 +08:00
//lnk20241225这里文件名
//指定文件夹名
2025-04-29 15:05:36 +08:00
QDir dir(cfg_dir);
if (!dir.exists()) {
qDebug() << "folder does not exist!";
return false;
}
2025-05-09 16:53:07 +08:00
//指定文件后缀名,可指定多种类型
2025-04-29 15:05:36 +08:00
QStringList filter(file_name);
2025-05-09 16:53:07 +08:00
//指定查找类型和排序,按最新的修改时间获取
2025-04-29 15:05:36 +08:00
QStringList files = dir.entryList(filter, QDir::Files | QDir::Readable | QDir::NoDotAndDotDot, QDir::Name | QDir::Time);
for (int i = 0; i < files.size(); i++) {
QString qstrRecallPath = cfg_dir + QString("/") + files[i];
qDebug() << qstrRecallPath;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
QDomDocument doc; //新建QDomDocument类对象它代表一个XML文档
2025-04-29 15:05:36 +08:00
QFile file(qstrRecallPath);
if (!file.open(QIODevice::ReadOnly))
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
qDebug() << "file.open error";
2025-05-09 16:53:07 +08:00
continue; //以只读方式打开
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
bool ret = doc.setContent(&file);
file.close();
if (!ret)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
qDebug() << "doc.setContent error";
continue;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//将文件内容读到doc中
QDomElement docElem = doc.documentElement(); //返回根元素
QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点
while (!n.isNull()) { //如果节点不为空
if (n.isElement()) { //如果节点是元素
QDomElement e = n.toElement(); //将其转换为元素
2025-04-29 15:05:36 +08:00
QString strTag = e.tagName();
if (strTag == "Work" || strTag == "New") {
2025-05-09 16:53:07 +08:00
QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表
for (int i = 0; i < list.count(); i++) { //遍历该列表
2025-04-29 15:05:36 +08:00
QDomNode node = list.at(i);
if (node.isElement()) {
QDomElement recall_e = node.toElement();
QString strTag2 = recall_e.tagName();
if (strTag2 == "Recall") {
parse_recall(recall_xml, strTag, recall_e, id);
} //else if ( strTag == "Trigger" )
}
2025-01-16 16:17:01 +08:00
}
}
}
2025-05-09 16:53:07 +08:00
n = n.nextSibling(); //下一个兄弟节点
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-04-29 15:05:36 +08:00
return APR_SUCCESS;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
void process_recall_config(recall_xml_t* recall_xml)
{
int i, j;
recall_t* recall;
recall_t* recall_work;
int recall_num;
int need_write_file;
2025-05-09 16:53:07 +08:00
QList<RecallInfo> recallinfo_list_hour; //待补招队列-以小时为最大间隔
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
need_write_file = FALSE;
recall = recall_xml->new_recalls;
recall_num = recall_xml->new_recall_num;
for (i = 0; i < recall_num; i++) {
recall_xml->work_recalls[recall_xml->work_recall_num++] = recall[i];
need_write_file = TRUE;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
recall = recall_xml->work_recalls;
recall_num = recall_xml->work_recall_num;
if (recall_num > 0) {
LD_info_t* LD_info = find_LD_info_only_from_mp_id(recall[0].line_id);
printf("\n recall[0].line_id == %s \n", recall[0].line_id);
printf("\n recall[0].start_time == %d \n", recall[0].start_time);
2025-01-16 16:17:01 +08:00
if (LD_info == NULL || LD_info->read_flag == 0) {
2025-04-29 15:05:36 +08:00
printf("\n recall[0].line_id == NULL \n");
2025-01-16 16:17:01 +08:00
printf("\n Find LD_info == null \n");
}
else {
2025-04-29 15:05:36 +08:00
printf("\n Find LD_info != null \n");
if (LD_info->autorecallflag != 0 || LD_info->autorecallcount == 0) { //
if (LD_info->autorecallcount != 0) {
for (int j = 0; j < LD_info->autorecallcount; j++) {
delete LD_info->autorecall[j];
}
delete LD_info->autorecall;
LD_info->autorecallcount = 0;
}
LD_info->autorecallcount = recall_num;
LD_info->autorecall = new autorecall_t * [recall_num];
for (int j = 0; j < recall_num; j++) {
printf("\n %d ===== %d\n", recall[j].start_time, recall[j].end_time);
LD_info->autorecall[j] = new autorecall_t[1];
LD_info->autorecall[j]->start = recall[j].start_time;
LD_info->autorecall[j]->end = recall[j].end_time;
2025-05-09 16:53:07 +08:00
//lnk20241030补充补招稳态暂态标志每个文件都有很多条时间记录
2025-04-29 15:05:36 +08:00
LD_info->autorecall[j]->need_steady = recall[j].need_steady;
LD_info->autorecall[j]->need_voltage = recall[j].need_voltage;
}
LD_info->autorecallflag = 0;
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-04-29 15:05:36 +08:00
//////////////////////////////////////////////////////////////////////////////////
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
void WebSocketThread::run()
{
//if (g_node_id != THREE_SECS_DATA_BASE_NODE_ID)
// return;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
printf("WebSocketThread::run() is called ...... \n");
struct sockaddr_in client_sockaddr;
memset(&client_sockaddr, 0, sizeof(client_sockaddr));
socklen_t address_len = 0;
while (1) {
address_len = sizeof(struct sockaddr_in);
int client_socket = accept(server_socket, (struct sockaddr*)&client_sockaddr, &address_len);
if (client_socket == -1)
{
printf("accept client %s:%d failed,error msg=%s\n\a", inet_ntoa(client_sockaddr.sin_addr), htons(client_sockaddr.sin_port), strerror(errno));
continue;
}
2025-05-09 16:53:07 +08:00
printf("\naccept client %s:%d succesaddress_len= %dclient_socket= %d\n", inet_ntoa(client_sockaddr.sin_addr), htons(client_sockaddr.sin_port), address_len, client_socket);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
char buffer[256];
int iRet = 0;
while (1) {
memset(buffer, 0, sizeof(buffer));
int recvLength = recv(client_socket, buffer, sizeof(buffer), 0);
if (recvLength > 0)
{
iRet = HandleReceiveMessage(client_socket, buffer);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
//if (0 != iRet)
// iRet = SendMessageToWeb(client_socket, iRet);
break;
}
else
{
if (errno == EINTR)
continue;
printf("end socket client %d(%s:%d) msg,disconnetc Socket client\n", client_socket, inet_ntoa(client_sockaddr.sin_addr), htons(client_sockaddr.sin_port));
break;
}
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
close(client_socket);
printf("close socket client %d(%s:%d) \n", client_socket, inet_ntoa(client_sockaddr.sin_addr), htons(client_sockaddr.sin_port));
msleep(1);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
close(server_socket);
return;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
string MatchErrorMessage(int errorCode) //根据错误码匹配错误消息
2025-04-29 15:05:36 +08:00
{
string strErrorMessage = "";
switch (errorCode)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
case 0:
2025-05-09 16:53:07 +08:00
strErrorMessage = "success"; //"成功"
2025-04-29 15:05:36 +08:00
break;
default:
2025-05-09 16:53:07 +08:00
strErrorMessage = "error"; //"错误";
2025-04-29 15:05:36 +08:00
break;
//case 10002:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "Incorrect message length structure"; //"报文长度结构错误";
2025-04-29 15:05:36 +08:00
// break;
//case 10003:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "JSON string parsing error"; //"JSON字符串解析出错";
2025-04-29 15:05:36 +08:00
// break;
//case 10004:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "Socket handling error"; //"socket处理出现异常";
2025-04-29 15:05:36 +08:00
// break;
//case 10005:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "The device corresponding to ID was not found"; //"ID对应的装置未找到";
2025-04-29 15:05:36 +08:00
// break;
//case 10006:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "The monitoring point corresponding to ID has not been found"; //"ID对应的监测点未找到";
2025-04-29 15:05:36 +08:00
// break;
//case 10007:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "Wrong parameter passed in"; //"传入的参数异常";
2025-04-29 15:05:36 +08:00
// break;
//case 10008:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "The same type of operation is being performed"; //"有同一类型的操作正在执行";
2025-04-29 15:05:36 +08:00
// break;
//case 10009:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "The device turned off the corresponding function"; //"装置关闭了对应功能";
2025-04-29 15:05:36 +08:00
// break;
//case 10010:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "The TYPE parameter passed in is exceptional"; //"传入的TYPE参数异常";
2025-04-29 15:05:36 +08:00
// break;
//default:
2025-05-09 16:53:07 +08:00
// strErrorMessage = "An unknown error"; //"未知错误";
2025-04-29 15:05:36 +08:00
// break;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
return strErrorMessage;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
int SendMessageToWeb(int socketClient, int iErrorCode) //向Web Socket客户端发送消息
2025-04-29 15:05:36 +08:00
{
string strSendJson = "";
char cTemp[8];
string strErrorCode = "";
sprintf(cTemp, "%06d", iErrorCode);
strErrorCode = cTemp;
char sendBuffer[256];
int sendLength = 0;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
string strErrorMessage = MatchErrorMessage(iErrorCode);
//if (2 == Log_Enable)
2025-05-09 16:53:07 +08:00
// printf("错误码:%d匹配到的消息%s\n", iErrorCode, strErrorMessage.c_str());
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
strSendJson = "{\"errors\":\"" + strErrorMessage + "\",\"status\":\"" + strErrorCode + "\"}";
strcpy(sendBuffer, strSendJson.c_str());
sendLength = send(socketClient, strSendJson.c_str(), strSendJson.length() + 1, 0);
if (-1 == sendLength)
{
printf("server to client[%d] send[%d] message error,error message:%s\n", socketClient, iErrorCode, strSendJson.c_str());
return -1;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
//if (1 == Log_Enable)
2025-05-09 16:53:07 +08:00
// printf("服务端向客户端%d发送[%d]消息:%s\n", socketClient, iErrorCode, sendBuffer);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
return sendLength;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
int ExecuteWebCommand(LD_info_t* LD_info, int iType) //执行Web Socket命令消息
2025-04-29 15:05:36 +08:00
{
try
{
//if (1 == Log_Enable)
2025-05-09 16:53:07 +08:00
// printf(">>>线路%d\"%s\"iType= %dreal_data= %ssoe_data= %slimit= %dcount= %d\n", LD_info->line_id, LD_info->name,
2025-04-29 15:05:36 +08:00
// iType, 0 == LD_info->real_data ? "False" : "True", 0 == LD_info->soe_data ? "False" : "True", 20, LD_info->count);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (0 == iType || 1 == iType)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
LD_info->count = 0;
if (0 == iType)
{
LD_info->real_data = 1;
LD_info->soe_data = 1;
//if (1 == Log_Enable)
2025-05-09 16:53:07 +08:00
// printf(">>>触发%d\"%s\"iType= %dreal_data= %ssoe_data= %slimit= %dcount= %d\n", LD_info->line_id, LD_info->name,
2025-04-29 15:05:36 +08:00
// iType, 0 == LD_info->real_data ? "False" : "True", 0 == LD_info->soe_data ? "False" : "True", 20, LD_info->count);
}
else
{
//LD_info->heart_beat = 1;
//if (1 == Log_Enable)
2025-05-09 16:53:07 +08:00
// printf(">>>持续%d\"%s\"iType= %dreal_data= %ssoe_data= %slimit= %dcount= %d\n", LD_info->line_id, LD_info->name,
2025-04-29 15:05:36 +08:00
// iType, 0 == LD_info->real_data ? "False" : "True", 0 == LD_info->soe_data ? "False" : "True", 20, LD_info->count);
}
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
if (2 == iType)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
LD_info->real_data = 0;
LD_info->soe_data = 0;
//if (1 == Log_Enable)
2025-05-09 16:53:07 +08:00
// printf(">>>停止%d\"%s\"iType= %dreal_data= %ssoe_data= %slimit= %dcount= %d\n", LD_info->line_id, LD_info->name,
2025-04-29 15:05:36 +08:00
// iType, 0 == LD_info->real_data ? "False" : "True", 0 == LD_info->soe_data ? "False" : "True", 20, LD_info->count);
2025-01-16 16:17:01 +08:00
}
}
2025-04-29 15:05:36 +08:00
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
printf("触发/停止线路%d\"%s\"失败,原因:%s\n", LD_info->line_id, LD_info->name, e.what());
2025-04-29 15:05:36 +08:00
return 10004;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
return 10000;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
void Get_Recall_Time_Char(char* start_time, char* end_time, QList<RecallInfo>& recallinfo_list_hour) //数据完整性补招判断
2025-04-29 15:05:36 +08:00
{
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QDateTime start_dt = QDateTime::fromString(start_time, "yyyy-MM-dd HH:mm:ss");
QDateTime end_dt = QDateTime::fromString(end_time, "yyyy-MM-dd HH:mm:ss");
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
long long starttime = start_dt.toMSecsSinceEpoch() / 1000; //补招起始时间
long long endtime = end_dt.toMSecsSinceEpoch() / 1000; //补招结束时间
QList<long long> timestamp_list; //数据库完整性记录时间点
QList<RecallInfo> recallinfo_list; //待补招队列
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
RecallInfo info;
info.starttime = starttime;
info.endtime = endtime;
recallinfo_list.append(info);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
for (int i = 0; i < recallinfo_list.size(); i++)
{
//printf("\n %lld ----- %11d\n", recallinfo_list[i].starttime, recallinfo_list[i].endtime);
long long duration = recallinfo_list[i].endtime - recallinfo_list[i].starttime;
long long max_interval = 3600;
for (long long j = 0; j <= duration; j += max_interval)
{
if (j + max_interval > duration) {
long long start = recallinfo_list[i].starttime + j;
long long end = recallinfo_list[i].endtime;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
RecallInfo info;
info.starttime = start;
info.endtime = end;
recallinfo_list_hour.append(info);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
else {
long long start = recallinfo_list[i].starttime + j;
long long end = recallinfo_list[i].starttime + j + max_interval;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
RecallInfo info;
info.starttime = start;
info.endtime = end - 1;
recallinfo_list_hour.append(info);
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-04-29 15:05:36 +08:00
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
int HandleReceiveMessage(int socketClient, char buffer[256]) //接收并处理Web Socket客户端发来的信息
2025-04-29 15:05:36 +08:00
{
int iErrorCode = 000000;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
try
{
QString qstrBuffer = QString(QLatin1String(buffer));
2025-05-09 16:53:07 +08:00
printf("来自ffe客户端%d消息qstrBur= %s\n", socketClient, qstrBuffer.toAscii().data());
cJSON* json_root = cJSON_Parse(qstrBuffer.toUtf8().constData()); //json格式序列化
2025-04-29 15:05:36 +08:00
if (json_root == NULL) {
return 10000;
}
2025-05-09 16:53:07 +08:00
QString qstrCode = NULL;//记录指令
2025-04-29 15:05:36 +08:00
cJSON* json_code = NULL;
cJSON* json_param = NULL;
cJSON* json_program_param = NULL;
cJSON* json_recall_param = NULL;
cJSON* json_wave_param = NULL;
cJSON* json_update_time = NULL;
cJSON* json_node = NULL;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QString update_time;
QList<QString> wave_param;
ProgramParam program_param;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
json_code = cJSON_GetObjectItem(json_root, "code"); //获取code
2025-04-29 15:05:36 +08:00
if (json_code != NULL) {
qstrCode = json_code->valuestring;
}
else {
return 10000;
}
2025-05-09 16:53:07 +08:00
json_param = cJSON_GetObjectItem(json_root, "param"); //获取param
2025-04-29 15:05:36 +08:00
if (json_param == NULL) {
return 10000;
}
if (qstrCode == "dev_update" || qstrCode == "model_update" || qstrCode == "program_update") {
2025-05-09 16:53:07 +08:00
//设备更新记录更新时间
json_update_time = cJSON_GetObjectItem(json_param, "update_time"); //获取update_time
2025-04-29 15:05:36 +08:00
if (json_update_time != NULL) {
update_time = json_update_time->valuestring;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
}
else if (qstrCode == "manual_wave") {
2025-05-09 16:53:07 +08:00
//手动录波:功能未完成
json_wave_param = cJSON_GetObjectItem(json_param, "wave_param"); //获取wave_param
int array_size = cJSON_GetArraySize(json_wave_param); //获取数组大小
2025-04-29 15:05:36 +08:00
int i;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
for (i = 0; i < array_size; i++)
{
json_node = cJSON_GetArrayItem(json_wave_param, i);//array
if (json_node != NULL) {
wave_param.append(json_node->valuestring);
}
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
}
else if (qstrCode == "model_update") {
2025-05-09 16:53:07 +08:00
//程序参数:终端列表和程序文件
json_program_param = cJSON_GetObjectItem(json_param, "program_param"); //获取program_param
2025-04-29 15:05:36 +08:00
cJSON* json_temp = NULL;
2025-05-09 16:53:07 +08:00
json_temp = cJSON_GetObjectItem(json_program_param, "terminal_list"); //获取
int array_size = cJSON_GetArraySize(json_temp); //获取数组大小
2025-04-29 15:05:36 +08:00
int i;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
for (i = 0; i < array_size; i++)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
json_node = cJSON_GetArrayItem(json_temp, i);//array
if (json_node != NULL) {
program_param.terminal_list.append(json_node->valuestring);
}
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
json_node = cJSON_GetObjectItem(json_program_param, "file_name"); //获取file_name
2025-04-29 15:05:36 +08:00
if (json_node != NULL) {
program_param.file_name = json_node->valuestring;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
}
2025-05-09 16:53:07 +08:00
else if (qstrCode == "manual_recall") {//手动补招的指令
//补招参数
json_recall_param = cJSON_GetObjectItem(json_param, "recall_param"); //获取recall_param
2025-04-29 15:05:36 +08:00
cJSON* json_temp = NULL;
2025-05-09 16:53:07 +08:00
int array_size = cJSON_GetArraySize(json_recall_param); //获取数组大小
2025-04-29 15:05:36 +08:00
int i;
QList<RecallInfo> recallinfo_list_hour;
char start_time[64];
char end_time[64];
QString mp_id;
for (i = 0; i < array_size; i++)
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
json_temp = cJSON_GetArrayItem(json_recall_param, i);//array
if (json_temp != NULL) {
2025-05-09 16:53:07 +08:00
json_node = cJSON_GetObjectItem(json_temp, "mp_id"); //获取mp_id
2025-04-29 15:05:36 +08:00
if (json_node != NULL) {
mp_id = QString::fromUtf8(json_node->valuestring);
}
if (i == 0) {
2025-05-09 16:53:07 +08:00
json_node = cJSON_GetObjectItem(json_temp, "start"); //获取start
2025-04-29 15:05:36 +08:00
if (json_node != NULL) {
apr_snprintf(start_time, sizeof(start_time), "%s", json_node->valuestring);//start_time
}
2025-05-09 16:53:07 +08:00
json_node = cJSON_GetObjectItem(json_temp, "end"); //获取end
2025-04-29 15:05:36 +08:00
if (json_node != NULL) {
apr_snprintf(end_time, sizeof(end_time), "%s", json_node->valuestring);//end_time
}
Get_Recall_Time_Char(start_time, end_time, recallinfo_list_hour);
}
for (int j = 0; j < recallinfo_list_hour.size(); j++) {
CJournalRecall jr;
jr.MonitorID = mp_id;
jr.StartTime = QDateTime::fromTime_t(recallinfo_list_hour[j].starttime).toString("yyyy-MM-dd hh:mm:ss");
jr.EndTime = QDateTime::fromTime_t(recallinfo_list_hour[j].endtime).toString("yyyy-MM-dd hh:mm:ss");
2025-05-09 16:53:07 +08:00
jr.STEADY = QString::number(1, 10);//默认都是11的十进制转化
2025-04-29 15:05:36 +08:00
jr.VOLTAGE = QString::number(1, 10);
g_StatisticLackList_list_mutex.lock();
g_StatisticLackList.push_back(jr);
g_StatisticLackList_list_mutex.unlock();
}
2025-01-16 16:17:01 +08:00
}
}
2025-04-29 15:05:36 +08:00
}
cJSON_Delete(json_root);
2025-05-09 16:53:07 +08:00
SendMessageToWeb(socketClient, 000000);//响应web
2025-04-29 15:05:36 +08:00
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
printf("处理客户端:%d发送的消息错误原因%s\n", socketClient, e.what());
2025-04-29 15:05:36 +08:00
return 10004;
}
return 000000;
}
2025-04-30 10:22:57 +08:00
///////////////////////////////////////////////////////////////////////////////////////
2025-04-29 15:05:36 +08:00
void Cout_account_information() {
ied_t* ied = NULL;
int iedno;
LD_info_t* LD_info = NULL;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
for (iedno = 0; iedno < g_node->n_clients; iedno++) {
ied = g_node->clients[iedno];
if (ied) {
LD_info_t* LD_info = NULL;
ied_usr_t* ied_usr = GET_IEDEXT_ADDR(ied);
int cpuno;
2025-05-09 16:53:07 +08:00
QString text;//待组装的pgsql语句
2025-04-29 15:05:36 +08:00
text.append(QString("terminal_code: \"%1\" ,ip:\"%2\" ,port:\"%3\" ,cpucount:\"%4\" ").arg(ied_usr->terminal_code).arg(ied->channel[0].addr_str).arg(ied->channel[0].port).arg(ied->cpucount));
add_comm_log(const_cast<char*>(text.toLocal8Bit().constData()));
for (cpuno = 0; cpuno < ied->cpucount; cpuno++) {
LD_info = &(ied_usr->LD_info[cpuno]);
2025-05-09 16:53:07 +08:00
QString text2;//待组装的pgsql语句
2025-04-29 15:05:36 +08:00
text2.append(QString("mp_id: \"%1\" terminal_code:\"%2\" ").arg(LD_info->mp_id).arg(LD_info->terminal_code));
add_comm_log(const_cast<char*>(text2.toLocal8Bit().constData()));
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-04-29 15:05:36 +08:00
/// <summary>
2025-05-09 16:53:07 +08:00
/// 删除过期的xml
2025-04-29 15:05:36 +08:00
/// </summary>
void DeletcRecallXml() {
QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/recall");
QString file_name = QString(subdir) + QString("_") + QString("*") + QString("_Recall.xml");
2025-05-09 16:53:07 +08:00
//指定文件夹名
2025-04-29 15:05:36 +08:00
QDir dir(cfg_dir);
if (!dir.exists()) {
qDebug() << "folder does not exist!";
return;
}
QStringList filter(file_name);
2025-05-09 16:53:07 +08:00
//指定查找类型和排序,按最新的修改时间获取
2025-04-29 15:05:36 +08:00
QStringList files = dir.entryList(filter, QDir::Files | QDir::Readable | QDir::NoDotAndDotDot, QDir::Name | QDir::Time);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 设定过滤的日期和时间
2025-04-29 15:05:36 +08:00
QDateTime saveDaysAgo = QDateTime::currentDateTime().addDays(-2);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
for (int i = 0; i < files.size(); i++) {//清空读取文件
2025-04-29 15:05:36 +08:00
QFileInfo fileInfo(dir.filePath(files[i]));
if (fileInfo.lastModified() < saveDaysAgo) {
QFile::remove(fileInfo.absoluteFilePath());
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-04-29 15:05:36 +08:00
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
void CreateRecallXml()
{
apr_time_t previousTime = apr_time_now();
long long stamp = static_cast<long long>(previousTime) / 1000000;
QDateTime deltime_Qtime = QDateTime::fromTime_t(stamp);
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
g_StatisticLackList_list_mutex.lock();
if (g_StatisticLackList.size() > 0)
{
2025-05-09 16:53:07 +08:00
printf("insert ID_CJournalRecall_Map\n");
2025-04-29 15:05:36 +08:00
QMap<QString, QList<CJournalRecall> > ID_CJournalRecall_Map;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
list<CJournalRecall>::iterator sl = g_StatisticLackList.begin();
while (sl != g_StatisticLackList.end())
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
CJournalRecall jr = *sl++;
if (ID_CJournalRecall_Map.contains(jr.MonitorID))
{
ID_CJournalRecall_Map[jr.MonitorID].append(jr);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
else
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
QList<CJournalRecall> TempList;
TempList.append(jr);
ID_CJournalRecall_Map.insert(jr.MonitorID, TempList);
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-04-29 15:05:36 +08:00
for (QMap<QString, QList<CJournalRecall> >::iterator it2 = ID_CJournalRecall_Map.begin(); it2 != ID_CJournalRecall_Map.end(); ++it2)
{
QString key2 = it2.key();
QList<CJournalRecall> value2 = it2.value();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/recall/");
QString qstrRecallPath = cfg_dir + QString(subdir) + QString("_") + QString(QString::number(g_front_seg_index, 10)) + QString("_") + key2 + QString("_") + QString(deltime_Qtime.toString("yyyyMMddhhmmss")) + QString("_Recall.xml");
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
std::string strRecallPath = qstrRecallPath.toStdString();
QFile file(strRecallPath.c_str());
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2025-05-09 16:53:07 +08:00
printf("补招查询完成,打开%s失败,无法写入线路补招配置!\n", qstrRecallPath.toAscii().data());
2025-04-29 15:05:36 +08:00
QMap<QString, QList<CJournalRecall> >().swap(ID_CJournalRecall_Map);
return;
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
QXmlStreamWriter writer(&file);
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeStartElement("RecallList");
writer.writeStartElement("Work");
writer.writeEndElement();
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
writer.writeStartElement("New");
while (!value2.isEmpty())
2025-01-16 16:17:01 +08:00
{
2025-04-29 15:05:36 +08:00
CJournalRecall jr = value2.takeFirst();
writer.writeStartElement("Recall");
writer.writeAttribute("MonitorID", jr.MonitorID);
writer.writeAttribute("StartTime", jr.StartTime);
writer.writeAttribute("EndTime", jr.EndTime);
writer.writeAttribute("STEADY", jr.STEADY);
writer.writeAttribute("VOLTAGE", jr.VOLTAGE);
writer.writeEndElement();
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
writer.writeEndElement();
writer.writeEndElement();
writer.writeEndDocument();
file.close();
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
QMap<QString, QList<CJournalRecall> >().swap(ID_CJournalRecall_Map);
}
g_StatisticLackList.clear();
g_StatisticLackList_list_mutex.unlock();
}
2025-05-09 16:53:07 +08:00
///////zw修改 2023-8-30 end
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
/*/////////////////////////////////////////////////////////lnk2024-10-11移除sql的测试代码/////////////////////////////////////////////////////////////*/
2025-04-29 15:05:36 +08:00
std::string intToString(int number) {
if (number == 0) return "0";
std::string str;
bool isNegative = number < 0;
if (isNegative) number = -number;
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
while (number > 0) {
str.insert(str.begin(), '0' + (number % 10));
number /= 10;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
if (isNegative) str.insert(str.begin(), '-');
return str;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
otl_datetime parseTimestamp(const std::string timestampStr) {
otl_datetime timestamp;
2025-05-09 16:53:07 +08:00
// 定义年、月、日、时、分、秒变量
2025-04-29 15:05:36 +08:00
int year, month, day, hour, minute, second;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 使用字符串流进行解析
2025-04-29 15:05:36 +08:00
std::istringstream ss(timestampStr);
2025-05-09 16:53:07 +08:00
char discard; // 用于丢弃分隔符
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 解析字符串
2025-04-29 15:05:36 +08:00
ss >> year >> discard >> month >> discard >> day >> hour >> discard >> minute >> discard >> second;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 将解析的值赋给 otl_datetime
2025-04-29 15:05:36 +08:00
timestamp.year = year;
timestamp.month = month;
timestamp.day = day;
timestamp.hour = hour;
timestamp.minute = minute;
timestamp.second = second;
return timestamp;
}
size_t req_reply_web(void* ptr, size_t size, size_t nmemb, void* stream)
{
string* str = (string*)stream;
(*str).append((char*)ptr, size * nmemb);
return size * nmemb;
}
2025-01-16 16:17:01 +08:00
2025-04-29 15:05:36 +08:00
void SendWebAPI_web(const string strUrl, const char* code, char** ptr)
{
2025-05-09 16:53:07 +08:00
// curl初始化
2025-04-29 15:05:36 +08:00
CURL* curl = curl_easy_init();
2025-05-09 16:53:07 +08:00
// curl返回值
2025-04-29 15:05:36 +08:00
CURLcode res;
if (curl)
{
char url[100];
sprintf(url, "%s?%s", strUrl.c_str(), code);
2025-05-09 16:53:07 +08:00
//printf(">>>json %s\n", url);//减少不必要的打印
// 设置URL
2025-04-29 15:05:36 +08:00
curl_easy_setopt(curl, CURLOPT_URL, url);
2025-05-09 16:53:07 +08:00
//设置数据接收和写入函数
2025-04-29 15:05:36 +08:00
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//数据接收
2025-04-29 15:05:36 +08:00
string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//设置超时时间
2025-04-29 15:05:36 +08:00
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//设置header
2025-04-29 15:05:36 +08:00
curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
2025-05-09 16:53:07 +08:00
// 开启post请求
2025-04-29 15:05:36 +08:00
res = curl_easy_perform(curl);
2025-05-09 16:53:07 +08:00
// 检查请求是否成功
2025-04-29 15:05:36 +08:00
if (res != CURLE_OK) {
printf("web failed res code: ");
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
else {
printf(">>> web return str:%s \n", resPost0.c_str());
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
*ptr = (char*)malloc(strlen(resPost0.c_str()) + 1); // 分配足够的内存空间
2025-04-29 15:05:36 +08:00
if (*ptr != NULL) {
strcpy(*ptr, resPost0.c_str());
}
else {
printf("Memory allocation failed!\n");
}
}
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
else
{
printf(">>> web curl init failed");
}
curl_easy_cleanup(curl);
2025-01-16 16:17:01 +08:00
}
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
/*/////////////////////////////////////////////////////////lnk10-24根据web接口修改/////////////////////////////////////////////////////////////*/
//添加了json字符串的入参
// 回调函数,将数据直接追加到 *ptr 中
2025-01-16 16:17:01 +08:00
size_t req_reply_http(void* contents, size_t size, size_t nmemb, void* userp) {
size_t realsize = size * nmemb;
2025-04-02 15:16:11 +08:00
char** responsePtr = (char**)userp;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
size_t oldLen = strlen(*responsePtr); // 当前已有长度
char* temp = (char*)realloc(*responsePtr, oldLen + realsize + 1); // +1 留空间给 '\0'
2025-01-16 16:17:01 +08:00
if (temp == NULL) {
2025-04-02 15:16:11 +08:00
printf("Memory reallocation failed!\n");
return 0;
2025-01-16 16:17:01 +08:00
}
2025-04-02 15:16:11 +08:00
*responsePtr = temp;
2025-05-09 16:53:07 +08:00
memcpy(*responsePtr + oldLen, contents, realsize); // 直接拷贝原始数据
(*responsePtr)[oldLen + realsize] = '\0'; // 手动添加字符串结束符
2025-04-02 15:16:11 +08:00
2025-01-16 16:17:01 +08:00
return realsize;
}
void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr) {
CURL* curl = curl_easy_init();
CURLcode res;
2025-05-09 16:53:07 +08:00
// 初始化 *ptr 并分配空字符串
2025-01-16 16:17:01 +08:00
*ptr = (char*)malloc(1);
if (*ptr == NULL) {
printf("Memory allocation failed!\n");
return;
}
2025-05-09 16:53:07 +08:00
(*ptr)[0] = '\0'; // 为空字符串以便 strncat 操作
2025-01-16 16:17:01 +08:00
if (curl) {
char url[256];
snprintf(url, sizeof(url), "%s?%s", strUrl.c_str(), code);
2025-05-09 16:53:07 +08:00
//printf(">>>json %s\n", url);//减少不必要的打印
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_http);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
if (!json.empty()) {
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
}
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
printf("web failed res code: %s\n", curl_easy_strerror(res));
} else {
//printf(">>> web return str: %s \n", *ptr);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
} else {
printf(">>> web curl init failed\n");
}
}
/*void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr) {
2025-05-09 16:53:07 +08:00
// curl 初始化
2025-01-16 16:17:01 +08:00
CURL* curl = curl_easy_init();
CURLcode res;
if (curl) {
char url[100];
sprintf(url, "%s?%s", strUrl.c_str(), code);
printf(">>>json %s\n", url);
2025-05-09 16:53:07 +08:00
// 设置 URL
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_URL, url);
2025-05-09 16:53:07 +08:00
// 设置数据接收和写入函数
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web);
2025-05-09 16:53:07 +08:00
// 数据接收
2025-01-16 16:17:01 +08:00
std::string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
2025-05-09 16:53:07 +08:00
// 设置超时时间
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
if(json != ""){
2025-05-09 16:53:07 +08:00
// 设置 HTTP 方法为 POST
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_POST, 1L);
2025-05-09 16:53:07 +08:00
// 设置 JSON 格式的 body 数据
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
}
2025-05-09 16:53:07 +08:00
// 设置请求头
2025-01-16 16:17:01 +08:00
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
2025-05-09 16:53:07 +08:00
// 执行请求
2025-01-16 16:17:01 +08:00
res = curl_easy_perform(curl);
2025-05-09 16:53:07 +08:00
// 检查请求是否成功
2025-01-16 16:17:01 +08:00
if (res != CURLE_OK) {
printf("web failed res code: %s\n", curl_easy_strerror(res));
} else {
printf(">>> web return str: %s \n", resPost0.c_str());
2025-05-09 16:53:07 +08:00
// 分配内存并复制返回结果
*ptr = (char*)malloc(resPost0.size() + 1); // 分配足够的内存空间
2025-01-16 16:17:01 +08:00
if (*ptr != NULL) {
strcpy(*ptr, resPost0.c_str());
} else {
printf("Memory allocation failed!\n");
}
}
2025-05-09 16:53:07 +08:00
// 清理请求头
2025-01-16 16:17:01 +08:00
curl_slist_free_all(headers);
} else {
printf(">>> web curl init failed");
}
curl_easy_cleanup(curl);
}*/
2025-05-09 16:53:07 +08:00
// 打印 terminal_dev_map 中所有内容的函数
2025-01-16 16:17:01 +08:00
void printTerminalDevMap(const QMap<QString, terminal_dev*>& terminal_dev_map) {
QMap<QString, terminal_dev*>::const_iterator it;
for (it = terminal_dev_map.constBegin(); it != terminal_dev_map.constEnd(); ++it) {
QString key = it.key();
terminal_dev* dev = it.value();
if (dev) {
qDebug() << "Key:" << key
<< ", Terminal ID:" << QString(dev->terminal_id)
<< ", Terminal Code:" << QString(dev->terminal_code)
<< ", Organization Name:" << QString(dev->org_name)
<< ", Maintenance Name:" << QString(dev->maint_name)
<< ", Station Name:" << QString(dev->station_name)
<< ", Factory:" << QString(dev->tmnl_factory)
<< ", Status:" << QString(dev->tmnl_status)
<< ", Device Type:" << QString(dev->dev_type)
<< ", Device Key:" << QString(dev->dev_key)
<< ", Device Series:" << QString(dev->dev_series)
2025-02-10 17:03:15 +08:00
<< ", Device processNo:" << QString(dev->processNo)
2025-01-16 16:17:01 +08:00
<< ", Address:" << QString(dev->addr_str)
<< ", Port:" << QString(dev->port)
<< ", Timestamp:" << QString(dev->timestamp);
2025-05-09 16:53:07 +08:00
// 打印监测点信息
2025-01-16 16:17:01 +08:00
for (int i = 0; i < 10; ++i) {
qDebug() << " Monitor ID:" << QString(dev->line[i].monitor_id)
<< ", Terminal Code:" << QString(dev->line[i].terminal_code)
<< ", Monitor Name:" << QString(dev->line[i].monitor_name)
<< ", Logical Device Seq:" << QString(dev->line[i].logical_device_seq)
<< ", Voltage Level:" << QString(dev->line[i].voltage_level)
<< ", Terminal Connect:" << QString(dev->line[i].terminal_connect)
<< ", Timestamp:" << QString(dev->line[i].timestamp)
<< ", Status:" << QString(dev->line[i].status);
}
} else {
qDebug() << "Key:" << key << ", Value is nullptr";
}
}
}
2025-05-09 16:53:07 +08:00
//打印当前进程的台账//////////////////////////////////////////////////////////////////////////
// 打印结构体信息的递归函数
2025-01-16 16:17:01 +08:00
void printLedger(const ied_usr_t& ied_usr) {
std::cout << "------------------------------------" << std::endl;
std::cout << "|-- terminal_id: " << ied_usr.terminal_id << std::endl;
std::cout << "|-- dev_index: " << ied_usr.dev_idx << std::endl;
std::cout << "|-- dev_type: " << ied_usr.dev_type << std::endl;
std::cout << "|-- dev_key: " << ied_usr.dev_key << std::endl;
std::cout << "|-- dev_series: " << ied_usr.dev_series << std::endl;
std::cout << "|-- dev_flag: " << ied_usr.dev_flag << std::endl;
std::cout << "|-- last_call_wavelist_time: " << ied_usr.last_call_wavelist_time << std::endl;
std::cout << "|-- org_name: " << ied_usr.org_name << std::endl;
std::cout << "|-- maint_name: " << ied_usr.maint_name << std::endl;
std::cout << "|-- station_name: " << ied_usr.station_name << std::endl;
std::cout << "|-- tmnl_factory: " << ied_usr.tmnl_factory << std::endl;
std::cout << "|-- time: " << ied_usr.time << std::endl;
std::cout << "|-- tmnl_status: " << ied_usr.tmnl_status << std::endl;
std::cout << "|-- terminal_code: " << ied_usr.terminal_code << std::endl;
std::cout << "|-- update_flag: " << ied_usr.update_flag << std::endl;
2025-05-09 16:53:07 +08:00
// 打印每个LD_info的内容
2025-01-16 16:17:01 +08:00
for (int i = 0; i < 10; ++i) {
if (strcmp(ied_usr.LD_info[i].mp_id, "") != 0) {
std::cout << "|-- LD_info[" << i << "]:" << std::endl;
//name
std::cout << " |-- name: " << ied_usr.LD_info[i].name << std::endl;
std::cout << " |-- LD_name: "
<< (strlen(ied_usr.LD_info[i].LD_name) == 0 ? "NA" : ied_usr.LD_info[i].LD_name)
<< std::endl;
std::cout << " |-- read_flag: " << ied_usr.LD_info[i].read_flag << std::endl;
//index
std::cout << " |-- line_id: " << ied_usr.LD_info[i].line_id << std::endl;
//monitorledger
std::cout << " |-- mp_id: " << ied_usr.LD_info[i].mp_id << std::endl;
std::cout << " |-- terminal_code: " << ied_usr.LD_info[i].terminal_code << std::endl;
std::cout << " |-- voltage_level: " << ied_usr.LD_info[i].voltage_level << std::endl;
std::cout << " |-- v_wiring_type: " << ied_usr.LD_info[i].v_wiring_type << std::endl;
std::cout << " |-- time: " << ied_usr.LD_info[i].time << std::endl;
std::cout << " |-- update_flag: " << ied_usr.LD_info[i].update_flag << std::endl;
std::cout << " |-- monitor_status: " << ied_usr.LD_info[i].monitor_status << std::endl;
2025-05-09 16:53:07 +08:00
//count暂不打印数组
2025-01-16 16:17:01 +08:00
std::cout << " |-- rptcount: " << ied_usr.LD_info[i].rptcount << std::endl;
std::cout << " |-- logcount: " << ied_usr.LD_info[i].logcount << std::endl;
//rpt
std::cout << " |-- rptRecvFlag: " << ied_usr.LD_info[i].rptRecvFlag << std::endl;
std::cout << " |-- rptRecvCheckFlag: " << ied_usr.LD_info[i].rptRecvCheckFlag << std::endl;
std::cout << " |-- rptPstRecvFlag: " << ied_usr.LD_info[i].rptPstRecvFlag << std::endl;
std::cout << " |-- rptPstRecvCheckFlag: " << ied_usr.LD_info[i].rptPstRecvCheckFlag << std::endl;
//rtdata
std::cout << " |-- real_data: " << ied_usr.LD_info[i].real_data << std::endl;
std::cout << " |-- soe_data: " << ied_usr.LD_info[i].soe_data << std::endl;
std::cout << " |-- limit: " << ied_usr.LD_info[i].limit << std::endl;
std::cout << " |-- count: " << ied_usr.LD_info[i].count << std::endl;
//RDRE
std::cout << " |-- RDRE_FltNum: " << ied_usr.LD_info[i].RDRE_FltNum << std::endl;
for (int j = 0; j < 256; ++j) {
if (ied_usr.LD_info[i].FltNum[j] != 0) {
std::cout << " |-- FltNum[" << j << "]:" << ied_usr.LD_info[i].FltNum[j] << std::endl;
}
}
//QVVR
std::cout << " |-- qvvr_idx: " << ied_usr.LD_info[i].qvvr_idx << std::endl;
std::cout << " |-- QVVRs:" << std::endl;
for (int j = 0; j < 256; ++j) {
if (ied_usr.LD_info[i].qvvr[j].used_status != 0) {
std::cout << " |-- QVVR[" << j << "]:" << std::endl;
std::cout << " |-- used_status: " << ied_usr.LD_info[i].qvvr[j].used_status << std::endl;
std::cout << " |-- QVVR_start: " << ied_usr.LD_info[i].qvvr[j].QVVR_start << std::endl;
std::cout << " |-- QVVR_type: " << ied_usr.LD_info[i].qvvr[j].QVVR_type << std::endl;
std::cout << " |-- QVVR_time: " << ied_usr.LD_info[i].qvvr[j].QVVR_time << std::endl;
std::cout << " |-- QVVR_PerTime: " << ied_usr.LD_info[i].qvvr[j].QVVR_PerTime << std::endl;
std::cout << " |-- QVVR_Amg: " << ied_usr.LD_info[i].qvvr[j].QVVR_Amg << std::endl;
std::cout << " |-- QVVR_Rptname: " << ied_usr.LD_info[i].qvvr[j].QVVR_Rptname << std::endl;
std::cout << " |-- timestamp: " << ied_usr.LD_info[i].qvvr[j].timestamp << std::endl;
}
}
}
}
std::cout << "------------------------------------" << std::endl;
}
void printLedgerinshell(const ied_usr_t& ied_usr, QIODevice* outputDevice) {
2025-02-21 16:24:41 +08:00
ied_t* ied;
ied = find_ied_from_dev_idx(ied_usr.dev_idx);
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write("------------------------------------\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- terminal_id: " + QByteArray(ied_usr.terminal_id) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_index: " + QByteArray::number(ied_usr.dev_idx) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_cpucount: " + QByteArray::number(ied->cpucount) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_ip: " + QByteArray(ied->channel[0].addr_str) + "\n");
2025-05-09 16:53:07 +08:00
char portStr[20]; // 用于存放端口号的字符串
sprintf(portStr, "%u", ied->channel[0].port); // 将端口号转为字符串
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_port: " + QByteArray(portStr) + "\n");
2025-02-21 16:24:41 +08:00
2025-05-09 16:53:07 +08:00
char statusStr[20]; // 用于存放状态的字符串
sprintf(statusStr, "%u", ied->channel[0].status); // 将连接状态转为字符串
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_connect_status: " + QByteArray(statusStr) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_type: " + QByteArray(ied_usr.dev_type) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_key: " + QByteArray(ied_usr.dev_key) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_series: " + QByteArray(ied_usr.dev_series) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_processNo: " + QByteArray(ied_usr.processNo) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_flag: " + QByteArray::number(ied_usr.dev_flag) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- last_call_wavelist_time: " + QByteArray::number(ied_usr.last_call_wavelist_time) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- org_name: " + QByteArray(ied_usr.org_name) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- maint_name: " + QByteArray(ied_usr.maint_name) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- station_name: " + QByteArray(ied_usr.station_name) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- tmnl_factory: " + QByteArray(ied_usr.tmnl_factory) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- time: " + QByteArray::number(ied_usr.time) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- tmnl_status: " + QByteArray(ied_usr.tmnl_status) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- terminal_code: " + QByteArray(ied_usr.terminal_code) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- update_flag: " + QByteArray::number(ied_usr.update_flag) + "\n");
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 打印每个LD_info的内容
2025-01-16 16:17:01 +08:00
for (int i = 0; i < 10; ++i) {
if (strcmp(ied_usr.LD_info[i].mp_id, "") != 0) {
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write("|-- LD_info[" + QByteArray::number(i) + "]:\n");
2025-01-16 16:17:01 +08:00
// name
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- name: " + QByteArray(ied_usr.LD_info[i].name) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- LD_name: "
2025-01-16 16:17:01 +08:00
+ (strlen(ied_usr.LD_info[i].LD_name) == 0 ? QByteArray("NA") : QByteArray(ied_usr.LD_info[i].LD_name))
+ "\n");
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- read_flag: " + QByteArray::number(ied_usr.LD_info[i].read_flag) + "\n");
2025-01-16 16:17:01 +08:00
// index
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- line_id: " + QByteArray::number(ied_usr.LD_info[i].line_id) + "\n");
2025-01-16 16:17:01 +08:00
// monitorledger
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- mp_id: " + QByteArray(ied_usr.LD_info[i].mp_id) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- terminal_code: " + QByteArray(ied_usr.LD_info[i].terminal_code) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- voltage_level: " + QByteArray(ied_usr.LD_info[i].voltage_level) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- v_wiring_type: " + QByteArray(ied_usr.LD_info[i].v_wiring_type) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- time: " + QByteArray::number(ied_usr.LD_info[i].time) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- update_flag: " + QByteArray::number(ied_usr.LD_info[i].update_flag) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- monitor_status: " + QByteArray(ied_usr.LD_info[i].monitor_status) + "\n");
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// count暂不打印数组
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptcount: " + QByteArray::number(ied_usr.LD_info[i].rptcount) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- logcount: " + QByteArray::number(ied_usr.LD_info[i].logcount) + "\n");
2025-01-16 16:17:01 +08:00
2025-03-07 18:27:03 +08:00
//recall
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- autorecallflag: " + QByteArray::number(ied_usr.LD_info[i].autorecallflag) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- autorecallcount: " + QByteArray::number(ied_usr.LD_info[i].autorecallcount) + "\n");
2025-03-13 16:35:19 +08:00
for (int j = 0;
j < ied_usr.LD_info[i].autorecallcount &&
2025-05-09 16:53:07 +08:00
ied_usr.LD_info[i].autorecall != NULL && // 保护 LD_info->autorecall 本身
2025-03-13 16:35:19 +08:00
ied_usr.LD_info[i].autorecall[j] != NULL;
j++)
{
outputDevice->write("\r\x1B[K");
outputDevice->write(" |-- autorecall_t[" + QByteArray::number(j) + "]:\n");
if (ied_usr.LD_info[i].autorecall[j] == NULL) {
outputDevice->write(" |-- [Error] autorecall[j] is NULL\n");
2025-05-09 16:53:07 +08:00
continue; // 避免访问 NULL 指针
2025-03-13 16:35:19 +08:00
}
outputDevice->write("\r\x1B[K");
outputDevice->write(" |-- start_time: " + QByteArray::number(ied_usr.LD_info[i].autorecall[j]->start) + "\n");
outputDevice->write("\r\x1B[K");
outputDevice->write(" |-- end_time: " + QByteArray::number(ied_usr.LD_info[i].autorecall[j]->end) + "\n");
outputDevice->write("\r\x1B[K");
outputDevice->write(" |-- need_steady: " + QByteArray::number(ied_usr.LD_info[i].autorecall[j]->need_steady) + "\n");
outputDevice->write("\r\x1B[K");
outputDevice->write(" |-- need_voltage: " + QByteArray::number(ied_usr.LD_info[i].autorecall[j]->need_voltage) + "\n");
}
2025-01-16 16:17:01 +08:00
// rpt
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptRecvFlag: " + QByteArray::number(ied_usr.LD_info[i].rptRecvFlag) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptRecvCheckFlag: " + QByteArray::number(ied_usr.LD_info[i].rptRecvCheckFlag) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptPstRecvFlag: " + QByteArray::number(ied_usr.LD_info[i].rptPstRecvFlag) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- rptPstRecvCheckFlag: " + QByteArray::number(ied_usr.LD_info[i].rptPstRecvCheckFlag) + "\n");
2025-01-16 16:17:01 +08:00
// rtdata
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- real_data: " + QByteArray::number(ied_usr.LD_info[i].real_data) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- soe_data: " + QByteArray::number(ied_usr.LD_info[i].soe_data) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- limit: " + QByteArray::number(ied_usr.LD_info[i].limit) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- count: " + QByteArray::number(ied_usr.LD_info[i].count) + "\n");
2025-01-16 16:17:01 +08:00
// RDRE
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- RDRE_FltNum: " + QByteArray::number(ied_usr.LD_info[i].RDRE_FltNum) + "\n");
2025-01-16 16:17:01 +08:00
for (int j = 0; j < 256; ++j) {
if (ied_usr.LD_info[i].FltNum[j] != 0) {
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- FltNum[" + QByteArray::number(j) + "]: "
2025-01-16 16:17:01 +08:00
+ QByteArray::number(ied_usr.LD_info[i].FltNum[j]) + "\n");
}
}
// QVVR
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- qvvr_idx: " + QByteArray::number(ied_usr.LD_info[i].qvvr_idx) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVRs:\n");
2025-01-16 16:17:01 +08:00
for (int j = 0; j < 256; ++j) {
2025-03-10 21:26:17 +08:00
if (ied_usr.LD_info[i].qvvr[j].used_status != QVVR_DATA_NOT_USED) {
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR[" + QByteArray::number(j) + "]:\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- used_status: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].used_status) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_start: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_start) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_type: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_type) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_time: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_time) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_PerTime: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_PerTime) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_Amg: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].QVVR_Amg) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- QVVR_Rptname: " + QByteArray(ied_usr.LD_info[i].qvvr[j].QVVR_Rptname) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write(" |-- timestamp: " + QByteArray::number(ied_usr.LD_info[i].qvvr[j].timestamp) + "\n");
2025-01-16 16:17:01 +08:00
}
}
}
}
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");outputDevice->write("------------------------------------\n");
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
// 打印所有设备信息或特定终端信息
2025-01-16 16:17:01 +08:00
void ledger(const char* terminal_id, QIODevice* outputDevice) {
2025-03-05 17:47:47 +08:00
outputDevice->write("\r\x1B[K");
2025-02-14 16:44:38 +08:00
outputDevice->write("print ledger in shell");
2025-02-24 16:45:42 +08:00
pthread_mutex_lock(&mtx); std::cout << "ledger()hold lock !!!!!!!!!!!" << std::endl;
2025-01-16 16:17:01 +08:00
bool found = false;
ied_t* ied;
ied_usr_t* ied_usr;
for (int t = 0; t < g_node->n_clients; t++) {
ied = (ied_t*)g_node->clients[t];
if(ied != NULL){
ied_usr = (ied_usr_t*)ied->usr_ext;
if (ied_usr != NULL && (terminal_id == NULL || strcmp(ied_usr->terminal_id, terminal_id) == 0)) {
2025-05-09 16:53:07 +08:00
printLedgerinshell(*ied_usr, outputDevice); // 使用 QIODevice 输出
2025-02-21 16:24:41 +08:00
//std::cout << "!!! print to log !!!"<< std::endl;
//printLedger(*ied_usr);
2025-03-05 17:47:47 +08:00
if(terminal_id != NULL && strcmp(ied_usr->terminal_id, terminal_id) == 0){
found = true;
}
2025-01-16 16:17:01 +08:00
}
}
}
2025-03-05 17:47:47 +08:00
pthread_mutex_unlock(&mtx); std::cout << "ledger()free lock !!!!!!!!!!!" << std::endl;
if (terminal_id != NULL && !found) {
std::cout << "terminal not exsist: " << terminal_id << std::endl;
QByteArray msg = "terminal not exsist: " + QByteArray(terminal_id) + "\n";
outputDevice->write("\r\x1B[K");
2025-05-09 16:53:07 +08:00
outputDevice->write(msg); // 输出到 QIODevice
2025-01-16 16:17:01 +08:00
}
2025-03-05 17:47:47 +08:00
2025-01-16 16:17:01 +08:00
}
2025-02-10 17:03:15 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250210打印指定的变量名
2025-02-10 17:03:15 +08:00
void value_print(const char *variableName, QTcpSocket *clientSocket) {
2025-05-09 16:53:07 +08:00
char buffer[256]; // 用于存储变量值的缓冲区
2025-02-10 17:03:15 +08:00
2025-02-24 16:45:42 +08:00
pthread_mutex_lock(&mtx); std::cout << "value_print hold lock !!!!!!!!!!!" << std::endl;
2025-05-09 16:53:07 +08:00
// 打印变量值
2025-02-10 17:03:15 +08:00
if (strcmp(variableName, "frontindex") == 0) {
2025-05-09 16:53:07 +08:00
sprintf(buffer, "frontindex = %d", g_front_seg_index); // 将 int 转换为字符串
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
2025-05-09 16:53:07 +08:00
clientSocket->write(buffer); // 发送字符串到客户端
}
else if (strcmp(variableName, "remtable") == 0) {
sprintf(buffer, "remtable = %d",g_pt61850app->chnl_counts);
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
clientSocket->write(buffer);
}
else if (strcmp(variableName, "iedcount") == 0) {
2025-02-12 16:08:36 +08:00
sprintf(buffer, "g_node->n_clients = %d, ied config count = %d",g_node->n_clients ,IED_COUNT);
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
2025-02-10 17:03:15 +08:00
clientSocket->write(buffer);
} else if (strcmp(variableName, "frontfun") == 0) {
sprintf(buffer, "frontfun = %s", subdir);
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
2025-03-03 18:20:00 +08:00
clientSocket->write(buffer);
} else if (strcmp(variableName, "log") == 0) {
sprintf(buffer, "showinshellflag = %d,debugOutputEnabled = %d,normalOutputEnabled = %d,warnOutputEnabled = %d,errorOutputEnabled = %d", showinshellflag,debugOutputEnabled,normalOutputEnabled,warnOutputEnabled,errorOutputEnabled);
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
2025-03-03 18:20:00 +08:00
clientSocket->write(buffer);
2025-03-04 17:29:04 +08:00
}else if (strcmp(variableName, "init") == 0) {
sprintf(buffer, "INITFLAG = %d",INITFLAG);
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
2025-03-04 17:29:04 +08:00
clientSocket->write(buffer);
2025-03-03 18:20:00 +08:00
}else {
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
2025-02-10 17:03:15 +08:00
clientSocket->write("Unknown variable name\n> ");
}
2025-02-24 16:45:42 +08:00
pthread_mutex_unlock(&mtx); std::cout << "value_print free lock !!!!!!!!!!!" << std::endl;
2025-02-10 17:03:15 +08:00
clientSocket->flush();
}
std::list<std::string>* getLogList(const QString& level) {
if (level == "ERROR") return &errorList;
if (level == "WARN") return &warnList;
if (level == "NORMAL") return &normalList;
if (level == "DEBUG") return &debugList;
return NULL;
}
pthread_mutex_t* getLogMutex(const QString& level) {
if (level == "ERROR") return &errorListMutex;
if (level == "WARN") return &warnListMutex;
if (level == "NORMAL") return &normalListMutex;
if (level == "DEBUG") return &debugListMutex;
return NULL;
}
void Worker::handleViewLogCommand(const QString& command, QTcpSocket* clientSocket) {
QStringList parts = command.split(" ");
if (parts.size() != 2) {
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
clientSocket->write("Usage: viewlog [ERROR|WARN|NORMAL|DEBUG]\n> ");
clientSocket->flush();
return;
}
QString logLevel = parts[1].toUpper();
std::list<std::string>* logList = getLogList(logLevel);
pthread_mutex_t* logMutex = getLogMutex(logLevel);
if (!logList || !logMutex) {
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
clientSocket->write("Invalid log level! Use ERROR, WARN, NORMAL, or DEBUG.\n> ");
clientSocket->flush();
return;
}
stopViewLog = false;
2025-05-09 16:53:07 +08:00
activeClient = clientSocket; // 记录当前 shell socket
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
2025-03-06 15:24:49 +08:00
clientSocket->write(QString("Viewing logs for level: %1 (Press '`' to exit)\n> ").arg(logLevel).toUtf8());
clientSocket->flush();
while (!stopViewLog) {
2025-05-09 16:53:07 +08:00
// **1. 监听输入,用户输入 ``` 退出**
if (clientSocket->waitForReadyRead(500)) { // ? 监听输入
QByteArray input = clientSocket->readAll().trimmed();
2025-05-09 16:53:07 +08:00
if (input == "`") { // ? 用户输入 ```,退出日志模式
2025-03-06 15:24:49 +08:00
std::cout << "Received '`' from shell socket! Exiting viewlog...\n";
stopViewLog = true;
2025-03-03 18:20:00 +08:00
showinshellflag = false;
break;
}
}
2025-05-09 16:53:07 +08:00
// **2. 获取日志内容并发送**
pthread_mutex_lock(logMutex);
if (!logList->empty()) {
std::string logEntry = logList->front();
logList->pop_front();
pthread_mutex_unlock(logMutex);
if (!logEntry.empty()) {
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
clientSocket->write((logEntry + "\n").c_str());
clientSocket->flush();
}
} else {
pthread_mutex_unlock(logMutex);
2025-05-09 16:53:07 +08:00
usleep(500000); // ? 防止 CPU 100% 占用
}
}
2025-05-09 16:53:07 +08:00
// **3. 退出 `viewlog`,返回 Shell**
2025-03-05 17:47:47 +08:00
clientSocket->write("\r\x1B[K");
clientSocket->write("\nLog view stopped. Returning to shell.\n> ");
clientSocket->flush();
}
2025-01-16 16:17:01 +08:00
//////////////////////////////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
// 解析 JSON 的函数 多前置动态均分
2025-01-16 16:17:01 +08:00
int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
const std::vector<std::string>& codes,
int index,
int num)
{
2025-05-09 16:53:07 +08:00
//后续修改为根据index来获取对应的台账num就没有作用了index用来均分的也没有作用了
2025-01-16 16:17:01 +08:00
if(1 == MULTIPLE_NODE_FLAG){
2025-05-09 16:53:07 +08:00
// 参数验证
2025-01-16 16:17:01 +08:00
if (num <= 0) {
std::cerr << "Error: 'num' must be greater than 0." << std::endl;
2025-05-09 16:53:07 +08:00
return 1; // 返回适当的错误码
2025-01-16 16:17:01 +08:00
}
index = index - 1;
if (index < 0 || index >= num) {
std::cerr << "Error: 'index' must be in the range [0, num-1]." << std::endl;
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
// 获取参数
2025-01-16 16:17:01 +08:00
if (codes.empty()) {
std::cerr << "Error: 'codes' vector is empty." << std::endl;
return 1;
}
std::string parm = codes[0];
char* ptr = NULL;
2025-05-09 16:53:07 +08:00
// 发送 API 请求
2025-01-16 16:17:01 +08:00
SendJsonAPI_web(WEB_DEVICE, "",parm.c_str(), &ptr);
if (ptr == NULL) {
std::cerr << "Error: Received NULL response from SendJsonAPI_web." << std::endl;
return 1;
}
2025-05-09 16:53:07 +08:00
// 调试用
2025-01-16 16:17:01 +08:00
printf("ptr:%s\n", ptr);
2025-05-09 16:53:07 +08:00
cJSON* root = cJSON_Parse(ptr); //json格式序列化
2025-01-16 16:17:01 +08:00
int retry = 0;
if (root == NULL) {
printf("web error %s\n", cJSON_GetErrorPtr());
2025-05-09 16:53:07 +08:00
//重发多次
2025-01-16 16:17:01 +08:00
while(root == NULL){
2025-05-09 16:53:07 +08:00
// 在重试前释放之前的 ptr 以避免内存泄漏
2025-01-16 16:17:01 +08:00
if (ptr != NULL) {
free(ptr);
ptr = NULL;
}
2025-05-09 16:53:07 +08:00
//测试用url参数
2025-01-16 16:17:01 +08:00
//SendJsonAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", parm.c_str(), "",&ptr);
SendJsonAPI_web(WEB_DEVICE, "",parm.c_str(), &ptr);
if(ptr == NULL){
retry++;if(retry>3)break;
continue;
}
root = cJSON_Parse(ptr);
retry++;if(retry>3)break;
}
2025-05-09 16:53:07 +08:00
// 如果重试后仍然失败,确保退出前释放任何已分配的内存
2025-01-16 16:17:01 +08:00
if (root == NULL) {
printf("web error %s\n", cJSON_GetErrorPtr());
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
// 获取 "code" 和 "msg"
2025-01-16 16:17:01 +08:00
cJSON* codeItem = cJSON_GetObjectItem(root, "code");
cJSON* msgItem = cJSON_GetObjectItem(root, "msg");
2025-05-09 16:53:07 +08:00
// 使用 std::string 获取值
2025-01-16 16:17:01 +08:00
std::string code = (codeItem != NULL && codeItem->type == cJSON_String) ? codeItem->valuestring : "not found";
std::string msg = (msgItem != NULL && msgItem->type == cJSON_String) ? msgItem->valuestring : "not found";
2025-05-09 16:53:07 +08:00
// 打印结果
2025-01-16 16:17:01 +08:00
std::cout << "code: " << code << std::endl;
std::cout << "msg: " << msg << std::endl;
2025-05-09 16:53:07 +08:00
// 获取 "data" 数组
2025-01-16 16:17:01 +08:00
cJSON* data = cJSON_GetObjectItem(root, "data");
if (!data || data->type != cJSON_Array) {
std::cerr << "Error: 'data' is not an array." << std::endl;
cJSON_Delete(root);
free(ptr);
return 1;
}
int data_size = cJSON_GetArraySize(data);
std::cout << "data_size " << data_size << std::endl;
if (data_size == 0) {
std::cerr << "Error: 'data' array is empty." << std::endl;
cJSON_Delete(root);
free(ptr);
return 1;
}
2025-05-09 16:53:07 +08:00
//后续修改为根据index来获取对应的台账将不再均分获取所有台账并判断进程号
2025-02-10 17:03:15 +08:00
#if 0
2025-01-16 16:17:01 +08:00
int base_size = 0;
int remainder = 0;
int start_index = 0;
int end_index = data_size;
if(1 == MULTIPLE_NODE_FLAG){
2025-05-09 16:53:07 +08:00
// 计算每份的大小
2025-01-16 16:17:01 +08:00
base_size = data_size / num;
remainder = data_size % num;
2025-05-09 16:53:07 +08:00
// 计算当前份的起始和结束索引
2025-01-16 16:17:01 +08:00
start_index = index * base_size + (index < remainder ? index : remainder);
end_index = start_index + base_size + (index < remainder ? 1 : 0);
2025-05-09 16:53:07 +08:00
// 确保结束索引不超过数组大小
2025-01-16 16:17:01 +08:00
if (end_index > data_size) {
end_index = data_size;
}
}
2025-02-10 17:03:15 +08:00
#endif
int start_index = 0;
int end_index = data_size;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 遍历指定范围内的元素
2025-01-16 16:17:01 +08:00
for (int i = start_index; i < end_index; ++i) {
cJSON* item = cJSON_GetArrayItem(data, i);
if (!item || item->type != cJSON_Object) {
std::cerr << "Warning: Invalid item at index " << i << "." << std::endl;
2025-05-09 16:53:07 +08:00
continue; // 跳过无效的项
2025-01-16 16:17:01 +08:00
}
terminal_dev* dev = new terminal_dev();
2025-05-09 16:53:07 +08:00
memset(dev, 0, sizeof(terminal_dev)); // 初始化结构体
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* id = cJSON_GetObjectItem(item, "id"); // terminal_id
if (id && id->type == cJSON_String) strncpy(dev->terminal_id, id->valuestring, sizeof(dev->terminal_id) - 1);
else strncpy(dev->terminal_id, "N/A", sizeof(dev->terminal_id) - 1);
cJSON* ip = cJSON_GetObjectItem(item, "ip"); // addr_str
if (ip && ip->type == cJSON_String) strncpy(dev->addr_str, ip->valuestring, sizeof(dev->addr_str) - 1);
else strncpy(dev->addr_str, "N/A", sizeof(dev->addr_str) - 1);
cJSON* terminalCode = cJSON_GetObjectItem(item, "name"); // terminal_code
if (terminalCode && terminalCode->type == cJSON_String) strncpy(dev->terminal_code, terminalCode->valuestring, sizeof(dev->terminal_code) - 1);
else strncpy(dev->terminal_code, "N/A", sizeof(dev->terminal_code) - 1);
cJSON* orgName = cJSON_GetObjectItem(item, "org_name"); // org_name
if (orgName && orgName->type == cJSON_String) strncpy(dev->org_name, orgName->valuestring, sizeof(dev->org_name) - 1);
else strncpy(dev->org_name, "N/A", sizeof(dev->org_name) - 1);
cJSON* maintName = cJSON_GetObjectItem(item, "maint_name"); // maint_name
if (maintName && maintName->type == cJSON_String) strncpy(dev->maint_name, maintName->valuestring, sizeof(dev->maint_name) - 1);
else strncpy(dev->maint_name, "N/A", sizeof(dev->maint_name) - 1);
cJSON* stationName = cJSON_GetObjectItem(item, "stationName"); // station_name
if (stationName && stationName->type == cJSON_String) strncpy(dev->station_name, stationName->valuestring, sizeof(dev->station_name) - 1);
else strncpy(dev->station_name, "N/A", sizeof(dev->station_name) - 1);
cJSON* manufacturer = cJSON_GetObjectItem(item, "manufacturer"); // tmnl_factory
if (manufacturer && manufacturer->type == cJSON_String) strncpy(dev->tmnl_factory, manufacturer->valuestring, sizeof(dev->tmnl_factory) - 1);
else strncpy(dev->tmnl_factory, "N/A", sizeof(dev->tmnl_factory) - 1);
cJSON* status = cJSON_GetObjectItem(item, "status"); // tmnl_status
if (status && status->type == cJSON_String) strncpy(dev->tmnl_status, status->valuestring, sizeof(dev->tmnl_status) - 1);
else strncpy(dev->tmnl_status, "N/A", sizeof(dev->tmnl_status) - 1);
cJSON* devType = cJSON_GetObjectItem(item, "devType"); // dev_type
if (devType && devType->type == cJSON_String) strncpy(dev->dev_type, devType->valuestring, sizeof(dev->dev_type) - 1);
else strncpy(dev->dev_type, "N/A", sizeof(dev->dev_type) - 1);
cJSON* devKey = cJSON_GetObjectItem(item, "devKey"); // dev_key
if (devKey && devKey->type == cJSON_String) strncpy(dev->dev_key, devKey->valuestring, sizeof(dev->dev_key) - 1);
else strncpy(dev->dev_key, "N/A", sizeof(dev->dev_key) - 1);
cJSON* series = cJSON_GetObjectItem(item, "series"); // dev_series
if (series && series->type == cJSON_String) strncpy(dev->dev_series, series->valuestring, sizeof(dev->dev_series) - 1);
else strncpy(dev->dev_series, "N/A", sizeof(dev->dev_series) - 1);
2025-05-09 16:53:07 +08:00
//lnk20250210台账进程号
cJSON* processNo = cJSON_GetObjectItem(item, "processNo"); // processNo转为字符串
2025-02-10 17:03:15 +08:00
if (processNo && processNo->type == cJSON_Number) snprintf(dev->processNo, sizeof(dev->processNo), "%d", processNo->valueint);
else strncpy(dev->processNo, "N/A", sizeof(dev->processNo) - 1);
2025-01-16 16:17:01 +08:00
cJSON* port = cJSON_GetObjectItem(item, "port"); // port
if (port && port->type == cJSON_String) strncpy(dev->port, port->valuestring, sizeof(dev->port) - 1);
else strncpy(dev->port, "N/A", sizeof(dev->port) - 1);
cJSON* updateTime = cJSON_GetObjectItem(item, "updateTime"); // timestamp
if (updateTime && updateTime->type == cJSON_String) strncpy(dev->timestamp, updateTime->valuestring, sizeof(dev->timestamp) - 1);
else strncpy(dev->timestamp, "N/A", sizeof(dev->timestamp) - 1);
2025-05-09 16:53:07 +08:00
// 解析 monitorData 数组
2025-01-16 16:17:01 +08:00
cJSON* monitorData = cJSON_GetObjectItem(item, "monitorData");
if (monitorData && monitorData->type == cJSON_Array) {
int j = 0;
cJSON* monitorItem;
cJSON_ArrayForEach(monitorItem, monitorData) {
if (j >= 10){
2025-05-09 16:53:07 +08:00
std::cout << "一个终端最多只能有十个监测点" << std::endl;
break; // 限制为最多10个
2025-01-16 16:17:01 +08:00
}
cJSON* monitor_id = cJSON_GetObjectItem(monitorItem, "id"); // monitor_id
if (monitor_id && monitor_id->type == cJSON_String) strncpy(dev->line[j].monitor_id, monitor_id->valuestring, sizeof(dev->line[j].monitor_id) - 1);
else strncpy(dev->line[j].monitor_id, "N/A", sizeof(dev->line[j].monitor_id) - 1);
cJSON* monitor_name = cJSON_GetObjectItem(monitorItem, "name"); // monitor_name
if (monitor_name && monitor_name->type == cJSON_String) strncpy(dev->line[j].monitor_name, monitor_name->valuestring, sizeof(dev->line[j].monitor_name) - 1);
else strncpy(dev->line[j].monitor_name, "N/A", sizeof(dev->line[j].monitor_name) - 1);
cJSON* lineNo = cJSON_GetObjectItem(monitorItem, "lineNo"); // logical_device_seq
if (lineNo && lineNo->type == cJSON_String) strncpy(dev->line[j].logical_device_seq, lineNo->valuestring, sizeof(dev->line[j].logical_device_seq) - 1);
else strncpy(dev->line[j].logical_device_seq, "N/A", sizeof(dev->line[j].logical_device_seq) - 1);
cJSON* voltageLevel = cJSON_GetObjectItem(monitorItem, "voltageLevel"); // voltage_level
if (voltageLevel && voltageLevel->type == cJSON_String) strncpy(dev->line[j].voltage_level, voltageLevel->valuestring, sizeof(dev->line[j].voltage_level) - 1);
else strncpy(dev->line[j].voltage_level, "N/A", sizeof(dev->line[j].voltage_level) - 1);
cJSON* ptType = cJSON_GetObjectItem(monitorItem, "ptType"); // terminal_connect
if (ptType && ptType->type == cJSON_String) strncpy(dev->line[j].terminal_connect, ptType->valuestring, sizeof(dev->line[j].terminal_connect) - 1);
else strncpy(dev->line[j].terminal_connect, "N/A", sizeof(dev->line[j].terminal_connect) - 1);
2025-05-09 16:53:07 +08:00
// 添加监测点状态
2025-01-16 16:17:01 +08:00
cJSON* monitorstatus = cJSON_GetObjectItem(monitorItem, "status"); // status
if (monitorstatus && monitorstatus->type == cJSON_String) strncpy(dev->line[j].status, monitorstatus->valuestring, sizeof(dev->line[j].status) - 1);
else strncpy(dev->line[j].status, "N/A", sizeof(dev->line[j].status) - 1);
j++;
}
}
2025-05-09 16:53:07 +08:00
// 准备键
QString key = QString(dev->terminal_id);//用id而不是code区分有的code存在乱码
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 检查是否存在重复键
2025-01-16 16:17:01 +08:00
if (terminal_dev_map->contains(key)) {
std::cerr << "Duplicate terminal_code found: " << key.toStdString() << std::endl;
2025-05-09 16:53:07 +08:00
// 删除旧的 terminal_dev 对象以避免内存泄漏
2025-01-16 16:17:01 +08:00
delete terminal_dev_map->value(key);
2025-05-09 16:53:07 +08:00
// 移除旧的键值对
2025-01-16 16:17:01 +08:00
terminal_dev_map->remove(key);
2025-05-09 16:53:07 +08:00
// 插入新的 terminal_dev 对象
if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号
//调试用
2025-02-10 17:03:15 +08:00
std::cout<< "process num match" << std::endl;
2025-05-09 16:53:07 +08:00
terminal_dev_map->insert(key, dev);}//后续修改为只有进程号匹配上index才录入当前进程
2025-01-16 16:17:01 +08:00
} else {
2025-05-09 16:53:07 +08:00
// 插入新的 terminal_dev 对象
if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号
//调试用
2025-02-10 17:03:15 +08:00
std::cout<< "process num match" << std::endl;
2025-05-09 16:53:07 +08:00
terminal_dev_map->insert(key, dev);}//后续修改为只有进程号匹配上index才录入当前进程
//调试用
2025-01-16 16:17:01 +08:00
//std::cout << "i = " << i << std::endl;
//std::cout << "terminal_dev_map.size:" << terminal_dev_map->size() << std::endl;
2025-05-09 16:53:07 +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(root);
free(ptr);
2025-05-09 16:53:07 +08:00
return 0; // 确保函数有返回值
2025-01-16 16:17:01 +08:00
}
int parse_device_cfg_web()
{
std::cout << "parse_device_cfg_web" << endl;
2025-05-09 16:53:07 +08:00
std::vector<std::string> codes; //入参集合
2025-04-29 15:05:36 +08:00
ied_t* ied;
ied_usr_t* ied_usr;
chnl_usr_t* chnl_usr;
2025-05-09 16:53:07 +08:00
int count_cfg = 0; //终端台账总数
int count_real = 0; //遍历终端台账的计数器
2025-04-29 15:05:36 +08:00
2025-05-09 16:53:07 +08:00
//接口合并只用一个web接口获取终端台账和监测点台账
2025-01-16 16:17:01 +08:00
QMap<QString, terminal_dev*> terminal_dev_map;
2025-05-09 16:53:07 +08:00
//构造入参json
2025-01-16 16:17:01 +08:00
std::string input_jstr = "{";
input_jstr += "\"ip\":\"" + std::string(FRONT_IP) + "\",";
input_jstr += "\"runFlag\":" + TERMINAL_STATUS + "";
input_jstr += "}";
2025-05-09 16:53:07 +08:00
std::cout << "input_jstr: " << input_jstr << std::endl; // 输出结果
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
codes.push_back(input_jstr); //是否需要筛选状态直接在配置文件控制
2025-01-16 16:17:01 +08:00
terminal_ledger_web(&terminal_dev_map,codes,g_front_seg_index,g_front_seg_num);
codes.clear();
2025-05-09 16:53:07 +08:00
//调试用
2025-01-16 16:17:01 +08:00
//printTerminalDevMap(terminal_dev_map);
2025-05-09 16:53:07 +08:00
count_cfg = terminal_dev_map.size();//容器的数量就是台账的数量
2025-01-16 16:17:01 +08:00
std::cout << "terminal_ledger_num:" << count_cfg << std::endl;
2025-01-21 17:48:37 +08:00
g_node->n_clients = count_cfg;
2025-05-09 16:53:07 +08:00
//这里开辟的ied的空间由配置文件中的终端台账数量决定lnk20250121
if(IED_COUNT < count_cfg){ //申请数至少是初始化能读取到的台账数,防止设置失误导致的崩溃。
//如果是多进程IED_COUNT应该设置为大于平均数
//如果是单进程则应该设置为大于终端总数,
//单进程多进程同时存在则单进程应该大于终端总数,否则添加台账时单进程部分就无法同步添加。
2025-02-17 16:58:14 +08:00
g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*));
2025-05-09 16:53:07 +08:00
//添加提示
2025-02-17 16:58:14 +08:00
std::cout << "!!!!!!!!!!single process can not add any ledger unless reboot!!!!!!!"<< std::endl;
}
else{
2025-05-09 16:53:07 +08:00
g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, IED_COUNT * sizeof(ied_t*));//g_node->clients 这块大内存空间存储了 count_cfg 个 ied_t* 类型的指针(即一个指针数组)这是(指向内存块的指针)的指针数组
2025-02-17 16:58:14 +08:00
}
2025-05-09 16:53:07 +08:00
//把ied放入数组
2025-02-11 18:23:19 +08:00
for (int k = 0; k < count_cfg; k++){
2025-05-09 16:53:07 +08:00
//调试用
2025-02-11 18:23:19 +08:00
std::cout << "!!!!!!!!!!gnodeindex:" << k << std::endl;
2025-05-09 16:53:07 +08:00
g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t));}//每个 g_node->clients[k] 指向的内存块是独立的(每个 ied_t 结构体占用的内存块)这是指向内存块的指针
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//读取终端台账表替换为web接口
2025-01-16 16:17:01 +08:00
//////////////////////////////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//读数据
2025-01-16 16:17:01 +08:00
try {
char terminal_id[64];
char terminal_code[64];
char org_name[64];
char maint_name[64];
char station_name[64];
char tmnl_factory[64];
char tmnl_status[64];
char dev_type[64];
char dev_key[255];
char dev_series[255];
char addr_str[64];
char port_char[64];
2025-02-10 17:03:15 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250210添加进程号
2025-02-10 17:03:15 +08:00
char processNo[64];
2025-01-16 16:17:01 +08:00
otl_datetime timestamp;
2025-05-09 16:53:07 +08:00
// 遍历终端台账容器
2025-01-16 16:17:01 +08:00
QMap<QString, terminal_dev*>::iterator it;
for (it = terminal_dev_map.begin(); it != terminal_dev_map.end(); ++it) {
terminal_dev* value = it.value();
2025-05-09 16:53:07 +08:00
// 确保 value 不为空
2025-01-16 16:17:01 +08:00
if (value != nullptr) {
2025-05-09 16:53:07 +08:00
// 找到容器中对应名称并取值
2025-01-16 16:17:01 +08:00
strncpy(terminal_id, value->terminal_id, sizeof(terminal_id) - 1);
strncpy(terminal_code, value->terminal_code, sizeof(terminal_code) - 1);
strncpy(org_name, value->org_name, sizeof(org_name) - 1);
strncpy(maint_name, value->maint_name, sizeof(maint_name) - 1);
strncpy(station_name, value->station_name, sizeof(station_name) - 1);
strncpy(tmnl_factory, value->tmnl_factory, sizeof(tmnl_factory) - 1);
strncpy(tmnl_status, value->tmnl_status, sizeof(tmnl_status) - 1);
strncpy(dev_type, value->dev_type, sizeof(dev_type) - 1);
strncpy(dev_key, value->dev_key, sizeof(dev_key) - 1);
strncpy(dev_series, value->dev_series, sizeof(dev_series) - 1);
strncpy(addr_str, value->addr_str, sizeof(addr_str) - 1);
strncpy(port_char, value->port, sizeof(port_char) - 1);
2025-05-09 16:53:07 +08:00
strncpy(processNo, value->processNo, sizeof(processNo) - 1);//进程号
2025-01-16 16:17:01 +08:00
timestamp = parseTimestamp(value->timestamp);
2025-05-09 16:53:07 +08:00
//处理终端台账
2025-01-16 16:17:01 +08:00
ied = g_node->clients[count_real++];
2025-05-09 16:53:07 +08:00
//这里申请的空间基于ied的数量挂载到ied上
ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t));//终端台账在initpool中申请空间
2025-01-16 16:17:01 +08:00
ied->usr_ext = ied_usr;
if (ied_usr == NULL)
return APR_ENOMEM;
ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000;
2025-05-09 16:53:07 +08:00
//这里申请的空间基于ied的数量挂载到ied上
ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t));//监测点台账在initpool中申请空间
2025-01-16 16:17:01 +08:00
if (ied_usr->LD_info == NULL)
return APR_ENOMEM;
2025-05-09 16:53:07 +08:00
ied_usr->dev_flag = ENABLE;//终端有效
ied->chncount = 1;//设备通信端口总数
//这里申请的空间基于ied的数量挂载到ied上
ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount);//通信结构在g_cfg_pool中申请空间终端的ip端口等
2025-01-16 16:17:01 +08:00
ied->channel[0].ied = ied;
ied->channel[0].status = STATUS_BREAKOFF;
ied->cpucount = 0;
if (strlen(terminal_id) != 0) {
apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", terminal_id);//terminal_id
cout << "ied_usr->terminal_id:" << ied_usr->terminal_id << endl;
}
if (terminal_code != NULL) {
apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", terminal_code);//terminal_code
cout << "ied_usr->terminal_code:" << ied_usr->terminal_code << endl;
}
2025-05-09 16:53:07 +08:00
/*不需要这三个信息
2025-01-16 16:17:01 +08:00
if (org_name != NULL) {
apr_snprintf(ied_usr->org_name, sizeof(ied_usr->org_name), "%s", org_name);//org_name
cout << "ied_usr->org_name:" << ied_usr->org_name << endl;
}
if (maint_name != NULL) {
apr_snprintf(ied_usr->maint_name, sizeof(ied_usr->maint_name), "%s", maint_name);//maint_name
cout << "ied_usr->maint_name:" << ied_usr->maint_name << endl;
}
if (station_name != NULL) {
apr_snprintf(ied_usr->station_name, sizeof(ied_usr->station_name), "%s", station_name);//station_name
cout << "ied_usr->station_name:" << ied_usr->station_name << endl;
}
*/
if (tmnl_factory != NULL) {
apr_snprintf(ied_usr->tmnl_factory, sizeof(ied_usr->tmnl_factory), "%s", tmnl_factory);//tmnl_factory
cout << "ied_usr->tmnl_factory:" << ied_usr->tmnl_factory << endl;
}
if (tmnl_status != NULL) {
apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", tmnl_status);//tmnl_status
cout << "ied_usr->tmnl_status:" << ied_usr->tmnl_status << endl;
}
if (dev_type != NULL) {
apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", dev_type);//dev_type
cout << "ied_usr->dev_type:" << ied_usr->dev_type << endl;
}
2025-02-10 17:03:15 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250210台账进程号
2025-02-10 17:03:15 +08:00
if (processNo != NULL) {
apr_snprintf(ied_usr->processNo, sizeof(ied_usr->processNo), "%s", processNo);//processNo
cout << "ied_usr->processNo:" << ied_usr->processNo << endl;
}
2025-01-16 16:17:01 +08:00
if (dev_series != NULL) {
apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", dev_series);//DEV_Series
cout << "defalut dev_series:" << ied_usr->dev_series << endl;
}
else
{
apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series
cout << "defalut dev_series:" << ied_usr->dev_series << endl;
}
if (dev_key != NULL) {
apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", dev_key);//DEV_Key
cout << "defalut dev_key:" << ied_usr->dev_key << endl;
}
else
{
apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key
cout << "defalut dev_key:" << ied_usr->dev_key << endl;
}
2025-05-09 16:53:07 +08:00
//lnk20241125实时数据用
2025-01-16 16:17:01 +08:00
ied_usr->dev_idx = count_real;
cout << "dev_idx:" << ied_usr->dev_idx << endl;
ied->channel[0].channel_type = CHANNEL_TYPE_IPV4;//channel
ied->channel[0].addr_str[LONGNAME - 1] = 0;//DEV_IP
if (addr_str != NULL) {
ied->channel[0].addr = ntohl(inet_addr(addr_str));//DEV_IP
strncpy(ied->channel[0].addr_str, addr_str, LONGNAME - 1);//DEV_IP
cout << "ied_usr->addr_str:" << ied->channel[0].addr_str << endl;
}
else
{
ied->channel[0].addr = ntohl(inet_addr("0.0.0.0"));//DEV_IP
strncpy(ied->channel[0].addr_str, addr_str, LONGNAME - 1);//DEV_IP
cout << "ied_usr->addr_str:" << ied->channel[0].addr_str << endl;
}
if (port_char != NULL) {
int port = 102;
if (stringToInt(port_char, &port)) {
2025-05-09 16:53:07 +08:00
// 转换成功portStr全为数字并且已经转换为int类型的port
2025-01-16 16:17:01 +08:00
ied->channel[0].port = port;//DEV_PortID
cout << "ied_usr->port:" << ied->channel[0].port << endl;//DEV_PortID
}
else {
ied->channel[0].port = 102;//DEV_PortID
2025-05-09 16:53:07 +08:00
cout << "ied_usr->port:" << port_char << ",非合法端口.使用默认端口:" << ied->channel[0].port << endl;//DEV_PortID
2025-01-16 16:17:01 +08:00
}
}
if (timestamp.year != 0) {
2025-05-09 16:53:07 +08:00
//// 构造struct tm对象
2025-01-16 16:17:01 +08:00
struct tm timeinfo;
2025-05-09 16:53:07 +08:00
timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900
timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1
2025-01-16 16:17:01 +08:00
timeinfo.tm_mday = timestamp.day;
timeinfo.tm_hour = timestamp.hour;
timeinfo.tm_min = timestamp.minute;
timeinfo.tm_sec = timestamp.second;
time_t time = std::mktime(&timeinfo);
ied_usr->time = static_cast<long long>(time);
cout << "ied_usr->time:" << ied_usr->time << endl;
}
2025-05-09 16:53:07 +08:00
//这里申请的空间基于ied的数量挂载到ied上
chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t));//拓展定义的通信结构在g_init_pool中申请空间拓展记录一些开关时间信息
2025-01-16 16:17:01 +08:00
ied->channel[0].connect = chnl_usr;
chnl_usr->chnl = &(ied->channel[0]);
chnl_usr->chnl_id = 0;
chnl_usr->m_state = CHANNEL_DISCONNECTED;
chnl_usr->m_ClosedMsTime = NEXT_CONNECT_TIME * (-1);
g_pt61850app->chnl_counts++;
2025-05-09 16:53:07 +08:00
//调试用
2025-01-16 16:17:01 +08:00
//std::cout << "value:" << terminal_id <<" "<<terminal_code <<" "<<tmnl_factory <<" "<<dev_series <<" "<<dev_key <<" "<< tmnl_status <<" "<<dev_type <<" "<<addr_str <<" "<<port_char <<" "<< timestamp.year << std::endl;
2025-05-09 16:53:07 +08:00
// 遍历监测点信息
2025-01-16 16:17:01 +08:00
LD_info_t line_info;
2025-05-09 16:53:07 +08:00
int count_real_monitor = 0; //遍历监测点台账的计数器
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//调试用
2025-01-16 16:17:01 +08:00
//std::cout << "n_clients:" << g_node->n_clients << std::endl;
if (g_node->n_clients <= 0) {
std::cout << "no terminal exist " << std::endl;
return APR_EBADF;
}
char monitor_id[64];
//char terminal_code[64];
char monitor_name[64];
char logical_device_seq[64];
char voltage_level[64];
char terminal_connect[64];
char monitor_status[64];
//otl_datetime timestamp;
2025-05-09 16:53:07 +08:00
//for (int j = 0; j < 10; ++j) { // 假设最多有10个监测点
2025-01-16 16:17:01 +08:00
for (int j = 0; value->line[j].monitor_id[0] != '\0'; ++j){
ledger_monitor& monitor = value->line[j];
2025-05-09 16:53:07 +08:00
// 检查监测点 ID 是否为空以避免访问无效数据
2025-01-16 16:17:01 +08:00
/*if (monitor.monitor_id[0] != '\0') {
std::cout << " Monitor ID: " << monitor.monitor_id << std::endl;
2025-05-09 16:53:07 +08:00
std::cout << " Terminal Code: " << monitor.terminal_code << std::endl; //应该为空json不带
2025-01-16 16:17:01 +08:00
std::cout << " Monitor Name: " << monitor.monitor_name << std::endl;
std::cout << " Logical Device Seq: " << monitor.logical_device_seq << std::endl;
std::cout << " Voltage Level: " << monitor.voltage_level << std::endl;
std::cout << " Terminal Connect: " << monitor.terminal_connect << std::endl;
2025-05-09 16:53:07 +08:00
std::cout << " Timestamp: " << monitor.timestamp << std::endl; //应该为空json不带
2025-01-16 16:17:01 +08:00
std::cout << " monitor_status: " << monitor.status << std::endl;*/
strncpy(monitor_id, monitor.monitor_id, sizeof(monitor_id) - 1);
2025-05-09 16:53:07 +08:00
//strncpy(terminal_code, monitor.terminal_code, sizeof(terminal_code) - 1); //从上级获取
2025-01-16 16:17:01 +08:00
strncpy(monitor_name, monitor.monitor_name, sizeof(monitor_name) - 1);
strncpy(logical_device_seq, monitor.logical_device_seq, sizeof(logical_device_seq) - 1);
strncpy(voltage_level, monitor.voltage_level, sizeof(voltage_level) - 1);
strncpy(terminal_connect, monitor.terminal_connect, sizeof(terminal_connect) - 1);
2025-05-09 16:53:07 +08:00
//timestamp = parseTimestamp(monitor.timestamp); //从上级获取
strncpy(monitor_status, monitor.status, sizeof(monitor_status) - 1);//添加监测点状态
//监测点台账处理
2025-01-16 16:17:01 +08:00
count_real_monitor++;
memset(&line_info, 0, sizeof(line_info));
2025-05-09 16:53:07 +08:00
line_info.line_id = count_real_monitor; //监测点排号
2025-01-16 16:17:01 +08:00
cout << "line_id:" << line_info.line_id << endl;
strcpy(line_info.mp_id, monitor_id);
cout << "mp_id:" << line_info.mp_id << endl;
2025-05-09 16:53:07 +08:00
strcpy(line_info.terminal_code, terminal_code); //从上级获取的终端号
2025-01-16 16:17:01 +08:00
cout << "terminal_code:" << line_info.terminal_code << endl;
if (isCharPtrEmpty(logical_device_seq)) {
2025-05-09 16:53:07 +08:00
line_info.cpuno = 1; //默认监测点实例号1
2025-01-16 16:17:01 +08:00
cout << "logical_device_seq:is null,set cpuno:"<< line_info.cpuno << endl;
}
else {
line_info.cpuno = std::atoi(logical_device_seq);
cout << "logical_device_seq:"<< line_info.cpuno << endl;
}
//cout << "cpuno:" << line_info.cpuno << endl;
strcpy(line_info.voltage_level, voltage_level);
cout << "voltage_level:" << line_info.voltage_level << endl;
strcpy(line_info.v_wiring_type, terminal_connect);
cout << "v_wiring_type:" << line_info.v_wiring_type << endl;
2025-05-09 16:53:07 +08:00
//lnk2024-8-14记录接线标志
2025-03-18 11:25:20 +08:00
if (strcmp(line_info.v_wiring_type, "0") != 0)
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
isdelta_flag = 1; //存在一个监测点为角型接线则这个前置就要启动第二个配置列表
2025-02-14 16:44:38 +08:00
cout << "monitor_id" << monitor_id << "v_wiring_type:" << line_info.v_wiring_type << "is delta wiring:" << isdelta_flag << endl;
}
2025-01-16 16:17:01 +08:00
strcpy(line_info.monitor_status, monitor_status);
cout << "monitor_status:" << line_info.monitor_status << endl;
2025-05-09 16:53:07 +08:00
//// 构造struct tm对象
2025-01-16 16:17:01 +08:00
struct tm timeinfo;
2025-05-09 16:53:07 +08:00
timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 //从上级获取的timestamp
timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1
2025-01-16 16:17:01 +08:00
timeinfo.tm_mday = timestamp.day;
timeinfo.tm_hour = timestamp.hour;
timeinfo.tm_min = timestamp.minute;
timeinfo.tm_sec = timestamp.second;
time_t time = std::mktime(&timeinfo);
line_info.time = static_cast<long long>(time);
cout << "time:" << line_info.time << endl;
strcpy(line_info.name, monitor_name);
cout << "name:" << line_info.name << endl;
2025-05-09 16:53:07 +08:00
line_info.read_flag = ENABLE; //监测点有效
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//ied = find_ied_from_dev_code(line_info.terminal_code); //不需要再找上级终端了,已经在终端里了
2025-01-16 16:17:01 +08:00
if (ied && ied->usr_ext && line_info.cpuno && (static_cast<int>(line_info.cpuno) < 10)) {
2025-05-09 16:53:07 +08:00
char str[256]; //256大小
2025-01-16 16:17:01 +08:00
byte_t cpuno = line_info.cpuno;
2025-02-14 16:44:38 +08:00
cout << "cpuno:" << (int)line_info.cpuno << endl;
2025-01-16 16:17:01 +08:00
cout << "index cpuno:" << cpuno-1 << endl;
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-05-09 16:53:07 +08:00
ied_usr->LD_info[cpuno - 1] = line_info; //cpuno默认是1
2025-01-16 16:17:01 +08:00
ied_usr->LD_info[cpuno - 1].ied = ied;
2025-05-09 16:53:07 +08:00
apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno);//将监测点逻辑号转为PQMonitorPQM+逻辑号
2025-02-08 17:04:39 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250208不使用apr_pstrdup后续直接复用
//ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str);//将 str 中的格式化字符串复制到内存池 g_init_pool 中。ied_usr->LD_info[cpuno - 1].LD_name 存储了这个字符串的副本LD_name 现在是 PQMonitorPQM{cpuno} 的形式。
// 从 g_init_pool 内存池中分配固定 256 字节的内存
2025-02-12 16:08:36 +08:00
ied_usr->LD_info[cpuno - 1].LD_name = (char *)apr_palloc(g_init_pool, 256);
2025-05-09 16:53:07 +08:00
// 清空内存,防止残留数据
2025-02-12 16:08:36 +08:00
memset(ied_usr->LD_info[cpuno - 1].LD_name, 0, 256);
2025-05-09 16:53:07 +08:00
// 将 str 中的内容复制到预先分配的内存中,最多复制 256 字节(包含结束符)
2025-02-12 16:08:36 +08:00
apr_cpystrn(ied_usr->LD_info[cpuno - 1].LD_name, str, 256);
2025-02-08 17:04:39 +08:00
2025-05-09 16:53:07 +08:00
//这里申请的空间基于ied的数量挂载到ied上
ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); //这两行代码分别为 ied_usr->LD_info[cpuno - 1] 的两个成员ht_fcd 和 ht_full_fcda创建了空的哈希表。apr_hash_make(g_init_pool) 会在 g_init_pool 内存池中为这两个哈希表分配内存空间
ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool);//它们的 key 值和 value 在后续的代码中可能会被填充
2025-01-16 16:17:01 +08:00
ied_usr->LD_info[cpuno - 1].rptcount = 0;
cout << "rptcount:" << ied_usr->LD_info[cpuno - 1].rptcount << endl;
if (cpuno > ied->cpucount) {
ied->cpucount = cpuno;
}
}
//}
}
}
}
2025-01-21 17:48:37 +08:00
//////////////////////////////////////////////////////////////////////////////////////////////////
2025-01-16 16:17:01 +08:00
if (count_real < count_cfg)
g_node->n_clients = count_real;
if (count_cfg != count_real)
return APR_EBADF;
cout << "dev init create count:" << count_real;
return APR_SUCCESS;
}
catch (otl_exception& e)
{
2025-04-30 10:22:57 +08:00
printf("\n device error,ERROR code= %d,msg= %s \n", e.code, e.msg);
2025-01-16 16:17:01 +08:00
return e.code;
}
}
int parse_model_web(QMap<QString, icd_model*>* icd_model_map,const std::vector<std::string>& codes)
{
2025-05-09 16:53:07 +08:00
std::string parm = codes[0]; //装置型号列表,格式["型号1","型号2"...]
2025-01-16 16:17:01 +08:00
char* ptr=NULL;
2025-05-09 16:53:07 +08:00
//测试用url参数
2025-01-16 16:17:01 +08:00
//SendJsonAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", parm.c_str(), "",&ptr);
SendJsonAPI_web(WEB_ICD,"",parm.c_str(),&ptr);
2025-05-09 16:53:07 +08:00
// 检查 ptr 是否为 NULL避免 std::string 初始化失败
2025-01-16 16:17:01 +08:00
if (ptr == NULL) {
2025-05-09 16:53:07 +08:00
// 处理 ptr 为 NULL 的情况,例如日志记录或错误处理
2025-01-16 16:17:01 +08:00
std::cout << "Error: Received NULL response"<< std::endl;
return 1;
}
2025-05-09 16:53:07 +08:00
//调试用
2025-01-16 16:17:01 +08:00
printf("ptr:%s\n",ptr);
2025-05-09 16:53:07 +08:00
cJSON* root = cJSON_Parse(ptr); //json格式序列化
2025-01-16 16:17:01 +08:00
int retry = 0;
if (root == NULL) {
printf("web error %s\n", cJSON_GetErrorPtr());
2025-05-09 16:53:07 +08:00
//重发多次
2025-01-16 16:17:01 +08:00
while(root == NULL){
2025-05-09 16:53:07 +08:00
// 在重试前释放之前的 ptr 以避免内存泄漏
2025-01-16 16:17:01 +08:00
if (ptr != NULL) {
free(ptr);
ptr = NULL;
}
2025-05-09 16:53:07 +08:00
//测试用url参数
2025-01-16 16:17:01 +08:00
//SendJsonAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", parm.c_str(), "",&ptr);
SendJsonAPI_web(WEB_ICD,"",parm.c_str(),&ptr);
if(ptr == NULL){
retry++;if(retry>3)break;
continue;
}
root = cJSON_Parse(ptr);
retry++;if(retry>3)break;
}
if (root == NULL) {
printf("web error %s\n", cJSON_GetErrorPtr());
return 1;
}
}
cJSON* codeItem = cJSON_GetObjectItem(root, "code");
cJSON* msgItem = cJSON_GetObjectItem(root, "msg");
2025-05-09 16:53:07 +08:00
// 使用 std::string 获取值
2025-01-16 16:17:01 +08:00
std::string code = (codeItem != NULL) ? codeItem->valuestring : "not found";
std::string msg = (msgItem != NULL) ? msgItem->valuestring : "not found";
2025-05-09 16:53:07 +08:00
// 打印结果
2025-01-16 16:17:01 +08:00
std::cout << "code: " << code << std::endl;
std::cout << "msg: " << msg << std::endl;
cJSON* data = cJSON_GetObjectItem(root, "data");
if (data && data->type == cJSON_Array) {
cJSON* item;
cJSON_ArrayForEach(item, data) {
icd_model* model = new icd_model;
cJSON* id = cJSON_GetObjectItem(item, "id");//model_id
if (id && id->type == cJSON_String) strncpy(model->model_id, id->valuestring, sizeof(model->model_id) - 1);
cJSON* fileName = cJSON_GetObjectItem(item, "fileName");//file_name
if (fileName && fileName->type == cJSON_String) strncpy(model->file_name, fileName->valuestring, sizeof(model->file_name) - 1);
2025-05-09 16:53:07 +08:00
cJSON* filePath = cJSON_GetObjectItem(item, "filePath");//新增
2025-01-16 16:17:01 +08:00
if (filePath && filePath->type == cJSON_String) strncpy(model->file_path, filePath->valuestring, sizeof(model->file_path) - 1);
cJSON* devType = cJSON_GetObjectItem(item, "devType");//tmnl_type
if (devType && devType->type == cJSON_String) strncpy(model->tmnl_type, devType->valuestring, sizeof(model->tmnl_type) - 1);
cJSON* updateTime = cJSON_GetObjectItem(item, "updateTime");//timestamp
if (updateTime && updateTime->type == cJSON_String) strncpy(model->timestamp, updateTime->valuestring, sizeof(model->timestamp) - 1);
2025-05-09 16:53:07 +08:00
// 添加到 QMap
2025-01-16 16:17:01 +08:00
icd_model_map->insert(model->model_id, model);
}
}
cJSON_Delete(root);
2025-05-09 16:53:07 +08:00
free(ptr); // 如果 SendJsonAPI_web 分配了内存,记得释放
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
return 0; // 确保函数有返回值
2025-01-16 16:17:01 +08:00
}
int parse_model_cfg_web()
{
2025-05-09 16:53:07 +08:00
std::vector<std::string> codes;//入参集合
2025-01-16 16:17:01 +08:00
QMap<QString, icd_model*> icd_model_map;
/////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//测试用
//codes.push_back("code1=model1"); //填入终端型号列表
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//使用中端型号列表构建入参json字符串
// 遍历前置所有监测点
2025-01-16 16:17:01 +08:00
ied_t* ied;
ied_usr_t* ied_usr;
std::cout << "g_node->n_clients" << g_node->n_clients << std::endl;
2025-05-09 16:53:07 +08:00
std::set<std::string> devTypes; // 用于去重的集合set
2025-01-16 16:17:01 +08:00
for (int t = 0; t < g_node->n_clients; t++) {
ied = (ied_t*)g_node->clients[t];
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-05-09 16:53:07 +08:00
// 假设 dev_type 是一个字符串类型,加入集合 ,这里会去重
2025-01-16 16:17:01 +08:00
if (strlen(ied_usr->dev_type) > 0) {
devTypes.insert(std::string(ied_usr->dev_type));
}
}
2025-05-09 16:53:07 +08:00
// 手动构建 JSON 字符串
2025-01-16 16:17:01 +08:00
std::string input_jstr = "[";
2025-05-09 16:53:07 +08:00
bool first = true; // 用于处理逗号
2025-01-16 16:17:01 +08:00
for (std::set<std::string>::iterator it = devTypes.begin(); it != devTypes.end(); ++it) {
if (!first) {
2025-05-09 16:53:07 +08:00
input_jstr += ","; // 添加逗号
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
first = false; // 第一次之后设置为 false
input_jstr += "\"" + *it + "\""; // 添加字符串
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
input_jstr += "]"; // 结束 JSON 数组
std::cout << "input_jstr: " << input_jstr << std::endl; // 输出结果
2025-01-16 16:17:01 +08:00
if(ICD_FLAG == "1"){
2025-05-09 16:53:07 +08:00
codes.push_back(input_jstr); //填入终端型号列表-获取指定的icd配置文件
2025-01-16 16:17:01 +08:00
}
else{
2025-05-09 16:53:07 +08:00
codes.push_back("[]"); //不填-获取所有的icd配置文件
2025-01-16 16:17:01 +08:00
}
/////////////////////////////////////////////////////////////////////////
parse_model_web(&icd_model_map,codes);
codes.clear();
try {
char model_id[64];
char tmnl_type[64];
//char tmnl_factory[64];
char file_name[128];
char file_path[128];
//char timestamp[64];
otl_datetime timestamp;
2025-05-09 16:53:07 +08:00
// 遍历终端台账容器
2025-01-16 16:17:01 +08:00
QMap<QString, icd_model*>::iterator it;
for (it = icd_model_map.begin(); it != icd_model_map.end(); ++it) {
icd_model* value = it.value();
2025-05-09 16:53:07 +08:00
// 确保 value 不为空
2025-01-16 16:17:01 +08:00
if (value != nullptr) {
2025-05-09 16:53:07 +08:00
// 找到容器中对应名称并取值
2025-01-16 16:17:01 +08:00
strncpy(model_id, value->model_id, sizeof(model_id) - 1);
strncpy(tmnl_type, value->tmnl_type, sizeof(tmnl_type) - 1);
strncpy(file_path, value->file_path, sizeof(file_path) - 1);
strncpy(file_name, value->file_name, sizeof(file_name) - 1);
//strncpy(timestamp, value->timestamp, sizeof(timestamp) - 1);
std::cout << "model_id" << model_id << std::endl;
std::cout << "tmnl_type" << tmnl_type << std::endl;
std::cout << "filepath" << file_path << std::endl;
std::cout << "filename" << file_name << std::endl;
2025-05-09 16:53:07 +08:00
//lnk20241125测试用
2025-01-16 16:17:01 +08:00
//strncpy(tmnl_type, "PS_NET", sizeof(tmnl_type) - 1);
Set_xml_databaseinfo(model_id, tmnl_type, file_path, file_name, timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second);
}
}
return APR_SUCCESS;
}
catch (otl_exception& e)
{
2025-04-30 10:22:57 +08:00
printf("\n icd model error,ERROR code= %d,msg= %s \n", e.code, e.msg);
2025-01-16 16:17:01 +08:00
return e.code;
}
}
2025-05-09 16:53:07 +08:00
////////////////////////////////////////////////////////////icd模型重构函数lnk20250116
2025-01-17 17:10:18 +08:00
char* parse_model_cfg_web_one(ied_t* ied)
{
2025-05-09 16:53:07 +08:00
std::vector<std::string> codes;//入参集合
2025-01-17 17:10:18 +08:00
QMap<QString, icd_model*> icd_model_map;
ied_usr_t* ied_usr;
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-05-09 16:53:07 +08:00
// 手动构建 JSON 字符串
2025-01-17 17:10:18 +08:00
std::string input_jstr = "[";
input_jstr += "\"" + std::string(ied_usr->dev_type) + "\"";
2025-05-09 16:53:07 +08:00
input_jstr += "]"; // 结束 JSON 数组
std::cout << "input_jstr: " << input_jstr << std::endl; // 输出结果
2025-01-17 17:10:18 +08:00
2025-05-09 16:53:07 +08:00
codes.push_back(input_jstr); //填入终端型号列表-获取指定的icd配置文件
2025-01-17 17:10:18 +08:00
parse_model_web(&icd_model_map,codes);
codes.clear();
try {
char model_id[64];
char tmnl_type[64];
char file_name[128];
char file_path[128];
2025-05-09 16:53:07 +08:00
otl_datetime timestamp;//不使用
2025-01-17 17:10:18 +08:00
2025-05-09 16:53:07 +08:00
// 遍历终端台账容器
2025-01-17 17:10:18 +08:00
QMap<QString, icd_model*>::iterator it;
for (it = icd_model_map.begin(); it != icd_model_map.end(); ++it) {
icd_model* value = it.value();
2025-05-09 16:53:07 +08:00
// 确保 value 不为空
2025-01-17 17:10:18 +08:00
if (value != nullptr) {
2025-05-09 16:53:07 +08:00
// 找到容器中对应名称并取值
2025-01-17 17:10:18 +08:00
strncpy(model_id, value->model_id, sizeof(model_id) - 1);
strncpy(tmnl_type, value->tmnl_type, sizeof(tmnl_type) - 1);
strncpy(file_path, value->file_path, sizeof(file_path) - 1);
strncpy(file_name, value->file_name, sizeof(file_name) - 1);
std::cout << "model_id" << model_id << std::endl;
std::cout << "tmnl_type" << tmnl_type << std::endl;
std::cout << "filepath" << file_path << std::endl;
std::cout << "filename" << file_name << std::endl;
2025-01-16 16:17:01 +08:00
2025-01-17 17:10:18 +08:00
Set_xml_databaseinfo(model_id, tmnl_type, file_path, file_name, timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second);
}
}
return model_id;
}
catch (otl_exception& e)
{
2025-04-30 10:22:57 +08:00
printf("\n icd model error,ERROR code= %d,msg= %s \n", e.code, e.msg);
2025-01-17 17:10:18 +08:00
return NULL;
}
}
////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//定时任务不需要定时日志清理和其他一些功能,统一放在这里修改
2025-01-16 16:17:01 +08:00
void OnTimerThread::run()
{
msleep(10000);
printf("OnTimerThread::run() is called ...... \n");
bool account_update = true;
bool asd = true;
2025-05-09 16:53:07 +08:00
//当前时间获取
2025-01-16 16:17:01 +08:00
apr_time_t previousTime = apr_time_now();//
apr_time_exp_t localTime;
apr_time_exp_gmt(&localTime, previousTime);
cout << "Local Time: "
<< localTime.tm_year + 1900 << "-" << localTime.tm_mon + 1 << "-" << localTime.tm_mday << " "
<< localTime.tm_hour << ":" << localTime.tm_min << ":" << localTime.tm_sec
<< endl;
2025-05-09 16:53:07 +08:00
//单联模式
2025-01-16 16:17:01 +08:00
if (g_onlyIP[0] != 0)
{
printf("g_onlyIP[0]=!0 ontimer--%s--\n", g_onlyIP);
add_comm_log(const_cast<char*>("g_onlyIP[0]=!0,g_onlyIP is --%s--", g_onlyIP));
}
else
{
printf("g_onlyIP[0] == 0!");
}
int pgflag = 0;
int pgmin = 0;
int mp_num_hour = 0;
2025-05-09 16:53:07 +08:00
//添加入参容器
2025-01-16 16:17:01 +08:00
std::vector<std::string> codes;
while (1)
{
2025-05-09 16:53:07 +08:00
//进入线程时间
2025-01-16 16:17:01 +08:00
previousTime = apr_time_now();
apr_time_exp_gmt(&localTime, previousTime);
2025-05-09 16:53:07 +08:00
//记录连接终端数
if (strcmp(subdir, "cfg_stat_data") == 0 || strcmp(subdir, "cfg_newhis_data") == 0) {//台账更新,多节点,通讯
2025-02-11 18:23:19 +08:00
2025-05-09 16:53:07 +08:00
//日志记录
2025-01-16 16:17:01 +08:00
if (mp_num_hour != localTime.tm_hour) {
2025-02-24 16:45:42 +08:00
pthread_mutex_lock(&mtx); std::cout << "ontime hold lock !!!!!!!!!!!" << std::endl;
2025-01-16 16:17:01 +08:00
std::string mp_num_str = "";
mp_num_str.append("connected device count:");
2025-05-09 16:53:07 +08:00
mp_num_str.append(QString::number(FRONT_MP_NUM).toStdString());//记录连接的检测点数
2025-01-16 16:17:01 +08:00
mp_num_str.append(",g_node clients:");
mp_num_str.append(QString::number(g_node->n_clients).toStdString());
add_comm_log(const_cast<char*>(mp_num_str.c_str()));
mp_num_hour = localTime.tm_hour;
2025-02-24 16:45:42 +08:00
pthread_mutex_unlock(&mtx); std::cout << "ontime free lock !!!!!!!!!!!" << std::endl;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
}
//添加日志开关控制lnk20250508
update_log_entries_countdown();
2025-01-16 16:17:01 +08:00
msleep(1000);
}
printf(">>>OnTimerThread::run() is end!!!\n");
}
2025-05-09 16:53:07 +08:00
//补招web处理函数
2025-01-16 16:17:01 +08:00
int recall_json_handle(const char* jstr)
{
2025-05-09 16:53:07 +08:00
//不指定稳态/暂态则全部补招
int stat = 0; //都不补
2025-01-16 16:17:01 +08:00
int voltage= 0;
try{
std::vector<RecallParam> recallParams;
2025-05-09 16:53:07 +08:00
cJSON* json_root = cJSON_Parse(jstr); //json格式序列化 //第一个参数
2025-01-16 16:17:01 +08:00
if (json_root == NULL) {
2025-05-09 16:53:07 +08:00
std::cout << "json root解析错误"<< std::endl;
2025-01-16 16:17:01 +08:00
return 10000;
}
2025-05-09 16:53:07 +08:00
// 遍历数组的每个对象
2025-01-16 16:17:01 +08:00
if (json_root->type == cJSON_Array) {
for (cJSON* item = json_root->child; item != nullptr; item = item->next) {
2025-05-09 16:53:07 +08:00
// 获取 monitorId 数组
2025-01-16 16:17:01 +08:00
cJSON* monitorIdArray = cJSON_GetObjectItem(item, "monitorId");
cJSON* timeIntervalArray = cJSON_GetObjectItem(item, "timeInterval");
2025-05-09 16:53:07 +08:00
//判断dataType是否为空
2025-01-16 16:17:01 +08:00
cJSON* datatype = cJSON_GetObjectItem(item, "dataType");
2025-05-09 16:53:07 +08:00
//添加异常判断防止崩溃
2025-01-16 16:17:01 +08:00
if(monitorIdArray == NULL || timeIntervalArray == NULL || datatype == NULL ){
2025-05-09 16:53:07 +08:00
std::cout << "json内容解析错误 "<< std::endl;
2025-01-16 16:17:01 +08:00
return 10000;
}
2025-05-09 16:53:07 +08:00
if(strcmp(datatype->valuestring, "") != 0)//非空
2025-01-16 16:17:01 +08:00
{
2025-05-09 16:53:07 +08:00
stat = (strcmp(datatype->valuestring, "0") == 0) ? 1 : 0;//稳态
voltage= (strcmp(datatype->valuestring, "1") == 0) ? 1 : 0;//暂态
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
{
stat = 1;
voltage= 1;
}
2025-05-09 16:53:07 +08:00
//调试用
if(monitorIdArray != nullptr && monitorIdArray->child != nullptr)std::cout << "monitorIdArray的成员为"<< monitorIdArray->child->valuestring << std::endl;
if(monitorIdArray != nullptr && monitorIdArray->child == nullptr)std::cout << "monitorIdArray没有成员"<< std::endl;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
//monitorIdArray有数据的情况
2025-01-16 16:17:01 +08:00
if (monitorIdArray != nullptr && monitorIdArray->type == cJSON_Array && timeIntervalArray->type == cJSON_Array && monitorIdArray->child != nullptr) {
2025-05-09 16:53:07 +08:00
// 遍历 monitorId 数组
2025-01-16 16:17:01 +08:00
for (cJSON* idItem = monitorIdArray->child; idItem != nullptr; idItem = idItem->next) {
QString monitorId = QString(idItem->valuestring);
2025-05-09 16:53:07 +08:00
//添加判断数组中当前监测点是否属于本进程20241230防止出现非本进程的监测点触发补招
2025-01-16 16:17:01 +08:00
int mppair = 0;
ied_t* ied;
ied_usr_t* ied_usr;
for (int t = 0; t < g_node->n_clients; t++){
ied = (ied_t*)g_node->clients[t];
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-05-09 16:53:07 +08:00
for (int m = 0; m<10; m++){//最多10个
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if(strcmp(ied_usr->LD_info[m].mp_id,"") == 0)continue;//跳过空的
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
if(strcmp(ied_usr->LD_info[m].mp_id,monitorId.toStdString().c_str()) == 0){//匹配上了
2025-01-16 16:17:01 +08:00
mppair = 1;
2025-05-09 16:53:07 +08:00
break;//找到就退出监测点循环
2025-01-16 16:17:01 +08:00
}
}
2025-05-09 16:53:07 +08:00
if(mppair == 1)break;//找到就退出终端循环
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
if(mppair == 0)continue;//当前进程的监测点都没有找到这个检测点号,说明不是本进程的监测点,处理数组的下一个监测点
//调试用
2025-01-16 16:17:01 +08:00
std::cout << "find mpid:" << monitorId.toStdString() << "in this process,mppair=" << mppair <<std::endl;
2025-05-09 16:53:07 +08:00
// 遍历 timeInterval 数组
2025-01-16 16:17:01 +08:00
for (cJSON* timeItem = timeIntervalArray->child; timeItem != nullptr; timeItem = timeItem->next) {
QString timeInterval = QString(timeItem->valuestring);
QString start = timeInterval.left(timeInterval.indexOf("~"));
QString end = timeInterval.mid(timeInterval.indexOf("~") + 1);
2025-05-09 16:53:07 +08:00
// 创建 RecallParam 对象并添加到列表中
2025-01-16 16:17:01 +08:00
RecallParam param;
param.mp_id = monitorId;
param.start = start;
param.end = end;
param.stat = stat;
param.voltage = voltage;
recallParams.push_back(param);
}
}
}
2025-05-09 16:53:07 +08:00
//monitorIdArray为空的情况
2025-01-16 16:17:01 +08:00
else if (monitorIdArray != nullptr && monitorIdArray->type == cJSON_Array && monitorIdArray->child == nullptr) {
2025-05-09 16:53:07 +08:00
// monitorIdArray 为空
2025-01-16 16:17:01 +08:00
std::cout << "monitorIdArray is null" << std::endl;
2025-05-09 16:53:07 +08:00
//所有监测点补招
// 遍历前置所有监测点
2025-01-16 16:17:01 +08:00
ied_t* ied;
ied_usr_t* ied_usr;
std::cout << "g_node->n_clients" << g_node->n_clients << std::endl;
for (int t = 0; t < g_node->n_clients; t++){
ied = (ied_t*)g_node->clients[t];
ied_usr = (ied_usr_t*)ied->usr_ext;
for (int m = 0; m<10; m++){
if(strcmp(ied_usr->LD_info[m].mp_id,"") == 0)continue;
std::cout << "ied_usr->LD_info[m].mp_id" << m << " "<< ied_usr->LD_info[m].mp_id << std::endl;
QString monitorId = QString(ied_usr->LD_info[m].mp_id);
2025-05-09 16:53:07 +08:00
// 遍历 timeInterval 数组
2025-01-16 16:17:01 +08:00
for (cJSON* timeItem = timeIntervalArray->child; timeItem != nullptr; timeItem = timeItem->next) {
QString timeInterval = QString(timeItem->valuestring);
QString start = timeInterval.left(timeInterval.indexOf("~"));
QString end = timeInterval.mid(timeInterval.indexOf("~") + 1);
2025-05-09 16:53:07 +08:00
// 创建 RecallParam 对象并添加到列表中
2025-01-16 16:17:01 +08:00
RecallParam param;
param.mp_id = monitorId;
param.start = start;
param.end = end;
param.stat = stat;
param.voltage = voltage;
recallParams.push_back(param);
}
}
}
}
else{
2025-05-09 16:53:07 +08:00
std::cout << "monitorIdArray 不存在或类型不正确" << std::endl;
2025-01-16 16:17:01 +08:00
}
}
}
2025-05-09 16:53:07 +08:00
cJSON_Delete(json_root); //web入参处理结束
//遍历容器取出所有补招
2025-01-16 16:17:01 +08:00
for (std::vector<RecallParam>::iterator it = recallParams.begin(); it != recallParams.end(); ++it) {
QList<RecallInfo> recallinfo_list_hour;
char start_time[64];
char end_time[64];
QString mp_id;
mp_id = it->mp_id;
apr_snprintf(start_time, sizeof(start_time), "%s", it->start.toStdString().c_str());//start_time
apr_snprintf(end_time, sizeof(end_time), "%s", it->end.toStdString().c_str());//end_time
qDebug() << "mp_id" << mp_id << " " << "start_time" << start_time << " " << "end_time" << " " << "stat" << it->stat << " " << "voltage" << it->voltage<< end_time;
Get_Recall_Time_Char(start_time, end_time, recallinfo_list_hour);
for (int j = 0; j < recallinfo_list_hour.size(); j++) {
CJournalRecall jr;
jr.MonitorID = mp_id;
jr.StartTime = QDateTime::fromTime_t(recallinfo_list_hour[j].starttime).toString("yyyy-MM-dd hh:mm:ss");
jr.EndTime = QDateTime::fromTime_t(recallinfo_list_hour[j].endtime).toString("yyyy-MM-dd hh:mm:ss");
2025-05-09 16:53:07 +08:00
//现在暂态稳态根据web获取
//jr.STEADY = QString::number(1, 10); // 将整数 1 转换为字符串并赋值
//jr.VOLTAGE = QString::number(1, 10);// 将整数 1 转换为字符串并赋值
//调试用
2025-01-16 16:17:01 +08:00
//std::cout << "stat" << it->stat << "voltage" << it->voltage << std::endl;
jr.STEADY = QString::number(it->stat);
jr.VOLTAGE = QString::number(it->voltage);
g_StatisticLackList_list_mutex.lock();
g_StatisticLackList.push_back(jr);
g_StatisticLackList_list_mutex.unlock();
}
}
}
catch (exception& e)
{
2025-05-09 16:53:07 +08:00
printf("处理客户端发送的消息错误,原因:%s\n", e.what());
2025-01-16 16:17:01 +08:00
return 10004;
}
return 000000;
}
int rtdata_http(const char* jstr)
{
}
2025-05-09 16:53:07 +08:00
// 声明外部函数http功能用库链接单独编译
2025-01-16 16:17:01 +08:00
#ifdef __cplusplus
extern "C" {
#endif
void httprun();
const char* getReceivedData(int fun);
void threadmsgweb(int fun);
bool threadmsghttp(int fun);
#ifdef __cplusplus
}
#endif
#if 0
void RecallJsonResponse(int result) {
char* ptr=NULL;
2025-05-09 16:53:07 +08:00
// 创建 JSON 对象
2025-01-16 16:17:01 +08:00
cJSON* json_response = cJSON_CreateObject();
2025-05-09 16:53:07 +08:00
// 添加字段
2025-01-16 16:17:01 +08:00
if(result == 000000){
cJSON_AddStringToObject(json_response, "code", "A0000");
2025-05-09 16:53:07 +08:00
cJSON_AddStringToObject(json_response, "msg", "数据补招执行成功");
2025-01-16 16:17:01 +08:00
}
else{
cJSON_AddStringToObject(json_response, "code", "A0002");
2025-05-09 16:53:07 +08:00
cJSON_AddStringToObject(json_response, "msg", "数据补招执行失败");
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
cJSON_AddNullToObject(json_response, "data"); // 设置为 null
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 将 JSON 对象转换为字符串
2025-01-16 16:17:01 +08:00
char* json_string = cJSON_Print(json_response);
std::cout << json_string << std::endl;
2025-05-09 16:53:07 +08:00
//发送回复给对方,只发一次
SendJsonAPI_web("调用方", "", json_string ,&ptr);
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(json_response);
2025-05-09 16:53:07 +08:00
free(json_string); // 释放打印字符串的内存
2025-01-16 16:17:01 +08:00
}
#endif
void WebhttpThread::run()
{
int ret = 1;
printf("WebhttpThread::run() is called ...... \n");
while(1){
2025-05-09 16:53:07 +08:00
//补招进程
if (!threadmsghttp(1) && g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) {//http处理一条消息,状态变为false不再处理消息http此时可能有消息来但是不处理后这个线程开始读取数据
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
const char* data = getReceivedData(1);//从http中取数据,指针
2025-01-16 16:17:01 +08:00
std::cout << "recall data cfg:" << data <<std::endl;
2025-02-24 16:45:42 +08:00
pthread_mutex_lock(&mtx); std::cout << "recall http hold lock !!!!!!!!!!!" << std::endl;
2025-05-09 16:53:07 +08:00
ret = recall_json_handle(data);//处理补招指令
2025-02-24 16:45:42 +08:00
pthread_mutex_unlock(&mtx); std::cout << "recall http free lock !!!!!!!!!!!" << std::endl;
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
threadmsgweb(1);//读取数据后开启http消息处理此时有消息来才会处理处理完状态变更等下一次循环
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
//3s数据进程
if (!threadmsghttp(2) && g_node_id == THREE_SECS_DATA_BASE_NODE_ID) {//http处理一条消息,状态变为false不再处理消息http此时可能有消息来但是不处理后这个线程开始读取数据
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
const char* data = getReceivedData(2);//从http中取数据,指针
2025-01-16 16:17:01 +08:00
std::cout << "rt data cfg:" << data <<std::endl;
2025-05-09 16:53:07 +08:00
ret = rtdata_http(data);//处理补招指令
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
threadmsgweb(2);//读取数据后开启http消息处理此时有消息来才会处理处理完状态变更等下一次循环
2025-01-16 16:17:01 +08:00
}
}
printf("WebhttpThread::run() is end ...... \n");
}
void httpThread::run()
{
printf("httpThread::run() is called ...... \n");
std::cout << "Server started at" << HTTP_IP << ":" << HTTP_PORT << std::endl;
2025-05-09 16:53:07 +08:00
httprun(); //开始运行http监听所有ip端口10004
2025-01-16 16:17:01 +08:00
printf("httpThread::run() is end ...... \n");
}
2025-05-09 16:53:07 +08:00
// Base64 编码函数,将输入的字符串编码为 Base64 格式 //实现json中的文件流
2025-01-16 16:17:01 +08:00
std::string base64_encode(const std::string& in) {
2025-05-09 16:53:07 +08:00
// Base64 字符集,由 64 个字符组成
2025-01-16 16:17:01 +08:00
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
2025-05-09 16:53:07 +08:00
std::string out; // 输出字符串
int val = 0; // 当前值
int valb = -6; // 值的位偏移量,初始为 -6
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 遍历输入字符串的每一个字符
2025-01-16 16:17:01 +08:00
for (std::string::const_iterator it = in.begin(); it != in.end(); ++it) {
2025-05-09 16:53:07 +08:00
// 将字符的 ASCII 值左移 8 位并加到 val 中
2025-01-16 16:17:01 +08:00
val = (val << 8) + *it;
2025-05-09 16:53:07 +08:00
valb += 8; // 更新位偏移量,每个字符占 8 位
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 当 valb 大于等于 0 时,说明有足够的位数可以进行编码
2025-01-16 16:17:01 +08:00
while (valb >= 0) {
2025-05-09 16:53:07 +08:00
// 将 val 的高 6 位转化为 Base64 字符,并添加到输出中
2025-01-16 16:17:01 +08:00
out.push_back(base64_chars[(val >> valb) & 0x3F]);
2025-05-09 16:53:07 +08:00
valb -= 6; // 每次编码后,位偏移量减少 6 位
2025-01-16 16:17:01 +08:00
}
}
2025-05-09 16:53:07 +08:00
// 如果还有剩余的位数,补充 '=' 字符
2025-01-16 16:17:01 +08:00
while (valb > -6) {
out.push_back('=');
2025-05-09 16:53:07 +08:00
valb -= 6; // 每次添加一个 '=',位偏移量减少 6 位
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
return out; // 返回编码后的字符串
2025-01-16 16:17:01 +08:00
}
void handleUploadResponse(const std::string& response, char* wavepath) {
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 == nullptr) {
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 && dataItem) {
std::string code = codeItem->valuestring;
std::cout << "Response Code: " << code << std::endl;
std::string msg = (msgItem != NULL) ? msgItem->valuestring : "not found";
std::cout << "Message: " << msg << std::endl;
cJSON* nameItem = cJSON_GetObjectItem(dataItem, "name");
cJSON* fileNameItem = cJSON_GetObjectItem(dataItem, "fileName");
cJSON* urlItem = cJSON_GetObjectItem(dataItem, "url");
if (nameItem && fileNameItem && urlItem) {
std::string name = nameItem->valuestring;
std::string fileName = fileNameItem->valuestring;
std::string url = urlItem->valuestring;
2025-05-09 16:53:07 +08:00
// 输出信息
2025-01-16 16:17:01 +08:00
std::cout << "File Path: " << name << std::endl;
std::cout << "Uploaded File Name: " << fileName << std::endl;
std::cout << "File URL: " << url << std::endl;
2025-05-09 16:53:07 +08:00
// 找到最后一个 '.'
2025-03-11 11:29:24 +08:00
size_t pos = fileName.find_last_of('.');
std::string nameWithoutExt;
if (pos != std::string::npos) {
2025-05-09 16:53:07 +08:00
// 截取去掉后缀的部分
2025-03-11 11:29:24 +08:00
nameWithoutExt = fileName.substr(0, pos);
2025-03-10 21:26:17 +08:00
} else {
2025-05-09 16:53:07 +08:00
// 如果没有后缀,直接使用原文件名
2025-03-11 11:29:24 +08:00
nameWithoutExt = fileName;
2025-03-10 21:26:17 +08:00
}
2025-03-11 11:29:24 +08:00
2025-05-09 16:53:07 +08:00
// 拷贝到 wavepath
2025-03-11 11:29:24 +08:00
strcpy(wavepath, nameWithoutExt.c_str());
2025-03-10 21:26:17 +08:00
std::cout << "wavepath: " << wavepath << std::endl;
2025-01-16 16:17:01 +08:00
}
} 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);
}
2025-05-09 16:53:07 +08:00
//这是json结构发送的方式
2025-01-16 16:17:01 +08:00
/*void SendFileWeb(const std::string& strUrl, const char* localpath, const char* cloudpath, char* wavepath) {
2025-05-09 16:53:07 +08:00
// 从本地路径读取文件内容
2025-01-16 16:17:01 +08:00
std::ifstream file(localpath, std::ios::binary);
if (!file) {
std::cerr << "Failed to open file: " << localpath << std::endl;
return;
}
std::ostringstream ss;
ss << file.rdbuf();
2025-05-09 16:53:07 +08:00
std::string fileContent = ss.str();//文件流
std::string encodedFile = base64_encode(fileContent);//文件流编码
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 创建 JSON 对象 实现入参要求
2025-01-16 16:17:01 +08:00
cJSON* json_root = cJSON_CreateObject();
cJSON_AddItemToObject(json_root, "multipartFile", cJSON_CreateString(encodedFile.c_str()));
2025-05-09 16:53:07 +08:00
cJSON_AddItemToObject(json_root, "path", cJSON_CreateString(cloudpath));//远端路径
cJSON_AddItemToObject(json_root, "isReserveName", cJSON_CreateBool(true)); // 布尔值
2025-01-16 16:17:01 +08:00
char* szjson = cJSON_Print(json_root);
std::cout << ">>> json: " << szjson << std::endl;
2025-05-09 16:53:07 +08:00
// curl 初始化
2025-01-16 16:17:01 +08:00
CURL* curl = curl_easy_init();
if (curl) {
2025-05-09 16:53:07 +08:00
// 设置请求为 POST 请求
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_slist_append(NULL, "Content-Type: application/json"));
2025-05-09 16:53:07 +08:00
// 设置超时时间
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
std::string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
2025-05-09 16:53:07 +08:00
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web); // 设置数据接收和写入函数
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 执行请求
2025-01-16 16:17:01 +08:00
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "lnk web failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "lnk web success, response: " << resPost0 << std::endl;
2025-05-09 16:53:07 +08:00
handleUploadResponse(resPost0,wavepath); // 处理响应
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(szjson);
} else {
std::cerr << ">>> curl init failed" << std::endl;
}
curl_easy_cleanup(curl);
cJSON_Delete(json_root);
}*/
2025-05-09 16:53:07 +08:00
//这是dataform发送方式
2025-01-16 16:17:01 +08:00
void SendFileWeb(const std::string& strUrl, const char* localpath, const char* cloudpath, char* wavepath) {
2025-05-09 16:53:07 +08:00
// 初始化 curl
2025-01-16 16:17:01 +08:00
CURL* curl = curl_easy_init();
if (curl) {
2025-05-09 16:53:07 +08:00
// 设置请求 URL 和 POST 请求
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1);
2025-05-09 16:53:07 +08:00
// 创建表单数据
2025-01-16 16:17:01 +08:00
curl_httppost* formpost = nullptr;
curl_httppost* lastptr = nullptr;
2025-05-09 16:53:07 +08:00
// 添加文件字段,直接从本地路径读取文件内容
2025-01-16 16:17:01 +08:00
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "file",
CURLFORM_FILE, localpath,
CURLFORM_END);
2025-05-09 16:53:07 +08:00
// 添加 `path` 字段
2025-01-16 16:17:01 +08:00
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "path",
CURLFORM_COPYCONTENTS, cloudpath,
CURLFORM_END);
2025-05-09 16:53:07 +08:00
// 添加 `isReserveName` 字段
2025-01-16 16:17:01 +08:00
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "isReserveName",
CURLFORM_COPYCONTENTS, "true",
CURLFORM_END);
2025-05-09 16:53:07 +08:00
// 设置表单数据到请求
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
2025-05-09 16:53:07 +08:00
// 设置头信息
2025-01-16 16:17:01 +08:00
struct curl_slist* header_list = nullptr;
header_list = curl_slist_append(header_list, "Content-Type: multipart/form-data");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
2025-05-09 16:53:07 +08:00
// 设置超时时间
2025-01-16 16:17:01 +08:00
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
2025-05-09 16:53:07 +08:00
// 设置写入响应数据的函数
2025-01-16 16:17:01 +08:00
std::string resPost0;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web);
2025-05-09 16:53:07 +08:00
// 执行请求
2025-01-16 16:17:01 +08:00
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "http web failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "http web success, response: " << resPost0 << std::endl;
2025-05-09 16:53:07 +08:00
handleUploadResponse(resPost0, wavepath); // 处理响应
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
// 清理
curl_formfree(formpost); // 释放表单数据
curl_slist_free_all(header_list); // 释放头部列表
2025-01-16 16:17:01 +08:00
curl_easy_cleanup(curl);
} else {
std::cerr << ">>> curl init failed" << std::endl;
}
}
void SOEFileWeb(char* localpath,char* cloudpath, char* wavepath)
{
2025-05-09 16:53:07 +08:00
//示例ip更换为实际ip即可
2025-01-16 16:17:01 +08:00
SendFileWeb(WEB_FILEUPLOAD,localpath,cloudpath,wavepath);
}
void SOEFileWeb_test()
{
2025-03-11 11:29:24 +08:00
char localpath[128] = {"/FeProject/comtrade/his/PQMonitor_PQM1_000420_20250310_151030_923.cfg"};
char cloudpath[128] = {"/comtrade/192.168.1.105/"};
2025-01-16 16:17:01 +08:00
char wavepath[128] = {""};
SOEFileWeb(localpath,cloudpath,wavepath);
2025-03-11 11:29:24 +08:00
std::cout << "wavepath:" << wavepath << std::endl;
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
/*/////////////////////////////////////////////////////////lnk10-24根据web接口修改/////////////////////////////////////////////////////////////*/
/*封装C可调用的台账更新函数 */////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025-01-16 16:17:01 +08:00
2025-01-21 17:48:37 +08:00
int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index,int ied_take)
2025-01-16 16:17:01 +08:00
{
chnl_usr_t* chnl_usr = NULL;
ied_usr_t* ied_usr = NULL;
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-05-09 16:53:07 +08:00
// 将 update[i] 中的数据写入到 ied_usr 中
2025-01-16 16:17:01 +08:00
if (strlen(update[i].terminal_id) != 0) {
apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", update[i].terminal_id);
printf("ied_usr->terminal_id: %s\n", ied_usr->terminal_id);
}
if (update[i].terminal_code != NULL) {
apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", update[i].terminal_code);
printf("ied_usr->terminal_code: %s\n", ied_usr->terminal_code);
}
if (update[i].tmnl_factory != NULL) {
apr_snprintf(ied_usr->tmnl_factory, sizeof(ied_usr->tmnl_factory), "%s", update[i].tmnl_factory);
printf("ied_usr->tmnl_factory: %s\n", ied_usr->tmnl_factory);
}
if (update[i].tmnl_status != NULL) {
apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", update[i].tmnl_status);
printf("ied_usr->tmnl_status: %s\n", ied_usr->tmnl_status);
}
if (update[i].dev_type != NULL) {
apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", update[i].dev_type);
printf("ied_usr->dev_type: %s\n", ied_usr->dev_type);
}
2025-02-11 18:23:19 +08:00
if (update[i].processNo != NULL) {
apr_snprintf(ied_usr->processNo, sizeof(ied_usr->processNo), "%s", update[i].processNo);
printf("ied_usr->processNo: %s\n", ied_usr->processNo);
}
2025-01-16 16:17:01 +08:00
if (update[i].dev_series != NULL) {
apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", update[i].dev_series);
printf("ied_usr->dev_series: %s\n", ied_usr->dev_series);
} else {
2025-05-09 16:53:07 +08:00
apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ""); // 默认为空字符串
2025-01-16 16:17:01 +08:00
printf("ied_usr->dev_series (default): %s\n", ied_usr->dev_series);
}
if (update[i].dev_key != NULL) {
apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", update[i].dev_key);
printf("ied_usr->dev_key: %s\n", ied_usr->dev_key);
} else {
2025-05-09 16:53:07 +08:00
apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ""); // 默认为空字符串
2025-01-16 16:17:01 +08:00
printf("ied_usr->dev_key (default): %s\n", ied_usr->dev_key);
}
2025-01-21 17:48:37 +08:00
2025-05-09 16:53:07 +08:00
ied_usr->dev_idx = terminal_index; //终端排号g_node下标
2025-01-16 16:17:01 +08:00
printf("dev_idx: %d\n", ied_usr->dev_idx);
2025-01-21 17:48:37 +08:00
2025-01-16 16:17:01 +08:00
ied->channel[0].channel_type = CHANNEL_TYPE_IPV4; // channel
ied->channel[0].addr_str[LONGNAME - 1] = 0; // DEV_IP
if (update[i].addr_str != NULL) {
ied->channel[0].addr = ntohl(inet_addr(update[i].addr_str)); // DEV_IP
strncpy(ied->channel[0].addr_str, update[i].addr_str, LONGNAME - 1); // DEV_IP
printf("ied_usr->addr_str: %s\n", ied->channel[0].addr_str);
} else {
ied->channel[0].addr = ntohl(inet_addr("0.0.0.0")); // DEV_IP
strncpy(ied->channel[0].addr_str, update[i].addr_str, LONGNAME - 1); // DEV_IP
printf("ied_usr->addr_str: %s\n", ied->channel[0].addr_str);
}
if (update[i].port != NULL) {
int port = 102;
if (stringToInt(update[i].port, &port)) {
2025-05-09 16:53:07 +08:00
// 转换成功portStr全为数字并且已经转换为int类型的port
2025-01-16 16:17:01 +08:00
ied->channel[0].port = port; // DEV_PortID
printf("ied_usr->port: %d\n", ied->channel[0].port); // DEV_PortID
} else {
ied->channel[0].port = 102; // DEV_PortID
2025-05-09 16:53:07 +08:00
printf("ied_usr->port: %s, 非合法端口. 使用默认端口: %d\n", update[i].port, ied->channel[0].port); // DEV_PortID
2025-01-16 16:17:01 +08:00
}
}
2025-01-21 17:48:37 +08:00
2025-01-16 16:17:01 +08:00
if (update[i].timestamp != NULL && strlen(update[i].timestamp) > 0) {
2025-05-09 16:53:07 +08:00
// 构造struct tm对象
struct tm timeinfo = {0}; // 初始化为0
// 假设时间字符串格式为 "YYYY-MM-DD HH:MM:SS"
// 使用sscanf从字符串中提取各个时间字段
2025-01-16 16:17:01 +08:00
if (sscanf(update[i].timestamp, "%4d-%2d-%2d %2d:%2d:%2d",
&timeinfo.tm_year, &timeinfo.tm_mon, &timeinfo.tm_mday,
&timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec) == 6) {
2025-05-09 16:53:07 +08:00
// 将年份从1900开始计算
2025-01-16 16:17:01 +08:00
timeinfo.tm_year -= 1900;
2025-05-09 16:53:07 +08:00
// 月份从0开始计算减去1
2025-01-16 16:17:01 +08:00
timeinfo.tm_mon -= 1;
2025-05-09 16:53:07 +08:00
// 对tm_isdst进行初始化通常可以设置为-1由mktime自动判断
2025-01-16 16:17:01 +08:00
timeinfo.tm_isdst = -1;
2025-05-09 16:53:07 +08:00
// 使用mktime将struct tm转换为time_t
2025-01-16 16:17:01 +08:00
time_t raw_time = mktime(&timeinfo);
2025-05-09 16:53:07 +08:00
// 判断mktime是否成功
2025-01-16 16:17:01 +08:00
if (raw_time != -1) {
ied_usr->time = (long long)raw_time;
printf("ied_usr->time: %lld\n", ied_usr->time);
} else {
printf("Error: mktime failed.\n");
}
} else {
printf("Error: sscanf failed. Invalid timestamp format.\n");
return -1;
}
}
2025-01-21 17:48:37 +08:00
2025-05-09 16:53:07 +08:00
//如果是使用已有空间则不需要再申请
2025-01-21 17:48:37 +08:00
if(!ied_take){
chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t));
ied->channel[0].connect = chnl_usr;
2025-05-09 16:53:07 +08:00
g_pt61850app->chnl_counts++; //新增的需要添加
2025-01-21 17:48:37 +08:00
}
else{
chnl_usr = (chnl_usr_t*)ied->channel[0].connect;
}
2025-05-09 16:53:07 +08:00
chnl_usr->chnl = &(ied->channel[0]);//如果是已有的ied这个值是原本就存在的再赋值一次
2025-01-16 16:17:01 +08:00
chnl_usr->chnl_id = 0;
chnl_usr->m_state = CHANNEL_DISCONNECTED;
chnl_usr->m_ClosedMsTime = NEXT_CONNECT_TIME * (-1);
2025-01-21 17:48:37 +08:00
2025-05-09 16:53:07 +08:00
// 将 monitorData 中的数据写入到 LD_info 中
int count_real_monitor = 0; //遍历监测点台账的计数器
2025-01-16 16:17:01 +08:00
int j;
for (j = 0; j < 10 && update[i].line[j].monitor_id[0] != '\0'; ++j) {
monitor monitor_data = update[i].line[j];
2025-05-09 16:53:07 +08:00
//监测点计数
2025-01-16 16:17:01 +08:00
count_real_monitor++;
2025-05-09 16:53:07 +08:00
// 初始化用于值拷贝的 LD_info里面涉及指针的部分都为空
2025-01-16 16:17:01 +08:00
LD_info_t line_info;
memset(&line_info, 0, sizeof(line_info));
2025-01-21 17:48:37 +08:00
2025-01-16 16:17:01 +08:00
char logical_device_seq[64];
2025-05-09 16:53:07 +08:00
// 填充监测点信息
2025-01-16 16:17:01 +08:00
strncpy(line_info.mp_id, monitor_data.monitor_id, sizeof(line_info.mp_id) - 1);
strncpy(line_info.name, monitor_data.monitor_name, sizeof(line_info.name) - 1);
strncpy(line_info.voltage_level, monitor_data.voltage_level, sizeof(line_info.voltage_level) - 1);
strncpy(line_info.v_wiring_type, monitor_data.terminal_connect, sizeof(line_info.v_wiring_type) - 1);
strncpy(line_info.monitor_status, monitor_data.status, sizeof(line_info.monitor_status) - 1);
strncpy(line_info.terminal_code, monitor_data.terminal_code, sizeof(line_info.terminal_code) - 1);
strncpy(logical_device_seq, monitor_data.logical_device_seq, sizeof(logical_device_seq) - 1);
if (isCharPtrEmpty(logical_device_seq)) {
2025-05-09 16:53:07 +08:00
line_info.cpuno = 1; // 默认监测点实例号1
2025-02-14 16:44:38 +08:00
printf("logical_device_seq: is null, set cpuno: %d\n", (int)line_info.cpuno);
2025-01-16 16:17:01 +08:00
} else {
line_info.cpuno = atoi(logical_device_seq);
2025-02-14 16:44:38 +08:00
printf("logical_device_seq: %d\n", (int)line_info.cpuno);
2025-01-16 16:17:01 +08:00
}
2025-05-09 16:53:07 +08:00
line_info.line_id = count_real_monitor; // 记录终端排号
2025-01-21 17:48:37 +08:00
2025-01-16 16:17:01 +08:00
printf("line_id: %d\n", line_info.line_id);
2025-01-16 19:16:26 +08:00
printf("mp_id: %s\n", line_info.mp_id);
2025-01-16 16:17:01 +08:00
printf("terminal_code: %s\n", line_info.terminal_code);
2025-01-16 19:16:26 +08:00
printf("voltage_level: %s\n", line_info.voltage_level);
printf("v_wiring_type: %s\n", line_info.v_wiring_type);
printf("monitor_status: %s\n", line_info.monitor_status);
2025-01-16 16:17:01 +08:00
printf("name: %s\n", line_info.name);
2025-01-21 17:48:37 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250214角形
2025-03-18 11:25:20 +08:00
if (strcmp(line_info.v_wiring_type, "0") != 0)
2025-02-14 16:44:38 +08:00
{
2025-05-09 16:53:07 +08:00
isdelta_flag = 1; //存在一个监测点为角型接线则这个前置就要启动第二个配置列表
2025-02-14 16:44:38 +08:00
cout << "monitor_id" << line_info.mp_id << "v_wiring_type:" << line_info.v_wiring_type << "is delta wiring:" << isdelta_flag << endl;
}
2025-05-09 16:53:07 +08:00
// 填充时间戳
2025-01-16 16:17:01 +08:00
if (update[i].timestamp[0] != '\0') {
struct tm timeinfo;
char timestamp[64];
2025-05-09 16:53:07 +08:00
// 假设update[i].timestamp格式为 "YYYY-MM-DD HH:MM:SS"
// 例如:"2023-01-14 12:34:56"
2025-01-16 16:17:01 +08:00
sscanf(update[i].timestamp, "%4d-%2d-%2d %2d:%2d:%2d",
&timeinfo.tm_year, &timeinfo.tm_mon, &timeinfo.tm_mday,
&timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec);
2025-05-09 16:53:07 +08:00
// 将年份从1900年开始计算
2025-01-16 16:17:01 +08:00
timeinfo.tm_year -= 1900;
2025-05-09 16:53:07 +08:00
// 月份从0开始减1
2025-01-16 16:17:01 +08:00
timeinfo.tm_mon -= 1;
2025-05-09 16:53:07 +08:00
// 对tm_isdst进行初始化通常可以设置为-1由mktime自动判断
2025-01-16 16:17:01 +08:00
timeinfo.tm_isdst = -1;
2025-05-09 16:53:07 +08:00
// 使用mktime将struct tm转换为time_t
2025-01-16 16:17:01 +08:00
time_t raw_time = mktime(&timeinfo);
2025-05-09 16:53:07 +08:00
// 判断mktime是否成功
2025-01-16 16:17:01 +08:00
if (raw_time != -1) {
line_info.time = (long long)raw_time;
printf("time: %lld\n", line_info.time);
} else {
printf("Error: mktime failed.\n");
return -1;
}
}
2025-05-09 16:53:07 +08:00
line_info.read_flag = 1; //监测点有效
// 填充 LD_info
2025-01-16 16:17:01 +08:00
if (ied && ied->usr_ext && line_info.cpuno && ((int)line_info.cpuno < 10)) {
char str[256];
2025-05-09 16:53:07 +08:00
byte_t cpuno = line_info.cpuno; //使用新台账的逻辑序列号在使用原有ied的情况下如果序列号数量小于原有数量那么新的部分会被覆盖如果删除时没有清理原有的其他部分会仍存在内存中但不会被使用
2025-02-14 16:44:38 +08:00
printf("cpuno: %d\n", (int)line_info.cpuno);
2025-01-16 16:17:01 +08:00
printf("index cpuno: %d\n", cpuno - 1);
2025-01-22 17:00:34 +08:00
2025-01-16 16:17:01 +08:00
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-05-09 16:53:07 +08:00
//ied_usr->LD_info[cpuno - 1] = line_info;//这个放在后面,因为需要先判断原有的指针
//ied_usr->LD_info[cpuno - 1].ied = ied; //这个放在后面,因为需要先判断原有的指针
2025-01-22 17:00:34 +08:00
2025-05-09 16:53:07 +08:00
//用来记录可能的已有的ldname
2025-01-22 17:00:34 +08:00
char *ldname = NULL;
2025-05-09 16:53:07 +08:00
//用来记录可能已有的报告、日志数组
2025-01-22 17:00:34 +08:00
loginfo_t **loginfo = NULL;
rptinfo_t **rptinfo = NULL;
2025-05-09 16:53:07 +08:00
//调试
2025-02-27 16:28:04 +08:00
//printf("check error111 !!!!!!!!!!!!!!\n");
2025-02-08 17:04:39 +08:00
2025-02-12 16:08:36 +08:00
2025-01-22 17:00:34 +08:00
2025-05-09 16:53:07 +08:00
///////// //清空已有的补招数组占用空间
2025-02-07 16:46:53 +08:00
if (ied_usr->LD_info[cpuno - 1].autorecallcount != 0) {
for (int j = 0; j < ied_usr->LD_info[cpuno - 1].autorecallcount; j++) {
if(NULL != ied_usr->LD_info[cpuno - 1].autorecall[j]){
delete ied_usr->LD_info[cpuno - 1].autorecall[j];
2025-01-22 17:00:34 +08:00
}
}
2025-02-07 16:46:53 +08:00
if(NULL != ied_usr->LD_info[cpuno - 1].autorecall){
delete ied_usr->LD_info[cpuno - 1].autorecall;
2025-01-22 17:00:34 +08:00
}
2025-02-07 16:46:53 +08:00
ied_usr->LD_info[cpuno - 1].autorecallcount = 0;
2025-01-22 17:00:34 +08:00
}
2025-05-09 16:53:07 +08:00
//调试
2025-02-27 16:28:04 +08:00
//printf("check error112 !!!!!!!!!!!!!!\n");
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
//////// //记录原有的报告和日志数组
2025-01-22 17:00:34 +08:00
loginfo = ied_usr->LD_info[cpuno - 1].loginfo?ied_usr->LD_info[cpuno - 1].loginfo:NULL;
rptinfo = ied_usr->LD_info[cpuno - 1].rptinfo?ied_usr->LD_info[cpuno - 1].rptinfo:NULL;
2025-05-09 16:53:07 +08:00
//调试
2025-02-27 16:28:04 +08:00
//printf("check error113 !!!!!!!!!!!!!!\n");
2025-01-21 17:48:37 +08:00
2025-05-09 16:53:07 +08:00
//避免重复分配内存如果使用已存在的ied那么它之前初始化就分配了哈希表如果在删除台账时没有清除则需要将原来的清除
2025-01-22 17:00:34 +08:00
if (ied_usr->LD_info[cpuno - 1].ht_fcd != NULL) {
2025-02-07 16:46:53 +08:00
apr_hash_clear(ied_usr->LD_info[cpuno - 1].ht_fcd);
2025-01-21 17:48:37 +08:00
}
2025-01-22 17:00:34 +08:00
if (ied_usr->LD_info[cpuno - 1].ht_full_fcda != NULL) {
2025-02-07 16:46:53 +08:00
apr_hash_clear(ied_usr->LD_info[cpuno - 1].ht_full_fcda);
2025-01-21 17:48:37 +08:00
}
2025-01-22 17:00:34 +08:00
2025-05-09 16:53:07 +08:00
//调试
2025-02-27 16:28:04 +08:00
//printf("check error116 !!!!!!!!!!!!!!\n");
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
//这些可能是已有的内存,如果存在则需要清除,(在台账删除时就应该清除)
2025-02-12 16:08:36 +08:00
apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno);
2025-05-09 16:53:07 +08:00
// 仅在没有值时更新 LD_name避免重复分配内存
2025-02-14 16:44:38 +08:00
if (ied_usr->LD_info[cpuno - 1].LD_name == NULL) {
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250208调试用
2025-02-12 16:08:36 +08:00
std::cout << "new space for LD_name" << std::endl;
2025-05-09 16:53:07 +08:00
//lnk20250208不使用apr_pstrdup使用固定大小后续都在这块内存上直接复用
2025-02-12 16:08:36 +08:00
//ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str);
2025-05-09 16:53:07 +08:00
// 从 g_init_pool 内存池中分配固定 256 字节的内存
2025-02-12 16:08:36 +08:00
ied_usr->LD_info[cpuno - 1].LD_name = (char *)apr_palloc(g_init_pool, 256);
2025-05-09 16:53:07 +08:00
// 清空内存,防止残留数据
2025-02-12 16:08:36 +08:00
memset(ied_usr->LD_info[cpuno - 1].LD_name, 0, 256);
2025-05-09 16:53:07 +08:00
// 将 str 中的内容复制到预先分配的内存中,最多复制 256 字节(包含结束符)
2025-02-12 16:08:36 +08:00
apr_cpystrn(ied_usr->LD_info[cpuno - 1].LD_name, str, 256);
2025-05-09 16:53:07 +08:00
} else {//已有则替换,在原有空间上覆盖
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250208调试用
2025-02-14 16:44:38 +08:00
std::cout << "old space for LD_name:" << ied_usr->LD_info[cpuno - 1].LD_name <<std::endl;
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
// 清空内存,防止残留数据
2025-02-12 16:08:36 +08:00
memset(ied_usr->LD_info[cpuno - 1].LD_name, 0, 256);
2025-02-27 16:28:04 +08:00
//printf("check error333 !!!!!!!!!!!!!!\n");
2025-02-14 16:44:38 +08:00
2025-05-09 16:53:07 +08:00
apr_cpystrn(ied_usr->LD_info[cpuno - 1].LD_name, str, 256); //原有空间覆盖
2025-02-14 16:44:38 +08:00
2025-02-27 16:28:04 +08:00
//printf("check error222 !!!!!!!!!!!!!!\n");
2025-02-12 16:08:36 +08:00
}
ldname = ied_usr->LD_info[cpuno - 1].LD_name;
2025-05-09 16:53:07 +08:00
//调试
2025-02-27 16:28:04 +08:00
//printf("check error114 !!!!!!!!!!!!!!\n");
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
ied_usr->LD_info[cpuno - 1] = line_info;//这个放在后面,因为需要先判断原有的指针
ied_usr->LD_info[cpuno - 1].ied = ied; //这个放在后面,因为需要先判断原有的指针
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
//调试
2025-02-27 16:28:04 +08:00
//printf("check error115 !!!!!!!!!!!!!!\n");
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
ied_usr->LD_info[cpuno - 1].LD_name = ldname;//记录原有的或者新的ldname
2025-01-22 17:00:34 +08:00
2025-05-09 16:53:07 +08:00
//调试
2025-02-12 16:08:36 +08:00
printf("ledger ied_usr->LD_info[cpuno - 1].LD_name: %s\n", ied_usr->LD_info[cpuno - 1].LD_name);
2025-05-09 16:53:07 +08:00
ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); //重新创建哈希表
2025-01-22 17:00:34 +08:00
ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool);
2025-05-09 16:53:07 +08:00
ied_usr->LD_info[cpuno - 1].rptcount = 0; //报告数清零这个值在ied_usr->LD_info[cpuno - 1] = line_info;时应该就已清0报告的空间会在报告块初始化时分配
2025-01-16 16:17:01 +08:00
printf("rptcount: %d\n", ied_usr->LD_info[cpuno - 1].rptcount);
2025-01-22 17:00:34 +08:00
2025-05-09 16:53:07 +08:00
//使用原有的报告日志空间
ied_usr->LD_info[cpuno - 1].loginfo = loginfo; //不管是新的还是旧的空间,后续初始化报告都会将它覆盖
2025-01-22 17:00:34 +08:00
ied_usr->LD_info[cpuno - 1].rptinfo = rptinfo;
2025-05-09 16:53:07 +08:00
if (cpuno > ied->cpucount) {//新台账的逻辑号大于ied原有的cpu数初始化是0则更新cpu数用来记录有多少个监测点
2025-01-22 17:00:34 +08:00
ied->cpucount = cpuno;
2025-01-16 16:17:01 +08:00
}
}
printf("Monitor Info [ID: %s, Name: %s] saved in LD_info\n", line_info.mp_id, line_info.name);
}
return 0;
}
2025-01-17 17:10:18 +08:00
2025-05-09 16:53:07 +08:00
////////////////////////////////////////////////////////////////////////台账更新记录日志
// 获取当前时间并格式化为 "YYYY-MM-DD HH:MM:SS"
2025-01-17 17:10:18 +08:00
std::string get_current_time() {
std::time_t t = std::time(NULL);
struct std::tm tm = *std::localtime(&t);
char buffer[80];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
return std::string(buffer);
}
2025-05-09 16:53:07 +08:00
// 写入日志条目
2025-01-17 17:10:18 +08:00
void write_log_entry(std::ofstream &log_file, const std::string &action, const std::string &terminal_id, const std::string &current_time) {
log_file << terminal_id << "\t" << action << "time:" << current_time << "\n";
}
2025-05-09 16:53:07 +08:00
// 创建台账更新日志
2025-01-17 17:10:18 +08:00
void create_ledger_log(trigger_update_xml_t* ledger_update_xml) {
2025-02-11 18:23:19 +08:00
std::cout << "create_ledger_log." << std::endl;
2025-01-17 17:10:18 +08:00
std::string log_filename = "../etc/" + std::string(LEDGER_UPDATE_FN);
2025-05-09 16:53:07 +08:00
std::ofstream log_file(log_filename.c_str(), std::ios::app); // 以追加模式打开文件
2025-01-17 17:10:18 +08:00
if (!log_file.is_open()) {
std::cerr << "Failed to open log file: " << log_filename << std::endl;
return;
}
2025-05-09 16:53:07 +08:00
std::vector<std::pair<std::string, std::string> > new_entries; // 用于存储new的terminal_id和时间
std::vector<std::pair<std::string, std::string> > modify_entries; // 用于存储modify的terminal_id和时间
std::vector<std::pair<std::string, std::string> > delete_entries; // 用于存储delete的terminal_id和时间
2025-01-17 17:10:18 +08:00
2025-05-09 16:53:07 +08:00
std::string current_time = get_current_time(); // 获取当前时间
2025-01-17 17:10:18 +08:00
2025-05-09 16:53:07 +08:00
// 处理 new_updates
2025-01-17 17:10:18 +08:00
for (int i = 0; i < ledger_update_xml->new_update_num; ++i) {
std::string terminal_id = ledger_update_xml->new_updates[i].terminal_id;
new_entries.push_back(std::make_pair(terminal_id, current_time));
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// 处理 modify_updates
2025-01-17 17:10:18 +08:00
for (int i = 0; i < ledger_update_xml->modify_update_num; ++i) {
std::string terminal_id = ledger_update_xml->modify_updates[i].terminal_id;
modify_entries.push_back(std::make_pair(terminal_id, current_time));
}
2025-05-09 16:53:07 +08:00
// 处理 delete_updates
2025-01-17 17:10:18 +08:00
for (int i = 0; i < ledger_update_xml->delete_update_num; ++i) {
std::string terminal_id = ledger_update_xml->delete_updates[i].terminal_id;
delete_entries.push_back(std::make_pair(terminal_id, current_time));
}
2025-05-09 16:53:07 +08:00
// 写入日志文件
2025-01-17 17:10:18 +08:00
if (!new_entries.empty()) {
log_file << "<new>\n";
for (size_t i = 0; i < new_entries.size(); ++i) {
write_log_entry(log_file, "add", new_entries[i].first, new_entries[i].second);
}
log_file << "</new>\n";
}
if (!modify_entries.empty()) {
log_file << "<modify>\n";
for (size_t i = 0; i < modify_entries.size(); ++i) {
write_log_entry(log_file, "modify", modify_entries[i].first, modify_entries[i].second);
}
log_file << "</modify>\n";
}
if (!delete_entries.empty()) {
log_file << "<delete>\n";
for (size_t i = 0; i < delete_entries.size(); ++i) {
write_log_entry(log_file, "delete", delete_entries[i].first, delete_entries[i].second);
}
log_file << "</delete>\n";
}
log_file.close();
std::cout << "Ledger log has been updated." << std::endl;
}
2025-05-09 16:53:07 +08:00
///////////////////////////////////////////////////////////////////////////台账内存分配部分功能代码:未使用
// 删除指定的子池
2025-01-21 17:48:37 +08:00
void delete_sub_pool(const char* terminal_id) {
std::list<std::pair<std::string, apr_pool_t*> >::iterator it;
for (it = pool_list.begin(); it != pool_list.end(); ++it) {
if (it->first == terminal_id) {
2025-05-09 16:53:07 +08:00
apr_pool_destroy(it->second); // 销毁子池
pool_list.erase(it); // 从容器中移除
2025-01-21 17:48:37 +08:00
break;
}
2025-01-17 17:10:18 +08:00
}
}
2025-05-09 16:53:07 +08:00
//找对应的子池
2025-01-21 17:48:37 +08:00
apr_pool_t* find_sub_pool(const char* terminal_id) {
std::list<std::pair<std::string, apr_pool_t*> >::iterator it;
for (it = pool_list.begin(); it != pool_list.end(); ++it) {
if (it->first == terminal_id) {
2025-05-09 16:53:07 +08:00
return it->second; // 找到对应的子池
2025-01-21 17:48:37 +08:00
}
}
2025-05-09 16:53:07 +08:00
return NULL; // 没有找到对应的子池
2025-01-21 17:48:37 +08:00
}
2025-05-09 16:53:07 +08:00
// 创建子池并添加到容器
2025-01-21 17:48:37 +08:00
apr_pool_t* create_sub_pool(apr_pool_t* parent_pool, const char* terminal_id) {
apr_pool_t* new_sub_pool = NULL;
2025-05-09 16:53:07 +08:00
// 在父池中创建一个子池
2025-01-21 17:48:37 +08:00
apr_pool_create(&new_sub_pool, parent_pool);
if (new_sub_pool == NULL) {
2025-05-09 16:53:07 +08:00
return NULL; // 创建失败
2025-01-21 17:48:37 +08:00
}
2025-05-09 16:53:07 +08:00
// 将子池和终端 ID 存储在容器中
2025-01-21 17:48:37 +08:00
pool_list.push_back(std::make_pair(std::string(terminal_id), new_sub_pool));
return new_sub_pool;
}
2025-01-22 17:00:34 +08:00
//////////////////////////////////////////////////////////////////////////////////////////////////
2025-05-09 16:53:07 +08:00
//台账变更的报告块初始化
2025-01-22 17:00:34 +08:00
int parse_rpt_log_ini_one(ied_t* ied)
{
QMap<QString, QStringList*> rpt_cfg_strlists;
QMap<QString, QStringList*> log_cfg_strlists;
int iedno, cpuno;
ied_usr_t* ied_usr;
LD_info_t* LD_info;
char buf[256];
ied_usr = GET_IEDEXT_ADDR(ied);
QString type;
type.append(ied_usr->dev_type);
if (!rpt_cfg_strlists.contains(type))
{
QStringList* rpt_temp = new QStringList();
QStringList* log_temp = new QStringList();
2025-05-09 16:53:07 +08:00
rpt_cfg_strlists.insert(type, rpt_temp);//报告控制列表
log_cfg_strlists.insert(type, log_temp);//日志控制列表
//g_DevFlag没有使用
2025-01-22 17:00:34 +08:00
parse_one_rpt_log_ini(g_DevFlag, rpt_cfg_strlists[type], log_cfg_strlists[type], ied_usr->dev_type);
}
2025-02-08 17:04:39 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250208调试用
2025-02-08 17:04:39 +08:00
std::cout << "ied->cpucount:" << (int)(ied->cpucount) <<std::endl;
2025-05-09 16:53:07 +08:00
for (cpuno = 0; cpuno < ied->cpucount; cpuno++) {//根据ied实际的检测点数遍历
2025-02-08 17:04:39 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250208调试用
2025-02-08 17:04:39 +08:00
std::cout << "cpuno:" << cpuno << "log init !!!!!!" <<std::endl;
2025-01-22 17:00:34 +08:00
LD_info = &(ied_usr->LD_info[cpuno]);
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//这些可能是已有的内存经过判断才能从g_init_pool中分配内存lnk20250122
2025-01-22 17:00:34 +08:00
char str[256];
char* tmp = Get_IED(ied_usr->dev_type);
2025-03-13 16:35:19 +08:00
if(tmp == NULL){std::cerr << "front read ied config error!" << std::endl;continue;}
2025-01-22 17:00:34 +08:00
qDebug() << tmp << endl;
apr_snprintf(str, sizeof(str), tmp, cpuno + 1);
2025-02-12 16:08:36 +08:00
2025-05-09 16:53:07 +08:00
//调试
printf("logini ied_usr->LD_info[cpuno - 1].LD_name: %s\n", ied_usr->LD_info[cpuno].LD_name);
2025-01-22 17:00:34 +08:00
2025-05-09 16:53:07 +08:00
delete[] tmp;//Get_IED中分配了内存使用后删除
2025-01-22 17:00:34 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250208调试用
2025-02-08 17:04:39 +08:00
std::cout << "cpuno:" << cpuno << " fill report control" <<std::endl;
2025-05-09 16:53:07 +08:00
//初始化监测点的报告控制
2025-01-22 17:00:34 +08:00
init_rptctrl_by_count(LD_info, rpt_cfg_strlists[type]->size());
for (int i = 0; i < rpt_cfg_strlists[type]->size(); ++i) {
apr_snprintf(buf, sizeof(buf), "%s", rpt_cfg_strlists[type]->at(i).toAscii().constData());
fill_rptctrl_by_cfg(LD_info, i, buf);
}
2025-05-09 16:53:07 +08:00
//初始化监测点的日志控制
2025-01-22 17:00:34 +08:00
init_logctrl_by_count(LD_info, log_cfg_strlists[type]->size());
for (int i = 0; i < log_cfg_strlists[type]->size(); ++i) {
apr_snprintf(buf, sizeof(buf), "%s", log_cfg_strlists[type]->at(i).toAscii().constData());
char* tmp = Get_LDevice(ied_usr->dev_type);
2025-03-13 16:35:19 +08:00
if(tmp == NULL){std::cerr << "front read monitor config error!" << std::endl;continue;}
2025-01-22 17:00:34 +08:00
fill_logctrl_by_cfg(LD_info, i, buf, tmp);
delete[] tmp;
}
}
2025-05-09 16:53:07 +08:00
//报告控制块和日志控制块处理结束后清理容器
2025-01-22 17:00:34 +08:00
for (QMap<QString, QStringList*>::iterator it1 = log_cfg_strlists.begin(); it1 != log_cfg_strlists.end(); ++it1)
{
delete it1.value();
}
for (QMap<QString, QStringList*>::iterator it2 = rpt_cfg_strlists.begin(); it2 != rpt_cfg_strlists.end(); ++it2)
{
delete it2.value();
}
rpt_cfg_strlists.clear();
log_cfg_strlists.clear();
return APR_SUCCESS;
}
////////////////////////////////////////////////////////////remdibtable
apr_status_t init_rem_dib_table_one(ied_t *ied)
{
int pos = 0;
int iedno,chnl_no;
struct in_addr ip;
chnl_usr_t *chnl_usr;
ied_usr_t* ied_usr;
2025-05-09 16:53:07 +08:00
//插入的位置和g_node一样
2025-01-22 17:00:34 +08:00
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-02-11 18:23:19 +08:00
pos = ied_usr->dev_idx - 1;
std::cout << "!!!!!!!!!rem_dib_table pos is " << pos << std::endl;
2025-01-22 17:00:34 +08:00
for(chnl_no=0 ; chnl_no<ied->chncount; chnl_no++) {
2025-05-09 16:53:07 +08:00
chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect;//初始化时已根据最大数量申请空间
2025-01-22 17:00:34 +08:00
g_pt61850app->chnl_usr[pos] = chnl_usr;
2025-02-11 18:23:19 +08:00
std::cout << "!!!!!!!!!g_pt61850app pos " << pos << "is " << ied_usr->terminal_id << "is" << (chnl_usr == NULL?"NULL":"NOTNULL") << std::endl;
2025-01-22 17:00:34 +08:00
ip.s_addr = htonl(ied->channel[chnl_no].addr);
strcpy(chnl_usr->ip_str,inet_ntoa(ip));
printf( " add_rem_dib_table %s:%d \n",chnl_usr->ip_str ,ied->channel[chnl_no].port );
2025-05-09 16:53:07 +08:00
add_rem_dib_table (pos++,chnl_usr->ip_str,ied->channel[chnl_no].port );//当前终端的IP端口记录到表中这里要注意添加的下标如果删除终端这个表内的内容仍存在再次使用时会被替换
2025-01-22 17:00:34 +08:00
{
char comm_str[256];
memset(comm_str,0,256);
apr_snprintf(comm_str,sizeof(comm_str),"%16s:%d\t\tinited",chnl_usr->ip_str,ied->channel[chnl_no].port);
add_comm_log(comm_str);
}
}
return APR_SUCCESS;
}
2025-05-09 16:53:07 +08:00
///////////////////////////////////////////////////////////////////////////////////////////////////清理ied
2025-01-23 16:32:26 +08:00
void clearLogInfo(loginfo_t *loginfo) {
if (loginfo == nullptr) {
2025-05-09 16:53:07 +08:00
return; // 如果传入的指针为空,直接返回
2025-01-23 16:32:26 +08:00
}
2025-05-09 16:53:07 +08:00
// 清空字符数组
2025-01-23 16:32:26 +08:00
memset(loginfo->logName, 0, sizeof(loginfo->logName));
2025-05-09 16:53:07 +08:00
// 清空其他非指针成员
2025-01-23 16:32:26 +08:00
loginfo->IntgPd = 0;
loginfo->reasonCode = 0;
loginfo->TrgOpt = 0;
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
loginfo->start_time = 0;
loginfo->end_time = 0;
loginfo->need_steady = 0;
loginfo->need_voltage = 0;
2025-05-09 16:53:07 +08:00
// 对指针成员进行清理,但不释放内存
2025-01-23 16:32:26 +08:00
if (loginfo->lcbName != nullptr) {
2025-05-09 16:53:07 +08:00
memset(loginfo->lcbName, 0, strlen(loginfo->lcbName)); // 清空字符串内容
2025-01-23 16:32:26 +08:00
}
if (loginfo->datasetName != nullptr) {
2025-05-09 16:53:07 +08:00
memset(loginfo->datasetName, 0, strlen(loginfo->datasetName)); // 清空字符串内容
2025-01-23 16:32:26 +08:00
}
2025-05-09 16:53:07 +08:00
// 由于 LD_info 是指针,它不清理,仍指向上级
2025-01-23 16:32:26 +08:00
}
void clearRptInfo(rptinfo_t *rptinfo) {
if (rptinfo == nullptr) {
2025-05-09 16:53:07 +08:00
return; // 如果传入的指针为空,直接返回
2025-01-23 16:32:26 +08:00
}
2025-05-09 16:53:07 +08:00
// 清空字符数组和非指针成员
2025-02-07 16:46:53 +08:00
rptinfo->instanceNeedSuffix = 0;
rptinfo->TrgOpt = 0;
2025-01-23 16:32:26 +08:00
memset(rptinfo->OptFlds, 0, sizeof(rptinfo->OptFlds));
rptinfo->IntgPd = 0;
rptinfo->report_PQ_type = 0;
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
rptinfo->rpt_registered = 0;
rptinfo->chnl_id = 0;
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
rptinfo->m_LastDataTime = 0;
rptinfo->m_LastGITime = 0;
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
rptinfo->m_LastRegisterFailedTime = 0;
rptinfo->m_LastUnRegisterFailedTime = 0;
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
memset(rptinfo->m_EntryID, 0, sizeof(rptinfo->m_EntryID));
rptinfo->m_curRptSuffix = 0;
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
rptinfo->count = 0;
rptinfo->rptNo = 0;
rptinfo->flickerflag = 0;
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
rptinfo->pstflag = 0;
2025-05-09 16:53:07 +08:00
// 对指针成员进行清理,但不释放内存
2025-01-23 16:32:26 +08:00
if (rptinfo->rptID != nullptr) {
2025-05-09 16:53:07 +08:00
memset(rptinfo->rptID, 0, strlen(rptinfo->rptID)); // 清空字符串内容
2025-01-23 16:32:26 +08:00
}
2025-05-09 16:53:07 +08:00
// 由于 LD_info 是指针,它不需要清理,仍指向父级
2025-01-23 16:32:26 +08:00
//rptinfo->LD_info = nullptr;
2025-05-09 16:53:07 +08:00
// 对 RCBC_INFO 结构体指针进行处理
2025-01-23 16:32:26 +08:00
if (rptinfo->m_rcb_info != nullptr) {
2025-05-09 16:53:07 +08:00
// 如果需要,可以选择清理结构体内部内容,但不释放内存
rptinfo->m_rcb_info = nullptr;//这里可以清空,因为这个指针指向的区域在连接通道关闭时会被清理
2025-01-23 16:32:26 +08:00
}
}
void clearLDInfo(LD_info_t *ld_info) {
if (ld_info == nullptr) {
std::cout << "ldinfo is null" << std::endl;
return;
}
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//保留原来的ied指向
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//清空报告
2025-02-07 16:46:53 +08:00
if (ld_info->rptinfo != nullptr) {
for (int i = 0; i < ld_info->rptcount; ++i) {
if (ld_info->rptinfo[i] != nullptr) {
2025-05-09 16:53:07 +08:00
clearRptInfo(ld_info->rptinfo[i]); //清空报告控制块
2025-02-07 16:46:53 +08:00
}
}
}
std::cout << "clean RptInfo!!!" << std::endl;
2025-05-09 16:53:07 +08:00
//清空日志
2025-01-23 16:32:26 +08:00
if (ld_info->loginfo != nullptr) {
for (int i = 0; i < ld_info->logcount; ++i) {
if (ld_info->loginfo[i] != nullptr) {
2025-05-09 16:53:07 +08:00
clearLogInfo(ld_info->loginfo[i]); //清空日志控制块
2025-01-23 16:32:26 +08:00
}
}
}
std::cout << "clean loginfo_t!!!" << std::endl;
2025-05-09 16:53:07 +08:00
//清空补招
2025-01-23 16:32:26 +08:00
if (ld_info->autorecall != nullptr) {
for (int i = 0; i < ld_info->autorecallcount; ++i) {
if (ld_info->autorecall[i] != nullptr) {
memset(ld_info->autorecall[i], 0, sizeof(autorecall_t));
2025-05-09 16:53:07 +08:00
delete ld_info->autorecall[i]; //删除数组元素空间,如果有正在补招的内容,则已经申请空间,需要释放
2025-01-23 16:32:26 +08:00
}
}
2025-05-09 16:53:07 +08:00
delete ld_info->autorecall; //删除数组空间
2025-01-23 16:32:26 +08:00
}
std::cout << "clean autorecall_t!!!" << std::endl;
if (ld_info->ht_fcd != nullptr) {
apr_hash_clear(ld_info->ht_fcd);
}
if (ld_info->ht_full_fcda != nullptr) {
apr_hash_clear(ld_info->ht_full_fcda);
}
2025-05-09 16:53:07 +08:00
// 清空其他指针成员
2025-02-07 16:46:53 +08:00
if (ld_info->name != nullptr) {
memset(ld_info->name, 0, sizeof(char) * 256);
}
2025-01-23 16:32:26 +08:00
if (ld_info->LD_name != nullptr) {
memset(ld_info->LD_name, 0, sizeof(char) * 256);
}
if (ld_info->mp_id != nullptr) {
memset(ld_info->mp_id, 0, sizeof(char) * 256);
}
if (ld_info->voltage_level != nullptr) {
memset(ld_info->voltage_level, 0, sizeof(char) * 256);
}
if (ld_info->v_wiring_type != nullptr) {
memset(ld_info->v_wiring_type, 0, sizeof(char) * 256);
}
if (ld_info->monitor_status != nullptr) {
memset(ld_info->monitor_status, 0, sizeof(char) * 64);
}
if (ld_info->terminal_code != nullptr) {
memset(ld_info->terminal_code, 0, sizeof(char) * 256);
}
2025-05-09 16:53:07 +08:00
ld_info->cpuno = 0; //清空逻辑序列号
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
ld_info->time = 0; //台账更新时间清0
ld_info->update_flag = 0; //监测点更新标志,暂不使用
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
ld_info->rptRecvFlag = 0;//重置报告标志
2025-02-07 16:46:53 +08:00
ld_info->rptRecvCheckFlag = 0;
ld_info->rptPstRecvFlag = 0;
ld_info->rptPstRecvCheckFlag = 0;
2025-05-09 16:53:07 +08:00
ld_info->read_flag = 0;//监测点无效
2025-02-07 16:46:53 +08:00
2025-01-23 16:32:26 +08:00
ld_info->rptcount = 0;
ld_info->logcount = 0;
ld_info->autorecallflag = 0;
ld_info->autorecallcount = 0;
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//ld_info->group = 0; //不使用
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//清空实时数据部分
2025-01-23 16:32:26 +08:00
ld_info->line_id = 0;
ld_info->real_data = 0;
ld_info->soe_data = 0;
ld_info->limit = 0;
ld_info->count = 0;
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//ld_info->SubV_Index = 0; //不使用
//ld_info->Dev_Index = 0; //不使用
//ld_info->Sub_Index = 0; //不使用
//ld_info->GD_Index = 0; //不使用
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//清空暂态结构
2025-02-07 16:46:53 +08:00
for (int i = 0; i < QVVR_NUM; ++i) {
ld_info->qvvr[i].used_status = 0;
ld_info->qvvr[i].QVVR_start = 0;
ld_info->qvvr[i].QVVR_type = 0;
ld_info->qvvr[i].QVVR_time = 0;
ld_info->qvvr[i].QVVR_PerTime = 0.0f;
ld_info->qvvr[i].QVVR_Amg = 0.0f;
2025-05-09 16:53:07 +08:00
memset(ld_info->qvvr[i].QVVR_Rptname, 0, sizeof(ld_info->qvvr[i].QVVR_Rptname)); // 清空字符数组
2025-02-07 16:46:53 +08:00
ld_info->qvvr[i].timestamp = 0;
}
ld_info->qvvr_idx = 0;
memset(ld_info->FltNum, 0, sizeof(ld_info->FltNum));
2025-05-09 16:53:07 +08:00
ld_info->RDRE_FltNum = 0; //录波号清零
2025-01-23 16:32:26 +08:00
}
void clearIedUsr(ied_usr_t *ied_usr) {
if (ied_usr == nullptr) {
std::cout << "ied_usr is null" << std::endl;
return;
}
2025-05-09 16:53:07 +08:00
// 清空 ied_usr_t 中的非指针部分
//ied_usr->dev_idx = 0;//保留index
2025-01-23 16:32:26 +08:00
ied_usr->dev_flag = UNUSED;
ied_usr->last_call_wavelist_time = 0;
2025-05-09 16:53:07 +08:00
ied_usr->time = 0; //台账更新时间
ied_usr->update_flag = 0; //台账更新标志暂不使用
2025-01-23 16:32:26 +08:00
2025-05-09 16:53:07 +08:00
// 清空指针部分,但不清理非空指针
2025-01-23 16:32:26 +08:00
if (ied_usr->LD_info != nullptr) {
2025-02-14 16:44:38 +08:00
2025-05-09 16:53:07 +08:00
// 如果 LD_info 不为空,清理它内部的内容
2025-01-23 16:32:26 +08:00
for (int i = 0; i < MAX_CPUNO; ++i) {
2025-02-14 16:44:38 +08:00
LD_info_t * ld =NULL;
ld = (LD_info_t *)&ied_usr->LD_info[i];
if (ld != NULL) {
clearLDInfo(ld);
2025-01-23 16:32:26 +08:00
}
}
}
2025-05-09 16:53:07 +08:00
if (ied_usr->cookie != nullptr) { //不使用
2025-01-23 16:32:26 +08:00
std::cout << "cookie not null" << std::endl;
}
2025-05-09 16:53:07 +08:00
// 清空其他非指针部分也可以不清0后续都会覆盖
2025-01-23 16:32:26 +08:00
memset(ied_usr->dev_type, 0, sizeof(ied_usr->dev_type));
memset(ied_usr->dev_key, 0, sizeof(ied_usr->dev_key));
memset(ied_usr->dev_series, 0, sizeof(ied_usr->dev_series));
memset(ied_usr->terminal_id, 0, sizeof(ied_usr->terminal_id));
memset(ied_usr->org_name, 0, sizeof(ied_usr->org_name));
memset(ied_usr->maint_name, 0, sizeof(ied_usr->maint_name));
memset(ied_usr->station_name, 0, sizeof(ied_usr->station_name));
memset(ied_usr->tmnl_factory, 0, sizeof(ied_usr->tmnl_factory));
memset(ied_usr->tmnl_status, 0, sizeof(ied_usr->tmnl_status));
memset(ied_usr->terminal_code, 0, sizeof(ied_usr->terminal_code));
}
2025-05-09 16:53:07 +08:00
// 清空 channel 和 cpuinfo 的非指针部分
2025-02-07 16:46:53 +08:00
void clear_channel_and_cpuinfo(byte_t chncount, channel_t *channel, byte_t cpucount, cpuinfo_t *cpuinfo) {
2025-05-09 16:53:07 +08:00
// 清空 channel 数组中的每个元素的非指针字段
2025-02-07 16:46:53 +08:00
for (byte_t i = 0; i < chncount && (&channel[i] != NULL); ++i) {
channel[i].master = 0;
channel[i].channel_type = 0;
memset(channel[i].addr_str, 0, LONGNAME);
channel[i].addr = 0;
channel[i].port = 0;
channel[i].status = 0;
channel[i].last_ticks = 0;
channel[i].last_send_ticks = 0;
channel[i].ied_id = 0;
2025-05-09 16:53:07 +08:00
// 清理 channel 里的 chnl_usr_t 部分
// 关闭连接时已清理,保留指针本身
2025-02-07 16:46:53 +08:00
}
2025-05-09 16:53:07 +08:00
// 清空 cpuinfo 数组中的每个元素的非指针字段
2025-02-07 16:46:53 +08:00
for (byte_t i = 0; i < cpucount && (&cpuinfo[i] != NULL); ++i) {
cpuinfo[i].addr = 0;
cpuinfo[i].status = 0;
cpuinfo[i].templ = 0;
memset(cpuinfo[i].name, 0, LONGNAME);
cpuinfo[i].last_gi = 0;
cpuinfo[i].last_gi_send = 0;
cpuinfo[i].next_gi_send = 0;
cpuinfo[i].last_ticks = 0;
cpuinfo[i].last_send_ticks = 0;
}
}
2025-01-23 16:32:26 +08:00
void clearIed(ied_t *ied) {
if (ied == nullptr) {
return;
}
2025-05-09 16:53:07 +08:00
// 清空 ied_t 的id
2025-02-07 16:46:53 +08:00
ied->id = 0;
2025-05-09 16:53:07 +08:00
//ied->flags = 0; //未使用
//ied->type = 0; //未使用
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//清理channel //清理cpuinfo
2025-02-07 16:46:53 +08:00
clear_channel_and_cpuinfo(ied->chncount,ied->channel,ied->cpucount,ied->cpuinfo);
2025-05-09 16:53:07 +08:00
ied->chncount = 0; //清空通道数
ied->cpucount = 0; //清空检测点数
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//名称清理
2025-02-07 16:46:53 +08:00
memset(ied->name, 0, LONGNAME);
2025-05-09 16:53:07 +08:00
//ied->station = 0; //未使用
//ied->node = 0; //未使用
//ied->frequency = 0; //未使用
//ied->delay = 0; //未使用
//ied->count = 0; //未使用
2025-02-07 16:46:53 +08:00
2025-05-09 16:53:07 +08:00
//数据组定义部分未使用
2025-02-07 16:46:53 +08:00
//ied->groups = NULL;
//ied->htgroups = NULL;
2025-05-09 16:53:07 +08:00
//系统令牌未使用
2025-02-07 16:46:53 +08:00
//ied->systoken_st = 0;
2025-01-23 16:32:26 +08:00
2025-05-09 16:53:07 +08:00
//ied->index = 0; //未使用
ied->status = STATUS_NOINIT; //设备状态设为未初始化
//ied->last_ticks = 0; //未使用
//ied->last_gi = 0; //未使用
2025-01-23 16:32:26 +08:00
2025-05-09 16:53:07 +08:00
// 清空指针部分
2025-01-23 16:32:26 +08:00
if (ied->usr_ext != nullptr) {
ied_usr_t *ied_usr = (ied_usr_t*)ied->usr_ext;
clearIedUsr(ied_usr);
}
2025-02-07 16:46:53 +08:00
if (ied->sys_ext != nullptr) {
2025-05-09 16:53:07 +08:00
//不使用
2025-02-07 16:46:53 +08:00
}
if (ied->app_ext != nullptr) {
2025-05-09 16:53:07 +08:00
//不使用
2025-02-07 16:46:53 +08:00
}
2025-01-23 16:32:26 +08:00
}
2025-05-09 16:53:07 +08:00
/*封装C可调用的台账更新函数 */////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//测试函数
2025-03-28 13:43:55 +08:00
std::string my_to_string(long long value) {
2025-02-18 17:10:22 +08:00
std::stringstream ss;
ss << value;
return ss.str();
}
2025-03-28 13:43:55 +08:00
2025-05-09 16:53:07 +08:00
//lnk20250328用来跳过匹配到的终端
2025-03-28 13:43:55 +08:00
bool shouldSkipTerminal(const char* terminal_id) {
for (size_t i = 0; i < TESTARRAY.size(); ++i) {
if (TESTARRAY[i] == terminal_id) {
return true;
}
}
return false;
}
2025-02-18 17:10:22 +08:00
void rocketmq_test_300(int mpnum,int front_index) {
Ckafka_data_t data;
data.strTopic = QString::fromStdString(G_ROCKETMQ_TOPIC);
data.mp_id = "0";
2025-05-09 16:53:07 +08:00
// 读取文件内容
std::ifstream file("long_string.txt"); // 文件中存储长字符串
2025-02-18 17:10:22 +08:00
std::stringstream buffer;
buffer << file.rdbuf();
2025-05-09 16:53:07 +08:00
std::string file_contents = buffer.str(); // 获取文件内容
2025-02-18 17:10:22 +08:00
std::string base_strText = file_contents;
2025-05-09 16:53:07 +08:00
// 获取当前时间作为开始时间
std::time_t t = std::time(NULL);//获取当前的系统时间(自 1970 年 1 月 1 日以来的秒数,通常称为 UNIX 时间戳)
std::tm* time_info = std::localtime(&t);//将 std::time_t表示当前的 UNIX 时间戳转换为本地时间std::tm 结构)
time_info->tm_sec = 0; // 清零秒位
//time_info->tm_msec = 0; // 清零毫秒位(如果需要更精确,使用高精度时间)
2025-02-18 17:10:22 +08:00
2025-05-09 16:53:07 +08:00
// 获取当前的时间戳(秒)
std::time_t base_time_t = std::mktime(time_info);//将 std::tm 结构(本地时间)转换回 std::time_t时间戳
2025-02-18 17:10:22 +08:00
2025-05-09 16:53:07 +08:00
// 计算每条消息的时间戳,精确到分钟,毫秒和秒清零
long long current_time_ms = static_cast<long long>(base_time_t) * 1000; // 每分钟递增,单位毫秒
2025-02-18 17:10:22 +08:00
2025-05-09 16:53:07 +08:00
// 设定总的消息数量
2025-02-18 17:10:22 +08:00
int total_messages = mpnum;
ied_t* ied;
ied_usr_t* ied_usr;
2025-05-09 16:53:07 +08:00
// 循环发送 300 条消息
2025-02-24 16:45:42 +08:00
for (int i = 0; (total_messages != 0 && g_front_seg_index == 1 && g_node_id == 100) && i < g_node->n_clients; ++i) {
2025-02-18 17:10:22 +08:00
ied = (ied_t*)g_node->clients[i];
if(ied != NULL){
ied_usr = (ied_usr_t*)ied->usr_ext;
2025-05-09 16:53:07 +08:00
//跳过正常的终端
2025-03-28 13:43:55 +08:00
if (shouldSkipTerminal(ied_usr->terminal_id)) {
std::cout << ied_usr->terminal_id << " use true message " << std::endl;
2025-02-18 17:10:22 +08:00
continue;
}
2025-01-16 16:17:01 +08:00
2025-02-18 17:10:22 +08:00
for (int j = 0; j < 10 && ied_usr->LD_info[j].mp_id[0] != '\0'; j++){
2025-05-09 16:53:07 +08:00
// 修改 Monitor 值
2025-02-18 17:10:22 +08:00
char monitor_id[256] = {};
strncpy(monitor_id, ied_usr->LD_info[j].mp_id, sizeof(monitor_id) - 1);
monitor_id[sizeof(monitor_id) - 1] = '\0';
data.mp_id = QString(monitor_id);
data.monitor_id = i + j;
2025-05-09 16:53:07 +08:00
std::string modified_time = my_to_string(current_time_ms); // 时间转换为整数类型Unix时间戳
2025-02-18 17:10:22 +08:00
2025-05-09 16:53:07 +08:00
// 替换消息中的 Monitor 和 TIME 字段(只匹配字段名,不匹配具体数值)
2025-02-18 17:10:22 +08:00
std::string modified_strText = base_strText;
2025-05-09 16:53:07 +08:00
// 替换 Monitor 字段
2025-02-18 17:10:22 +08:00
size_t monitor_pos = modified_strText.find("\"Monitor\"");
if (monitor_pos != std::string::npos) {
size_t colon_pos = modified_strText.find(":", monitor_pos);
size_t quote_pos = modified_strText.find("\"", colon_pos);
size_t end_quote_pos = modified_strText.find("\"", quote_pos + 1);
if (colon_pos != std::string::npos && quote_pos != std::string::npos && end_quote_pos != std::string::npos) {
modified_strText.replace(quote_pos + 1, end_quote_pos - quote_pos - 1, data.mp_id.toStdString());
}
}
2025-05-09 16:53:07 +08:00
// 替换 TIME 字段
2025-02-18 17:10:22 +08:00
size_t time_pos = modified_strText.find("\"TIME\"");
if (time_pos != std::string::npos) {
size_t colon_pos = modified_strText.find(":", time_pos);
size_t quote_pos = colon_pos;
size_t end_quote_pos = modified_strText.find(",", quote_pos + 1);
if (colon_pos != std::string::npos && quote_pos != std::string::npos && end_quote_pos != std::string::npos) {
modified_strText.replace(quote_pos + 1, end_quote_pos - quote_pos - 1, modified_time);
}
}
2025-05-09 16:53:07 +08:00
// 更新数据
2025-02-18 17:10:22 +08:00
data.strText = QString::fromStdString(modified_strText);
2025-05-09 16:53:07 +08:00
// 发送数据
2025-02-18 17:10:22 +08:00
my_rocketmq_send(data);
2025-05-09 16:53:07 +08:00
// 输出调试信息
2025-02-18 17:10:22 +08:00
std::cout << "Sent message " << (i + 1) << " with Monitor " << data.monitor_id << " and TIME " << modified_time << std::endl;
2025-05-09 16:53:07 +08:00
// 等待下一条消息的发送固定为1分钟
//QThread::sleep(60); // 每次发送间隔1分钟
2025-02-18 17:10:22 +08:00
}
}
}
std::cout << "Finished sending " << total_messages << " messages." << std::endl;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
///////////////////////////////////////////////////////////////////////////////lnk实时日志部分20250205
// ------------------ 全局日志列表和锁 ------------------
2025-02-25 16:33:11 +08:00
std::list<std::string> errorList;
std::list<std::string> warnList;
std::list<std::string> normalList;
2025-05-09 16:53:07 +08:00
std::list<std::string> debugList; // 新增 debugList
2025-02-25 16:33:11 +08:00
2025-02-27 16:28:04 +08:00
pthread_mutex_t errorListMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t warnListMutex = PTHREAD_MUTEX_INITIALIZER;
2025-02-25 16:33:11 +08:00
pthread_mutex_t normalListMutex = PTHREAD_MUTEX_INITIALIZER;
2025-05-09 16:53:07 +08:00
pthread_mutex_t debugListMutex = PTHREAD_MUTEX_INITIALIZER; // 新增 debugList 互斥锁
2025-02-27 16:28:04 +08:00
2025-05-09 16:53:07 +08:00
// ------------------ 输出开关 ------------------
bool errorOutputEnabled = false; // 是否将 error 级别写入 errorList
bool warnOutputEnabled = false; // 是否将 warn 级别写入 warnList
bool normalOutputEnabled = false; // 是否将 normal 级别写入 normalList
bool debugOutputEnabled = false; // 新增 debug 开关
2025-02-27 16:28:04 +08:00
2025-05-09 16:53:07 +08:00
// ------------------ 用于恢复原始缓冲区 ------------------
2025-02-27 16:28:04 +08:00
static std::streambuf* g_originalCoutBuf = NULL;
static std::streambuf* g_originalClogBuf = NULL;
static std::streambuf* g_originalCerrBuf = NULL;
2025-03-03 18:20:00 +08:00
2025-05-09 16:53:07 +08:00
// ------------------ 日志级别枚举C++98 ------------------
2025-02-27 16:28:04 +08:00
enum LogLevel {
LOGERROR,
LOGWARN,
LOGNORMAL,
2025-05-09 16:53:07 +08:00
LOGDEBUG // 新增 debug 级别
2025-02-25 16:33:11 +08:00
};
2025-02-27 16:28:04 +08:00
// ------------------------------------------------------------------
2025-05-09 16:53:07 +08:00
// TeeStreamBuf: 先写到原始buf(保持终端输出)再拷贝到list里
2025-02-27 16:28:04 +08:00
// ------------------------------------------------------------------
class TeeStreamBuf : public std::streambuf
{
public:
2025-05-09 16:53:07 +08:00
// 默认构造先把指针设为NULL
2025-02-27 16:28:04 +08:00
TeeStreamBuf()
: m_originalBuf(NULL), m_level(LOGNORMAL)
2025-02-27 16:28:04 +08:00
{
2025-03-05 17:47:47 +08:00
pthread_mutex_init(&m_mutex, NULL);
2025-02-27 16:28:04 +08:00
}
2025-05-09 16:53:07 +08:00
// 带参构造:直接初始化
2025-02-27 16:28:04 +08:00
TeeStreamBuf(std::streambuf* originalBuf, LogLevel level)
: m_originalBuf(originalBuf), m_level(level)
{
2025-03-05 17:47:47 +08:00
pthread_mutex_init(&m_mutex, NULL);
}
2025-05-09 16:53:07 +08:00
// 析构函数:销毁互斥锁
2025-03-05 17:47:47 +08:00
virtual ~TeeStreamBuf()
{
pthread_mutex_destroy(&m_mutex);
2025-02-27 16:28:04 +08:00
}
2025-05-09 16:53:07 +08:00
// 自定义 init(...) 函数:在同一个对象上重新设置
2025-02-27 16:28:04 +08:00
void init(std::streambuf* originalBuf, LogLevel level)
{
m_originalBuf = originalBuf;
m_level = level;
2025-03-05 17:47:47 +08:00
pthread_mutex_lock(&m_mutex);
2025-02-27 16:28:04 +08:00
m_buffer.clear();
2025-03-05 17:47:47 +08:00
pthread_mutex_unlock(&m_mutex);
2025-02-27 16:28:04 +08:00
}
protected:
2025-05-09 16:53:07 +08:00
// 当 flush 或 std::endl 时会调用 sync()
2025-02-27 16:28:04 +08:00
virtual int sync()
{
2025-05-09 16:53:07 +08:00
// 先让原始缓冲区执行同步
2025-02-27 16:28:04 +08:00
if (m_originalBuf) {
m_originalBuf->pubsync();
}
2025-05-09 16:53:07 +08:00
// 再将自身的缓存 flush
2025-02-27 16:28:04 +08:00
flushBuffer();
2025-05-09 16:53:07 +08:00
return 0; // 成功
2025-02-27 16:28:04 +08:00
}
2025-05-09 16:53:07 +08:00
// 当写入一个新字符时overflow() 被调用
2025-02-27 16:28:04 +08:00
virtual int_type overflow(int_type ch)
{
if (ch == traits_type::eof()) {
return ch;
}
2025-05-09 16:53:07 +08:00
// 1) 写到原始缓冲区 → 保留终端输出
2025-02-27 16:28:04 +08:00
if (m_originalBuf) {
if (m_originalBuf->sputc(static_cast<char>(ch)) == traits_type::eof()) {
return traits_type::eof();
}
}
2025-05-09 16:53:07 +08:00
// 2) 存到我们的临时缓存,注意加锁保护
pthread_mutex_lock(&m_mutex); //防止多线程推入崩溃lnk20250305
2025-03-05 17:47:47 +08:00
m_buffer.push_back(static_cast<char>(ch));
2025-05-09 16:53:07 +08:00
// 3) 遇到换行就 flushBuffer()
2025-02-27 16:28:04 +08:00
if (ch == '\n') {
2025-03-05 17:47:47 +08:00
flushBuffer_locked();
2025-02-27 16:28:04 +08:00
}
2025-03-05 17:47:47 +08:00
pthread_mutex_unlock(&m_mutex);
2025-02-27 16:28:04 +08:00
return ch;
}
private:
2025-05-09 16:53:07 +08:00
// 内部版本:假定互斥锁已经被加锁
2025-03-05 17:47:47 +08:00
void flushBuffer_locked()
2025-02-27 16:28:04 +08:00
{
if (m_buffer.empty()) {
return;
}
2025-05-09 16:53:07 +08:00
// 根据等级和对应开关,将 m_buffer 写入相应的 list
2025-02-27 16:28:04 +08:00
switch (m_level) {
case LOGERROR:
2025-03-05 17:47:47 +08:00
if (debugOutputEnabled) {
pthread_mutex_lock(&debugListMutex);
debugList.push_back(m_buffer);
pthread_mutex_unlock(&debugListMutex);
}
2025-03-03 18:20:00 +08:00
else if (normalOutputEnabled) {
pthread_mutex_lock(&normalListMutex);
normalList.push_back(m_buffer);
pthread_mutex_unlock(&normalListMutex);
2025-02-27 16:28:04 +08:00
}
2025-03-05 17:47:47 +08:00
else if (warnOutputEnabled) {
2025-02-27 16:28:04 +08:00
pthread_mutex_lock(&warnListMutex);
warnList.push_back(m_buffer);
pthread_mutex_unlock(&warnListMutex);
}
2025-03-05 17:47:47 +08:00
else if (errorOutputEnabled) {
2025-03-03 18:20:00 +08:00
pthread_mutex_lock(&errorListMutex);
errorList.push_back(m_buffer);
pthread_mutex_unlock(&errorListMutex);
2025-02-27 16:28:04 +08:00
}
break;
case LOGWARN:
2025-03-05 17:47:47 +08:00
if (debugOutputEnabled) {
pthread_mutex_lock(&debugListMutex);
debugList.push_back(m_buffer);
pthread_mutex_unlock(&debugListMutex);
}
2025-03-03 18:20:00 +08:00
else if (normalOutputEnabled) {
2025-02-27 16:28:04 +08:00
pthread_mutex_lock(&normalListMutex);
normalList.push_back(m_buffer);
pthread_mutex_unlock(&normalListMutex);
}
2025-03-05 17:47:47 +08:00
else if (warnOutputEnabled) {
2025-03-03 18:20:00 +08:00
pthread_mutex_lock(&warnListMutex);
warnList.push_back(m_buffer);
pthread_mutex_unlock(&warnListMutex);
}
2025-02-27 16:28:04 +08:00
break;
case LOGNORMAL:
2025-03-05 17:47:47 +08:00
if (debugOutputEnabled) {
pthread_mutex_lock(&debugListMutex);
debugList.push_back(m_buffer);
pthread_mutex_unlock(&debugListMutex);
}
2025-03-03 18:20:00 +08:00
else if (normalOutputEnabled) {
2025-02-27 16:28:04 +08:00
pthread_mutex_lock(&normalListMutex);
normalList.push_back(m_buffer);
pthread_mutex_unlock(&normalListMutex);
}
2025-03-03 18:20:00 +08:00
break;
2025-02-27 16:28:04 +08:00
}
m_buffer.clear();
}
2025-05-09 16:53:07 +08:00
// 对外接口,内部对 m_buffer 加锁
2025-03-05 17:47:47 +08:00
void flushBuffer()
{
pthread_mutex_lock(&m_mutex);
flushBuffer_locked();
pthread_mutex_unlock(&m_mutex);
}
2025-02-27 16:28:04 +08:00
private:
2025-05-09 16:53:07 +08:00
// 禁止自动生成的赋值函数
2025-03-05 17:47:47 +08:00
TeeStreamBuf& operator=(const TeeStreamBuf&);
2025-02-27 16:28:04 +08:00
private:
std::streambuf* m_originalBuf;
LogLevel m_level;
std::string m_buffer;
2025-03-05 17:47:47 +08:00
pthread_mutex_t m_mutex;
2025-02-27 16:28:04 +08:00
};
2025-05-09 16:53:07 +08:00
// ------------------ 全局Tee对象避免重复赋值 ------------------
2025-02-27 16:28:04 +08:00
static TeeStreamBuf g_errorTeeBuf;
static TeeStreamBuf g_warnTeeBuf;
static TeeStreamBuf g_normalTeeBuf;
2025-05-09 16:53:07 +08:00
// ------------------ 我们另外提供一个全局的 debug 输出流 ------------------
// 其原始buf默认为 NULL不输出到终端只存到 debugList(若开关开)
2025-03-03 18:20:00 +08:00
//static std::ostream g_debug(&g_debugTeeBuf);
2025-05-09 16:53:07 +08:00
// 让 qDebug() 映射到这个全局流
2025-03-03 18:20:00 +08:00
//#define qDebug() g_debug
2025-02-27 16:28:04 +08:00
2025-05-09 16:53:07 +08:00
// ------------------ 重定向函数 ------------------
// 只在第一次启用时,用 init(...) 初始化 TeeStreamBuf
// 之后再启用时,不再 new 或 赋值,而是直接用之前构造好的对象。
2025-02-27 16:28:04 +08:00
void redirectErrorOutput(bool enabled)
{
errorOutputEnabled = enabled;
if (enabled) {
if (g_originalCerrBuf == NULL) {
g_originalCerrBuf = std::cerr.rdbuf();
g_errorTeeBuf.init(g_originalCerrBuf, LOGERROR);
2025-02-27 16:28:04 +08:00
}
std::cerr.rdbuf(&g_errorTeeBuf);
} else {
if (g_originalCerrBuf) {
std::cerr.rdbuf(g_originalCerrBuf);
}
}
2025-02-25 16:33:11 +08:00
}
2025-02-27 16:28:04 +08:00
void redirectWarnOutput(bool enabled)
{
warnOutputEnabled = enabled;
if (enabled) {
if (g_originalClogBuf == NULL) {
g_originalClogBuf = std::clog.rdbuf();
g_warnTeeBuf.init(g_originalClogBuf, LOGWARN);
2025-02-27 16:28:04 +08:00
}
std::clog.rdbuf(&g_warnTeeBuf);
} else {
if (g_originalClogBuf) {
std::clog.rdbuf(g_originalClogBuf);
}
}
2025-02-25 16:33:11 +08:00
}
2025-02-27 16:28:04 +08:00
void redirectNormalOutput(bool enabled)
{
normalOutputEnabled = enabled;
if (enabled) {
if (g_originalCoutBuf == NULL) {
g_originalCoutBuf = std::cout.rdbuf();
g_normalTeeBuf.init(g_originalCoutBuf, LOGNORMAL);
2025-02-27 16:28:04 +08:00
}
std::cout.rdbuf(&g_normalTeeBuf);
} else {
if (g_originalCoutBuf) {
std::cout.rdbuf(g_originalCoutBuf);
}
}
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
// ------------------ 重定向函数 ------------------
2025-03-03 18:20:00 +08:00
void redirectDebugOutput(bool enable)
{
2025-03-03 18:20:00 +08:00
debugOutputEnabled = enable;
2025-05-09 16:53:07 +08:00
// 不去改 clog.rdbuf()
// 不去 install 任何 msg handler
2025-03-03 18:20:00 +08:00
}
2025-05-09 16:53:07 +08:00
// ------------------ Qt4 消息处理函数 ------------------
2025-03-03 18:20:00 +08:00
void myQtMsgHandler(QtMsgType type, const char *msg)
{
2025-05-09 16:53:07 +08:00
// 不论消息类型如何,都写入 debugList
2025-03-03 18:20:00 +08:00
if (debugOutputEnabled) {
pthread_mutex_lock(&debugListMutex);
2025-03-04 17:29:04 +08:00
debugList.push_back(msg);
2025-03-03 18:20:00 +08:00
pthread_mutex_unlock(&debugListMutex);
}
2025-05-09 16:53:07 +08:00
// 根据消息类型选择输出流
2025-03-04 17:29:04 +08:00
FILE* output = nullptr;
2025-03-03 18:20:00 +08:00
const char* typeStr = "";
switch (type) {
case QtDebugMsg:
typeStr = "Debug";
2025-05-09 16:53:07 +08:00
output = stdout; // Debug 走标准输出
2025-03-03 18:20:00 +08:00
break;
case QtWarningMsg:
typeStr = "Warning";
2025-05-09 16:53:07 +08:00
output = stderr; // Warning 走标准错误
2025-03-03 18:20:00 +08:00
break;
case QtCriticalMsg:
typeStr = "Critical";
2025-05-09 16:53:07 +08:00
output = stderr; // Critical 走标准错误
2025-03-03 18:20:00 +08:00
break;
case QtFatalMsg:
typeStr = "Fatal";
2025-05-09 16:53:07 +08:00
output = stderr; // Fatal 走标准错误
2025-03-03 18:20:00 +08:00
break;
}
2025-03-03 18:20:00 +08:00
2025-03-04 17:29:04 +08:00
fprintf(output, "[%s] %s\n", typeStr, msg);
fflush(output);
2025-05-09 16:53:07 +08:00
// Fatal 时进程退出
2025-03-04 17:29:04 +08:00
if (type == QtFatalMsg) {
2025-03-03 18:20:00 +08:00
abort();
2025-03-04 17:29:04 +08:00
}
}
2025-05-09 16:53:07 +08:00
// ------------------ 自定义 printf 输出 ------------------
// 这里示例:把它当成 normal 级别 => 最终会进入normalList(若开关开)
// 定义一个全局静态的互斥锁,名称为 printfmtx
static pthread_mutex_t printfmtx = PTHREAD_MUTEX_INITIALIZER;
2025-05-09 16:53:07 +08:00
// RAII风格的锁包装类
class LockGuard {
public:
explicit LockGuard(pthread_mutex_t& mutex) : mtx(mutex) {
pthread_mutex_lock(&mtx);
}
~LockGuard() {
pthread_mutex_unlock(&mtx);
}
private:
pthread_mutex_t& mtx;
};
2025-02-27 16:28:04 +08:00
int customPrintf(const char* format, ...)
{
2025-05-09 16:53:07 +08:00
// 在进入函数时自动加锁,退出时自动解锁
LockGuard lock(printfmtx);
2025-02-25 16:33:11 +08:00
va_list args;
va_start(args, format);
2025-02-27 16:28:04 +08:00
2025-02-25 16:33:11 +08:00
char buffer[1024];
2025-02-26 16:39:10 +08:00
int written = vsnprintf(buffer, sizeof(buffer), format, args);
2025-02-25 16:33:11 +08:00
va_end(args);
2025-02-26 16:39:10 +08:00
if (written < 0) {
return -1;
2025-02-25 16:33:11 +08:00
}
2025-05-09 16:53:07 +08:00
// 将格式化后的字符串输出到 std::cout
2025-02-27 16:28:04 +08:00
std::cout << buffer << std::endl;
2025-02-25 16:33:11 +08:00
2025-02-27 16:28:04 +08:00
return written;
2025-02-25 16:33:11 +08:00
}
2025-03-04 17:29:04 +08:00
///////////////////////////////////////////////////////////////////////////////
void echo_msg_errexy(const char *file_name, int line_no, int rv, const char *fmt, ...) {
char __buf[1024];
va_list __ap;
va_start(__ap, fmt);
vsnprintf(__buf, sizeof(__buf), fmt, __ap);
va_end(__ap);
2025-05-09 16:53:07 +08:00
// 终端输出
2025-03-04 17:29:04 +08:00
printf("[ERROR] rv=%d %s:%d => %s", rv, file_name, line_no, __buf);
fflush(stdout);
2025-05-09 16:53:07 +08:00
// 写入 errorList
2025-03-04 17:29:04 +08:00
if (errorOutputEnabled) {
pthread_mutex_lock(&errorListMutex);
errorList.push_back(std::string(__buf));
pthread_mutex_unlock(&errorListMutex);
}
}
void echo_msg_warnexy(const char *file_name, int line_no, const char *fmt, ...) {
char __buf[1024];
va_list __ap;
va_start(__ap, fmt);
vsnprintf(__buf, sizeof(__buf), fmt, __ap);
va_end(__ap);
2025-05-09 16:53:07 +08:00
// 终端输出
2025-03-04 17:29:04 +08:00
printf("[WARN ] %s:%d => %s", file_name, line_no, __buf);
fflush(stdout);
2025-03-03 18:20:00 +08:00
2025-05-09 16:53:07 +08:00
// 写入 warnList
2025-03-04 17:29:04 +08:00
if (warnOutputEnabled) {
pthread_mutex_lock(&warnListMutex);
warnList.push_back(std::string(__buf));
pthread_mutex_unlock(&warnListMutex);
}
}
void echo_msg_debugexy(const char *file_name, int line_no, const char *fmt, ...) {
char __buf[1024];
va_list __ap;
va_start(__ap, fmt);
vsnprintf(__buf, sizeof(__buf), fmt, __ap);
va_end(__ap);
2025-05-09 16:53:07 +08:00
// 终端输出
2025-03-04 17:29:04 +08:00
printf("[DEBUG] %s:%d => %s", file_name, line_no, __buf);
fflush(stdout);
2025-05-09 16:53:07 +08:00
// 写入 normalList
2025-03-04 17:29:04 +08:00
if (normalOutputEnabled) {
pthread_mutex_lock(&normalListMutex);
normalList.push_back(std::string(__buf));
pthread_mutex_unlock(&normalListMutex);
}
}
2025-02-25 16:33:11 +08:00
///////////////////////////////////////////////////////////////////////////////
2025-03-07 18:27:03 +08:00
void Worker::telnetetst(QTcpSocket* clientSocket) {
2025-03-06 18:41:48 +08:00
int ip_count = 0;
int telnet_count = 0;
2025-05-09 16:53:07 +08:00
//在测试连接时给台账加锁lnk20250114
2025-03-06 18:41:48 +08:00
pthread_mutex_lock(&mtx); std::cout << "testping hold lock !!!!!!!!!!!" << std::endl;
2025-03-07 18:27:03 +08:00
Worker::init_ping_telnet(clientSocket,ip_count, telnet_count);
2025-03-06 18:41:48 +08:00
Cout_account_information();
pthread_mutex_unlock(&mtx); std::cout << "testping free lock !!!!!!!!!!!" << std::endl;
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
////////////////////////////////////////////////////////////////////////////////
const char* get_front_msg_from_subdir() {
if (std::strstr(subdir, "cfg_3s_data") != NULL)
return "实时数据进程";
else if (std::strstr(subdir, "cfg_soe_comtrade") != NULL)
return "暂态和告警进程";
else if (std::strstr(subdir, "cfg_recallhis_data") != NULL)
return "稳态补招进程";
else if (std::strstr(subdir, "cfg_stat_data") != NULL)
return "稳态统计进程";
else
return "unknown";
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void send_reply_to_kafka(const std::string& guid, const std::string& step, const std::string& result) {
// 构造 JSON 字符串
std::ostringstream oss;
oss << "{"
<< "\"guid\":\"" << guid << "\","
<< "\"step\":\"" << step << "\","
<< "\"result\":\"" << result << "\""
<< "}";
std::string jsonString = oss.str();
// 封装 Kafka 消息
Ckafka_data_t connect_info;
connect_info.strTopic = QString::fromStdString(Topic_Reply_Topic);
connect_info.strText = QString::fromStdString(jsonString);
// 加入发送队列(带互斥锁保护)
kafka_data_list_mutex.lock();
kafka_data_list.append(connect_info);
kafka_data_list_mutex.unlock();
}
2025-01-16 16:17:01 +08:00
2025-05-09 16:53:07 +08:00
void send_heartbeat_to_kafka(const std::string& status) {
// 构造 JSON 字符串
std::ostringstream oss;
oss << "{"
<< "\"nodeId\":\"" << FRONT_INST << "\","
<< "\"frontType\":\"" << get_front_type_from_subdir() << "\","
<< "\"processNum\":\"" << g_front_seg_index << "\","
<< "\"status\":\"" << status << "\""
<< "}";
std::string jsonString = oss.str();
// 封装 Kafka 消息
Ckafka_data_t connect_info;
connect_info.strTopic = QString::fromStdString(Heart_Beat_Topic);
connect_info.strText = QString::fromStdString(jsonString);
// 加入发送队列(带互斥锁保护)
kafka_data_list_mutex.lock();
kafka_data_list.append(connect_info);
kafka_data_list_mutex.unlock();
}