using namespace std; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define OTL_ODBC_ODBC #define OTL_ODBC_UNIX #include #include "otlv4.h" #include #include //lnk 2024-10-16 #include //写去重的设备类型 #include //上传文件 #include "../mms/db_interface.h" #include "../json/save2json.h" #include "../json/mms_json_inter.h" #include "../mms/rdb_client.h" #include "../mms/interface.h" #include "../json/cjson.h"//WW 2023-08-27新增json解析函数 #include "../include/curl/curl.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ 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; extern char g_onlyIP[255]; //直连某个IP,仅仅为方便测试 int g_DevFlag = 0; #ifdef __cplusplus } #endif ///////////////////////////////lnk20250118台账变更使用的内存池:动态内存池的方式,每个内存池放一个ied的所有相关内容,这个方案暂不使用,只保留相关实现函数 // 用于存储终端 ID 和对应的子池 std::list > pool_list; /////////////////////////////////////////////////// //ZW 2023-10-10 单条补招结构 class RecallInfo { public: long long starttime; long long endtime; }; //CZY 2023-09-17 控制命令解析 class ProgramParam // { public: QList terminal_list;//终端id列表 QString file_name;//程序下装可用,下装程序在oss中的位置 }; //CZY 2023-09-17 控制命令解析 class RecallParam // { public: QString mp_id;//监测点id QString start;//补招数据起始时间 QString end;//补招数据结束时间 int voltage;//暂态数据标志 int stat;//稳态数据标志 }; //CZY 2023-10-12 装置识别码与密钥 class terminal_ext // { public: char terminal_identify_code[100];//终端识别码 char terminal_key[100];//终端密钥 }; class CJournalRecall //日志补招结构类 { public: QString MonitorID; //线路监测点号 QString StartTime; //数据补招起始时间 QString EndTime; //数据补招结束时间 QString STEADY; //补招历史统计数据标识 0-不补招;1-补招 QString VOLTAGE; //补招暂态事件标识 0-不补招;1-补招 }; /*lnk 2024-10-15 */ class ledger_monitor //监测点台账 { 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]; char count_cfg[64]; //不是台账的一部分,用来记录数据库或业务中台的台账数量 }; class terminal_dev //终端台账 { 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]; //lnk20250210添加进程号 char processNo[64]; ledger_monitor line[10]; char count_cfg[64]; //不是台账的一部分,用来记录数据库或业务中台的台账数量 }; class icd_model //icd模型 { public: char model_id[64]; char tmnl_type[64]; char tmnl_type_id[64]; //不使用 char tmnl_factory[64]; //不使用 char file_name[128]; char file_path[128]; char timestamp[64]; }; class front_list//前置表 { public: char front_ip[64]; char front_port[64]; char front_inst[64]; char front_type[64]; char front_status[64]; char front_version[64]; char mp_num[64]; }; class intact_list//前置表 { public: char monitor_id[64]; char statistical_date[64]; char exp_num[64]; char act_num[64]; std::vector value_time; //时间集合 char last_value_time[64]; }; /*lnk 2024-10-15 */ list g_StatisticLackList; //日志补招结构类链表 QMutex g_StatisticLackList_list_mutex; //recall队列数据锁 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");//不用 //lnk20241220创建一个用来台账更新的文件,保证数据完整的情况下更新台账 std::string LEDGER_UPDATE_FN = "LedgerUpdate.log"; const int MAX_CPUNO = 10; //lnk20250121终端台账数量配置 int IED_COUNT = 300; //默认300 extern int INITFLAG; //WW 2-23-08-20 add start otl_connect db; //OTL数据库连接对象 WW 2023-08-20 int g_iOTLFlag = 0; //Sql是否执行标志(0-不执行;1-执行) //lnk202410-22替换web接口后关闭 std::string g_strOTLType = "PostgreSQL"; //OTL连接数据库类型 //std::string g_strOTLConnect = "pqsadmin/dnzladmin_001@pgsql"; //OTL数据库连接参数 //std::string g_strOTLConnect = "postgres/postgres@pgsql"; //OTL数据库连接参数 std::string g_strOTLConnect = "postgres/bmdev@123@pgsql"; //OTL数据库连接参数 //lnk2024-8-14添加角型接线标志,0不存在角形接线,1存在角形接线 int isdelta_flag = 0; //////CZY 2023-09-06 config //多前置flag:1为开启,0为关闭 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; char* POSTGRES_DATABASE;//数据库库名 char* POSTGRES_USERNAME;//数据库用户名 char* POSTGRES_PASSWORD;//数据库密码 char* POSTGRES_SCHEMA;//数据库模式名 char* POSTGRES_DNSNAME;//取postgres/guass库 char* POSTGRES_TABLEPREFIX;//表名前缀 char* CLIENT_ID;//中台CLIENT_ID char* CLIENT_SECRET;//中台CLIENT_SECRET char* TOKEN_URL;//中台取token接口 char* DEVICE_URL;//中台取终端接口 char* GRANT_TYPE;//中台GRANT_TYPE char* UDS_UPLOAD_URL; char* UDS_DOWNLOAD_URL; char* UDS_DELETE_URL; //char * OSS_ENDPOINT; //char * ACCESS_KEY_ID; //char * ACCESS_KEY_SECRET; //char * BUCKET_NAME; 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; /*移植配置变量lnk10-9*/ //生产者 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 = ""; //消费者 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 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 std::string G_CONNECT_TOPIC = "";//consumer topie std::string G_CONNECT_TAG = "";//consumer tag std::string G_CONNECT_KEY = "";//consumer key int G_TEST_FLAG = 0; int G_TEST_NUM = 0; int TEST_PORT = 11000;//用于当前进程登录测试shell的端口 //终端和监测点的状态筛选 std::string TERMINAL_STATUS = ""; std::string MONITOR_STATUS = ""; std::string ICD_FLAG = ""; //保留socket连接设置开关 int SOCKET_PORT = 13000; int SOCKETENABLE = 0; //添加http配置和台账配置lnk20241031 int HTTPENABLE = 0; std::string HTTP_IP = ""; int HTTP_PORT = 12000; /*添加web接口lnk202411-6*/ std::string WEB_DEVICE = ""; std::string WEB_ICD = ""; std::string WEB_INTEGRITY = ""; //暂不使用 std::string WEB_COMFLAG = ""; std::string WEB_EVENT = ""; std::string WEB_FILEUPLOAD = ""; std::string WEB_FILEDOWNLOAD = ""; //lnk20250115添加台账锁 extern pthread_mutex_t mtx; /*lnk 2024-10-21 */ std::string intToString(int number); int OTL_Select_DecideRecall_web(char* time, char* id);//判断是否需要补招 void OTL_Select_recall_web(char* time, char* id); //数据完整性补招判断 bool CheckPG_To_Recall_web(long long start, long long end, char* Monitorid); ////////////////////////////////////////////////////////////////////////// std::string g_strUID = ""; //OTL数据库连接用户名 int g_iOTLConnectLimit = 3; //OTL数据库超时连接次数限制 注:数据库允许最大连接次数,单次数据库连接计数超过3次,重新执行数据库线程! //数据库Sql链表--------------------------------------- extern QList Sql_data_list; //Sql执行语句链表 extern QMutex Sql_data_list_mutex; //Sql执行语句锁 extern int server_socket; //Web Socket服务端实例 extern unsigned int g_node_id; //前置程序类型(100-500) //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(); } ////////////////////////////////////////////////////////////////////////////////////////////////// //lnk20250114不使用的代码 #if 0 /* xml 示例 设备终端配置 6 1268918860 PQS-882A 127.0.0.1 102 IXFhekB3c3gzZWRjNHJmdg== UHFzJmNuODcwMjk5 0 */ int parse_device_cfg() { ied_t* ied; ied_usr_t* ied_usr; chnl_usr_t* chnl_usr; unsigned int count_cfg = 0; unsigned int count_real = 0; QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/"); QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(cfg_dir + DEVIE_CONFIG_FN); if (!file.open(QIODevice::ReadOnly)) return APR_EBADPATH; //以只读方式打开 if (!doc.setContent(&file)) { file.close(); return APR_EBADF; } //将文件内容读到doc中 QDomElement docElem = doc.documentElement(); //返回根元素 QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点 while (!n.isNull()) { //如果节点不为空 if (n.isElement()) //如果节点是元素 { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); if (strTag == "DevAccountList") { QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历该列表 { QDomNode node = list.at(i); if (node.isElement()) { QString strTag2 = node.toElement().tagName(); if (strTag2 == "Count") { count_cfg = node.toElement().text().toUInt(); g_node->n_clients = count_cfg; g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (unsigned int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); } else if (strTag2 == "DevAccount") { ied = g_node->clients[count_real++]; ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t)); if (ied_usr->LD_info == NULL) return APR_ENOMEM; ied_usr->dev_flag = g_DevFlag; ied->chncount = 1; ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); ied->channel[0].ied = ied; ied->channel[0].status = STATUS_BREAKOFF; QDomNodeList list2 = node.childNodes(); //获得元素node的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) { //遍历该列表 QDomNode node2 = list2.at(i2); if (node2.isElement()) { QString devPropTag = node2.toElement().tagName(); QString devPropVal = node2.toElement().text(); if (devPropTag == "DEV_Index") { ied_usr->dev_idx = devPropVal.toInt(); apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", devPropVal.toAscii().data()); apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_code), "%s", devPropVal.toAscii().data()); } else if (devPropTag == "DEV_Type") { apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", devPropVal.toAscii().data()); cout << "dev_type" << ied_usr->dev_type << endl; } else if (devPropTag == "DEV_Code") { apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", devPropVal.toAscii().data()); cout << "dev_code" << ied_usr->terminal_code << endl; } else if (devPropTag == "DEV_Key") { QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii()); apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ba.data()); } else if (devPropTag == "DEV_Series") { QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii()); apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ba.data()); } else if (devPropTag == "DEV_DevFlag") ied_usr->dev_flag = devPropVal.toInt(); else if (devPropTag == "DEV_IP") { ied->channel[0].channel_type = CHANNEL_TYPE_IPV4; ied->channel[0].addr = ntohl(inet_addr(devPropVal.toAscii().data())); strncpy(ied->channel[0].addr_str, devPropVal.toAscii().data(), LONGNAME - 1); ied->channel[0].addr_str[LONGNAME - 1] = 0; } else if (devPropTag == "DEV_PortID") ied->channel[0].port = devPropVal.toUInt(); } }// for(int i2=0; i2channel[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++; } //else if ( strTag2 == "DevAccount" ) } } } } n = n.nextSibling(); //下一个兄弟节点 } if (count_real < count_cfg) g_node->n_clients = count_real; if (count_cfg != count_real) return APR_EBADF; return APR_SUCCESS; } int parse_line_cfg() { ied_t* ied; ied_usr_t* ied_usr; int count_cfg = 0; int count_real = 0; LD_info_t line_info; int dev_idx_in_line = 0; QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/"); QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(cfg_dir + LINE_CONFIG_FN); if (!file.open(QIODevice::ReadOnly)) return APR_EBADPATH; //以只读方式打开 if (!doc.setContent(&file)) { file.close(); return APR_EBADF; } //将文件内容读到doc中 QDomElement docElem = doc.documentElement(); //返回根元素 QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点 while (!n.isNull()) { //如果节点不为空 if (n.isElement()) //如果节点是元素 { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); if (strTag == "MonitorAccountList") { QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历该列表 { QDomNode node = list.at(i); if (node.isElement()) { QString strTag2 = node.toElement().tagName(); if (strTag2 == "Count") { count_cfg = node.toElement().text().toInt(); } else if (strTag2 == "MonitorAccount") { count_real++; dev_idx_in_line = -1; memset(&line_info, 0, sizeof(line_info)); QDomNodeList list2 = node.childNodes(); //获得元素node的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) { //遍历该列表 QDomNode node2 = list2.at(i2); if (node2.isElement()) { QString devPropTag = node2.toElement().tagName(); QString devPropVal = node2.toElement().text(); if (devPropTag == "LINE_Index") { line_info.line_id = devPropVal.toInt(); strcpy(line_info.mp_id, devPropVal.toAscii().data()); } else if (devPropTag == "DEV_Index") { strcpy(line_info.terminal_code, devPropVal.toAscii().data()); dev_idx_in_line = devPropVal.toInt(); } else if (devPropTag == "CPUNO") line_info.cpuno = devPropVal.toInt(); else if (devPropTag == "Name") apr_snprintf(line_info.name, sizeof(line_info.name), "%s", devPropVal.toAscii().data()); //strcpy(line_info.mp_id, "not def"); //strcpy(line_info.terminal_code, "tmpcode1"); strcpy(line_info.voltage_level, "14"); line_info.read_flag = 1; } }// for(int i2=0; i2usr_ext && line_info.cpuno) { char str[256]; byte_t cpuno = line_info.cpuno; ied_usr = (ied_usr_t*)ied->usr_ext; ied_usr->LD_info[cpuno - 1] = line_info; ied_usr->LD_info[cpuno - 1].ied = ied; apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].rptcount = 0; if (cpuno > ied->cpucount) ied->cpucount = cpuno; } } //else if ( strTag2 == "DevAccount" ) } } } } n = n.nextSibling(); //下一个兄弟节点 } if (count_cfg != count_real) return APR_EBADF; return APR_SUCCESS; } #endif //////////////////////////////////////////////////////////CZY void update_odbc(char* newServicename, char* newPort) { const char* filename = "/etc/odbc.ini"; const char* searchip = "Servername="; // 要查找的行的开头 const char* searchport = "Port="; // 要查找的行的开头 const char* tempFilename = "/tmp/odbc.ini.XXXXXX"; // 临时文件名 FILE* file = fopen(filename, "r"); if (file == NULL) { printf("Error opening file\n"); return; } // 创建临时文件 char tempFilenameBuffer[256]; strcpy(tempFilenameBuffer, tempFilename); int tempfd = mkstemp(tempFilenameBuffer); FILE* tempfile = fdopen(tempfd, "w"); // 逐行读取文件 char line[256]; while (fgets(line, sizeof(line), file)) { if (strncmp(line, searchip, strlen(searchip)) == 0) { // 如果找到要修改的行,则写入新的值 fprintf(tempfile, "Servername=%s\n", newServicename); } else if (strncmp(line, searchport, strlen(searchport)) == 0) { // 如果找到要修改的行,则写入新的值 fprintf(tempfile, "Port=%s\n", newPort); } else { // 否则将原始行写入临时文件 fputs(line, tempfile); } } // 关闭文件 fclose(file); fclose(tempfile); // 替换原始文件 remove(filename); rename(tempFilenameBuffer, filename); } //CZY 2023-09-06 config void init_config() { QByteArray ba; QString MyKafkaIniFilename = QString("../etc/") + QString("mykafka.ini"); //+QString::fromAscii(subdir) 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; //台账配置lnk20241031////////////////////////////////////////////////////////////// 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; IED_COUNT = settings.value("Ledger/IedCount", 0).toInt(); //////////////////////////////////////////////////添加socket开关/////////////////// SOCKETENABLE = settings.value("Socket/SocketEnable", 0).toInt(); SOCKET_PORT = settings.value("Socket/SocketPort", 0).toInt(); //////添加http配置////////////////////////////////////////////////////////////////// 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()); /*QString postgres_password = settings.value("Postgres/Password", "").toString(); ba = QByteArray::fromBase64(postgres_password.toAscii());*/ 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; /*添加rocketmq的解析10-9 *///////////////////////////////////////////////////////////////// //生产者 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(); //消费者 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()); 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()); 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()); //MQ测试 G_TEST_FLAG = settings.value("RocketMq/Testflag", 0).toInt(); G_TEST_NUM = settings.value("RocketMq/Testnum", 0).toInt(); //测试shell TEST_PORT = settings.value("RocketMq/TestPort", 0).toInt(); //生产者相关打印 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; 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; 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; //消费者相关打印 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; 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; //Mq测试相关打印 std::cout << "Read G_TEST_FLAG:" << G_TEST_FLAG << std::endl; std::cout << "Read G_TEST_NUM:" << G_TEST_NUM << std::endl; ///////////////////////////////////////////////////////////////////////////////////////// /*Nacos_GetParam(POSTGRES_USERNAME, POSTGRES_PASSWORD, CLIENT_ID, CLIENT_SECRET); qDebug() << "Read CLIENT_ID:" << CLIENT_ID << endl; qDebug() << "Read CLIENT_SECRET:" << CLIENT_SECRET << endl; qDebug() << "Read POSTGRES_USERNAME:" << POSTGRES_USERNAME << endl; qDebug() << "Read POSTGRES_PASSWORD:" << POSTGRES_PASSWORD << endl;*/ /*lnk10-12 暂不使用Nacos*/ /* char* database_ip = NULL; char* database_port = NULL; sleep(3); Read_Nacos_Param_Postgres(&database_ip, &database_port, &POSTGRES_DATABASE, &POSTGRES_USERNAME, &POSTGRES_PASSWORD, &POSTGRES_SCHEMA, &POSTGRES_DNSNAME, &POSTGRES_TABLEPREFIX); qDebug() << "Read database_ip:" << database_ip << endl; qDebug() << "Read database_port:" << database_port << endl; update_odbc(database_ip, database_port); 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; sleep(3); Read_Nacos_Param_Kafka(&BROKER_LIST, &TOPIC_STAT, &TOPIC_PST, &TOPIC_PLT, &TOPIC_EVENT, &TOPIC_ALARM, &TOPIC_SNG, &PROTOCOL, &MECHANISMS, &SERVICE_NAME, &PRINCIPAL, &DOMAIN_NAME); qDebug() << "Read BROKER_LIST:" << BROKER_LIST << endl; qDebug() << "Read TOPIC_STAT:" << TOPIC_STAT << 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 PROTOCOL:" << PROTOCOL << endl; qDebug() << "Read PRINCIPAL:" << PRINCIPAL << endl; sleep(3); Read_Nacos_Param_Web(&CLIENT_ID, &CLIENT_SECRET, &TOKEN_URL, &DEVICE_URL, &GRANT_TYPE); 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; sleep(3); Read_Nacos_Param_Flag(&FILE_FLAG, &SEND_FLAG, &FRONT_INST, &FRONT_IP); sleep(3); Read_Nacos_Param_Recall(&recall_len, &recall_sta, &recall_daily); qDebug() << "Read SEND_FLAG:" << SEND_FLAG << endl; qDebug() << "Read FILE_FLAG:" << FILE_FLAG << endl; qDebug() << "Read FRONT_INST:" << FRONT_INST << endl; qDebug() << "Read FRONT_IP:" << FRONT_IP << endl; qDebug() << "Read recall_lenth:" << recall_len << endl; qDebug() << "Read recall_start:" << recall_sta << endl; qDebug() << "Read recall_dailytime:" << recall_daily << endl; sleep(3); Read_Nacos_Param_Uds(&UDS_UPLOAD_URL, &UDS_DOWNLOAD_URL, &UDS_DELETE_URL); qDebug() << "Read UDS_UPLOAD_URL:" << UDS_UPLOAD_URL << endl; qDebug() << "Read UDS_DOWNLOAD_URL:" << UDS_DOWNLOAD_URL << endl; qDebug() << "Read UDS_DELETE_URL:" << UDS_DELETE_URL << endl; */ //2024-10-25lnk 不需要多前置,前置ip从配置文件获取,不连接数据库 /* if (g_front_seg_index != 0 && g_front_seg_num != 0) { FRONT_INST = g_front_seg_index; if (FRONT_IP != nullptr) { free(FRONT_IP); // 如果是通过malloc分配的 } FRONT_IP = (char*)malloc(64); // 分配内存 // 使用sprintf将int值为字符串 sprintf(FRONT_IP, "%d", g_front_seg_index); } qDebug() << "Read FRONT_INST:" << FRONT_INST << endl; qDebug() << "Read FRONT_IP:" << FRONT_IP << endl; g_strOTLConnect = POSTGRES_USERNAME; g_strOTLConnect.append("/"); g_strOTLConnect.append(POSTGRES_PASSWORD); g_strOTLConnect.append("@"); g_strOTLConnect.append(POSTGRES_DNSNAME); cout << "Read g_strOTLConnect:" << g_strOTLConnect << endl;*/ //20241212lnk添加多前置 if (g_front_seg_index != 0 && g_front_seg_num != 0) { MULTIPLE_NODE_FLAG = 1; std::cout << "this is multiple process of index:" << g_front_seg_index << std::endl; } else{ MULTIPLE_NODE_FLAG = 0; std::cout << "this is single process" << std::endl; } //20250109lnk添加进程测试打印端口 if (g_node_id == STAT_DATA_BASE_NODE_ID)//统计采集 TEST_PORT = TEST_PORT + STAT_DATA_BASE_NODE_ID + g_front_seg_index; else if (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) {//补召 TEST_PORT = TEST_PORT + RECALL_HIS_DATA_BASE_NODE_ID + g_front_seg_index; } else if (g_node_id == THREE_SECS_DATA_BASE_NODE_ID) {//3秒采集 TEST_PORT = TEST_PORT + THREE_SECS_DATA_BASE_NODE_ID + g_front_seg_index; } else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波 TEST_PORT = TEST_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index; } } // CZY 测试 ping IP // 执行命令并获取输出结果 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; } // 设置连接超时时间为5秒 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) { // 连接超时 close(sockfd); return false; } else { int error; socklen_t len = sizeof(error); getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); if (error == 0) { // 连接成功 close(sockfd); return true; } else { // 连接失败 close(sockfd); return false; } } } else { // 连接失败 close(sockfd); return false; } } // 连接成功 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); // 判断输出结果是否包含 "1 packets transmitted, 1 received" 字符串 if (result.find("1 packets transmitted, 1 received") != std::string::npos) { return true; } else { return false; } } void pingPrint(QTcpSocket* clientSocket, const std::string &msg) { // 输出到标准输出 std::cout << msg << std::endl; // 记录到日志文件 add_comm_log(const_cast(msg.c_str())); // 如果 clientSocket 不为空,则发送到 shell if (clientSocket != nullptr) { clientSocket->write((msg + "\r\n").c_str()); clientSocket->flush(); } } int Worker::init_ping_telnet(QTcpSocket* clientSocket, int& ip_count, int& telnet_count) { pingPrint(clientSocket, "start test ping telnet"); ied_t* ied = NULL; int iedno; // 遍历所有设备 for (iedno = 0; iedno < g_node->n_clients && !g_stopTelnetTest; iedno++) { // **1. 监听输入,用户输入 ``` 退出** if (clientSocket->waitForReadyRead(100)) { // ? 监听输入 QByteArray input = clientSocket->readAll().trimmed(); if (input == "`") { // ? 用户输入 ```,退出日志模式 std::cout << "Received '`' from shell socket! Exiting viewlog...\n"; g_stopTelnetTest = true; break; } } 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(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(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); // 更新配置文件 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; } //CZY 2023-08-30 read device account from web api long long charToLongLong(const char* time_str) { string str_time = "2022-01-01 10:00:00"; struct tm tm_time = {}; strptime(str_time.c_str(), "%Y-%m-%d %H:%M:%S", &tm_time); time_t time_stamp = mktime(&tm_time); //cout << "时间戳为:" << time_stamp << endl; return time_stamp; } //CZY 2023-08-30 chat* null or emptry bool isCharPtrEmpty(const char* str) { return str == nullptr || str[0] == '\0' || str == ""; } // CZY 2024-07-24 函数:检查字符串是否全为数字 int isAllDigits(const char* str) { while (*str) { if (!isdigit((unsigned char)*str)) { return 0; // 发现非数字字符 } str++; } return 1; // 所有字符都是数字 } // CZY 2024-07-24函数:将字符串转换为int(如果可能) int stringToInt(const char* str, int* result) { if (isAllDigits(str)) { *result = atoi(str); // 使用atoi进行转换,注意atoi不会检查溢出 return 1; // 转换成功 } return 0; // 转换失败 } //lnk20241206不使用的代码 #if 0 void GetWebApiJson(int perpage, int page, int flag); //CZY 2023-10-12 int read_terminal_ext_pg(QMap* terminal_ext_map) { cout << "start read terminal_ext" << endl; terminal_ext* ext; //读取数据 try { OTLConnect(); //int rtState = OTLState(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select \"terminal_code\",\"terminal_identify_code\",\"terminal_key\" from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_terminal_ext"); str1.append("\";"); //cout << "pg sql1 is:" << str1 << endl; //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream while (!i.eof()) { //while not end-of-data char terminal_code[100]; char terminal_identify_code[100]; char terminal_key[100]; i >> terminal_code >> terminal_identify_code >> terminal_key; //qDebug() << "terminal_ext1:" << terminal_code << "," <contains(terminal_code)) { ext = new terminal_ext(); terminal_ext_map->insert(terminal_code, ext); apr_snprintf(ext->terminal_identify_code, sizeof(ext->terminal_identify_code), "%s", terminal_identify_code);//terminal_code apr_snprintf(ext->terminal_key, sizeof(ext->terminal_key), "%s", terminal_key);//terminal_code //qDebug() << "terminal_ext2:" << terminal_code << "," << ext->terminal_identify_code << "," << ext->terminal_key << endl; } else { qDebug() << terminal_code << endl; } } OTLDisconnect(); cout << "end read terminal_ext" << endl; return 1; } catch (otl_exception& e) { printf("\ndev PostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } } static QString strDevCJson; static QString strToken; //CZY 2023-09-10 web device //flag int parse_device_cfg_json() { qDebug() << "parse_device_cfg_json" << endl; if (FRONT_INST == 0 || FRONT_IP[0] == '\0') { MULTIPLE_NODE_FLAG = 0; cout << "set MULTIPLE_NODE_FLAG:0,because do not have FRONT_INST or FRONT_IP" << endl; } char front_type[2]; int mp_num; if (MULTIPLE_NODE_FLAG) { //std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(POSTGRES_SCHEMA); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("meas_pq_front_list_tr"); str1.append("\" where \"front_ip\" = '"); str1.append(FRONT_IP); str1.append("' and \"front_inst\" = "); std::string str3 = QString::number(FRONT_INST).toStdString(); str1.append(str3); str1.append(";"); try { OTLConnect(); otl_stream i1(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream int front_count; while (!i1.eof()) { //while not end-of-data i1 >> front_count; //cout << "count=" << f2 << endl; } cout << "count=" << front_count << endl; OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } QString selectFrontSql; selectFrontSql.append(QString("select \"front_type\",\"mp_num\" from \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); selectFrontSql.append(QString("where \"front_ip\" = '0.0.0.0' and \"front_inst\"=0")); cout << selectFrontSql.toStdString().c_str() << endl; try { OTLConnect(); otl_stream i2(1, // buffer size selectFrontSql.toStdString().c_str(), //SELECT statement db //connect object ); //create select stream while (!i2.eof()) { //while not end-of-data i2 >> front_type >> mp_num; break; //cout << "count=" << f2 << endl; } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } QString addFrontSql; addFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); addFrontSql.append(QString("values('%1',10000,%2,'%3','01','%4',200) ").arg(FRONT_IP).arg(FRONT_INST).arg(front_type).arg(PROGRAM_VERSION)); addFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); addFrontSql.append(QString("\"front_type\"= '%1',\"front_version\"='%2'").arg(front_type).arg(PROGRAM_VERSION)); cout << addFrontSql.toStdString().c_str() << endl; OTLConnect(); int rt = write_to_db(addFrontSql.toStdString().c_str()); OTLDisconnect(); } cout << "mp_num:" << mp_num << " FRONT_INST:" << FRONT_INST << endl; ied_t* ied; ied_usr_t* ied_usr; chnl_usr_t* chnl_usr; int count_cfg = 0; int count_real = 0; //多个设备循环,中台读取台账终端数量 int array_size = 0; //读取数据 //string* json_buf; cJSON* json = NULL; cJSON* json_value = NULL; cJSON* json_records = NULL; cJSON* json_node = NULL; int dev_num = 0; QMap terminal_ext_map; read_terminal_ext_pg(&terminal_ext_map); try { int effective_flag = 1; //读取台账失败次数 5次 int dev_read_count = 0; int total; while (effective_flag == 1 && dev_read_count <= 5) { effective_flag = 0; dev_read_count++; GetWebApiJson(1, 1, CITY_FLAG); if (strDevCJson == "") { cout << "json select total error" << endl; return APR_EBADF; } //char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"16M00000128569231\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}}],\"searchCount\":true,\"size\":1,\"total\":391}},\"status\":\"000000\"}"; /* char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"16M00000128569231\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}},{\"assets\":[],\"distribution\":1,\"id\":\"af8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"16M00002128569231\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"af8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"100.232.245.97\"}}],\"searchCount\":true,\"size\":2,\"total\":391}},\"status\":\"000000\"}"; json = cJSON_Parse(json_buf);*/ //char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"E8300\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.161.208.227\",\"equipCode\":\"22M00000299758903\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"20102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}},{\"assets\":[],\"distribution\":1,\"id\":\"af8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"E8300\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.161.208.237\",\"equipCode\":\"22M00000299800679\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"af8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"10022\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"100.232.245.97\"}}],\"searchCount\":true,\"size\":2,\"total\":391}},\"status\":\"000000\"}"; //json = cJSON_Parse(json_buf); //char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}}],\"searchCount\":true,\"size\":1,\"total\":391}},\"status\":\"000000\"}"; json = cJSON_Parse(strDevCJson.toUtf8().constData()); //json格式序列化 //cout << cJSON_Print(json) << endl; if (NULL == json) { printf("cJSON_Parse error:%s\n", cJSON_GetErrorPtr()); return APR_EBADF; } json_records = cJSON_GetObjectItem(json, "result"); //获取result json_records = cJSON_GetObjectItem(json_records, "0751002"); //获取0751002 json_value = cJSON_GetObjectItem(json_records, "total"); //获取 total if (json_value != NULL) { total = json_value->valueint; } cJSON_Delete(json); if (MULTIPLE_NODE_FLAG && g_front_seg_num == 0) { GetWebApiJson(mp_num, FRONT_INST, CITY_FLAG); } else if (MULTIPLE_NODE_FLAG && g_front_seg_num != 0) { int front_num = (total / g_front_seg_num) + 1; GetWebApiJson(front_num, FRONT_INST, CITY_FLAG); } else { /* cout << "dev total:" << total << endl; if (total > 300) { total = 300; cout << "update dev total:" << total << endl; }*/ GetWebApiJson(total, 1, CITY_FLAG); } if (strDevCJson == "") { cout << "select dev json error" << endl; return APR_EBADF; } json = cJSON_Parse(strDevCJson.toUtf8().constData()); //json格式序列化 //json = cJSON_Parse(json_buf); json_records = cJSON_GetObjectItem(json, "result"); //获取result json_records = cJSON_GetObjectItem(json_records, "0751002"); //获取0751002 json_value = cJSON_GetObjectItem(json_records, "size"); //获取 size json_records = cJSON_GetObjectItem(json_records, "records"); //获取records array_size = cJSON_GetArraySize(json_records); //获取数组大小 if (array_size <= 1) { effective_flag = 1; if (dev_read_count <= 5) { cJSON_Delete(json); } } } count_cfg = array_size; cout << "count_cfg" << "--" << count_cfg << endl; g_node->n_clients = count_cfg; g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); printf("array_size=%d\n", array_size); for (int i = 0; i < array_size; i++) { json_node = cJSON_GetArrayItem(json_records, i);//array json_node = cJSON_GetObjectItem(json_node, "resource"); //获取resource ied = g_node->clients[count_real++]; ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t)); for (int num = 0; num < MAX_CPUNO; num++) { ied_usr->LD_info[num].read_flag = 0; } if (ied_usr->LD_info == NULL) return APR_ENOMEM; ied_usr->dev_flag = g_DevFlag; ied->chncount = 1; ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); ied->channel[0].ied = ied; ied->channel[0].status = STATUS_BREAKOFF; json_value = cJSON_GetObjectItem(json_node, "astId"); //获取 astId if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", json_value->valuestring);//terminal_id cout << "terminal_id:" << json_value->valuestring << "--" << ied_usr->terminal_id << endl; } else { apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", "");//terminal_id cout << "default terminal_id:" << ied_usr->terminal_id << endl; } json_value = cJSON_GetObjectItem(json_node, "equipCode"); //获取 equipCode if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", json_value->valuestring);//terminal_code cout << "terminal_code:" << json_value->valuestring << "--" << ied_usr->terminal_code << endl; } else { apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", "");//terminal_code cout << "default terminal_code:" << ied_usr->terminal_code << endl; } json_value = cJSON_GetObjectItem(json_node, "city#Name"); //获取 city#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->org_name, sizeof(ied_usr->org_name), "%s", json_value->valuestring);//org_name cout << "org_name:" << json_value->valuestring << "--" << ied_usr->org_name << endl; } json_value = cJSON_GetObjectItem(json_node, "maintOrg#Name"); //获取 maintOrg#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->maint_name, sizeof(ied_usr->maint_name), "%s", json_value->valuestring);//maint_name cout << "maint_name:" << json_value->valuestring << "--" << ied_usr->maint_name << endl; } json_value = cJSON_GetObjectItem(json_node, "station#Name"); //获取 station#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->station_name, sizeof(ied_usr->station_name), "%s", json_value->valuestring);//station_name cout << "station_name:" << json_value->valuestring << "--" << ied_usr->station_name << endl; } json_value = cJSON_GetObjectItem(json_node, "manufacturer#Name"); //获取 manufacturer#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->tmnl_factory, sizeof(ied_usr->tmnl_factory), "%s", json_value->valuestring);//tmnl_factory cout << "tmnl_factory:" << json_value->valuestring << "--" << ied_usr->tmnl_factory << endl; } json_value = cJSON_GetObjectItem(json_node, "deployState"); //获取 deployState if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", json_value->valuestring);//tmnl_status cout << "tmnl_status:" << json_value->valuestring << "--" << ied_usr->tmnl_status << endl; } else { apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", "10");//tmnl_status cout << "default tmnl_status:" << ied_usr->tmnl_status << endl; } //json_value = cJSON_GetObjectItem(json_node, "lastUpdateTime"); //获取 lastUpdateTime json_value = cJSON_GetObjectItem(json_node, "ctime"); //获取 ctime if (json_value != NULL && json_value->string != NULL) { //ied_usr->time = strtoll(json_value->valuestring, NULL, 10);//time ied_usr->time = charToLongLong(json_value->valuestring);//time cout << "time:" << ied_usr->time << endl; } json_value = cJSON_GetObjectItem(json_node, "model"); //获取 model if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", json_value->valuestring);//DEV_Type cout << "dev_type:" << json_value->valuestring << "--" << ied_usr->dev_type << endl; } else { apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", "no-type");//DEV_Type cout << "default dev_type:" << ied_usr->dev_type << endl; } int t = 0; if (t) { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "!qaz@wsx3edc4rfv");//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "Pqs&cn870299");//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { cout << "code:" << ied_usr->terminal_code << endl; if (terminal_ext_map.contains(QString::fromUtf8(ied_usr->terminal_code))) { //terminal_ext* ext = terminal_ext_map.value(ied_usr->terminal_code); terminal_ext* ext = terminal_ext_map.value(QString::fromUtf8(ied_usr->terminal_code)); //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ext->terminal_key);//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ext->terminal_identify_code);//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key cout << "defalut dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series cout << "defalut dev_series:" << ied_usr->dev_series << endl; } } ied_usr->dev_flag = 0;//DEV_DevFlag ied->channel[0].channel_type = CHANNEL_TYPE_IPV4;//channel cout << "channel_type:" << ied->channel[0].channel_type << endl; ied->channel[0].addr_str[LONGNAME - 1] = 0;//DEV_IP json_value = cJSON_GetObjectItem(json_node, "ipAddress"); //获取 ipAddress if (json_value != NULL && json_value->string != NULL) { if (t && i == 0) { ied->channel[0].addr = ntohl(inet_addr("172.40.251.35"));//DEV_IP strncpy(ied->channel[0].addr_str, "172.40.251.35", LONGNAME - 1);//DEV_IP } else { ied->channel[0].addr = ntohl(inet_addr(json_value->valuestring));//DEV_IP strncpy(ied->channel[0].addr_str, json_value->valuestring, LONGNAME - 1);//DEV_IP } cout << "addr:" << json_value->valuestring << "--" << ied->channel[0].addr << "--" << ied->channel[0].addr_str << endl; } else { ied->channel[0].addr = ntohl(inet_addr("0.0.0.1"));//DEV_IP strncpy(ied->channel[0].addr_str, "0.0.0.1", LONGNAME - 1);//DEV_IP //} cout << "default addr:" << ied->channel[0].addr_str << endl; } json_value = cJSON_GetObjectItem(json_node, "portNum"); //获取 portNum if (json_value != NULL && json_value->string != NULL) { ied->channel[0].port = atoi(json_value->valuestring);//DEV_PortID if (t) { ied->channel[0].port = atoi("102");//DEV_PortID } cout << "port:" << "--" << atoi(json_value->valuestring) << "--" << ied->channel[0].port << endl; } else { ied->channel[0].port = 0;//DEV_PortID if (t) { ied->channel[0].port = atoi("102");//DEV_PortID } cout << "default port:" << ied->channel[0].port << endl; } chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); 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++; } cJSON_Delete(json); //list循环结束 if (MULTIPLE_NODE_FLAG) { QString updateFrontSql;//待组装的pgsql语句 updateFrontSql.append(QString("update \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("set \"mp_num\"= %1 ").arg(count_real)); updateFrontSql.append(QString("where \"front_ip\" = '%1' and \"front_inst\"=%2").arg(FRONT_IP).arg(FRONT_INST)); OTLConnect(); int rt = write_to_db(updateFrontSql.toStdString().c_str()); OTLDisconnect(); } 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 (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } //CZY 2023-09-15 pg device int parse_device_cfg_pg() { qDebug() << "parse_device_cfg_pg" << endl; if (FRONT_INST == 0 || FRONT_IP[0] == '\0') { MULTIPLE_NODE_FLAG = 0; cout << "set MULTIPLE_NODE_FLAG:0,because do not have FRONT_INST or FRONT_IP" << endl; } char front_type[2]; int mp_num; if (MULTIPLE_NODE_FLAG) { QString selectFrontSql; selectFrontSql.append(QString("select \"front_type\",\"mp_num\" from \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); selectFrontSql.append(QString("where \"front_ip\" = '0.0.0.0' and \"front_inst\"=0")); cout << selectFrontSql.toStdString().c_str() << endl; try { OTLConnect(); otl_stream i2(1, // buffer size selectFrontSql.toStdString().c_str(), //SELECT statement db //connect object ); //create select stream while (!i2.eof()) { //while not end-of-data i2 >> front_type >> mp_num; break; //cout << "count=" << f2 << endl; } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } QString addFrontSql; addFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); addFrontSql.append(QString("values('%1',10000,%2,'%3','01','%4',200) ").arg(FRONT_IP).arg(FRONT_INST).arg(front_type).arg(PROGRAM_VERSION)); addFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); addFrontSql.append(QString("\"front_type\"= '%1',\"front_version\"='%2'").arg(front_type).arg(PROGRAM_VERSION)); cout << addFrontSql.toStdString().c_str() << endl; OTLConnect(); int rt = write_to_db(addFrontSql.toStdString().c_str()); OTLDisconnect(); } cout << "mp_num:" << mp_num << " FRONT_INST:" << FRONT_INST << endl; ied_t* ied; ied_usr_t* ied_usr; chnl_usr_t* chnl_usr; int count_cfg = 0; int count_real = 0; QMap terminal_ext_map; read_terminal_ext_pg(&terminal_ext_map); //读取数据 try { OTLConnect(); //int rtState = OTLState(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("meas_pq_dev_tr"); str1.append("\" where tmnl_status='20';"); cout << "pg sql1 is:" << str1 << endl; //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream int f2; while (!i.eof()) { //while not end-of-data i >> f2; //cout << "count=" << f2 << endl; } OTLDisconnect(); count_cfg = f2;;//读数据库 cout << "dev_count=" << count_cfg << endl; } catch (otl_exception& e) { printf("\ndev PostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } std::string strSchame = POSTGRES_SCHEMA;//schame analy std::string strDevSQL = "select \"terminal_id\",\"terminal_code\",\"org_name\",\"maint_name\",\"station_name\",\"tmnl_ip\",\"tmnl_port\",\"tmnl_factory\",\"tmnl_type\",\"tmnl_status\",\"update_time\" from \""; strDevSQL.append(strSchame); strDevSQL.append("\".\""); strDevSQL.append(POSTGRES_TABLEPREFIX); strDevSQL.append("meas_pq_dev_tr"); strDevSQL.append("\" where tmnl_status='20'"); if (MULTIPLE_NODE_FLAG && g_front_seg_num == 0) { strDevSQL.append(" ORDER BY terminal_id OFFSET "); strDevSQL.append(QString::number((FRONT_INST - 1) * mp_num).toStdString()); strDevSQL.append(" LIMIT "); strDevSQL.append(QString::number(mp_num).toStdString()); if (mp_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * mp_num; } else { count_cfg = mp_num; } } else if (MULTIPLE_NODE_FLAG && g_front_seg_num != 0) { int front_num = (count_cfg / g_front_seg_num) + 1; strDevSQL.append(" ORDER BY terminal_code OFFSET "); strDevSQL.append(QString::number((FRONT_INST - 1) * front_num).toStdString()); strDevSQL.append(" LIMIT "); strDevSQL.append(QString::number(front_num).toStdString()); if (front_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * front_num; } else { count_cfg = front_num; } } cout << strDevSQL << endl; g_node->n_clients = count_cfg; g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); //读数据 try { cout << "read dev information." << endl; OTLConnect(); //cout << "pg sql2 is:" << str1 << endl; //int rtState = OTLState(); // 执行长的select语句 otl_stream i(1, // buffer size strDevSQL.c_str(), //SELECT statement db //connect object ); //create select stream 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[64]; char dev_series[64]; char addr_str[64]; char port_char[64]; otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> terminal_id >> terminal_code >> org_name >> maint_name >> station_name >> addr_str >> port_char >> tmnl_factory >> dev_type >> tmnl_status >> timestamp; //cout << "monitor_id=" << monitor_id << " terminal_code=" << terminal_code << " monitor_name=" << monitor_name << " logical_device_seq=" << logical_device_seq; //cout << " voltage_level=" << voltage_level << " terminal_connect=" << terminal_connect; //cout << " timestamp: " << timestamp.year << "-" << timestamp.month << "-" << timestamp.day << " " << timestamp.hour << ":" << timestamp.minute << ":" << timestamp.second << endl; ied = g_node->clients[count_real++]; ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t)); if (ied_usr->LD_info == NULL) return APR_ENOMEM; ied_usr->dev_flag = g_DevFlag; ied->chncount = 1; ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); 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; } 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; } cout << "code" << ied_usr->terminal_code << endl; if (terminal_ext_map.contains(QString::fromUtf8(ied_usr->terminal_code))) { //terminal_ext* ext = terminal_ext_map.value(ied_usr->terminal_code); terminal_ext* ext = terminal_ext_map.value(QString::fromUtf8(ied_usr->terminal_code)); //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ext->terminal_key);//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ext->terminal_identify_code);//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key cout << "defalut dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series cout << "defalut dev_series:" << ied_usr->dev_series << 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)) { // 转换成功,portStr全为数字,并且已经转换为int类型的port 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 cout << "ied_usr->port:" << port_char << ",非合法端口.使用默认端口:" << ied->channel[0].port << endl;//DEV_PortID } } if (timestamp.year != 0) { //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); cout << "ied_usr->time:" << ied_usr->time << endl; } chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); 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++; } OTLDisconnect(); //list循环结束 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) { printf("\ndev PostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } } //CZY 2023-08-30 read line account from web api int parse_line_cfg_pg() { ied_t* ied; ied_usr_t* ied_usr; int count_cfg = 0; int count_real = 0; LD_info_t line_info; try { //int rtState = OTLState(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor"); str1.append("\" where status<>'04' and status<>'05' and \"terminal_code\" in ("); //str1.append("\".\"MEAS_PQ_FRONT_LIST_TR\""); int dev_no = 0; cout << "n_clients:" << g_node->n_clients << endl; if (g_node->n_clients <= 0) { cout << "no terminal exist " << endl; return APR_EBADF; } for (dev_no = 0; dev_no < g_node->n_clients; dev_no++) { str1.append("'"); str1.append(((ied_usr_t*)(g_node->clients[dev_no]->usr_ext))->terminal_code); str1.append("'"); if (dev_no < g_node->n_clients - 1) { str1 += ","; } } str1.append(")"); cout << "pg sql1 is:" << str1 << endl; //int rtState = OTLState(); OTLConnect(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream int f2; while (!i.eof()) { //while not end-of-data i >> f2; //cout << "count=" << f2 << endl; } OTLDisconnect(); count_cfg = f2;;//读数据库 cout << "line_count=" << count_cfg << endl; } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } //读数据 try { OTLConnect(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select \"monitor_id\",\"terminal_code\",\"monitor_name\",\"logical_device_seq\",\"voltage_level\",\"terminal_connect\",\"update_time\" from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor"); str1.append("\" where status<>'04' and status<>'05' and \"terminal_code\" in ("); int dev_no = 0; for (dev_no = 0; dev_no < g_node->n_clients; dev_no++) { str1.append("'"); str1.append(((ied_usr_t*)(g_node->clients[dev_no]->usr_ext))->terminal_code); str1.append("'"); if (dev_no < g_node->n_clients - 1) { str1 += ","; } } str1.append(")"); cout << "pg sql2 is:" << str1 << endl; //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream 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]; otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> monitor_id >> terminal_code >> monitor_name >> logical_device_seq >> voltage_level >> terminal_connect >> timestamp; cout << "monitor_id=" << monitor_id << " terminal_code=" << terminal_code << " monitor_name=" << monitor_name << " logical_device_seq=" << logical_device_seq; cout << " voltage_level=" << voltage_level << " terminal_connect=" << terminal_connect; cout << " timestamp: " << timestamp.year << "-" << timestamp.month << "-" << timestamp.day << " " << timestamp.hour << ":" << timestamp.minute << ":" << timestamp.second << endl; count_real++; memset(&line_info, 0, sizeof(line_info)); line_info.line_id = count_real; //cout << "line_id:" << line_info.line_id << endl; strcpy(line_info.mp_id, monitor_id); //cout << "mp_id:" << line_info.mp_id << endl; strcpy(line_info.terminal_code, terminal_code); //cout << "terminal_code:" << line_info.terminal_code << endl; if (isCharPtrEmpty(logical_device_seq)) { line_info.cpuno = 1; //cout << "logical_device_seq:is null~"<< line_info.cpuno << endl; } else { line_info.cpuno = std::atoi(logical_device_seq); //cout << "logical_device_seq:"<< logical_device_seq << 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; //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); //cout << "time:" << line_info.time << endl; strcpy(line_info.name, monitor_name); //cout << "name:" << line_info.name << endl; line_info.read_flag = 1; ied = find_ied_from_dev_code(line_info.terminal_code); if (ied && ied->usr_ext && line_info.cpuno && line_info.cpuno < 10) { char str[256]; byte_t cpuno = line_info.cpuno; //cout << "cpuno:" << line_info.cpuno << endl; //cout << "byte_t cpuno:" << cpuno-1 << endl; ied_usr = (ied_usr_t*)ied->usr_ext; ied_usr->LD_info[cpuno - 1] = line_info; ied_usr->LD_info[cpuno - 1].ied = ied; apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].rptcount = 0; //cout << "rptcount:" << ied_usr->LD_info[cpuno - 1].rptcount << endl; if (cpuno > ied->cpucount) { //int c = cpuno; //cout << "cpucount(linecount old):" << (int)(ied->cpucount) << "new:" << c << endl; ied->cpucount = cpuno; //cout << "byte_t cpucount:" << ied->cpucount+1 << endl; } } } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } if (count_cfg != count_real) return APR_EBADF; return APR_SUCCESS; } int parse_device_cfg_json_test() { qDebug() << "parse_device_cfg_json_test" << endl; ied_t* ied; ied_usr_t* ied_usr; chnl_usr_t* chnl_usr; int count_cfg = 0; int count_real = 0; //读取数据 //string* json_buf; cJSON* json = NULL; cJSON* json_value = NULL; cJSON* json_records = NULL; cJSON* json_node = NULL; int dev_num = 0; QMap terminal_ext_map; read_terminal_ext_pg(&terminal_ext_map); try { //GetWebApiJson(1); /* if (strDevCJson == "") { cout << "json select total error" << endl; return APR_EBADF; }*/ char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"testcode\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}}],\"searchCount\":true,\"size\":1,\"total\":391}},\"status\":\"000000\"}"; //char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"testcode\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}},{\"assets\":[],\"distribution\":1,\"id\":\"af8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"16M00002128569231\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"af8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"100.232.245.97\"}}],\"searchCount\":true,\"size\":2,\"total\":391}},\"status\":\"000000\"}"; json = cJSON_Parse(json_buf); //json = cJSON_Parse(strDevCJson.toUtf8().constData()); //json格式序列化 //cout << cJSON_Print(json) << endl; int total; if (NULL == json) { printf("cJSON_Parse error:%s\n", cJSON_GetErrorPtr()); return APR_EBADF; } json_records = cJSON_GetObjectItem(json, "result"); //获取result json_records = cJSON_GetObjectItem(json_records, "0751002"); //获取0751002 json_value = cJSON_GetObjectItem(json_records, "total"); //获取 total if (json_value != NULL && json_value != NULL) { total = json_value->valueint; } cout << "dev total:" << total << endl; cJSON_Delete(json); //GetWebApiJson(1); /*if (strDevCJson == "") { cout << "select dev json error" << endl; return APR_EBADF; }*/ //json = cJSON_Parse(strDevCJson.toUtf8().constData()); //json格式序列化 json = cJSON_Parse(json_buf); json_records = cJSON_GetObjectItem(json, "result"); //获取result json_records = cJSON_GetObjectItem(json_records, "0751002"); //获取0751002 json_value = cJSON_GetObjectItem(json_records, "size"); //获取 size if (json_value != NULL && json_value != NULL) { count_cfg = json_value->valueint; cout << "count_cfg" << "--" << json_value->valueint << "--" << count_cfg << endl; } g_node->n_clients = count_cfg; g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); //多个设备循环 int array_size = 0; json_records = cJSON_GetObjectItem(json_records, "records"); //获取records array_size = cJSON_GetArraySize(json_records); //获取数组大小 printf("array_size=%d\n", array_size); for (int i = 0; i < array_size; i++) { json_node = cJSON_GetArrayItem(json_records, i);//array json_node = cJSON_GetObjectItem(json_node, "resource"); //获取resource ied = g_node->clients[count_real++]; ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, 500 * sizeof(LD_info_t)); if (ied_usr->LD_info == NULL) return APR_ENOMEM; ied_usr->dev_flag = g_DevFlag; ied->chncount = 1; ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); ied->channel[0].ied = ied; ied->channel[0].status = STATUS_BREAKOFF; json_value = cJSON_GetObjectItem(json_node, "astId"); //获取 astId if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", json_value->valuestring);//terminal_id cout << "terminal_id" << json_value->valuestring << "--" << ied_usr->terminal_id << endl; } json_value = cJSON_GetObjectItem(json_node, "equipCode"); //获取 equipCode if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", "testcode");//terminal_code cout << "terminal_code" << json_value->valuestring << "--" << ied_usr->terminal_code << endl; } json_value = cJSON_GetObjectItem(json_node, "city#Name"); //获取 city#Name if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->org_name, sizeof(ied_usr->org_name), "%s", json_value->valuestring);//org_name cout << "org_name" << json_value->valuestring << "--" << ied_usr->org_name << endl; } json_value = cJSON_GetObjectItem(json_node, "maintOrg#Name"); //获取 maintOrg#Name if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->maint_name, sizeof(ied_usr->maint_name), "%s", json_value->valuestring);//maint_name cout << "maint_name" << json_value->valuestring << "--" << ied_usr->maint_name << endl; } json_value = cJSON_GetObjectItem(json_node, "station#Name"); //获取 station#Name if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->station_name, sizeof(ied_usr->station_name), "%s", json_value->valuestring);//station_name cout << "station_name" << json_value->valuestring << "--" << ied_usr->station_name << endl; } json_value = cJSON_GetObjectItem(json_node, "manufacturer#Name"); //获取 manufacturer#Name if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->tmnl_factory, sizeof(ied_usr->tmnl_factory), "%s", json_value->valuestring);//tmnl_factory cout << "tmnl_factory" << json_value->valuestring << "--" << ied_usr->tmnl_factory << endl; } json_value = cJSON_GetObjectItem(json_node, "deployState"); //获取 deployState if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", json_value->valuestring);//tmnl_status cout << "tmnl_status" << json_value->valuestring << "--" << ied_usr->tmnl_status << endl; } //json_value = cJSON_GetObjectItem(json_node, "lastUpdateTime"); //获取 lastUpdateTime json_value = cJSON_GetObjectItem(json_node, "ctime"); //获取 ctime if (json_value != NULL && json_value != NULL) { //ied_usr->time = strtoll(json_value->valuestring, NULL, 10);//time ied_usr->time = charToLongLong(json_value->valuestring);//time cout << "time" << json_value->valuestring << "--" << ied_usr->time << endl; } json_value = cJSON_GetObjectItem(json_node, "model"); //获取 model if (json_value != NULL && json_value != NULL) { apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", json_value->valuestring);//DEV_Type cout << "dev_type:" << json_value->valuestring << "--" << ied_usr->dev_type << endl; } int t = 1; if (t) { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "!qaz@wsx3edc4rfv");//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "Pqs&cn870299");//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { cout << "code" << ied_usr->terminal_code << endl; if (terminal_ext_map.contains(QString::fromUtf8(ied_usr->terminal_code))) { //terminal_ext* ext = terminal_ext_map.value(ied_usr->terminal_code); terminal_ext* ext = terminal_ext_map.value(QString::fromUtf8(ied_usr->terminal_code)); //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ext->terminal_identify_code);//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ext->terminal_key);//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key cout << "defalut dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series cout << "defalut dev_series:" << ied_usr->dev_series << endl; } } ied_usr->dev_flag = 0;//DEV_DevFlag ied->channel[0].channel_type = CHANNEL_TYPE_IPV4;//channel cout << "channel_type:" << ied->channel[0].channel_type << endl; ied->channel[0].addr_str[LONGNAME - 1] = 0;//DEV_IP json_value = cJSON_GetObjectItem(json_node, "ipAddress"); //获取 ipAddress if (json_value != NULL && json_value != NULL) { if (i == 0) { ied->channel[0].addr = ntohl(inet_addr("192.168.1.212"));//DEV_IP strncpy(ied->channel[0].addr_str, "192.168.1.212", LONGNAME - 1);//DEV_IP } else { ied->channel[0].addr = ntohl(inet_addr(json_value->valuestring));//DEV_IP strncpy(ied->channel[0].addr_str, json_value->valuestring, LONGNAME - 1);//DEV_IP } cout << "addr:" << json_value->valuestring << "--" << ied->channel[0].addr << "--" << ied->channel[0].addr_str << endl; } json_value = cJSON_GetObjectItem(json_node, "portNum"); //获取 portNum if (json_value != NULL && json_value != NULL) { //ied->channel[0].port = atoi(json_value->valuestring);//DEV_PortID ied->channel[0].port = atoi("102");//DEV_PortID cout << "port:" << "--" << atoi(json_value->valuestring) << "--" << ied->channel[0].port << endl; } chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); 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++; } cJSON_Delete(json); //list循环结束 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 (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } int parse_line_cfg_pg_test() { ied_t* ied; ied_usr_t* ied_usr; int count_cfg = 0; int count_real = 0; LD_info_t line_info; try { OTLConnect(); //int rtState = OTLState(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor\""); cout << "pg sq1 is:" << str1 << endl; //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), db //connect object ); //create select stream int f2; while (!i.eof()) { //while not end-of-data i >> f2; //cout << "count=" << f2 << endl; } OTLDisconnect(); count_cfg = f2;;//读数据库 cout << "line_count=" << count_cfg << endl; } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } //读数据 try { OTLConnect(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select \"monitor_id\",\"terminal_code\",\"monitor_name\",\"logical_device_seq\",\"voltage_level\",\"terminal_connect\",\"update_time\" from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor\""); //cout << "pg sql2 is:" << str1 << endl; //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream 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]; otl_datetime timestamp; int cpuno_count = 1; while (!i.eof()) { //while not end-of-data i >> monitor_id >> terminal_code >> monitor_name >> logical_device_seq >> voltage_level >> terminal_connect >> timestamp; //cout << "monitor_id=" << monitor_id << " terminal_code=" << terminal_code << " monitor_name=" << monitor_name << " logical_device_seq=" << logical_device_seq; //cout << " voltage_level=" << voltage_level << " terminal_connect=" << terminal_connect; //cout << " timestamp: " << timestamp.year << "-" << timestamp.month << "-" << timestamp.day << " " << timestamp.hour << ":" << timestamp.minute << ":" << timestamp.second << endl; count_real++; memset(&line_info, 0, sizeof(line_info)); line_info.line_id = count_real; //cout << "line_id:" << line_info.line_id << endl; strcpy(line_info.mp_id, monitor_id); //cout << "mp_id:" << line_info.mp_id << endl; strcpy(line_info.terminal_code, "testcode"); //cout << "terminal_code:" << line_info.terminal_code << endl; if (isCharPtrEmpty(logical_device_seq)) { line_info.cpuno = 1; //cout << "logical_device_seq:is null~"<< line_info.cpuno << endl; } else { line_info.cpuno = std::atoi(logical_device_seq); //cout << "logical_device_seq:"<< logical_device_seq << 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; //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); //cout << "time:" << line_info.time << endl; strcpy(line_info.name, monitor_name); //cout << "name:" << line_info.name << endl; ied = find_ied_from_dev_code("testcode"); if (ied && ied->usr_ext && line_info.cpuno) { char str[256]; byte_t cpuno = cpuno_count; //cout << "cpuno:" << line_info.cpuno << endl; //cout << "byte_t cpuno:" << cpuno-1 << endl; ied_usr = (ied_usr_t*)ied->usr_ext; ied_usr->LD_info[cpuno - 1] = line_info; ied_usr->LD_info[cpuno - 1].ied = ied; apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].rptcount = 0; //cout << "rptcount:" << ied_usr->LD_info[cpuno - 1].rptcount << endl; if (cpuno > ied->cpucount) { int c = cpuno; ied->cpucount = cpuno; cout << "byte_t cpucount:" << ied->cpucount + 1 << endl; } } cpuno_count++; if (cpuno_count > 150) { break; } } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } if (count_cfg != count_real) return APR_EBADF; return APR_SUCCESS; } void dev_account_add() { } void dev_account_delete() { } void dev_account_update() { } void line_account_add() { } void line_account_delete(int update_flag) { } void line_account_update(int update_flag) { } int create_temp_device_cfg_json(QMap& dev_map) { qDebug() << "parse_device_cfg_json" << endl; if (FRONT_INST == 0 || FRONT_IP[0] == '\0') { MULTIPLE_NODE_FLAG = 0; cout << "set MULTIPLE_NODE_FLAG:0,because do not have FRONT_INST or FRONT_IP" << endl; } char front_type[2]; int mp_num; if (MULTIPLE_NODE_FLAG) { //std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(POSTGRES_SCHEMA); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("meas_pq_front_list_tr"); str1.append("\" where \"front_ip\" = '"); str1.append(FRONT_IP); str1.append("' and \"front_inst\" = "); std::string str3 = QString::number(FRONT_INST).toStdString(); str1.append(str3); str1.append(";"); try { OTLConnect(); otl_stream i1(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream int front_count; while (!i1.eof()) { //while not end-of-data i1 >> front_count; //cout << "count=" << f2 << endl; } cout << "count=" << front_count << endl; OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } QString selectFrontSql; selectFrontSql.append(QString("select \"front_type\",\"mp_num\" from \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); selectFrontSql.append(QString("where \"front_ip\" = '0.0.0.0' and \"front_inst\"=0")); cout << selectFrontSql.toStdString().c_str() << endl; try { OTLConnect(); otl_stream i2(1, // buffer size selectFrontSql.toStdString().c_str(), //SELECT statement db //connect object ); //create select stream while (!i2.eof()) { //while not end-of-data i2 >> front_type >> mp_num; break; //cout << "count=" << f2 << endl; } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } } cout << "mp_num:" << mp_num << " FRONT_INST:" << FRONT_INST << endl; ied_t* ied; ied_usr_t* ied_usr; chnl_usr_t* chnl_usr; int count_cfg = 0; int count_real = 0; //读取数据 //string* json_buf; cJSON* json = NULL; cJSON* json_value = NULL; cJSON* json_records = NULL; cJSON* json_node = NULL; int dev_num = 0; QMap terminal_ext_map; read_terminal_ext_pg(&terminal_ext_map); try { int total; GetWebApiJson(1, 1, CITY_FLAG); if (strDevCJson == "") { cout << "json select total error" << endl; return APR_EBADF; } //char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"16M00000128569231\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}}],\"searchCount\":true,\"size\":1,\"total\":391}},\"status\":\"000000\"}"; /* char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"16M00000128569231\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}},{\"assets\":[],\"distribution\":1,\"id\":\"af8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"PQS-883\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.232.245.101\",\"equipCode\":\"16M00002128569231\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"af8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"100.232.245.97\"}}],\"searchCount\":true,\"size\":2,\"total\":391}},\"status\":\"000000\"}"; json = cJSON_Parse(json_buf);*/ //char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"E8300\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.161.208.227\",\"equipCode\":\"22M00000299758903\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"20102\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}},{\"assets\":[],\"distribution\":1,\"id\":\"af8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"signalInputForm\":\"02\",\"source#Name\":\"设备增加-基本建设\",\"source\":\"01\",\"currsigInputChanqutity\":\"1\",\"astOrg#Name\":\"国网湖南省电力公司\",\"astOrg\":\"02DC9D994CE579E4E053661EDF0AFC25\",\"cabinetType\":\"05\",\"ctime\":\"2022-02-19 00:00:00\",\"model\":\"E8300\",\"station#Name\":\"110kV宝塔变电站\",\"equipmentOwner\":\"E94A0732B2FB5AA1E0430901E80A21E9\",\"manufactureNum\":\"202596\",\"ipAddress\":\"10.161.208.237\",\"equipCode\":\"22M00000299800679\",\"subnetMask\":\"255.255.255.224\",\"astId\":\"af8080817efe6c21017f1064ab7c0c7e\",\"macAddress\":\"00:B7:8D:00:DC:23\",\"astNum\":\"200102118916\",\"signalInputForm#Name\":\"数字信号\",\"maintOrg#Name\":\"张家界供电公司检修公司\",\"name\":\"110kV 珍宝线504电能质量监测装置\",\"deviceLevel\":\"01\",\"projectNum\":\"GGXM20220219BT\",\"projectName\":\"电能质量监测装置\",\"operateDate\":\"2021-11-19 00:00:00\",\"deployState\":\"20\",\"hardDiskCapacity\":\"64\",\"city\":\"02DC9D994EED79E4E053661EDF0AFC25\",\"timeSynchronization\":\"02\",\"astNature\":\"03\",\"manufacturer\":\"041696\",\"astOrgName\":\"国网湖南省电力公司\",\"voltsigInputChanqutity\":\"1\",\"cabinetType#Name\":\"紧凑型金属封闭式\",\"runDevName\":\"504\",\"devPowerVoltage\":\"220\",\"station\":\"531b04dd7c8a5f84214ff783280150531a67987189\",\"manufactureDate\":\"2020-12-19 00:00:00\",\"astNature#Name\":\"省(直辖市、自治区)公司\",\"portNum\":\"10022\",\"maintGroup#Name\":\"变电运维二班\",\"maintGroup\":\"02DC9D994F3A79E4E053661EDF0AFC25\",\"manufacturer#Name\":\"南京灿能电力自动化股份有限公司\",\"detectDate\":\"2021-02-19 00:00:00\",\"city#Name\":\"国网张家界供电公司\",\"deployState#Name\":\"在运\",\"equipmentOwner#Name\":\"\",\"deviceLevel#Name\":\"A类\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"100.232.245.97\"}}],\"searchCount\":true,\"size\":2,\"total\":391}},\"status\":\"000000\"}"; //json = cJSON_Parse(json_buf); //char json_buf[] = "{\"errors\":\"成功\",\"message\":\"成功\",\"result\":{\"0751002\":{\"current\":1,\"orders\":[],\"pages\":391,\"records\":[{\"assets\":[],\"distribution\":1,\"id\":\"ff8080817efe6c21017f1064ab7c0c7e\",\"modelId\":\"0751002Z\",\"resource\":{\"deviceKind\":\"0751002\",\"maintOrg\":\"02DC9D994F2879E4E053661EDF0AFC25\",\"cabinet\":\"4dcc03dbc58a5f84225130303b01514dcba0cd1be5\",\"gateway\":\"10.232.245.97\"}}],\"searchCount\":true,\"size\":1,\"total\":391}},\"status\":\"000000\"}"; json = cJSON_Parse(strDevCJson.toUtf8().constData()); //json格式序列化 //cout << cJSON_Print(json) << endl; if (NULL == json) { printf("cJSON_Parse error:%s\n", cJSON_GetErrorPtr()); return APR_EBADF; } json_records = cJSON_GetObjectItem(json, "result"); //获取result json_records = cJSON_GetObjectItem(json_records, "0751002"); //获取0751002 json_value = cJSON_GetObjectItem(json_records, "total"); //获取 total if (json_value != NULL) { total = json_value->valueint; } cJSON_Delete(json); if (MULTIPLE_NODE_FLAG && g_front_seg_num == 0) { if (strcmp(front_type, "01") == 0) { GetWebApiJson(mp_num, FRONT_INST, CITY_FLAG); } else { GetWebApiJson(mp_num, FRONT_INST, CITY_FLAG); } } else if (MULTIPLE_NODE_FLAG && g_front_seg_num != 0) { int front_num = (total / g_front_seg_num) + 1; GetWebApiJson(front_num, FRONT_INST, CITY_FLAG); } else { /* cout << "dev total:" << total << endl; if (total > 300) { total = 300; cout << "update dev total:" << total << endl; }*/ GetWebApiJson(total, 1, CITY_FLAG); } if (strDevCJson == "") { cout << "select dev json error" << endl; return APR_EBADF; } json = cJSON_Parse(strDevCJson.toUtf8().constData()); //json格式序列化 //json = cJSON_Parse(json_buf); json_records = cJSON_GetObjectItem(json, "result"); //获取result json_records = cJSON_GetObjectItem(json_records, "0751002"); //获取0751002 json_value = cJSON_GetObjectItem(json_records, "size"); //获取 size //多个设备循环 int array_size = 0; json_records = cJSON_GetObjectItem(json_records, "records"); //获取records array_size = cJSON_GetArraySize(json_records); //获取数组大小 /*count_cfg = array_size; cout << "count_cfg" << "--" << count_cfg << endl; g_node->n_clients = count_cfg; g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t));*/ printf("array_size=%d\n", array_size); for (int i = 0; i < array_size; i++) { json_node = cJSON_GetArrayItem(json_records, i);//array json_node = cJSON_GetObjectItem(json_node, "resource"); //获取resource ied = (ied_t*)apr_pcalloc(g_temp_dev_pool, sizeof(ied_t)); count_real++; ied_usr = (ied_usr_t*)apr_pcalloc(g_temp_dev_pool, sizeof(ied_usr_t)); ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_temp_dev_pool, MAX_CPUNO * sizeof(LD_info_t)); if (ied_usr->LD_info == NULL) return APR_ENOMEM; ied_usr->dev_flag = g_DevFlag; ied->chncount = 1; ied->channel = (channel_t*)apr_pcalloc(g_temp_dev_pool, sizeof(channel_t) * ied->chncount); ied->channel[0].ied = ied; ied->channel[0].status = STATUS_BREAKOFF; json_value = cJSON_GetObjectItem(json_node, "astId"); //获取 astId if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", json_value->valuestring);//terminal_id cout << "terminal_id:" << json_value->valuestring << "--" << ied_usr->terminal_id << endl; } else { apr_snprintf(ied_usr->terminal_id, sizeof(ied_usr->terminal_id), "%s", "");//terminal_id cout << "default terminal_id:" << ied_usr->terminal_id << endl; } json_value = cJSON_GetObjectItem(json_node, "equipCode"); //获取 equipCode if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", json_value->valuestring);//terminal_code cout << "terminal_code:" << json_value->valuestring << "--" << ied_usr->terminal_code << endl; } else { apr_snprintf(ied_usr->terminal_code, sizeof(ied_usr->terminal_code), "%s", "");//terminal_code cout << "default terminal_code:" << ied_usr->terminal_code << endl; } json_value = cJSON_GetObjectItem(json_node, "city#Name"); //获取 city#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->org_name, sizeof(ied_usr->org_name), "%s", json_value->valuestring);//org_name cout << "org_name:" << json_value->valuestring << "--" << ied_usr->org_name << endl; } json_value = cJSON_GetObjectItem(json_node, "maintOrg#Name"); //获取 maintOrg#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->maint_name, sizeof(ied_usr->maint_name), "%s", json_value->valuestring);//maint_name cout << "maint_name:" << json_value->valuestring << "--" << ied_usr->maint_name << endl; } json_value = cJSON_GetObjectItem(json_node, "station#Name"); //获取 station#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->station_name, sizeof(ied_usr->station_name), "%s", json_value->valuestring);//station_name cout << "station_name:" << json_value->valuestring << "--" << ied_usr->station_name << endl; } json_value = cJSON_GetObjectItem(json_node, "manufacturer#Name"); //获取 manufacturer#Name if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->tmnl_factory, sizeof(ied_usr->tmnl_factory), "%s", json_value->valuestring);//tmnl_factory cout << "tmnl_factory:" << json_value->valuestring << "--" << ied_usr->tmnl_factory << endl; } json_value = cJSON_GetObjectItem(json_node, "deployState"); //获取 deployState if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", json_value->valuestring);//tmnl_status cout << "tmnl_status:" << json_value->valuestring << "--" << ied_usr->tmnl_status << endl; } else { apr_snprintf(ied_usr->tmnl_status, sizeof(ied_usr->tmnl_status), "%s", "10");//tmnl_status cout << "default tmnl_status:" << ied_usr->tmnl_status << endl; } //json_value = cJSON_GetObjectItem(json_node, "lastUpdateTime"); //获取 lastUpdateTime json_value = cJSON_GetObjectItem(json_node, "ctime"); //获取 ctime if (json_value != NULL && json_value->string != NULL) { //ied_usr->time = strtoll(json_value->valuestring, NULL, 10);//time ied_usr->time = charToLongLong(json_value->valuestring);//time cout << "time:" << ied_usr->time << endl; } json_value = cJSON_GetObjectItem(json_node, "model"); //获取 model if (json_value != NULL && json_value->string != NULL) { apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", json_value->valuestring);//DEV_Type cout << "dev_type:" << json_value->valuestring << "--" << ied_usr->dev_type << endl; } else { apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", "no-type");//DEV_Type cout << "default dev_type:" << ied_usr->dev_type << endl; } int t = 1; if (t) { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "!qaz@wsx3edc4rfv");//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "Pqs&cn870299");//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { cout << "code:" << ied_usr->terminal_code << endl; if (terminal_ext_map.contains(QString::fromUtf8(ied_usr->terminal_code))) { //terminal_ext* ext = terminal_ext_map.value(ied_usr->terminal_code); terminal_ext* ext = terminal_ext_map.value(QString::fromUtf8(ied_usr->terminal_code)); //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ext->terminal_key);//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ext->terminal_identify_code);//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key cout << "defalut dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series cout << "defalut dev_series:" << ied_usr->dev_series << endl; } } ied_usr->dev_flag = 0;//DEV_DevFlag ied->channel[0].channel_type = CHANNEL_TYPE_IPV4;//channel cout << "channel_type:" << ied->channel[0].channel_type << endl; ied->channel[0].addr_str[LONGNAME - 1] = 0;//DEV_IP json_value = cJSON_GetObjectItem(json_node, "ipAddress"); //获取 ipAddress if (json_value != NULL && json_value->string != NULL) { if (t && i == 0) { ied->channel[0].addr = ntohl(inet_addr("172.40.251.35"));//DEV_IP strncpy(ied->channel[0].addr_str, "172.40.251.35", LONGNAME - 1);//DEV_IP } else { ied->channel[0].addr = ntohl(inet_addr(json_value->valuestring));//DEV_IP strncpy(ied->channel[0].addr_str, json_value->valuestring, LONGNAME - 1);//DEV_IP } cout << "addr:" << json_value->valuestring << "--" << ied->channel[0].addr << "--" << ied->channel[0].addr_str << endl; } else { ied->channel[0].addr = ntohl(inet_addr("0.0.0.1"));//DEV_IP strncpy(ied->channel[0].addr_str, "0.0.0.1", LONGNAME - 1);//DEV_IP //} cout << "default addr:" << ied->channel[0].addr_str << endl; } json_value = cJSON_GetObjectItem(json_node, "portNum"); //获取 portNum if (json_value != NULL && json_value->string != NULL) { ied->channel[0].port = atoi(json_value->valuestring);//DEV_PortID if (t) { ied->channel[0].port = atoi("102");//DEV_PortID } cout << "port:" << "--" << atoi(json_value->valuestring) << "--" << ied->channel[0].port << endl; } else { ied->channel[0].port = 0;//DEV_PortID if (t) { ied->channel[0].port = atoi("102");//DEV_PortID } cout << "default port:" << ied->channel[0].port << endl; } dev_map.insert(QString::fromUtf8(ied_usr->terminal_code), ied); } cJSON_Delete(json); //list循环结束 cout << "temp dev qmap init create count:" << count_real; return APR_SUCCESS; } catch (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } int create_temp_line_cfg_pg(QMap& dev_map) { ied_t* ied; ied_usr_t* ied_usr; int count_cfg = 0; int count_real = 0; LD_info_t line_info; try { //int rtState = OTLState(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor"); str1.append("\" where \"terminal_code\" in ("); //str1.append("\".\"MEAS_PQ_FRONT_LIST_TR\""); QMap::const_iterator cit; for (cit = dev_map.constBegin(); cit != dev_map.constEnd();) { QString key = cit.key(); str1.append("'"); str1.append(key.toStdString()); str1.append("'"); if (++cit != dev_map.constEnd()) { str1 += ","; } } str1.append(")"); cout << "dev line pg sql1 is:" << str1 << endl; //int rtState = OTLState(); OTLConnect(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream int f2; while (!i.eof()) { //while not end-of-data i >> f2; //cout << "count=" << f2 << endl; } OTLDisconnect(); count_cfg = f2;;//读数据库 cout << "line_count=" << count_cfg << endl; } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } //读数据 try { OTLConnect(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select \"monitor_id\",\"terminal_code\",\"monitor_name\",\"logical_device_seq\",\"voltage_level\",\"terminal_connect\",\"update_time\" from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor"); str1.append("\" where \"terminal_code\" in ("); QMap::const_iterator cit; for (cit = dev_map.constBegin(); cit != dev_map.constEnd();) { QString key = cit.key(); str1.append("'"); str1.append(key.toStdString()); str1.append("'"); if (++cit != dev_map.constEnd()) { str1 += ","; } } str1.append(")"); cout << "qmap line pg sql2 is:" << str1 << endl; //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream 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]; otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> monitor_id >> terminal_code >> monitor_name >> logical_device_seq >> voltage_level >> terminal_connect >> timestamp; //cout << "monitor_id=" << monitor_id << " terminal_code=" << terminal_code << " monitor_name=" << monitor_name << " logical_device_seq=" << logical_device_seq; //cout << " voltage_level=" << voltage_level << " terminal_connect=" << terminal_connect; //cout << " timestamp: " << timestamp.year << "-" << timestamp.month << "-" << timestamp.day << " " << timestamp.hour << ":" << timestamp.minute << ":" << timestamp.second << endl; count_real++; memset(&line_info, 0, sizeof(line_info)); line_info.line_id = count_real; //cout << "line_id:" << line_info.line_id << endl; strcpy(line_info.mp_id, monitor_id); //cout << "mp_id:" << line_info.mp_id << endl; strcpy(line_info.terminal_code, terminal_code); //cout << "terminal_code:" << line_info.terminal_code << endl; if (isCharPtrEmpty(logical_device_seq)) { line_info.cpuno = 1; //cout << "logical_device_seq:is null~"<< line_info.cpuno << endl; } else { line_info.cpuno = std::atoi(logical_device_seq); //cout << "logical_device_seq:"<< logical_device_seq << 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; //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); //cout << "time:" << line_info.time << endl; strcpy(line_info.name, monitor_name); //cout << "name:" << line_info.name << endl; ied = dev_map.value(QString::fromUtf8(line_info.terminal_code)); //ied = find_ied_from_dev_code(line_info.terminal_code); if (ied && ied->usr_ext && line_info.cpuno && line_info.cpuno < 10) { char str[256]; byte_t cpuno = line_info.cpuno; //cout << "cpuno:" << line_info.cpuno << endl; //cout << "byte_t cpuno:" << cpuno-1 << endl; ied_usr = (ied_usr_t*)ied->usr_ext; ied_usr->LD_info[cpuno - 1] = line_info; ied_usr->LD_info[cpuno - 1].ied = ied; apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_temp_dev_pool, str); ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_temp_dev_pool); ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_temp_dev_pool); ied_usr->LD_info[cpuno - 1].rptcount = 0; //cout << "rptcount:" << ied_usr->LD_info[cpuno - 1].rptcount << endl; if (cpuno > ied->cpucount) { //int c = cpuno; //cout << "cpucount(linecount old):" << (int)(ied->cpucount) << "new:" << c << endl; ied->cpucount = cpuno; //cout << "byte_t cpucount:" << ied->cpucount+1 << endl; } } } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } if (count_cfg != count_real) return APR_EBADF; return APR_SUCCESS; } void g_node_add_dev() { int count_cfg = g_node->n_clients; g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); } //CZY 2023-08-25 int compare_line_account(ied_usr_t* run_ied_usr, ied_usr_t* temp_ied_usrs, int run_cpucount, int temp_cpucount) { int run_cpuno, temp_cpuno; for (run_cpuno = 0; run_cpuno < run_cpucount; run_cpuno++) { int delete_flag = 1; for (temp_cpuno = 0; temp_cpuno < temp_cpucount; temp_cpuno++) { if (run_ied_usr->LD_info[run_cpuno].mp_id == temp_ied_usrs->LD_info[temp_cpuno].mp_id) {//exist same mp_id(update,keep) if (run_ied_usr->LD_info[run_cpuno].time < temp_ied_usrs->LD_info[temp_cpuno].time) {//line_update run_ied_usr->LD_info[run_cpuno].update_flag = 4; temp_ied_usrs->LD_info[temp_cpuno].update_flag = 4; } else {//line_keep run_ied_usr->LD_info[run_cpuno].update_flag = 0; temp_ied_usrs->LD_info[temp_cpuno].update_flag = 0; } delete_flag = 0; break; } } if (delete_flag == 1) {//line_delete run_ied_usr->LD_info[run_cpuno].update_flag = 2; } } for (temp_cpuno = 0; temp_cpuno < temp_cpucount; temp_cpuno++) { int add_flag = 1; for (run_cpuno = 0; run_cpuno < run_cpucount; run_cpuno++) { if (run_ied_usr->LD_info[run_cpuno].mp_id == temp_ied_usrs->LD_info[temp_cpuno].mp_id) {//exist same mp_id add_flag = 0; break; } } if (add_flag == 1) {//line_add temp_ied_usrs->LD_info[temp_cpuno].update_flag = 8; } } return 0; } //CZY 2023-08-22 compare account int compare_node_account(node_t* run_g_node, node_t* temp_g_node, int* add_count) { if (run_g_node == NULL) { return 1; } if (temp_g_node == NULL) { return 2; } int i, j; for (i = 0; i < run_g_node->n_clients; i++) { ied_usr_t* run_ied_usr = (ied_usr_t*)run_g_node->clients[i]->usr_ext; run_ied_usr->update_flag = 0; int delete_flag = 1; for (j = 0; j < temp_g_node->n_clients; j++) { ied_usr_t* temp_ied_usr = (ied_usr_t*)temp_g_node->clients[j]->usr_ext; if (run_ied_usr->terminal_id == temp_ied_usr->terminal_id) {//exist same terminal_id(update,delete,keep) if (temp_ied_usr->time > run_ied_usr->time)//dev_update or delete { if (strcmp(temp_ied_usr->tmnl_status, "20") != 0 && strcmp(run_ied_usr->tmnl_status, "20") == 0) {//dev_delete temp_ied_usr->update_flag = 2; run_ied_usr->update_flag = 2; int cpuno; for (cpuno = 0; cpuno < run_g_node->clients[i]->cpucount; cpuno++) {//line_delete run_ied_usr->LD_info[cpuno].update_flag = 2; } } else {//dev_update run_ied_usr->update_flag = 4; temp_ied_usr->update_flag = 4; int cpuno; //for (cpuno = 0; cpuno < temp_g_node->clients[j]->cpucount; cpuno++) {//line_update // temp_ied_usr->LD_info[cpuno].update_flag = 8; //} int f = compare_line_account(run_ied_usr, temp_ied_usr, run_g_node->clients[i]->cpucount, temp_g_node->clients[j]->cpucount);//line_compare } } else {//dev_keep int f = compare_line_account(run_ied_usr, temp_ied_usr, run_g_node->clients[i]->cpucount, temp_g_node->clients[j]->cpucount);//line_compare } delete_flag = 0; break; } } if (delete_flag == 1) {//dev_delete run_ied_usr->update_flag = 2; } } for (i = 0; i < temp_g_node->n_clients; i++) { ied_usr_t* temp_ied_usr = (ied_usr_t*)temp_g_node->clients[i]->usr_ext; if (temp_ied_usr->update_flag == 2) { continue; } int add_flag = 1; for (j = 0; j < run_g_node->n_clients; j++) { ied_usr_t* run_ied_usr = (ied_usr_t*)run_g_node->clients[j]->usr_ext; if (temp_ied_usr->terminal_id == run_ied_usr->terminal_id) { add_flag = 0; break; } } if (add_flag == 1) {//dev_add temp_ied_usr->update_flag = 8; int cpuno; for (cpuno = 0; cpuno < temp_g_node->clients[i]->cpucount; cpuno++) {//line_add temp_ied_usr->LD_info[cpuno].update_flag = 8; *add_count += 1; } } } return 0; } // void handle_line_account(ied_usr_t* run_ied_usr, ied_usr_t* temp_ied_usrs, int run_cpucount, int temp_cpucount) { int run_cpuno, temp_cpuno; for (run_cpuno = 0; run_cpuno < run_cpucount; run_cpuno++) { if (run_ied_usr->LD_info[run_cpuno].update_flag = 0) { } else if (run_ied_usr->LD_info[run_cpuno].update_flag = 2) { line_account_delete(run_ied_usr->update_flag); } else if (run_ied_usr->LD_info[run_cpuno].update_flag = 4) { line_account_update(run_ied_usr->update_flag); } } for (temp_cpuno = 0; temp_cpuno < temp_cpucount; temp_cpuno++) { if (temp_ied_usrs->LD_info[run_cpuno].update_flag = 8) { line_account_add(); } } } // CZY 2023-09-12 handle account void handle_node_account(node_t* run_g_node, node_t* temp_g_node, int dev_count) { int i; for (i = 0; i < run_g_node->n_clients; i++) { ied_usr_t* run_ied_usr = (ied_usr_t*)run_g_node->clients[i]->usr_ext; if (run_ied_usr->update_flag == 0) { } else if (run_ied_usr->update_flag == 2) { dev_account_delete(); } else if (run_ied_usr->update_flag == 4) { dev_account_update(); } } //增加dev的数量 for (i = 0; i < temp_g_node->n_clients; i++) { ied_usr_t* temp_ied_usr = (ied_usr_t*)temp_g_node->clients[i]->usr_ext; if (temp_ied_usr->update_flag == 8) { dev_account_add(); } } } //CZY 2023-08-25 void create_temp_g_node(node_t* temp_g_node) { /*create_temp_device_cfg_json(temp_g_node); create_temp_line_cfg_pg(temp_g_node); int* add_count = 0; compare_node_account(g_node, temp_g_node, add_count);*/ } void dev_update() { QMap dev_map; //create_temp_device_cfg_json(dev_map); } #endif int GetServerIndexFromDB() //获取前置服务器序号 { register int fd, interface; const int MAXINTERFACES = 100; struct ifreq buf[MAXINTERFACES]; struct arpreq arp; struct ifconf ifc; char mac[32] = ""; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { ifc.ifc_len = sizeof buf; ifc.ifc_buf = (caddr_t)buf; if (!ioctl(fd, SIOCGIFCONF, (char*)&ifc)) { interface = ifc.ifc_len / sizeof(struct ifreq); printf("\ninterface num is interface= %d\n", interface); while (interface-- > 0) { printf("net device %s\n", buf[interface].ifr_name); /*确保网卡是否支持混杂模式 Jugde whether the net card status is promisc */ 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); } /*判断网卡状态是否打开 Judge whether the net card status is up */ if (buf[interface].ifr_flags & IFF_UP) { printf("the interface status is UP\n"); } else { printf("the interface status is DOWN\n"); } /*获取网卡IP地址 Get IP of the net card */ if (!(ioctl(fd, SIOCGIFADDR, (char*)&buf[interface]))) { printf("IP address is: %s\n", inet_ntoa(((struct sockaddr_in*)(&buf[interface].ifr_addr))->sin_addr)); } else { char str[256] = ""; sprintf(str, "cpm: ioctl device %s", buf[interface].ifr_name); perror(str); } /*获取网卡的HW地址 Get HW ADDRESS of the net card */ 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); } } } else perror("cpm: ioctl"); } else perror("cpm: socket"); close(fd); return 0; } /////////////////////////////////////////////////////////CZY void parse_one_rpt_log_ini(int idx, QStringList* rpt_cfg_strlist, QStringList* log_cfg_strlist, char* type) { char* tmp; tmp = Get_xmlpath(type);//获取模型id号 if (tmp == NULL) {//找不到模型编号使用默认的型号和配置文件 //zw修改 2023 - 8 - 15 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 if (strcmp(subdir, "cfg_stat_data") == 0) { QString devtype; devtype.append(type); QString devtype2; devtype2.append("HL-6810");//稳态默认型号HL-6810 qDebug() << "cfg_stat_data"; QString xml_dir = QString("../") + QString("etc/"); //Linux下调试路径 QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(xml_dir + QString("JiangSu_Config.xml"));//默认配置文件JiangSu_Config.xml if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { qDebug() << "Read RPT Error1"; return; } if (!doc.setContent(&file)) //将文件内容读到doc中 { qDebug() << "Read RPT Error2"; file.close(); return; } file.close(); QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate" QDomElement docElem = doc.documentElement(); //返回根节点元素 QDomNode n = docElem.firstChild(); //获得doc的第一个节点,即"Topic" while (!n.isNull()) //如果Topic节点不为空 { if (n.isElement()) { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); // if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 { qDebug() << "ReportStat"; QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { QString strTag2 = node.toElement().tagName(); //DataType节点 if ("ReportStat" == strTag2) { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl")); qDebug() << "devtype:" << devtype << node2.toElement().attribute("ReportControl").toAscii().data(); } } } } } } } n = n.nextSibling(); } 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"; QString xml_dir = QString("../") + QString("etc/"); //Linux下调试路径 QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(xml_dir + QString("JiangSu_Config.xml")); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { qDebug() << "Read RPT Error1"; return; } if (!doc.setContent(&file)) //将文件内容读到doc中 { qDebug() << "Read RPT Error2"; file.close(); return; } file.close(); QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate" QDomElement docElem = doc.documentElement(); //返回根节点元素 QDomNode n = docElem.firstChild(); //获得doc的第一个节点,即"Topic" while (!n.isNull()) //如果Topic节点不为空 { if (n.isElement()) { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); // if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 { qDebug() << "ReportEvent"; QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { QString strTag2 = node.toElement().tagName(); //DataType节点 if ("ReportEvent" == strTag2) { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl")); qDebug() << node2.toElement().attribute("ReportControl").toAscii().data(); } } } } } } } n = n.nextSibling(); } 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); } } else//型号不为空读取指定的配置文件 { QString tmppath; tmppath.append("/FeProject/dat/").append(tmp).append(".xml"); qDebug() << tmppath; //lnk20241126调试用 std::cout << "rptcfgfile:" << tmppath.toStdString() << std::endl; //zw修改 2023 - 8 - 15 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 if (strcmp(subdir, "cfg_stat_data") == 0) { qDebug() << "cfg_stat_data"; QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(tmppath); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { qDebug() << "Read RPT Error1"; //lnk20241126调试用 std::cout << "Read RPT Error1" << std::endl; return; } if (!doc.setContent(&file)) //将文件内容读到doc中 { qDebug() << "Read RPT Error2"; //lnk20241126调试用 std::cout << "Read RPT Error2" << std::endl; file.close(); return; } file.close(); QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate" QDomElement docElem = doc.documentElement(); //返回根节点元素 QDomNode n = docElem.firstChild(); //获得doc的第一个节点,即"Topic" while (!n.isNull()) //如果Topic节点不为空 { if (n.isElement()) { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); // if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 { qDebug() << "ReportStat"; QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { QString strTag2 = node.toElement().tagName(); //DataType节点 if ("ReportStat" == strTag2) { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl")); qDebug() << node2.toElement().attribute("ReportControl").toAscii().data();//读取各个报告配置 } } } } } } } n = n.nextSibling(); } QString log_cfg_str = "LLN0$LG$lcStatisticData,dsStatisticData,PQM1,0,600000,1,0,0,0";//日志的配置是写死的 log_cfg_strlist->append(log_cfg_str); } //lnk添加实时数据20241125 if (strcmp(subdir, "cfg_3s_data") == 0) { qDebug() << "cfg_3s_data"; QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(tmppath); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { qDebug() << "Read RPT Error1"; return; } if (!doc.setContent(&file)) //将文件内容读到doc中 { qDebug() << "Read RPT Error2"; file.close(); return; } file.close(); QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate" QDomElement docElem = doc.documentElement(); //返回根节点元素 QDomNode n = docElem.firstChild(); //获得doc的第一个节点,即"Topic" while (!n.isNull()) //如果Topic节点不为空 { if (n.isElement()) { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); // if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 { qDebug() << "ReportReal"; QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { QString strTag2 = node.toElement().tagName(); //DataType节点 if ("ReportReal" == strTag2) { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl")); qDebug() << node2.toElement().attribute("ReportControl").toAscii().data(); } } } } } } } n = n.nextSibling(); } //实时数据没有日志 //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"; QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(tmppath); if (!file.open(QIODevice::ReadOnly | QFile::Text)) //以只读方式打开xml { qDebug() << "Read RPT Error1"; return; } if (!doc.setContent(&file)) //将文件内容读到doc中 { qDebug() << "Read RPT Error2"; file.close(); return; } file.close(); QDomNode firstNode = doc.firstChild(); //根节点"JSConfigTemplate" QDomElement docElem = doc.documentElement(); //返回根节点元素 QDomNode n = docElem.firstChild(); //获得doc的第一个节点,即"Topic" while (!n.isNull()) //如果Topic节点不为空 { if (n.isElement()) { QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); // if ("ReportMap" == strTag)//zw修改 2023 - 8 - 15 增加判断 将触发报告的解析移至XML 原配置RptLogCfg.ini取消 { qDebug() << "ReportEvent"; QDomNodeList list = e.childNodes(); //获得元素的所有子节点的列表 for (int i = 0; i < list.count(); i++) //遍历 DataType列表 { QDomNode node = list.at(i); //node1 if (node.isElement()) { QString strTag2 = node.toElement().tagName(); //DataType节点 if ("ReportEvent" == strTag2)//区分点 { QDomNodeList list2 = node.childNodes(); //获得元素DataType的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) //遍历 Monitor列表 { QDomNode node2 = list2.at(i2); //node2 if (node2.isElement()) { rpt_cfg_strlist->append(node2.toElement().attribute("ReportControl")); qDebug() << node2.toElement().attribute("ReportControl").toAscii().data(); } } } } } } } n = n.nextSibling(); } 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); } delete[] tmp; } } int parse_rpt_log_ini() { const int MAX_DEV_FLAG = 10; bool not_loaded[MAX_DEV_FLAG]; //QStringList rpt_cfg_strlists[MAX_DEV_FLAG]; //QStringList log_cfg_strlists[MAX_DEV_FLAG]; QMap rpt_cfg_strlists; QMap log_cfg_strlists; int iedno, cpuno; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; char buf[256]; /*for (int i = 0; i < MAX_DEV_FLAG; ++i) not_loaded[i] = true;*/ 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)) { QStringList* rpt_temp = new QStringList(); QStringList* log_temp = new QStringList(); rpt_cfg_strlists.insert(type, rpt_temp); log_cfg_strlists.insert(type, log_temp); //g_DevFlag没有使用 parse_one_rpt_log_ini(g_DevFlag, rpt_cfg_strlists[type], log_cfg_strlists[type], ied_usr->dev_type); } /*if (not_loaded[ied_usr->dev_flag]) { parse_one_rpt_log_ini(ied_usr->dev_flag, rpt_cfg_strlists[ied_usr->dev_flag], log_cfg_strlists[ied_usr->dev_flag], ied_usr->dev_type); not_loaded[ied_usr->dev_flag] = false; }*/ for (cpuno = 0; cpuno < ied->cpucount; cpuno++) { LD_info = &(ied_usr->LD_info[cpuno]); char str[256]; //256大小 char* tmp = Get_IED(ied_usr->dev_type); qDebug() << tmp << endl; apr_snprintf(str, sizeof(str), tmp, cpuno + 1); //lnk20250208不使用apr_pstrdup,使用固定大小,后续都在这块内存上直接复用 //ied_usr->LD_info[cpuno].LD_name = apr_pstrdup(g_init_pool, str);//domin // 从 g_init_pool 内存池中分配固定 256 字节的内存 // ied_usr->LD_info[cpuno].LD_name = (char *)apr_palloc(g_init_pool, 256);//lnk20250212重复申请删除 // 清空内存,防止残留数据 // memset(ied_usr->LD_info[cpuno].LD_name, 0, 256); // 将 str 中的内容复制到预先分配的内存中,最多复制 256 字节(包含结束符) // apr_cpystrn(ied_usr->LD_info[cpuno].LD_name, str, 256); delete[] tmp; 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);// } 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); fill_logctrl_by_cfg(LD_info, i, buf, tmp); delete[] tmp; } } } //报告控制块和日志控制块处理结束后清理容器 for (QMap::iterator it1 = log_cfg_strlists.begin(); it1 != log_cfg_strlists.end(); ++it1) { delete it1.value(); } for (QMap::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; } int parse_json_cfg() { QString cfg_dir = QString("../") + QString("etc/"); QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(cfg_dir + JSON_CONFIG_FN_old); if (!file.open(QIODevice::ReadOnly)) return APR_EBADPATH; //以只读方式打开 if (!doc.setContent(&file)) { file.close(); return APR_EBADF; } //将文件内容读到doc中 QDomElement docElem = doc.documentElement(); //返回根元素 QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点 while (!n.isNull()) { //如果节点不为空 if (n.isElement()) { //如果节点是元素 QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); QString topic = e.attribute("name"); if (strTag == "Topic" && (topic == "HISDATA" || topic == "RTDATA")) { QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表 e for (int i = 0; i < list.count(); i++) { //遍历该列表 QDomNode node = list.at(i); if (node.isElement()) { QString strTag2 = node.toElement().tagName(); QString data_type = node.toElement().attribute("value"); if (strTag2 == "DataType") { //node QDomNodeList list2 = node.childNodes(); //获得元素node的所有子节点的列表 for (int i2 = 0; i2 < list2.count(); i2++) { //遍历该列表 QDomNode node2 = list2.at(i2); ////node2 if (node2.isElement()) { QString strTag3 = node2.toElement().tagName(); /////////////////////////// if (strTag3 == "Monitor") { QDomNodeList list3 = node2.childNodes(); //获得元素node的所有子节点的列表 for (int i3 = 0; i3 < list3.count(); i3++) { //遍历该列表 QDomNode node3 = list3.at(i3); //node3 if (node3.isElement()) { QString strTag4 = node3.toElement().tagName(); //**////**////**////**////**////**////**////**////**////**////**// if (strTag4 == "Item") { QString item = node3.toElement().attribute("name"); QDomNodeList list4 = node3.childNodes(); //获得元素node的所有子节点的列表 for (int i4 = 0; i4 < list4.count(); i4++) { //遍历该列表 QDomNode node4 = list4.at(i4); //node4 if (node4.isElement()) { QString strTag5 = node4.toElement().tagName(); //////////*********************//////////////////// if (strTag5 == "Sequence") { uint sequence = node4.toElement().attribute("value").toUInt(); QDomNodeList list5 = node4.childNodes(); //获得元素node的所有子节点的列表 for (int i5 = 0; i5 < list5.count(); i5++) { //遍历该列表 QDomNode node5 = list5.at(i5); //node5 if (node5.isElement()) { QDomElement e_Value = node5.toElement(); //将其转换为元素 QString strTag6 = e_Value.tagName(); // if (strTag6 == "Value") { QString name_str = e_Value.attribute("name"); QString DO_str = e_Value.attribute("DO"); QString DA_str = e_Value.attribute("DA"); uint mask = 1; for (int j = 0; j <= 3; j++) { if (mask & sequence) qDebug() << topic << " " << data_type << " " << item << " Phs=" << j << " " << name_str << " " << DO_str << DA_str; mask *= 2; } //todo ,to read the attribute of Value } } } } //////////*********************//////////////////// } } } //**////**////**////**////**////**////**////**////**////**////**// } } } //////////////////////////////// } }// for(int i2=0; i2 find_xml_belong_to_this_process() { char prefix[20]; // 假设最多需要20个字符(根据实际需要调整) sprintf(prefix, "%d_%d", g_node_id, g_front_seg_index); // 将g_node_id和g_front_seg_index格式化为字符串 DIR *dir = opendir(LEDGER_UPDATE_DIR.c_str()); // 打开目录 struct dirent *entry; std::list found_files; // 用于存储找到的所有匹配文件名 if (dir == NULL) { std::cout << "Failed to open directory: " << LEDGER_UPDATE_DIR << std::endl; return found_files; // 返回空的list } //std::cout << "we should find file with prefix:" << prefix << std::endl; // 遍历目录中的所有文件 while ((entry = readdir(dir)) != NULL) { std::string filename = entry->d_name; // 排除 "." 和 ".." 目录 if (filename == "." || filename == "..") { continue; } std::cout << "find" << filename << "in" << LEDGER_UPDATE_DIR << std::endl; //std::cout << "filename.find(prefix):" << filename.find(prefix) << std::endl; //std::cout << "filename.substr(filename.find_last_of('.') + 1)" << filename.substr(filename.find_last_of('.') + 1) << std::endl; // 判断文件名是否以 prefix 开头且扩展名是 .xml if (filename.find(prefix) == 0 && filename.substr(filename.find_last_of('.') + 1) == "xml") { std::string full_path = LEDGER_UPDATE_DIR + filename; found_files.push_back(full_path); // 将完整路径加入容器 } } closedir(dir); // 关闭目录 return found_files; // 返回所有找到的文件名 } // 提取标签中的值的通用函数 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("", start_pos); if (end_pos == std::string::npos) return ""; return data.substr(start_pos + tag.length() + 2, end_pos - start_pos - tag.length() - 2); } // 根据 str_tag 将 terminal 添加到对应的数组 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!!!!"<new_update_num < MAX_UPDATEA_NUM) { trigger_update_xml->new_updates[trigger_update_xml->new_update_num] = work_terminal; trigger_update_xml->new_update_num+= 1; // 更新新终端的数量 } else { std::cerr << "Exceeded MAX_UPDATEA_NUM limit for new updates!" << std::endl; } } else if (str_tag == "modify") { std::cout << "modify ledger!!!"<modify_update_num < MAX_UPDATEA_NUM) { trigger_update_xml->modify_updates[trigger_update_xml->modify_update_num] = work_terminal; trigger_update_xml->modify_update_num+= 1; // 更新修改终端的数量 } else { std::cerr << "Exceeded MAX_UPDATEA_NUM limit for modify updates!" << std::endl; } } else { std::cerr << "Unknown tag: " << str_tag << std::endl; } } // 解析 XML 数据并提取 terminal 信息 void parse_terminal_from_data(trigger_update_xml_t* trigger_update_xml, const std::string& str_tag, const std::string& data) { terminal work_terminal = {}; // 创建新的 terminal 对象 // 提取各个字段 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()); size_t monitor_pos = 0; size_t monitor_count = 0; // 查找每个 monitorData,最多处理 10 个 while ((monitor_pos = data.find(" 的位置 } // 根据 str_tag 将 terminal 添加到相应的数组 add_terminal_to_trigger_update(trigger_update_xml, str_tag, work_terminal); } void parse_ledger_update(trigger_update_xml_t* trigger_update_xml, const std::string& strTag, const std::string& data) { std::cout << "record one xml.."<delete_update_num < MAX_UPDATEA_NUM) { trigger_update_xml->delete_updates[trigger_update_xml->delete_update_num] = delete_terminal; trigger_update_xml->delete_update_num += 1; // 增加计数 } } } else { std::cerr << "Unsupported strTag: " << strTag << std::endl; } } 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.."< 标签 size_t ledger_pos = content.find(""); if (ledger_pos == std::string::npos) { std::cerr << "ledger_update tag not found!" << std::endl; return -1; } // 查找 , , 标签 size_t add_pos = content.find("", ledger_pos); size_t delete_pos = content.find("", ledger_pos); size_t modify_pos = content.find("", ledger_pos); // 确定哪个标签存在,并获取相应的位置 size_t target_pos = std::string::npos; std::string target_tag; 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"; } //没找到正确的标签退出处理 if (target_pos == std::string::npos) { std::cerr << "No , , or tag found!" << std::endl; return -1; } // 查找目标标签的结束位置 size_t end_pos = content.find("", target_pos); if (end_pos == std::string::npos) { std::cerr << "Closing tag not found!" << std::endl; return -1; } // 提取目标标签的内容 std::string target_content = content.substr(target_pos + target_tag.length() + 2, end_pos - (target_pos + target_tag.length() + 2)); // 解析 和其中的内容 size_t data_pos = 0; while ((data_pos = target_content.find("", data_pos)) != std::string::npos) { size_t data_end_pos = target_content.find("", data_pos); if (data_end_pos == std::string::npos) { std::cerr << "Closing tag not found!" << std::endl; return -1; } std::string data_content = target_content.substr(data_pos + 14, data_end_pos - (data_pos + 14)); std::cout << "ledger data_content is " << data_content <标签,目前每个文件只有一个台账 data_pos = data_end_pos + 15; } std::cout << "load one xml finish"< result = find_xml_belong_to_this_process(); if (!result.empty()) { std::cout << "Found XML files:" << std::endl; for (std::list::iterator it = result.begin(); it != result.end(); ++it) { const std::string& filename = *it; std::cout << filename << std::endl; //解析每个文件,提取终端,判断终端是否满足更新条件 apr_sleep(apr_time_from_sec(1) / 10); //加载一个文件的内容到数据结构 if (!load_ledger_update_from_xml(trigger_update_xml, filename)) { std::cout << "read /etc/ledgerupdate/" << filename << " success..." << std::endl; } //处理过的文件删除掉 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; } } } else { //std::cout << "No matching XML files found." << std::endl;//减少不必要的打印 return APR_EGENERAL; } //有数据返回成功,后续进行处理 //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"); return APR_SUCCESS; } else{//无数据返回失败,后续不处理 printf("ledger update xml no data...\n"); return APR_EGENERAL; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //实时触发部分///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QString THREE_SECS_WEBSERVICE_DIR = QString("../etc/trigger3s/"); QString get_3s_trig_fn() { 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; } //lnk20241125添加打印调试用///////////////////////////////////////////////////////////////////////////////////////////////// // 打印 trigger_t 结构体的函数 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); } // 打印 trigger_3s_xml_t 结构体的函数 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]); } 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]); } 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]); } 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]); } } //实时触发文件处理部分////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void parse_3s_trigger(trigger_3s_xml_t* trigger_3s_xml, QString parentTag, QDomElement& trigger_e) { QString e_atr(""); trigger_t trigger; trigger.dev_idx = trigger_e.attribute("DevSeries").toInt(); trigger.line_id = trigger_e.attribute("Line").toInt(); e_atr = trigger_e.attribute("RealData").toLower(); trigger.real_data = getValueFromElemAttrStr(e_atr); e_atr = trigger_e.attribute("SOEData").toLower(); trigger.soe_data = getValueFromElemAttrStr(e_atr); trigger.limit = trigger_e.attribute("Limit").toInt(); trigger.count = trigger_e.attribute("Count").toInt(); //qDebug()< " << dev_idx<<" "<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; } //调试用lnk20241125 print_trigger_3s_xml(*trigger_3s_xml); } int load_3s_data_from_xml(trigger_3s_xml_t* trigger_3s_xml, QString xml_fn) { QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(xml_fn); if (!file.open(QIODevice::ReadOnly)) return APR_EBADPATH; //以只读方式打开 bool ret = doc.setContent(&file); file.close(); if (!ret) return APR_EBADF; //将文件内容读到doc中 QDomElement docElem = doc.documentElement(); //返回根元素 QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点 while (!n.isNull()) { //如果节点不为空 if (n.isElement()) { //如果节点是元素 QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); if (strTag == "Work" || strTag == "New" || strTag == "Delete" || strTag == "Modify") { QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表 for (int i = 0; i < list.count(); i++) { //遍历该列表 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" ) } } } } n = n.nextSibling(); //下一个兄弟节点 } return APR_SUCCESS; } 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)); //这个文件是用来记录正在进行中的实时触发 QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/"); load_3s_data_from_xml(trigger_3s_xml, (cfg_dir + THREE_SECS_CONFIG_FN)); //加载/Feproject/etc/Trigger3S.xml QString the_webservice_xml_fn = get_3s_trig_fn();// ../etc/trigger3s/目录下的最新的xml文件,这个文件是用来打开实时触发的开关 printf("the_webservice_xml_fn.size():%d\n",the_webservice_xml_fn.size()); if (the_webservice_xml_fn.size() > 4) {//文件名大于4说明找到文件 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); printf("/etc/trigger3s/*.xml success...\n"); return APR_SUCCESS; } printf("3s xml fail...\n"); return APR_EGENERAL; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //3s触发记录写入文件 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); } } int create_3s_xml(trigger_3s_xml_t* trigger_3s_xml) { QDomDocument doc; doc.appendChild(doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"gb2312\"")); QDomElement root = doc.createElement("Trigger3S"); doc.appendChild(root); 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); 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; } QTextStream out(&file); out.setCodec("gb2312"); doc.save(out, 4); file.close(); return APR_SUCCESS; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 函数功能:从指定的 .cfg 配置文件中提取起始时间和触发时间,并将其转化为毫秒级时间戳。 // 输入参数: // - comtrade_fn:输入的文件名,作为参考用于定位对应的 .cfg 配置文件。 // 输出参数: // - start_tm:返回的起始时间戳(单位:毫秒)。 // - trig_tm:返回的触发时间戳(单位:毫秒)。 // 返回值: // - 返回 APR_SUCCESS 表示成功,返回 APR_EBADF 表示文件错误。 int extract_timestamp_from_cfg_file(char* comtrade_fn, long long* start_tm, long long* trig_tm) { // 获取文件名信息,路径和文件名提取 QFileInfo fi(QString::fromAscii(comtrade_fn)); QString fn = fi.fileName(); QString cfgFileName_temp = QString("../comtrade/") + fn; // 拼接.cfg文件的路径 // 检查文件是否以 ".cfg" 或 ".CFG" 结尾 if (!cfgFileName_temp.endsWith(".cfg", Qt::CaseInsensitive) && !cfgFileName_temp.endsWith(".CFG", Qt::CaseInsensitive)) return APR_EBADF; // 如果文件名不符合要求,返回文件错误 // 打开配置文件 QFile cfgFile_temp(cfgFileName_temp); if (!cfgFile_temp.exists()) { // 如果文件不存在 qDebug() << QString("Cannot find corresponding .cfg file: %1").arg(cfgFileName_temp); cfgFile_temp.close(); return APR_EBADF; } else if (!cfgFile_temp.open(QFile::ReadOnly | QFile::Text)) { // 如果文件无法打开 qDebug() << QString("Cannot open file %1:\n%2.").arg(cfgFileName_temp).arg(cfgFile_temp.errorString()); return APR_EBADF; } else { QStringList datContentList_temp; QTextStream in_temp(&cfgFile_temp); // 创建文本流读取文件 // 忽略 GBK 编码相关的代码(被注释掉了) QString start_time_str(""); // 用于存储起始时间字符串 QString trigger_time_str(""); // 用于存储触发时间字符串 // 按行读取配置文件内容 while (!in_temp.atEnd()) { QString line_temp = in_temp.readLine().trimmed(); // 读取并去除空白字符 QString upper_line_temp = line_temp.toUpper(); // 转换为大写字符 // 如果读取到 "ASCII" 或 "BINARY" 字符串,则停止处理 if ((upper_line_temp == QString("ASCII")) || (upper_line_temp == QString("BINARY"))) break; else { // 如果没有,更新起始时间和触发时间 start_time_str = trigger_time_str; trigger_time_str = line_temp; } } // 如果提取到的 start_time_str 长度大于3,则去掉最后3个字符(通常是毫秒部分) if (start_time_str.size() > 3) start_time_str = start_time_str.left(start_time_str.size() - 3); // 将 start_time_str 转换为 QDateTime 对象,并转换为自纪元以来的毫秒数 QDateTime start_time_dt = QDateTime::fromString(start_time_str, "dd/MM/yyyy,hh:mm:ss.zzz"); *start_tm = start_time_dt.toMSecsSinceEpoch(); // 转换为毫秒时间戳并赋值给 start_tm // 同样处理触发时间(去掉最后3个字符并转换为时间戳) if (trigger_time_str.size() > 3) trigger_time_str = trigger_time_str.left(trigger_time_str.size() - 3); QDateTime trigger_time_dt = QDateTime::fromString(trigger_time_str, "dd/MM/yyyy,hh:mm:ss.zzz"); *trig_tm = trigger_time_dt.toMSecsSinceEpoch(); // 转换为毫秒时间戳并赋值给 trig_tm cfgFile_temp.close(); // 关闭文件 } return APR_SUCCESS; // 成功返回 } #if 0 int extract_timestamp_from_cfg_file(char* comtrade_fn, long long* start_tm, long long* trig_tm) { QFileInfo fi(QString::fromAscii(comtrade_fn)); QString fn = fi.fileName(); QString cfgFileName_temp = QString("../comtrade/") + fn; if (!cfgFileName_temp.endsWith(".cfg", Qt::CaseInsensitive) && !cfgFileName_temp.endsWith(".CFG", Qt::CaseInsensitive))//fn_str.endsWith(".cfg", Qt::CaseInsensitive) || fn_str.endsWith(".CFG", Qt::CaseInsensitive) return APR_EBADF; QFile cfgFile_temp(cfgFileName_temp); if (!cfgFile_temp.exists()) { qDebug() << QString("Cannot find corresponding .cfg file: %1").arg(cfgFileName_temp); cfgFile_temp.close(); return APR_EBADF; } else if (!cfgFile_temp.open(QFile::ReadOnly | QFile::Text)) { qDebug() << QString("Cannot open file %1:\n%2.").arg(cfgFileName_temp).arg(cfgFile_temp.errorString()); return APR_EBADF; } else { QStringList datContentList_temp; QTextStream in_temp(&cfgFile_temp); /*QTextCodec *codec_temp=QTextCodec::codecForName("gbk"); in_temp.setCodec(codec_temp);*/ QString start_time_str(""); QString trigger_time_str(""); while (!in_temp.atEnd()) { QString line_temp = in_temp.readLine().trimmed(); QString upper_line_temp = line_temp.toUpper(); if ((upper_line_temp == QString("ASCII")) || (upper_line_temp == QString("BINARY"))) break; else { start_time_str = trigger_time_str; trigger_time_str = line_temp; } } //11/05/2018,15:28:53.343000 if (start_time_str.size() > 3) start_time_str = start_time_str.left(start_time_str.size() - 3); QDateTime start_time_dt = QDateTime::fromString(start_time_str, "dd/MM/yyyy,hh:mm:ss.zzz"); *start_tm = start_time_dt.toMSecsSinceEpoch(); if (trigger_time_str.size() > 3) trigger_time_str = trigger_time_str.left(trigger_time_str.size() - 3); QDateTime trigger_time_dt = QDateTime::fromString(trigger_time_str, "dd/MM/yyyy,hh:mm:ss.zzz"); *trig_tm = trigger_time_dt.toMSecsSinceEpoch(); cfgFile_temp.close(); } return APR_SUCCESS; } #endif //录波部分/////////////////////////////////////////////////////////////////////////////// //WW 2023-11-01 增加录波段号采用int类型匹配 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) { int j; printf(">>>>>>>>>>>>>>>>>>pares_file_names file list match fltnum=%d", fltnum); *cfg_idx = -1; *dat_idx = -1; for (j = 0; j < filenum; ++j) { char fileNameTemp[64]; strcpy(fileNameTemp, filenames[j]); //临时存放 装置录波文件名 printf(" %s ", fileNameTemp); if (strstr(fileNameTemp, domname) == NULL) //例:域名:"PQMonitor_PQM1" 不是 装置录波文件名:"PQMonitor_PQM1_000001_20191121_154534_689.CFG/.DAT/.HDR"的子串 continue; char* p = strtok(fileNameTemp, "_"); //PQMonitor p = strtok(NULL, "_"); //PQM1 p = strtok(NULL, "_"); //000001 int nFltNum = atoi(p); //将字符转换成整型 if (nFltNum == fltnum) { 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; QFileInfo fi(fn_str); QString fn = fi.baseName(); strcpy(file_base_name, fn.toAscii().data()); 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()); } else if (fn_str.endsWith(".dat", Qt::CaseInsensitive) || fn_str.endsWith(".DAT", Qt::CaseInsensitive)) *dat_idx = j; } if (*cfg_idx != -1 && *dat_idx != -1)//两个文件都已经找到 break; } printf("\n<<<<<<<<<<<<<<<<<<<<= 0 && (*dat_idx) >= 0) return APR_SUCCESS; else return APR_EBADF; } //WW2023-11-01 end int parse_file_names(char* file_match_str, char** filenames, int filenum, int* cfg_idx, int* dat_idx, char* file_base_name, char* file_yyyymm) { int j; *cfg_idx = -1; *dat_idx = -1; for (j = 0; j < filenum; ++j) { if (strstr(filenames[j], file_match_str) != NULL) { QString fn_str = QString::fromAscii(filenames[j]); if (fn_str.endsWith(".cfg", Qt::CaseInsensitive)) { //PQMonitor_PQM4_000349_20180531_113701_618.CFG *cfg_idx = j; QFileInfo fi(fn_str); QString fn = fi.baseName(); strcpy(file_base_name, fn.toAscii().data()); QString remain_str = fn_str.split(QString::fromAscii(file_match_str)).at(1); QString yyyymm_str = remain_str.mid(1, 6); strcpy(file_yyyymm, yyyymm_str.toAscii().data()); } else if (fn_str.endsWith(".dat", Qt::CaseInsensitive)) *dat_idx = j; } } if ((*cfg_idx) >= 0 && (*dat_idx) >= 0) return APR_SUCCESS; else return APR_EBADF; } //补招部分//////////////////////////////////////////////////////////////////////////////// void parse_recall(recall_xml_t* recall_xml, QString parentTag, QDomElement& recall_e, char* id) { recall_t recall; /*QString ied; ied.append(recall_e.attribute("MonitorID")); QByteArray byteArray = ied.toLocal8Bit(); char* charArray = new char[byteArray.size()]; memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0';*/ recall.line_id = id; 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; recall.need_steady = recall_e.attribute("STEADY").toInt(); recall.need_voltage = recall_e.attribute("VOLTAGE").toInt(); qDebug() << parentTag << "-> " << " " << recall.line_id << " " << recall.need_steady << " " << recall.need_voltage << " " << recall.start_time << " " << recall.end_time; 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; } } int delete_recall_xml(char* id) { // ied_t *ied; // ied_usr_t *ied_usr; // LD_info_t line_info; // int dev_idx_in_line = 0; 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"); //指定文件夹名 QDir dir(cfg_dir); if (!dir.exists()) { qDebug() << "folder does not exist!"; return false; } //指定文件后缀名,可指定多种类型 //qDebug() << qstrRecallPath; QStringList filter(file_name); //指定查找类型和排序,按最新的修改时间获取 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]; QFile::remove(qstrRecallPath); } return APR_SUCCESS; } int parse_recall_xml(recall_xml_t* recall_xml, char* id) { // ied_t *ied; // ied_usr_t *ied_usr; // LD_info_t line_info; // int dev_idx_in_line = 0; 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"); //lnk20241225这里文件名 //指定文件夹名 QDir dir(cfg_dir); if (!dir.exists()) { qDebug() << "folder does not exist!"; return false; } //指定文件后缀名,可指定多种类型 //qDebug() << qstrRecallPath; QStringList filter(file_name); //指定查找类型和排序,按最新的修改时间获取 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; QDomDocument doc; //新建QDomDocument类对象,它代表一个XML文档 QFile file(qstrRecallPath); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "file.open error"; continue; //以只读方式打开 } bool ret = doc.setContent(&file); file.close(); if (!ret) { qDebug() << "doc.setContent error"; continue; } //将文件内容读到doc中 QDomElement docElem = doc.documentElement(); //返回根元素 QDomNode n = docElem.firstChild(); //返回根节点的第一个子节点 while (!n.isNull()) { //如果节点不为空 if (n.isElement()) { //如果节点是元素 QDomElement e = n.toElement(); //将其转换为元素 QString strTag = e.tagName(); if (strTag == "Work" || strTag == "New") { QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表 for (int i = 0; i < list.count(); i++) { //遍历该列表 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" ) } } } } n = n.nextSibling(); //下一个兄弟节点 } } //for (int i = 0; i < files.size(); i++) {//清空读取文件 // QString qstrRecallPath = cfg_dir + QString("/") + files[i]; // QFile::remove(qstrRecallPath); //} return APR_SUCCESS; } 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; QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 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; } 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); if (LD_info == NULL || LD_info->read_flag == 0) { printf("\n recall[0].line_id == NULL \n"); printf("\n Find LD_info == null \n"); } else { 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; //lnk20241030补充补招稳态暂态标志,每个文件都有很多条时间记录 LD_info->autorecall[j]->need_steady = recall[j].need_steady; LD_info->autorecall[j]->need_voltage = recall[j].need_voltage; } LD_info->autorecallflag = 0; } } } } int remove_recall_xml() { QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/"); QString filename(cfg_dir + RECALL_CONFIG_FN); return QFile::remove(filename); } ////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////WW 20230819 增加数据库连接函数 int OTLConnect() //OTL连接Oracle数据库 { try { otl_connect::otl_initialize(); //初始化OTL连接库的环境的静态函数 //db.rlogon(g_strOTLConnect.c_str()); //连接数据库Oracle(用户名/密码) //db.rlogon("postgres", "dnzl@#001", "pgsql", 0); //db.rlogon("postgres", "1234567", "pgsql", 0); //db.rlogon("postgres", "bmdev@123", "pgsql", 0); db.rlogon(POSTGRES_USERNAME, POSTGRES_PASSWORD, POSTGRES_DNSNAME, 0); printf("\nPostgreSL\"%s\"connect succ\n", g_strOTLConnect.c_str()); } catch (otl_exception& e) { //printf("\nPostgreSL\"%s\"failed,ERROR code= %d, msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); if (e.code != 32031) printf("\nPostgreSL\"%s\"failed,ERROR code= %d, msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } return 0; } int OTLDisconnect() //OTL断开Oracle数据库 { try { db.logoff(); printf("\nPostgreSL\"%s\"disconnect\n\n", g_strOTLConnect.c_str()); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"disconnect failed,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } return 0; } int OTLTestSelect() //OTL连接Oracle数据库 { try { OTLConnect(); //int rtState = OTLState(); otl_stream i(1, // buffer size "select \"MODEL_ID\" from \"gaussdb\".\"MEAS_PQ_ICD_MODEL_TR\"", //SELECT statement db //connect object ); //create select stream char f2[64]; while (!i.eof()) { //while not end-of-data i >> f2; qDebug() << " MODEL_ID =" << f2 << endl; } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } return 0; } int OTLState() //OTL连接Oracle数据库状态 { try { otl_datetime tm; std::string strSql = "select sysdate from dual"; //std::string strSql = "select * from pgsql_test_gy"; otl_stream i(1, strSql.c_str(), db); if (!i.eof()) { i >> tm; QString qstrYear = QString("%1").arg(tm.year, 4, 10, QLatin1Char('0')); QString qstrMonth = QString("%1").arg(tm.month, 2, 10, QLatin1Char('0')); int iYear = qstrYear.toInt(); int iMonth = qstrMonth.toInt(); QString qCurrentYear = QDateTime::currentDateTime().toString("yyyy"); QString qCurrentMonth = QDateTime::currentDateTime().toString("MM"); if (!qstrYear.isEmpty() && !qstrMonth.isEmpty()) { if ((iYear >= 1970) || (iMonth >= 1)) return 0; else { printf("qstrYear= %s,iYear= %d,qCurrentYear= %s且qstrMonth= %s,iMonth= %d,qCurrentMonth= %s不等,需检查数据库OTL连接!\n", qstrYear.toAscii().data(), iYear, qCurrentYear.toAscii().data(), qstrMonth.toAscii().data(), iMonth, qCurrentMonth.toAscii().data()); return -1; } } else { printf("Sql查询系统日期qstrYear= %s或qstrMonth= %s为空,需检查数据库OTL连接!\n", qstrYear.toAscii().data(), qstrMonth.toAscii().data()); return -1; } printf(">>>Sql查询系统日期qstrYear= %s,qCurrentYear= %s,qstrMonth= %s,qCurrentMonth= %s \n", qstrYear.toAscii().data(), qCurrentYear.toAscii().data(), qstrMonth.toAscii().data(), qCurrentMonth.toAscii().data()); } } catch (otl_exception& e) { printf("Sql查询系统日期时间失败,ERROR code= %d, msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } return 0; } int OTLDbconnected() { cout << "db.connect is :" << db.connected << endl; return db.connected; } ////////////////////////////////////////////////////////////////////////////////数据库部分 int write_to_db(const char* sqlstm) //写数据库 { try { apr_sleep(apr_time_from_sec(1) / 1000); otl_stream i(1, sqlstm, db); i.flush(); i.close(); db.commit(); printf(">>>当前写数据库Sql= %s\n", sqlstm); } catch (otl_exception& e) { if (e.code != 1) { printf("写数据库失败,code= %d,msg= %s,Sql= %s\n", e.code, e.msg, sqlstm); OTLConnect(); } return e.code; } return 0; } void WebSocketThread::run() { //if (g_node_id != THREE_SECS_DATA_BASE_NODE_ID) // return; 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; } printf("\naccept client %s:%d succes,address_len= %d,client_socket= %d\n", inet_ntoa(client_sockaddr.sin_addr), htons(client_sockaddr.sin_port), address_len, client_socket); 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); //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; } } 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); } close(server_socket); return; } string MatchErrorMessage(int errorCode) //根据错误码匹配错误消息 { string strErrorMessage = ""; switch (errorCode) { case 0: strErrorMessage = "success"; //"成功" break; default: strErrorMessage = "error"; //"错误"; break; //case 10002: // strErrorMessage = "Incorrect message length structure"; //"报文长度结构错误"; // break; //case 10003: // strErrorMessage = "JSON string parsing error"; //"JSON字符串解析出错"; // break; //case 10004: // strErrorMessage = "Socket handling error"; //"socket处理出现异常"; // break; //case 10005: // strErrorMessage = "The device corresponding to ID was not found"; //"ID对应的装置未找到"; // break; //case 10006: // strErrorMessage = "The monitoring point corresponding to ID has not been found"; //"ID对应的监测点未找到"; // break; //case 10007: // strErrorMessage = "Wrong parameter passed in"; //"传入的参数异常"; // break; //case 10008: // strErrorMessage = "The same type of operation is being performed"; //"有同一类型的操作正在执行"; // break; //case 10009: // strErrorMessage = "The device turned off the corresponding function"; //"装置关闭了对应功能"; // break; //case 10010: // strErrorMessage = "The TYPE parameter passed in is exceptional"; //"传入的TYPE参数异常"; // break; //default: // strErrorMessage = "An unknown error"; //"未知错误"; // break; } return strErrorMessage; } int SendMessageToWeb(int socketClient, int iErrorCode) //向Web Socket客户端发送消息 { string strSendJson = ""; char cTemp[8]; string strErrorCode = ""; sprintf(cTemp, "%06d", iErrorCode); strErrorCode = cTemp; char sendBuffer[256]; int sendLength = 0; string strErrorMessage = MatchErrorMessage(iErrorCode); //if (2 == Log_Enable) // printf("错误码:%d,匹配到的消息:%s\n", iErrorCode, strErrorMessage.c_str()); 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; } //if (1 == Log_Enable) // printf("服务端向客户端%d发送[%d]消息:%s\n", socketClient, iErrorCode, sendBuffer); return sendLength; } int ExecuteWebCommand(LD_info_t* LD_info, int iType) //执行Web Socket命令消息 { try { //if (1 == Log_Enable) // printf(">>>线路%d,\"%s\",iType= %d,real_data= %s,soe_data= %s,limit= %d,count= %d\n", LD_info->line_id, LD_info->name, // iType, 0 == LD_info->real_data ? "False" : "True", 0 == LD_info->soe_data ? "False" : "True", 20, LD_info->count); if (0 == iType || 1 == iType) { LD_info->count = 0; if (0 == iType) { LD_info->real_data = 1; LD_info->soe_data = 1; //if (1 == Log_Enable) // printf(">>>触发%d,\"%s\",iType= %d,real_data= %s,soe_data= %s,limit= %d,count= %d\n", LD_info->line_id, LD_info->name, // 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) // printf(">>>持续%d,\"%s\",iType= %d,real_data= %s,soe_data= %s,limit= %d,count= %d\n", LD_info->line_id, LD_info->name, // iType, 0 == LD_info->real_data ? "False" : "True", 0 == LD_info->soe_data ? "False" : "True", 20, LD_info->count); } } if (2 == iType) { LD_info->real_data = 0; LD_info->soe_data = 0; //if (1 == Log_Enable) // printf(">>>停止%d,\"%s\",iType= %d,real_data= %s,soe_data= %s,limit= %d,count= %d\n", LD_info->line_id, LD_info->name, // iType, 0 == LD_info->real_data ? "False" : "True", 0 == LD_info->soe_data ? "False" : "True", 20, LD_info->count); } } catch (exception& e) { printf("触发/停止线路%d,\"%s\"失败,原因:%s\n", LD_info->line_id, LD_info->name, e.what()); return 10004; } return 10000; } void Get_Recall_Time_Char(char* start_time, char* end_time, QList& recallinfo_list_hour) //数据完整性补招判断 { 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"); long long starttime = start_dt.toMSecsSinceEpoch() / 1000; //补招起始时间 long long endtime = end_dt.toMSecsSinceEpoch() / 1000; //补招结束时间 QList timestamp_list; //数据库完整性记录时间点 QList recallinfo_list; //待补招队列 //QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 RecallInfo info; info.starttime = starttime; info.endtime = endtime; recallinfo_list.append(info); 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; RecallInfo info; info.starttime = start; info.endtime = end; recallinfo_list_hour.append(info); } else { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].starttime + j + max_interval; RecallInfo info; info.starttime = start; info.endtime = end - 1; recallinfo_list_hour.append(info); } } } } int HandleReceiveMessage(int socketClient, char buffer[256]) //接收并处理Web Socket客户端发来的信息 { int iErrorCode = 000000; try { QString qstrBuffer = QString(QLatin1String(buffer)); printf("来自ffe客户端%d消息:qstrBur= %s\n", socketClient, qstrBuffer.toAscii().data()); cJSON* json_root = cJSON_Parse(qstrBuffer.toUtf8().constData()); //json格式序列化 if (json_root == NULL) { return 10000; } QString qstrCode = NULL;//记录指令 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; QString update_time; QList wave_param; ProgramParam program_param; json_code = cJSON_GetObjectItem(json_root, "code"); //获取code if (json_code != NULL) { qstrCode = json_code->valuestring; } else { return 10000; } json_param = cJSON_GetObjectItem(json_root, "param"); //获取param if (json_param == NULL) { return 10000; } if (qstrCode == "dev_update" || qstrCode == "model_update" || qstrCode == "program_update") { //设备更新记录更新时间 json_update_time = cJSON_GetObjectItem(json_param, "update_time"); //获取update_time if (json_update_time != NULL) { update_time = json_update_time->valuestring; } } else if (qstrCode == "manual_wave") { //手动录波:功能未完成 json_wave_param = cJSON_GetObjectItem(json_param, "wave_param"); //获取wave_param int array_size = cJSON_GetArraySize(json_wave_param); //获取数组大小 int i; 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); } } } else if (qstrCode == "model_update") { //程序参数:终端列表和程序文件 json_program_param = cJSON_GetObjectItem(json_param, "program_param"); //获取program_param cJSON* json_temp = NULL; json_temp = cJSON_GetObjectItem(json_program_param, "terminal_list"); //获取 int array_size = cJSON_GetArraySize(json_temp); //获取数组大小 int i; for (i = 0; i < array_size; i++) { json_node = cJSON_GetArrayItem(json_temp, i);//array if (json_node != NULL) { program_param.terminal_list.append(json_node->valuestring); } } json_node = cJSON_GetObjectItem(json_program_param, "file_name"); //获取file_name if (json_node != NULL) { program_param.file_name = json_node->valuestring; } } else if (qstrCode == "manual_recall") {//手动补招的指令 //补招参数 json_recall_param = cJSON_GetObjectItem(json_param, "recall_param"); //获取recall_param cJSON* json_temp = NULL; int array_size = cJSON_GetArraySize(json_recall_param); //获取数组大小 int i; QList recallinfo_list_hour; char start_time[64]; char end_time[64]; QString mp_id; for (i = 0; i < array_size; i++) { json_temp = cJSON_GetArrayItem(json_recall_param, i);//array if (json_temp != NULL) { json_node = cJSON_GetObjectItem(json_temp, "mp_id"); //获取mp_id if (json_node != NULL) { mp_id = QString::fromUtf8(json_node->valuestring); } if (i == 0) { json_node = cJSON_GetObjectItem(json_temp, "start"); //获取start if (json_node != NULL) { apr_snprintf(start_time, sizeof(start_time), "%s", json_node->valuestring);//start_time } json_node = cJSON_GetObjectItem(json_temp, "end"); //获取end 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"); jr.STEADY = QString::number(1, 10);//默认都是1,1的十进制转化 jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } } cJSON_Delete(json_root); SendMessageToWeb(socketClient, 000000);//响应web } catch (exception& e) { printf("处理客户端:%d发送的消息错误,原因:%s\n", socketClient, e.what()); return 10004; } return 000000; } //// 判断时间差是否超过十分钟 //bool IsTimeDifferenceGreaterThanTenMinutes(apr_time_t time1, apr_time_t time2) { // // 计算时间差 // apr_int64_t timeDiff = apr_time_diff(time1, time2); // // // 转换为分钟 // apr_int64_t minutes = apr_time_sec(timeDiff) / 60; // // // 判断时间差是否大于十分钟 // return (minutes > 10); //} void Get_Recall_Time(char* time, QList& recallinfo_list_hour); void Cout_account_information() { ied_t* ied = NULL; int iedno; LD_info_t* LD_info = NULL; 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; QString text;//待组装的pgsql语句 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(text.toLocal8Bit().constData())); for (cpuno = 0; cpuno < ied->cpucount; cpuno++) { LD_info = &(ied_usr->LD_info[cpuno]); QString text2;//待组装的pgsql语句 text2.append(QString("mp_id: \"%1\" terminal_code:\"%2\" ").arg(LD_info->mp_id).arg(LD_info->terminal_code)); add_comm_log(const_cast(text2.toLocal8Bit().constData())); } } } } //将时间戳转qstring QString timestampToYYYYMMDD(long long timestamp) { // 将long long时间戳转换为QDateTime QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(timestamp * 1000); // 提取日期部分,并格式化为YYYYMMDD // 格式化QDateTime对象为QString,精确到小时 QString formattedDateTime = dateTime.toString("yyyyMMddHH"); return formattedDateTime; } bool containsDash(const char* str, size_t len) { for (size_t i = 0; i < len; ++i) { if (str[i] == '-') { return true; // 找到'-'字符,返回true } } return false; // 没有找到'-'字符,返回false } bool CheckPG_To_Recall(long long start, long long end, char* Monitorid) { QDateTime deltime_Qtime = QDateTime::fromTime_t(start); QDateTime deltime_Qtime_end = QDateTime::fromTime_t(end); QString tmp_chr1 = deltime_Qtime.toString("yyyy-MM-dd"); //当前天 QString start_chr1 = deltime_Qtime.toString("yyyy-MM-dd hh:mm:ss"); //当前天 QString end_chr1 = deltime_Qtime_end.toString("yyyy-MM-dd hh:mm:ss"); //当前天 int timespan = 3;//默认时间间隔 try { int rtState = OTLDbconnected(); //int rtState = db.connected; if (rtState == 0) { int ret = OTLConnect(); } //printf("\nPostgreSL 1 %s \n", POSTGRES_SCHEMA); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "select \"exp_num\",\"act_num\" from \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_measpoint_intact_tr\" "); str1.append("WHERE \"statistical_date\" = '"); str1.append(tmp_chr1.toAscii().data()); str1.append("' AND \"monitor_id\" = '"); str1.append(Monitorid); str1.append("'"); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); double exp_num; double act_num; while (!i.eof()) { //while not end-of-data i >> exp_num >> act_num; timespan = 1440 / exp_num; printf("\n %f %f %d \n", exp_num, act_num, timespan); } //OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } try { long long starttime = start; //补招起始时间 long long endtime = starttime + 3599; //补招结束时间 QList timestamp_list; //数据库完整性记录时间点 QList recallinfo_list; //待补招队列 QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 int rtState = OTLDbconnected(); //int rtState = db.connected; if (rtState == 0) { int ret = OTLConnect(); } /*OTLConnect();*/ std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "SELECT unnest(value_time) AS timestamp_value FROM \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_measpoint_intact_tr\" "); str1.append("WHERE \"statistical_date\" = '"); str1.append(tmp_chr1.toAscii().data()); str1.append("' AND \"monitor_id\" = '"); str1.append(Monitorid); str1.append("' ORDER BY timestamp_value"); std::string str4 = "select b1.timestamp_value from ("; str4.append(str1); str4.append(") b1 where b1.timestamp_value >= '"); str4.append(start_chr1.toAscii().data()); str4.append("' and b1.timestamp_value <= '"); str4.append(end_chr1.toAscii().data()); str4.append("'"); otl_stream i(1, // buffer size str4.c_str(), //SELECT statement db //connect object ); otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> timestamp; struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 timeinfo.tm_mday = timestamp.day; timeinfo.tm_hour = timestamp.hour; timeinfo.tm_min = timestamp.minute; timeinfo.tm_sec = timestamp.second; time_t timestamp = std::mktime(&timeinfo); long long stamp = static_cast(timestamp); timestamp_list.append(stamp); } //OTLDisconnect(); if (timestamp_list.size() <= (60 / timespan) * 0.97) //完整性数据表无数据 { printf("\n return ture %d %f\n", timestamp_list.size(), (60 / timespan) * 0.97); return true; } else { printf("\n return false %d %f\n", timestamp_list.size(), (60 / timespan) * 0.97); return false; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } printf("\n>>>error quit!!\n"); return true; } //2024-10-21 lnk定时任务替换web接口 #if 0 void OnTimerThread::run() { msleep(10000); printf("OnTimerThread::run() is called ...... \n"); static int delectflag = 1;//定时日志清理标记 bool account_update = true; bool asd = true; 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; QMap dic_task_block; // 向QMap中添加键值对 dic_task_block.insert("account", false); dic_task_block.insert("recruit ", false); dic_task_block.insert("log", false); dic_task_block.insert("multi_node", false); int ip_count = 0; int telnet_count = 0; // 查找键值对 if (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) { init_ping_telnet(ip_count, telnet_count); Cout_account_information(); } if (g_onlyIP[0] != 0) { printf("g_onlyIP[0]=!0 ontimer--%s--\n", g_onlyIP); add_comm_log(const_cast("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; int recall_flag1 = 1; //char recalllllll[256] = "0923000982"; //CheckPG_To_Recall(1705168800, 1705168800 + 3599, recalllllll); while (1) { /*cout << "ip_count:" << ip_count << " telnet_count:" << telnet_count << endl; msleep(1000);*/ //进入线程时间 previousTime = apr_time_now(); apr_time_exp_gmt(&localTime, previousTime); //apr_time_t elapsedTime = currentTime - previousTime; //apr_time_as_msec(elapsedTime); //cout << "front num:" << FRONT_MP_NUM << endl; if (strcmp(subdir, "cfg_stat_data") == 0 || strcmp(subdir, "cfg_newhis_data") == 0) {//台账更新,多节点,通讯 //读取上次台账更新时间 //判断间隔执行 if (false) { //执行台账任务; } //记录现在时间 // //判断执行此任务时间段内是否有 任务被堵塞 if (MULTIPLE_NODE_FLAG && pgflag) { if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { QString updateFrontSql;//待组装的pgsql语句 updateFrontSql.append(QString("update \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("set \"mp_num\"= %1,front_version='%2' ").arg(FRONT_MP_NUM).arg(PROGRAM_VERSION)); updateFrontSql.append(QString("where \"front_ip\" = '%1' and \"front_inst\"=%2;").arg(FRONT_IP).arg(FRONT_INST)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(updateFrontSql); Sql_data_list_mutex.unlock(); //解锁 } pgflag = 0; } else if (MULTIPLE_NODE_FLAG && pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } if (mp_num_hour != localTime.tm_hour) { std::string mp_num_str = ""; mp_num_str.append("connected device count:"); mp_num_str.append(QString::number(FRONT_MP_NUM).toStdString()); mp_num_str.append(",g_node clients:"); mp_num_str.append(QString::number(g_node->n_clients).toStdString()); add_comm_log(const_cast(mp_num_str.c_str())); mp_num_hour = localTime.tm_hour; } //2023-10-17 zw新增 定期obs oss和sql数据库记录删除 if (delectflag == 1 && localTime.tm_hour == 16) { delectflag = 0; //time_t timestamp = apr_time_as_time_t(previousTime); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; if (FILE_FLAG == 1) //阿里云 oss 文件删除 { //PutOSS("comtrade/not def/20231111/temp2.log", "/FeProject/dat/9D3AAA2BDCE430BA7E3E1302F132B880.xml"); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); long long deltime = stamp - (60 * 60 * 24 * 30);//减去30天 QDateTime deltime_Qtime = QDateTime::fromTime_t(deltime); QString tmp_chr1 = deltime_Qtime.toString("yyyyMMdd"); QString Oss_Del_Path = NULL; Oss_Del_Path.append("comtrade/"); Oss_Del_Path.append(LD_info->mp_id).append("/"); Oss_Del_Path.append(tmp_chr1).append("/"); //cout << Oss_Del_Path.toAscii().data() << endl; DelOSS(Oss_Del_Path.toAscii().data()); cpuno++; } i++; } //PutOSS("comtrade/not def/20231111/temp.log","/FeProject/dat/6A5C8A2A7BBC1A61D9EC3F1AE2A25A03.xml"); //PutOSS("comtrade/not def/20231111/temp2.log", "/FeProject/dat/6A5C8A2A7BBC1A61D9EC3F1AE2A25A03.xml"); //PutOSS("comtrade/not def/20231111/temp3.log", "/FeProject/dat/6A5C8A2A7BBC1A61D9EC3F1AE2A25A03.xml"); //DelOSS("comtrade/not def/20231111/temp3.log"); } else if (FILE_FLAG == 2)//华为云 obs 文件删除 { //OBSFile("/FeProject/dat/67BC249C13B5EC819CF4DF0307DB71C5.xml", "comtrade/not def/20231111/temp3.log", "putObject"); //OBSFile_del("comtrade/not def/20231111/temp3.log", "deleteObject"); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); long long deltime = stamp - (60 * 60 * 24 * 30);//减去30天 QDateTime deltime_Qtime = QDateTime::fromTime_t(deltime); QString tmp_chr1 = deltime_Qtime.toString("yyyyMMdd"); QString Oss_Del_Path = NULL; Oss_Del_Path.append("comtrade/"); Oss_Del_Path.append(LD_info->mp_id).append("/"); Oss_Del_Path.append(tmp_chr1).append("/"); //cout << Oss_Del_Path.toAscii().data() << endl; OBSFile_del(Oss_Del_Path.toAscii().data(), "deleteObject"); cpuno++; } i++; } } //pgsql删除记录 long long deltime = stamp - (60 * 60 * 24 * 30);//减去30天 QDateTime deltime_Qtime = QDateTime::fromTime_t(deltime); QString tmp_chr1 = deltime_Qtime.toString("yyyy-MM-dd"); QString pgsql0; pgsql0.append(QString("DELETE FROM \"%1\".\"%2meas_pq_comm_status_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql1; pgsql1.append(QString("DELETE FROM \"%1\".\"%2meas_pq_comm_error_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql2; pgsql2.append(QString("DELETE FROM \"%1\".\"%2meas_pq_measpoint_rationality_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql3; pgsql3.append(QString("DELETE FROM \"%1\".\"%2meas_pq_measpoint_intact_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql4; pgsql4.append(QString("DELETE FROM \"%1\".\"%2meas_pq_measpoint_match_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql0); Sql_data_list.append(pgsql1); Sql_data_list.append(pgsql2); Sql_data_list.append(pgsql3); Sql_data_list.append(pgsql4); Sql_data_list_mutex.unlock(); //解锁 } if (delectflag == 0 && localTime.tm_hour != 16) { delectflag = 1; } //2023-10-17 zw新增 定期obs oss和sql数据库记录删除 end } if (strcmp(subdir, "cfg_newhis_data") == 0) {//上海定时招装置日志 static int hour_time = 0; if (localTime.tm_hour != hour_time) { hour_time = localTime.tm_hour; printf(">>>cfg_newhis_data is run!!!\n"); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; long long start = stamp - (stamp % 3600) - 3600 - 3600;//开始时间 当前整点值往前推两小时 long long end = start + 3599;//结束时间 QList recallinfo_list_hour; RecallInfo info; info.starttime = start - 10; info.endtime = end; recallinfo_list_hour.append(info); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) { while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; if (LD_info->logcount <= 0 || LD_info->read_flag == 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { for (int j = 0; j < recallinfo_list_hour.size(); j++) { CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } i++; } } } if (strcmp(subdir, "cfg_recallall_data") == 0) { static int recall_xml_time = 0; if (localTime.tm_min != recall_xml_time) { recall_xml_time = localTime.tm_min; //补招开始与截止时间 static long long recall_start_time = 0; static long long recall_end_time = 0; static int flag = 0; if (recall_start_time == 0 && recall_end_time == 0) {//无缓存数据 //查询一条 -1状态(代补招)的记录 char front_ip[42]; cout << "start select:" << endl; QString selectFrontSql; selectFrontSql.append(QString("select \"front_ip\" from \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); selectFrontSql.append(QString("where front_inst=%1 and \"front_status\" = '-1' LIMIT 1;").arg(g_front_seg_index)); cout << selectFrontSql.toStdString().c_str() << endl; try { otl_stream i(1, // buffer size selectFrontSql.toStdString().c_str(), db //connect object ); //create select stream while (!i.eof()) { //while not end-of-data i >> front_ip; break; //cout << "count=" << f2 << endl; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); continue; } if (containsDash(front_ip, 21)) { //插入更新记录 QString insertFrontSql; insertFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); insertFrontSql.append(QString("values('%1',10000,%2,'03','-1','%3',200) ").arg(front_ip).arg(g_front_seg_index).arg(PROGRAM_VERSION)); insertFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); insertFrontSql.append(QString("\"front_status\"= '%1'").arg("-2")); cout << insertFrontSql.toStdString().c_str() << endl; Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(insertFrontSql); Sql_data_list_mutex.unlock(); //解锁 //缓存数据 cout << "front_ip=" << front_ip << endl; QString startDate, endDate; // 分割字符串 startDate = QString::fromAscii(front_ip).left(10); // 取前10个字符作为开始日期 qDebug() << "startDate=" << startDate << endl; endDate = QString::fromAscii(front_ip + 11).left(10); // 从第10个字符开始取8个字符作为结束日期 qDebug() << "endDate=" << endDate << endl; QDateTime start_dt = QDateTime::fromString(startDate, "yyyyMMddHH"); qDebug() << "start_dt=" << start_dt << endl; recall_start_time = start_dt.toMSecsSinceEpoch() / 1000; qDebug() << "recall_start_time=" << recall_start_time << endl; QDateTime end_dt = QDateTime::fromString(endDate, "yyyyMMddHH"); qDebug() << "end_dt=" << end_dt << endl; recall_end_time = end_dt.toMSecsSinceEpoch() / 1000; qDebug() << "recall_end_time=" << recall_end_time << endl; } flag = 0; } else if (recall_start_time != 0 && recall_end_time != 0) {//有缓存数据 // 将时间戳转换为YYYYMMDD格式 QString date1 = timestampToYYYYMMDD(recall_start_time); QString date2 = timestampToYYYYMMDD(recall_end_time); // 拼接两个日期,并用'-'分隔 QString dateRange = date1 + "-" + date2; qDebug() << "dateRange=" << dateRange << endl; char front_status[4]; QString selectFrontSql; selectFrontSql.append(QString("select front_status from \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); selectFrontSql.append(QString("where front_inst=%1 and \"front_ip\" = '%2'").arg(g_front_seg_index).arg(dateRange)); cout << selectFrontSql.toStdString().c_str() << endl; try { otl_stream i(1, // buffer size selectFrontSql.toStdString().c_str(), db //connect object ); //create select stream while (!i.eof()) { //while not end-of-data i >> front_status; break; //cout << "count=" << f2 << endl; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); continue; } qDebug() << "front_status=" << front_status << endl; //再次判断是否为执行中状态 if (strcmp(front_status, "-1") == 0) { //状态为-1 重新插入更新记录 QString updateFrontSql; updateFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("values('%1',10000,%2,'03','-1','%3',200) ").arg(dateRange).arg(g_front_seg_index).arg(PROGRAM_VERSION)); updateFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); updateFrontSql.append(QString("\"front_status\"= '%1'").arg("-2")); cout << updateFrontSql.toStdString().c_str() << endl; Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(updateFrontSql); Sql_data_list_mutex.unlock(); //解锁 flag = 0; } else if (strcmp(front_status, "-2") == 0) {//状态为-2 补招 flag = 1; } else { flag = 0; recall_end_time = 0; recall_start_time = 0; } } if (recall_start_time != 0 && recall_end_time != 0 && flag == 1) { qDebug() << "start recall time=" << recall_start_time << endl; qDebug() << "end recall time=" << recall_end_time << endl; long long starttime = recall_start_time; //补招起始时间 long long endtime = recall_end_time; //补招结束时间 flag = 0; recall_start_time = 0; recall_end_time = 0; QList recallinfo_list; //待补招队列 QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 RecallInfo info; info.starttime = starttime; info.endtime = endtime; recallinfo_list.append(info); 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; RecallInfo info; info.starttime = start; info.endtime = end; recallinfo_list_hour.append(info); } else { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].starttime + j + max_interval; RecallInfo info; info.starttime = start; info.endtime = end - 1; recallinfo_list_hour.append(info); } } } int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; printf("/home/pq mpid=%s %d\n", LD_info->mp_id, LD_info->read_flag); if (LD_info->logcount <= 0 || LD_info->read_flag == 0) { continue; } printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { g_StatisticLackList_list_mutex.lock(); for (int j = 0; j < recallinfo_list_hour.size(); j++) { //替换成web接口 2024-10-21 lnk // if (CheckPG_To_Recall(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { // printf("CheckPG_To_Recall == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); if (CheckPG_To_Recall_web(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { printf("CheckPG_To_Recall_web == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); continue; } CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList.push_back(jr); } g_StatisticLackList_list_mutex.unlock(); } } i++; } } } } if (strcmp(subdir, "cfg_his_data") == 0) { if (pgflag) { if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { QString updateFrontSql; updateFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("values('his',10000,1,'02','01','%1',200) ").arg(PROGRAM_VERSION)); updateFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); updateFrontSql.append(QString("\"mp_num\"= '%1',front_version='%2'").arg(FRONT_MP_NUM).arg(PROGRAM_VERSION)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(updateFrontSql); Sql_data_list_mutex.unlock(); //解锁 } pgflag = 0; } else if (pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } static int cfg_his_data_hour_time = 0; if (localTime.tm_hour != cfg_his_data_hour_time) { cfg_his_data_hour_time = localTime.tm_hour; printf(">>>cfg_his_data is run!!!\n"); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; long long start = stamp - (stamp % 3600) - 3600 - 3600;//开始时间 当前整点值往前推两小时 long long end = start + 3599;//结束时间 QList recallinfo_list_hour; RecallInfo info; info.starttime = start - 10; info.endtime = end; recallinfo_list_hour.append(info); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) { while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; if (LD_info->logcount <= 0 || LD_info->read_flag == 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { for (int j = 0; j < recallinfo_list_hour.size(); j++) { //替换成web接口 2024-10-21 lnk //if (CheckPG_To_Recall(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { //printf("CheckPG_To_Recall == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); if (CheckPG_To_Recall_web(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { printf("CheckPG_To_Recall_web == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); continue; } CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } i++; } } } if (strcmp(subdir, "cfg_recallhis_data") == 0) { if (pgflag) { if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { QString updateFrontSql; updateFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("values('recallhis',10000,1,'02','01','%1',200) ").arg(PROGRAM_VERSION)); updateFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); updateFrontSql.append(QString("\"mp_num\"= '%1',front_version='%2'").arg(FRONT_MP_NUM).arg(PROGRAM_VERSION)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(updateFrontSql); Sql_data_list_mutex.unlock(); //解锁 } pgflag = 0; } else if (pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } } //g_node_id == HIS_DATA_BASE_NODE_ID && //printf("/home/pq hour=%d\n", localTime.tm_hour); if (0 && g_node_id == HIS_DATA_BASE_NODE_ID && (localTime.tm_hour <= 12 || localTime.tm_hour >= 20) && recall_flag1 == 1) { recall_flag1 = 0; QString MyKafkaIniFilename = QString("../etc/") + QString("mykafka.ini"); //+QString::fromAscii(subdir) QSettings settings(MyKafkaIniFilename, QSettings::IniFormat); QString dateString = settings.value("Recall/select_day").toString(); QList recallinfo_list_hour; QByteArray byteArray = dateString.toUtf8(); // 使用 UTF-8 编码 char* charArray = byteArray.data(); Get_Recall_Time(charArray, recallinfo_list_hour); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); if (LD_info->logcount <= 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 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->autorecallflag = 0; LD_info->autorecallcount = recallinfo_list_hour.size(); LD_info->autorecall = new autorecall_t * [recallinfo_list_hour.size()]; printf("/home/pq recall mpid=%s\n", LD_info->mp_id); for (int j = 0; j < recallinfo_list_hour.size(); j++) { printf("\n %lld ===== %11d\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime); LD_info->autorecall[j] = new autorecall_t[1]; LD_info->autorecall[j]->start = recallinfo_list_hour[j].starttime; LD_info->autorecall[j]->end = recallinfo_list_hour[j].endtime; } } cpuno++; } i++; } QDate date = QDate::fromString(dateString, "yyyy-MM-dd"); date.addDays(-1); // 一天 settings.setValue("Recall/select_day", date.toString("yyyy-MM-dd")); // 重新写入日期字符串 } if (localTime.tm_hour > 12 && localTime.tm_hour < 20 && recall_flag1 == 0) { recall_flag1 = 1; } msleep(1000); } printf(">>>OnTimerThread::run() is end!!!\n"); } #endif //不使用的代码lnk20241206 #if 0 /////////////////////////////////////////CZY 2023-09-04 /// /// 拼接请求入参json /// /// /// /// /// /// /// /// 是否删选青浦地市 void AppendCJson(cJSON* json_roots, cJSON* json_root, cJSON* json_params, cJSON* json_filters, int perpage, int page, int flag) { //[]层 //cJSON_AddItemToArray(json_roots, json_root); //第一层 cJSON_AddItemToObject(json_root, "distribution", cJSON_CreateString("1")); cJSON_AddItemToObject(json_root, "id", cJSON_CreateString("")); cJSON_AddItemToObject(json_root, "modelId", cJSON_CreateString("")); cJSON_AddItemToObject(json_root, "params", json_params); cJSON_AddItemToObject(json_root, "psrType", cJSON_CreateString("0751002")); //params层 cJSON_AddItemToObject(json_params, "current", cJSON_CreateNumber(1)); cJSON_AddItemToObject(json_params, "fields", cJSON_CreateString("astId")); cJSON_AddItemToObject(json_params, "filters", json_filters); cJSON_AddItemToObject(json_params, "orderBy", cJSON_CreateString("astId desc")); cJSON_AddItemToObject(json_params, "page", cJSON_CreateNumber(page)); cJSON_AddItemToObject(json_params, "perpage", cJSON_CreateNumber(perpage)); cJSON_AddItemToObject(json_params, "size", cJSON_CreateNumber(1)); //filters数组层 cJSON* json_filter = cJSON_CreateObject(); cJSON_AddItemToArray(json_filters, json_filter); //filter层 cJSON_AddItemToObject(json_filter, "compare", cJSON_CreateString("=")); cJSON_AddItemToObject(json_filter, "fieldName", cJSON_CreateString("deployState")); cJSON_AddItemToObject(json_filter, "fieldValue", cJSON_CreateString("20")); if (g_onlyIP[0] != 0) {//单连 //filters数组层 cJSON* json_filter_ip = cJSON_CreateObject(); cJSON_AddItemToArray(json_filters, json_filter_ip); //json_filter_ip层 cJSON_AddItemToObject(json_filter_ip, "compare", cJSON_CreateString("=")); cJSON_AddItemToObject(json_filter_ip, "fieldName", cJSON_CreateString("ipAddress")); cJSON_AddItemToObject(json_filter_ip, "fieldValue", cJSON_CreateString(g_onlyIP)); } if (flag == 1) { //filters数组层 cJSON* json_filter_city = cJSON_CreateObject(); cJSON_AddItemToArray(json_filters, json_filter_city); //json_filter_city层 cJSON_AddItemToObject(json_filter_city, "compare", cJSON_CreateString("=")); cJSON_AddItemToObject(json_filter_city, "fieldName", cJSON_CreateString("city")); cJSON_AddItemToObject(json_filter_city, "fieldValue", cJSON_CreateString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFSP09")); } else if (flag == 2) { //json_filter_city数组层 cJSON* json_filter_city = cJSON_CreateObject(); cJSON_AddItemToArray(json_filters, json_filter_city); //json_filter_city层 cJSON_AddItemToObject(json_filter_city, "compare", cJSON_CreateString("!=")); cJSON_AddItemToObject(json_filter_city, "fieldName", cJSON_CreateString("city")); cJSON_AddItemToObject(json_filter_city, "fieldValue", cJSON_CreateString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFSP09")); } } void GetCJson(const char* ptr) { //cout << ">>>GetDevice in reply" << (char*)ptr; strDevCJson = ""; cJSON* json = cJSON_Parse((char*)ptr); //json格式序列化 cJSON* json_node; if (json == NULL) { printf("cJSON pares error %s\n", cJSON_GetErrorPtr()); } else { json_node = cJSON_GetObjectItem(json, "status"); //获取result if (json_node == NULL || json_node->valuestring == NULL || json_node->valuestring == "/0" || json_node->valuestring == "" || strcmp(json_node->valuestring, "000000") != 0) { printf("status error %s\n", cJSON_GetErrorPtr()); } else { cout << ">>>create strDevCJson success"; strDevCJson = QString::fromUtf8((char*)ptr); } } cJSON_Delete(json); } ////////////////////////////////// ////////////////////////////////////////////WW 2023-08-19 end ////////////////////////////////////////// //WW 2023-08-26 增加webap调用 流程上先获取token,然后用token调用API //http://172.40.237.145:30010/psr-auth/oauth/accessToken //鉴权信息: //client_id : 2a78ecf0074111ed806c7a5cabbedfb4 // client_secret : 58nOklQlP0SGEuXbrd0wgcVO7HX7IODAgvzHiCm + mAgWSadcX0we2wffjyTUYGsK // grant_type : credentials //get请求和post请求数据响应函数 size_t req_reply(void* ptr, size_t size, size_t nmemb, void* stream) { //在注释的里面可以打印请求流,cookie的信息 string* str = (string*)stream; (*str).append((char*)ptr, size * nmemb); return size * nmemb; } //get请求和post请求数据响应函数 void req_reply_token(const char* ptr) { //在注释的里面可以打印请求流,cookie的信息 printf(">>>GetToken in reply %s\n", ptr); cJSON* msg = cJSON_Parse(ptr); if (msg == NULL) { printf("cJSON pares error %s\n", cJSON_GetErrorPtr()); } else { cJSON* json_status = cJSON_GetObjectItem(msg, "status"); cJSON* json_error = cJSON_GetObjectItem(msg, "error"); if (json_error == NULL) { cJSON* json_result = cJSON_GetObjectItem(msg, "result"); cJSON* json_accesstoken = cJSON_GetObjectItem(msg, "access_token"); strToken = QString::fromAscii(json_accesstoken->valuestring); } cJSON_Delete(msg); } } void GetToken(const string strUrl, const string strclientid, const string strclientsecret)//获取Token { // curl初始化 CURL* curl = curl_easy_init(); // curl返回值 CURLcode res; if (curl) { // set params //设置curl的请求头 struct curl_slist* header_list = NULL; header_list = curl_slist_append(header_list, "Content-Type:application/x-www-form-urlencoded;"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); //不接收响应头数据0代表不接收 1代表接收 curl_easy_setopt(curl, CURLOPT_HEADER, 0); //设置请求为post请求 //curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_POST, 1); //设置请求的URL地址 curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); printf("token_url2: %s\n", strUrl.c_str()); //设置post请求的参数 char* pszEncodeAuth = curl_easy_escape(curl, strclientid.c_str(), strclientid.length()); char* pszEncodeSecret = curl_easy_escape(curl, strclientsecret.c_str(), strclientsecret.length()); string strTempBody; strTempBody.append("client_id="); strTempBody.append(pszEncodeAuth); strTempBody.append("&"); strTempBody.append("client_secret="); strTempBody.append(pszEncodeSecret); strTempBody.append("&grant_type="); strTempBody.append(GRANT_TYPE); printf(">>>TestTokenPost in curl %s \n", strTempBody.c_str()); curl_free(pszEncodeAuth); curl_free(pszEncodeSecret); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strTempBody.c_str()); //设置ssl验证 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); //CURLOPT_VERBOSE的值为1时,会显示详细的调试信息 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); //设置数据接收和写入函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply); string resPost0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); //curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)strBody.toAscii().data()); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //设置超时时间 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); printf(">>>Token Post in curl post\n"); // 开启post请求 res = curl_easy_perform(curl); // 检查请求是否成功 if (res != CURLE_OK) { cout << "token curl_easy_perform() failed res code: " << res << endl; } else { cout << ">>>token curl post success res code:" << res << endl; req_reply_token(resPost0.c_str()); } curl_slist_free_all(header_list); } else { printf(">>> token curl init failed"); } curl_easy_cleanup(curl); } void GetDevice(const QString strUrl, const QString strxToken, int perpage, int page, int flag) { // curl初始化 CURL* curl = curl_easy_init(); // curl返回值 CURLcode res; if (curl) { //QDateTime askTime = QDateTime::currentDateTime(); //long lTim = askTime.toMSecsSinceEpoch(); //printf(">>>TestDevicePost in curl %ld\n", lTim); //QString xTime; //xTime.append(QString("x-date:%l").arg(lTim)); printf(">>>token %s \n", strxToken.toAscii().data()); // set params //设置curl的请求头 struct curl_slist* header_list = NULL; header_list = curl_slist_append(header_list, "Content-Type:application/json;"); header_list = curl_slist_append(header_list, strxToken.toAscii().data()); //header_list = curl_slist_append(header_list, xTime.toAscii().data()); //header_list = curl_slist_append(header_list, "x-signature:1234"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); //不接收响应头数据0代表不接收 1代表接收 curl_easy_setopt(curl, CURLOPT_HEADER, 0); //设置请求为post请求 curl_easy_setopt(curl, CURLOPT_POST, 1); //设置请求的URL地址 curl_easy_setopt(curl, CURLOPT_URL, strUrl.toAscii().data()); //设置post请求的参数 cJSON* json_roots = cJSON_CreateArray(); cJSON* json_root = cJSON_CreateObject(); cJSON* json_params = cJSON_CreateObject(); cJSON* json_filters = cJSON_CreateArray(); AppendCJson(json_roots, json_root, json_params, json_filters, perpage, page, flag); char* szjson = cJSON_Print(json_root); printf(">>>json %s\n", szjson); //string strjson = szjson; //char* pszEncodeSecret = curl_easy_escape(curl, strclientsecret.c_str(), strclientsecret.length()); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson); //设置ssl验证 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); //CURLOPT_VERBOSE的值为1时,会显示详细的调试信息 curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); //设置数据接收和写入函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply); string resPost0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //设置超时时间 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); printf(">>>Device Post in curl post\n"); // 开启post请求 res = curl_easy_perform(curl); // 检查请求是否成功 if (res != CURLE_OK) { cout << "device curl_easy_perform() failed res code: " << res << endl; } else { cout << ">>>dev curl post success res code:" << res << endl; GetCJson(resPost0.c_str()); } free(szjson); curl_slist_free_all(header_list); cJSON_Delete(json_roots); } else { printf(">>> token curl init failed"); } curl_easy_cleanup(curl); } void TestToken()//获取电网资源业务中台回复 { string client_id = "2a78ecf0074111ed806c7a5cabbedfb4";//client_id= string client_secret = "58nOklQlP0SGEuXbrd0wgcVO7HX7IODAgvzHiCm+mAgWSadcX0we2wffjyTUYGsK";//client_secret= string token_url = "http://172.40.237.145:30010/psr-auth/oauth/accessToken"; QString device_url = QString("http://172.40.237.145:30010/assetCenter/astQueryServices/listDeviceByFilters"); GetToken(token_url, client_id, client_secret);//获取token QString xtoken = QString("x-token:") + strToken; GetDevice(device_url, xtoken, 1, 1, 0);//获取台账 } void GetWebApiJson(int perpage, int page, int flag)//获取电网资源业务中台回复 { //string client_id = "2a78ecf0074111ed806c7a5cabbedfb4";//client_id= //string client_secret = "58nOklQlP0SGEuXbrd0wgcVO7HX7IODAgvzHiCm+mAgWSadcX0we2wffjyTUYGsK";//client_secret= //string token_url = "http://172.40.237.145:30010/psr-auth/oauth/accessToken"; //QString device_url = QString("http://172.40.237.145:30010/assetCenter/astQueryServices/listDeviceByFilters"); string client_id = CLIENT_ID;//client_id= string client_secret = CLIENT_SECRET;//client_secret= string token_url = TOKEN_URL; QString device_url = QString(DEVICE_URL); /*cout << "client_id1: " << client_id << ",client_secret1: " << client_secret<<",token_url1: "<< token_url.c_str()<>>>>cJSON pares 1 %s \n", strJson.c_str()); cJSON* msg = cJSON_Parse(strJson.c_str()); if (msg == NULL) { printf("cJSON pares error %s\n", cJSON_GetErrorPtr()); } else { printf(">>>>>cJSON pares 3"); cJSON* json_status = cJSON_GetObjectItem(msg, "status"); cJSON* json_error = cJSON_GetObjectItem(msg, "error"); if (json_error == NULL) { printf(">>>>>cJSON pares 4"); cJSON* json_result = cJSON_GetObjectItem(msg, "result"); cJSON* json_accesstoken = cJSON_GetObjectItem(msg, "access_token"); printf(">>>>>cJSON pares 5"); QString strToken1 = QString::fromAscii(json_accesstoken->valuestring); cJSON_Delete(msg); printf(">>>>>cJSON pares 6 %s\n ", strToken1.toAscii().data()); } } } #endif #if 0//WW 2023-08-29测试代码s //get请求和post请求数据响应函数 size_t req_reply_test(void* ptr, size_t size, size_t nmemb, void* stream) { //在注释的里面可以打印请求流,cookie的信息 string* str = (string*)stream; (*str).append((char*)ptr, size * nmemb); return size * nmemb; } //http POST请求 CURLcode curl_post_req(const string& url, const string& postParams, string& response) { // curl初始化 CURL* curl = curl_easy_init(); // curl返回值 CURLcode res; if (curl) { printf(">>>TestSMSPost in curl \n"); // set params //设置curl的请求头 struct curl_slist* header_list = NULL; header_list = curl_slist_append(header_list, "Content-Type:application/json; charset=UTF-8"); header_list = curl_slist_append(header_list, "Authorization:Basic bmpjbnRlc3Q6bmpjbnBxcw=="); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); //不接收响应头数据0代表不接收 1代表接收 curl_easy_setopt(curl, CURLOPT_HEADER, 0); //设置请求为post请求 curl_easy_setopt(curl, CURLOPT_POST, 1); //设置请求的URL地址 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); //设置post请求的参数 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postParams.c_str()); //设置ssl验证 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); //CURLOPT_VERBOSE的值为1时,会显示详细的调试信息 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); //设置数据接收和写入函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&response); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //设置超时时间 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 6); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6); printf(">>>TestSMSPost in curl post\n"); // 开启post请求 res = curl_easy_perform(curl); curl_slist_free_all(header_list); } //释放curl curl_easy_cleanup(curl); printf(">>>TestSMSPost in curl end\n"); return res; } void TestSMSPost()//WW 测试qt post { printf(">>>TestSMSPost Start \n"); string url_post0 = "http://192.168.1.13:10214/oauth/token"; string paramsLogin0 = "grant_type=sms_code&phone=13914774158&smsCode=123456"; string resPost0; CURLcode res3 = curl_post_req(url_post0, paramsLogin0, resPost0); printf(">>>TestSMSPost End %s\n", resPost0.c_str()); } CURLcode curl_post_body_req(const string& url, string& response) { // curl初始化 CURL* curl = curl_easy_init(); // curl返回值 CURLcode res; if (curl) { printf(">>>TestBodyPost in curl \n"); // set params //设置curl的请求头 struct curl_slist* header_list = NULL; header_list = curl_slist_append(header_list, "Content-Type:application/json;"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); //不接收响应头数据0代表不接收 1代表接收 curl_easy_setopt(curl, CURLOPT_HEADER, 0); //设置请求为post请求 curl_easy_setopt(curl, CURLOPT_POST, 1); //设置请求的URL地址 curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); //设置post请求的参数 cJSON* json_root = cJSON_CreateObject(); //第一层 cJSON_AddItemToObject(json_root, "sname", cJSON_CreateString("hongawen")); cJSON_AddItemToObject(json_root, "value", cJSON_CreateNumber(12.5)); char* szjson = cJSON_Print(json_root); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, szjson); //设置ssl验证 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); //CURLOPT_VERBOSE的值为1时,会显示详细的调试信息 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); //设置数据接收和写入函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply); string resPost0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //设置超时时间 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1); printf(">>>TestBodyPost in curl post\n"); // 开启post请求 res = curl_easy_perform(curl); free(szjson); cJSON_Delete(json_root); curl_slist_free_all(header_list); } else { printf(">>> token curl init failed"); } curl_easy_cleanup(curl); } void TestBodyPost()//WW 测试qt post { printf(">>>TestBodyPost Start \n"); string url_post0 = "http://192.168.1.111:8090/enhance/testBody"; string resPost0; CURLcode res3 = curl_post_body_req(url_post0, resPost0); printf(">>>TestBodyPost End %s\n", resPost0.c_str()); } #endif //WW 2023-08-26 增加webap调用 end ////////////////////////////////////////// ///////zw修改 2023-8-30 xml模型数据库读取 int OTL_Select_xmlModel() //xml模型数据库读取 { try { OTLConnect(); //printf("\nPostgreSL 1 %s \n", POSTGRES_SCHEMA); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "select \"model_id\",\"tmnl_type\",\"tmnl_factory\",\"file_name\",\"update_time\" from \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_icd_model_tr\" "); //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); char MODEL_ID[64]; char TMNL_TYPE[64]; char TMNL_FACTORY[64]; char FILE_NAME[128]; otl_datetime UPDATE_TIME; //printf("\nPostgreSL 2\n"); //create select stream while (!i.eof()) { //while not end-of-data //printf("\nPostgreSL 3\n"); i >> MODEL_ID >> TMNL_TYPE >> TMNL_FACTORY >> FILE_NAME >> UPDATE_TIME; //QString tempdate = QString("%1-%2-%3 %4:%5:%6").arg(UPDATE_TIME.year, 4, 10, QLatin1Char('0')).arg(UPDATE_TIME.month, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.day, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.hour, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.minute, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.second, 2, 10, QLatin1Char('0')); //QDateTime dt = QDateTime::fromString(tempdate, "yyyy-MM-dd hh:mm:ss"); Set_xml_databaseinfo(MODEL_ID, TMNL_TYPE, TMNL_FACTORY, FILE_NAME, UPDATE_TIME.year, UPDATE_TIME.month, UPDATE_TIME.day, UPDATE_TIME.hour, UPDATE_TIME.minute, UPDATE_TIME.second); //cout << "FRONT_IP=" << f2 << endl; } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } return 0; } int OTL_Select_DecideRecall(char* time, char* id)//判断是否需要补招 { int flag = 1; try { int rtState = OTLDbconnected(); //int rtState = db.connected; if (rtState == 0) { int ret = OTLConnect(); } //printf("\nPostgreSL 1 %s \n", POSTGRES_SCHEMA); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "select \"exp_num\",\"act_num\" from \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_measpoint_intact_tr\" "); str1.append("WHERE \"statistical_date\" = '"); str1.append(time); str1.append("' AND \"monitor_id\" = '"); str1.append(id); str1.append("'"); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); double exp_num; double act_num; while (!i.eof()) { //while not end-of-data i >> exp_num >> act_num; if (exp_num * 0.8 <= act_num) { flag = 0; } //printf("\n %f %f %f \n", exp_num, act_num, exp_num * 0.8); } //OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); flag = 0; } return flag; } void OTL_Select_recall(char* time, char* id) //数据完整性补招判断 { try { QDateTime dt = QDateTime::fromString(time, "yyyy-MM-dd"); long long starttime = dt.toMSecsSinceEpoch() / 1000; //补招起始时间 long long endtime = starttime + 86399; //补招结束时间 QList timestamp_list; //数据库完整性记录时间点 QList recallinfo_list; //待补招队列 QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 int rtState = OTLDbconnected(); //int rtState = db.connected; if (rtState == 0) { int ret = OTLConnect(); } /*OTLConnect();*/ std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "SELECT unnest(value_time) AS timestamp_value FROM \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_measpoint_intact_tr\" "); str1.append("WHERE \"statistical_date\" = '"); str1.append(time); str1.append("' AND \"monitor_id\" = '"); str1.append(id); str1.append("' ORDER BY timestamp_value"); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> timestamp; struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 timeinfo.tm_mday = timestamp.day; timeinfo.tm_hour = timestamp.hour; timeinfo.tm_min = timestamp.minute; timeinfo.tm_sec = timestamp.second; time_t timestamp = std::mktime(&timeinfo); long long stamp = static_cast(timestamp); timestamp_list.append(stamp); /*QDateTime dt = QDateTime::fromString(time, "yyyy-MM-dd"); long long timestamp2 = dt.toMSecsSinceEpoch() / 1000; printf("\n %lld \n", timestamp2);*/ /*QString tempdate = QString("%1-%2-%3 %4:%5:%6").arg(UPDATE_TIME.year, 4, 10, QLatin1Char('0')).arg(UPDATE_TIME.month, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.day, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.hour, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.minute, 2, 10, QLatin1Char('0')).arg(UPDATE_TIME.second, 2, 10, QLatin1Char('0')); printf("\n %s \n", tempdate.toAscii().data());*/ //QDateTime dt = QDateTime::fromString(tempdate, "yyyy-MM-dd hh:mm:ss"); } //OTLDisconnect(); if (timestamp_list.size() == 0) //完整性数据表无数据 { RecallInfo info; info.starttime = starttime; info.endtime = endtime; recallinfo_list.append(info); } else if (timestamp_list.size() == 1)//存在1条数据 { long long temptime = timestamp_list[0]; if (temptime != starttime && temptime != endtime) { RecallInfo info1; info1.starttime = starttime; info1.endtime = temptime - 1; RecallInfo info2; info2.starttime = temptime + 1; info2.endtime = endtime; recallinfo_list.append(info1); recallinfo_list.append(info2); } else { RecallInfo info; info.starttime = starttime + 1; info.endtime = endtime - 1; recallinfo_list.append(info); } } else //存在多条数据 { for (int i = 1; i < timestamp_list.size(); i++) { if (i == 1) { timestamp_list[0];//头数据 timestamp_list[timestamp_list.size() - 1];//尾数据 if (timestamp_list[0] - starttime > 600) { RecallInfo info; info.starttime = starttime + 1; info.endtime = timestamp_list[0] - 1; recallinfo_list.append(info); } if (endtime - timestamp_list[timestamp_list.size() - 1] > 600) { RecallInfo info; info.starttime = timestamp_list[timestamp_list.size() - 1] + 1; info.endtime = endtime - 1; recallinfo_list.append(info); } } long long temptime1 = timestamp_list[i - 1]; long long temptime2 = timestamp_list[i]; if (temptime2 - temptime1 > 600) { RecallInfo info; info.starttime = temptime1 + 1; info.endtime = temptime2 - 1; recallinfo_list.append(info); } } } 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; RecallInfo info; info.starttime = start - 10; info.endtime = end - 10; recallinfo_list_hour.append(info); } else { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].starttime + j + max_interval; RecallInfo info; info.starttime = start - 10; info.endtime = end - 10; recallinfo_list_hour.append(info); } } } LD_info_t* LD_info = find_LD_info_only_from_mp_id(id); if (LD_info == NULL || LD_info->read_flag == 0) { printf("\n Find LD_info == null \n"); } else { for (int j = 0; j < recallinfo_list_hour.size(); j++) { CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } //if (recallinfo_list_hour.size() != 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->autorecallflag = 0; // LD_info->autorecallcount = recallinfo_list_hour.size(); // LD_info->autorecall = new autorecall_t * [recallinfo_list_hour.size()]; // for (int j = 0; j < recallinfo_list_hour.size(); j++) { // //printf("\n %lld ===== %11d\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime); // LD_info->autorecall[j] = new autorecall_t[1]; // LD_info->autorecall[j]->start = recallinfo_list_hour[j].starttime; // LD_info->autorecall[j]->end = recallinfo_list_hour[j].endtime; // } //} } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); } } //CZY void Get_Recall_Time(char* time, QList& recallinfo_list_hour) //数据完整性补招判断 { QDateTime dt = QDateTime::fromString(time, "yyyy-MM-dd"); // 将 QDateTime 对象转换为字符串 QString dateTimeString = dt.toString("yyyy-MM-dd"); printf("\nQDateTime dt is\"%s\" \n", dateTimeString.toStdString().c_str()); long long starttime = dt.toMSecsSinceEpoch() / 1000; //补招起始时间 long long endtime = starttime + 86399; //补招结束时间 QList timestamp_list; //数据库完整性记录时间点 QList recallinfo_list; //待补招队列 //QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 RecallInfo info; info.starttime = starttime; info.endtime = endtime; recallinfo_list.append(info); 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; RecallInfo info; info.starttime = start; info.endtime = end; recallinfo_list_hour.append(info); } else { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].starttime + j + max_interval; RecallInfo info; info.starttime = start; info.endtime = end; recallinfo_list_hour.append(info); } } } } char* getoneday(int num) { apr_time_t previousTime = apr_time_now(); long long stamp = static_cast(previousTime) / 1000000; long long deltime = stamp - (60 * 60 * 24 * num);//减去1天 QDateTime deltime_Qtime = QDateTime::fromTime_t(deltime); QString tmp_chr1 = deltime_Qtime.toString("yyyy-MM-dd"); QByteArray byteArray = tmp_chr1.toLocal8Bit(); char* charArray = new char[byteArray.size()]; memcpy(charArray, byteArray.data(), byteArray.size()); charArray[byteArray.size()] = '\0'; return charArray; } void deletechar(char* day) { delete[] day; } /// /// 删除过期的xml /// void DeletcRecallXml() { QString cfg_dir = QString("../")/*+QString::fromAscii(subdir)*/ + QString("etc/recall"); QString file_name = QString(subdir) + QString("_") + QString("*") + QString("_Recall.xml"); //指定文件夹名 QDir dir(cfg_dir); if (!dir.exists()) { qDebug() << "folder does not exist!"; return; } QStringList filter(file_name); //指定查找类型和排序,按最新的修改时间获取 QStringList files = dir.entryList(filter, QDir::Files | QDir::Readable | QDir::NoDotAndDotDot, QDir::Name | QDir::Time); // 设定过滤的日期和时间 QDateTime saveDaysAgo = QDateTime::currentDateTime().addDays(-2); for (int i = 0; i < files.size(); i++) {//清空读取文件 QFileInfo fileInfo(dir.filePath(files[i])); if (fileInfo.lastModified() < saveDaysAgo) { QFile::remove(fileInfo.absoluteFilePath()); } } } void CreateRecallXml() { apr_time_t previousTime = apr_time_now(); long long stamp = static_cast(previousTime) / 1000000; QDateTime deltime_Qtime = QDateTime::fromTime_t(stamp); /*CJournalRecall jr; jr.MonitorID = QString::number(1100, 10); jr.StartTime = deltime_Qtime.toString("yyyy-MM-dd hh:mm:ss"); jr.EndTime = deltime_Qtime.toString("yyyy-MM-dd hh:mm:ss"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); for (int i = 0;i < 10;i++) { g_StatisticLackList.push_back(jr); }*/ g_StatisticLackList_list_mutex.lock(); if (g_StatisticLackList.size() > 0) { printf("insert ID_CJournalRecall_Map!\n"); QMap > ID_CJournalRecall_Map; list::iterator sl = g_StatisticLackList.begin(); while (sl != g_StatisticLackList.end()) { CJournalRecall jr = *sl++; if (ID_CJournalRecall_Map.contains(jr.MonitorID)) { ID_CJournalRecall_Map[jr.MonitorID].append(jr); } else { QList TempList; TempList.append(jr); ID_CJournalRecall_Map.insert(jr.MonitorID, TempList); } } for (QMap >::iterator it2 = ID_CJournalRecall_Map.begin(); it2 != ID_CJournalRecall_Map.end(); ++it2) { QString key2 = it2.key(); QList value2 = it2.value(); 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"); std::string strRecallPath = qstrRecallPath.toStdString(); QFile file(strRecallPath.c_str()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { printf("补招查询完成,打开%s失败,无法写入线路补招配置!\n", qstrRecallPath.toAscii().data()); QMap >().swap(ID_CJournalRecall_Map); return; } QXmlStreamWriter writer(&file); writer.setAutoFormatting(true); writer.writeStartDocument(); writer.writeStartElement("RecallList"); writer.writeStartElement("Work"); writer.writeEndElement(); writer.writeStartElement("New"); while (!value2.isEmpty()) { 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(); } writer.writeEndElement(); writer.writeEndElement(); writer.writeEndDocument(); file.close(); } QMap >().swap(ID_CJournalRecall_Map); } g_StatisticLackList.clear(); g_StatisticLackList_list_mutex.unlock(); } ///////zw修改 2023-8-30 end /*/////////////////////////////////////////////////////////lnk2024-10-11移除sql的测试代码/////////////////////////////////////////////////////////////*/ std::string intToString(int number) { if (number == 0) return "0"; std::string str; bool isNegative = number < 0; if (isNegative) number = -number; while (number > 0) { str.insert(str.begin(), '0' + (number % 10)); number /= 10; } if (isNegative) str.insert(str.begin(), '-'); return str; } otl_datetime parseTimestamp(const std::string timestampStr) { otl_datetime timestamp; // 定义年、月、日、时、分、秒变量 int year, month, day, hour, minute, second; // 使用字符串流进行解析 std::istringstream ss(timestampStr); char discard; // 用于丢弃分隔符 // 解析字符串 ss >> year >> discard >> month >> discard >> day >> hour >> discard >> minute >> discard >> second; // 将解析的值赋给 otl_datetime 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; } void SendWebAPI_web(const string strUrl, const char* code, char** ptr) { // curl初始化 CURL* curl = curl_easy_init(); // curl返回值 CURLcode res; if (curl) { char url[100]; sprintf(url, "%s?%s", strUrl.c_str(), code); //printf(">>>json %s\n", url);//减少不必要的打印 // 设置URL curl_easy_setopt(curl, CURLOPT_URL, url); //设置数据接收和写入函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web); //数据接收 string resPost0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); //设置超时时间 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); //设置header curl_slist* headers = NULL; headers = curl_slist_append(headers, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // 开启post请求 res = curl_easy_perform(curl); // 检查请求是否成功 if (res != CURLE_OK) { printf("web failed res code: "); } else { printf(">>> web return str:%s \n", resPost0.c_str()); *ptr = (char*)malloc(strlen(resPost0.c_str()) + 1); // 分配足够的内存空间 if (*ptr != NULL) { strcpy(*ptr, resPost0.c_str()); } else { printf("Memory allocation failed!\n"); } } } else { printf(">>> web curl init failed"); } curl_easy_cleanup(curl); } //20241206不使用的代码lnk #if 0 //终端识别码密钥web接口 int parse_device_web_test_ext(QMap* terminal_ext_map,const std::vector& codes) { std::cout << "parse_device_web_test_ext" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; if(function == "info"){ code = std::string("code1=pg_ext&code2=read&code3=info"); } char* terminal_code=NULL; char* terminal_identify_code=NULL; char* terminal_key=NULL; char* ptr=NULL; terminal_ext* ext; try{ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (terminal_code != NULL) { // 如果已经分配了内存,则释放内存 free(terminal_code); } terminal_code = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(terminal_code, json_value->valuestring); std::cout << "terminal_code:" << terminal_code <type == cJSON_String) { if (terminal_identify_code != NULL) { // 如果已经分配了内存,则释放内存 free(terminal_identify_code); } terminal_identify_code = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(terminal_identify_code, json_value->valuestring); std::cout << "terminal_identify_code:" << terminal_identify_code <type == cJSON_String) { if (terminal_key != NULL) { // 如果已经分配了内存,则释放内存 free(terminal_key); } terminal_key = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(terminal_key, json_value->valuestring); std::cout << "terminal_key:" << terminal_key <contains(terminal_code)) { ext = new terminal_ext(); terminal_ext_map->insert(terminal_code, ext); apr_snprintf(ext->terminal_identify_code, sizeof(ext->terminal_identify_code), "%s", terminal_identify_code);//terminal_code apr_snprintf(ext->terminal_key, sizeof(ext->terminal_key), "%s", terminal_key);//terminal_code } else { qDebug() << terminal_code << endl; } } } if (ptr) { free(ptr); } cJSON_Delete(json); return APR_SUCCESS; } catch (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } //模型web接口 int parse_model_web_test(QMap* icd_model_map,const std::vector& codes) { std::cout << "parse_model_web_test" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; if(function == "info"){ code = std::string("code1=model&code2=read&code3=info"); } char* model_id=NULL; char* tmnl_type=NULL; char* tmnl_factory=NULL; char* file_name=NULL; char* timestamp=NULL; char* ptr=NULL; icd_model* model; try{ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (model_id != NULL) { // 如果已经分配了内存,则释放内存 free(model_id); } model_id = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(model_id, json_value->valuestring); std::cout << "model_id:" << model_id <type == cJSON_String) { if (tmnl_type != NULL) { // 如果已经分配了内存,则释放内存 free(tmnl_type); } tmnl_type = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(tmnl_type, json_value->valuestring); std::cout << "tmnl_type:" << tmnl_type <type == cJSON_String) { if (tmnl_factory != NULL) { // 如果已经分配了内存,则释放内存 free(tmnl_factory); } tmnl_factory = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(tmnl_factory, json_value->valuestring); std::cout << "tmnl_factory:" << tmnl_factory <type == cJSON_String) { if (file_name != NULL) { // 如果已经分配了内存,则释放内存 free(file_name); } file_name = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(file_name, json_value->valuestring); std::cout << "file_name:" << file_name <type == cJSON_String) { if (timestamp != NULL) { // 如果已经分配了内存,则释放内存 free(timestamp); } timestamp = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(timestamp, json_value->valuestring); std::cout << "timestamp:" << timestamp <contains(model_id)) { model = new icd_model(); icd_model_map->insert(model_id, model); apr_snprintf(model->model_id, sizeof(model->model_id), "%s", model_id);//org_name apr_snprintf(model->tmnl_type, sizeof(model->tmnl_type), "%s", tmnl_type);//maint_name apr_snprintf(model->tmnl_factory, sizeof(model->tmnl_factory), "%s", tmnl_factory);//station_name apr_snprintf(model->file_name, sizeof(model->file_name), "%s", file_name);//addr_str apr_snprintf(model->timestamp, sizeof(model->timestamp), "%s", timestamp);//timestamp } else { qDebug() << model_id << endl; } } } if (ptr) { free(ptr); } cJSON_Delete(json); return APR_SUCCESS; } catch (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } //监测点台账web接口 int parse_line_web_test(QMap* ledger_monitor_map,const std::vector& codes) { std::cout << "parse_line_web_test" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; if(function == "info"){ code = std::string("code1=line&code2=read&code3=info"); } else if(function == "count_cfg"){ //code = std::string("code1=line&code2=read&code3=count_cfg"); //读取台账表的记录总数 } char* ptr=NULL; char* monitor_id=NULL; char* terminal_code=NULL; char* monitor_name=NULL; char* logical_device_seq=NULL; char* voltage_level=NULL; char* terminal_connect=NULL; char* timestamp=NULL; char* count=NULL; ledger_monitor* line; try{ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } if (json != NULL) { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (monitor_id != NULL) { // 如果已经分配了内存,则释放内存 free(monitor_id); } monitor_id = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(monitor_id, json_value->valuestring); std::cout << "monitor_id:" << monitor_id <type == cJSON_String) { if (terminal_code != NULL) { // 如果已经分配了内存,则释放内存 free(terminal_code); } terminal_code = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(terminal_code, json_value->valuestring); std::cout << "terminal_code:" << terminal_code <type == cJSON_String) { if (monitor_name != NULL) { // 如果已经分配了内存,则释放内存 free(monitor_name); } monitor_name = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(monitor_name, json_value->valuestring); std::cout << "monitor_name:" << monitor_name <type == cJSON_String) { if (logical_device_seq != NULL) { // 如果已经分配了内存,则释放内存 free(logical_device_seq); } logical_device_seq = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(logical_device_seq, json_value->valuestring); std::cout << "logical_device_seq:" << logical_device_seq <type == cJSON_String) { if (voltage_level != NULL) { // 如果已经分配了内存,则释放内存 free(voltage_level); } voltage_level = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(voltage_level, json_value->valuestring); std::cout << "voltage_level:" << voltage_level <type == cJSON_String) { if (terminal_connect != NULL) { // 如果已经分配了内存,则释放内存 free(terminal_connect); } terminal_connect = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(terminal_connect, json_value->valuestring); std::cout << "terminal_connect:" << terminal_connect <type == cJSON_String) { if (timestamp != NULL) { // 如果已经分配了内存,则释放内存 free(timestamp); } timestamp = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(timestamp, json_value->valuestring); std::cout << "timestamp:" << timestamp <type == cJSON_String) { if (count != NULL) { // 如果已经分配了内存,则释放内存 free(count); } count = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(count, json_value->valuestring); std::cout << "count:" << count <contains(monitor_id)) { line = new ledger_monitor(); if(function == "info"){ ledger_monitor_map->insert(monitor_id, line); apr_snprintf(line->monitor_id, sizeof(line->monitor_id), "%s", monitor_id);//terminal_id apr_snprintf(line->terminal_code, sizeof(line->terminal_code), "%s", terminal_code);//terminal_code apr_snprintf(line->monitor_name, sizeof(line->monitor_name), "%s", monitor_name);//org_name apr_snprintf(line->logical_device_seq, sizeof(line->logical_device_seq), "%s", logical_device_seq);//maint_name apr_snprintf(line->voltage_level, sizeof(line->voltage_level), "%s", voltage_level);//station_name apr_snprintf(line->terminal_connect, sizeof(line->terminal_connect), "%s", terminal_connect);//addr_str apr_snprintf(line->timestamp, sizeof(line->timestamp), "%s", timestamp);//timestamp } else if(function == "count_cfg"){ ledger_monitor_map->insert("count_cfg", line); apr_snprintf(line->count_cfg, sizeof(line->count_cfg), "%s", count);//表count } } else { qDebug() << monitor_id << endl; } } } /* 根据前置现有的终端号筛选监测点 */ /* 遍历 ledger_monitor_map 容器并删除不在 g_node->n_clients 中的 terminal_code */ QMap::iterator it; it = ledger_monitor_map->begin(); while (it != ledger_monitor_map->end()) { // 假设 value 是一个结构体,包含 terminal_code ledger_monitor* data = it.value(); // 获取 monitor_id 对应的数据 std::string terminal_code_line = data->terminal_code; // 从数据中提取 terminal_code // 标志是否找到匹配的终端号 bool found = false; // 遍历 g_node->n_clients,检查 terminal_code 是否存在 for (int dev_no = 0; dev_no < g_node->n_clients; dev_no++) { ied_usr_t* user_ext = (ied_usr_t*)(g_node->clients[dev_no]->usr_ext); std::string client_terminal_code = user_ext->terminal_code; // 如果找到了匹配的终端号,标记 found 为 true 并停止循环 if (client_terminal_code == terminal_code_line) { found = true; break; } } // 如果没找到匹配的 terminal_code,就删除该记录 if (!found) { it = ledger_monitor_map->erase(it); // 删除当前记录,erase 会返回下一个迭代器 std::cout << "Removed monitor_id: " << it.key().toStdString() << " with terminal_code: " << terminal_code << std::endl; // 调试输出 } else { ++it; // 否则继续下一个记录 } } if (ptr) { free(ptr); } cJSON_Delete(json); return APR_SUCCESS; } catch (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } //终端台账web接口 int parse_device_web_test_dev(QMap* terminal_dev_map,const std::vector& codes) { std::cout << "parse_device_web_test_dev" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; if(function == "info"){ /*入参初始化 */ std::string front_inst = ""; std::string mp_number = ""; std::string cnt_cfg = ""; std::string mult_flag = ""; std::string front_num = ""; //入参 front_inst = codes[1]; mp_number = codes[2]; cnt_cfg = codes[3]; mult_flag = codes[4]; //单/多前置 front_num = codes[5]; std::cout << "param:" << front_inst << mp_number << cnt_cfg << mult_flag << front_num << std::endl; code = std::string("code1=pg_dev&code2=read&code3=info") + "&code4=" + front_inst + "&code5=" + mp_number + "&code6=" + cnt_cfg + "&code7=" + mult_flag + "&code8=" + front_num; } else if(function == "count_cfg"){ code = std::string("code1=pg_dev&code2=read&code3=count_cfg"); //读取台账表的记录总数 } char* ptr=NULL; char* terminal_id=NULL; char* terminal_code=NULL; char* org_name=NULL; char* maint_name=NULL; char* station_name=NULL; char* addr_str=NULL; char* port=NULL; char* tmnl_factory=NULL; char* dev_type=NULL; char* tmnl_status=NULL; char* timestamp=NULL; char* count=NULL; terminal_dev* dev; try{ //参数:pg_dev取终端台账,后续的参数分别为:FRONT_INST 前置实例号;mp_num 前置对应检测点数;count_cfg 前置表读取的检测点数;MULTIPLE_NODE_FLAG 多前置标志;g_front_seg_num 多前置前置总数; SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } if (json != NULL) { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (terminal_id != NULL) { // 如果已经分配了内存,则释放内存 free(terminal_id); } terminal_id = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(terminal_id, json_value->valuestring); std::cout << "terminal_id:" << terminal_id <type == cJSON_String) { if (terminal_code != NULL) { // 如果已经分配了内存,则释放内存 free(terminal_code); } terminal_code = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(terminal_code, json_value->valuestring); std::cout << "terminal_code:" << terminal_code <type == cJSON_String) { if (org_name != NULL) { // 如果已经分配了内存,则释放内存 free(org_name); } org_name = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(org_name, json_value->valuestring); std::cout << "org_name:" << org_name <type == cJSON_String) { if (maint_name != NULL) { // 如果已经分配了内存,则释放内存 free(maint_name); } maint_name = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(maint_name, json_value->valuestring); std::cout << "maint_name:" << maint_name <type == cJSON_String) { if (station_name != NULL) { // 如果已经分配了内存,则释放内存 free(station_name); } station_name = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(station_name, json_value->valuestring); std::cout << "station_name:" << station_name <type == cJSON_String) { if (addr_str != NULL) { // 如果已经分配了内存,则释放内存 free(addr_str); } addr_str = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(addr_str, json_value->valuestring); std::cout << "addr_str:" << addr_str <type == cJSON_String) { if (port != NULL) { // 如果已经分配了内存,则释放内存 free(port); } port = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(port, json_value->valuestring); std::cout << "port:" << port <type == cJSON_String) { if (tmnl_factory != NULL) { // 如果已经分配了内存,则释放内存 free(tmnl_factory); } tmnl_factory = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(tmnl_factory, json_value->valuestring); std::cout << "tmnl_factory:" << tmnl_factory <type == cJSON_String) { if (dev_type != NULL) { // 如果已经分配了内存,则释放内存 free(dev_type); } dev_type = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(dev_type, json_value->valuestring); std::cout << "dev_type:" << dev_type <type == cJSON_String) { if (tmnl_status != NULL) { // 如果已经分配了内存,则释放内存 free(tmnl_status); } tmnl_status = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(tmnl_status, json_value->valuestring); std::cout << "tmnl_status:" << tmnl_status <type == cJSON_String) { if (timestamp != NULL) { // 如果已经分配了内存,则释放内存 free(timestamp); } timestamp = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(timestamp, json_value->valuestring); std::cout << "timestamp:" << timestamp <type == cJSON_String) { if (count != NULL) { // 如果已经分配了内存,则释放内存 free(count); } count = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(count, json_value->valuestring); std::cout << "count:" << count <contains(terminal_code)) { dev = new terminal_dev(); if(function == "info"){ terminal_dev_map->insert(terminal_code, dev); apr_snprintf(dev->terminal_id, sizeof(dev->terminal_id), "%s", terminal_id);//terminal_id apr_snprintf(dev->terminal_code, sizeof(dev->terminal_code), "%s", terminal_code);//terminal_code apr_snprintf(dev->org_name, sizeof(dev->org_name), "%s", org_name);//org_name apr_snprintf(dev->maint_name, sizeof(dev->maint_name), "%s", maint_name);//maint_name apr_snprintf(dev->station_name, sizeof(dev->station_name), "%s", station_name);//station_name apr_snprintf(dev->addr_str, sizeof(dev->addr_str), "%s", addr_str);//addr_str apr_snprintf(dev->port, sizeof(dev->port), "%s", port);//port_int apr_snprintf(dev->tmnl_factory, sizeof(dev->tmnl_factory), "%s", tmnl_factory);//tmnl_factory apr_snprintf(dev->dev_type, sizeof(dev->dev_type), "%s", dev_type);//dev_type apr_snprintf(dev->tmnl_status, sizeof(dev->tmnl_status), "%s", tmnl_status);//tmnl_status apr_snprintf(dev->timestamp, sizeof(dev->timestamp), "%s", timestamp);//timestamp } else if(function == "count_cfg"){ terminal_dev_map->insert("count_cfg", dev); apr_snprintf(dev->count_cfg, sizeof(dev->count_cfg), "%s", count);//表count } } else { qDebug() << terminal_code << endl; } } } if (ptr) { free(ptr); } cJSON_Delete(json); return APR_SUCCESS; } catch (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } //前置表web接口-写 int parse_device_web_test_front_write(const std::vector& codes) { std::cout << "parse_device_web_test_front_write" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; char* ret=NULL; char* ptr=NULL; if(function == "insertfront"){ /*入参初始化 */ std::string front_ip = ""; std::string front_inst = ""; std::string front_type = ""; std::string program_version = ""; std::string front_status = ""; //入参 front_ip = codes[1]; front_inst = codes[2]; front_type = codes[3]; program_version = codes[4]; front_status = codes[5]; std::cout << "insert param:" << front_ip << front_inst << front_type << program_version << front_status <3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (ret != NULL) { // 如果已经分配了内存,则释放内存 free(ret); } ret = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(ret, json_value->valuestring); std::cout << "ret:" << ret <* front_map,const std::vector& codes) { std::cout << "parse_device_web_test_front" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; if(function == "info"){ code = std::string("code1=pg_front&code2=read&code3=info"); } else if(function == "frontip"){ std::string front_index = ""; std::string front_status = ""; front_index = codes[1]; front_status = codes[2]; code = std::string("code1=pg_front&code2=read&code3=frontip") + "&code4=" + front_index + "&code5=" + front_status; } else if(function == "frontstatus"){ std::string front_ip = ""; std::string front_index = ""; front_ip = codes[1]; front_index = codes[2]; code = std::string("code1=pg_front&code2=read&code3=frontstatus") + "&code4=" + front_ip + "&code5=" + front_index; } char* front_type=NULL; char* mp_num=NULL; char* front_ip=NULL; char* front_status=NULL; char* ptr=NULL; //QMap front_map; front_list* front; try{ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (front_type != NULL) { // 如果已经分配了内存,则释放内存 free(front_type); } front_type = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(front_type, json_value->valuestring); std::cout << "front_type:" << front_type <type == cJSON_String) { if (mp_num != NULL) { // 如果已经分配了内存,则释放内存 free(mp_num); } mp_num = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(mp_num, json_value->valuestring); std::cout << "mp_num:" << mp_num <type == cJSON_String) { if (front_ip != NULL) { // 如果已经分配了内存,则释放内存 free(front_ip); } front_ip = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(front_ip, json_value->valuestring); std::cout << "front_ip:" << front_ip <type == cJSON_String) { if (front_status != NULL) { // 如果已经分配了内存,则释放内存 free(front_status); } front_status = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(front_status, json_value->valuestring); std::cout << "front_status:" << front_status <contains("0.0.0.0")) { front = new front_list(); front_map->insert("0.0.0.0", front); apr_snprintf(front->front_inst, sizeof(front->front_inst), "%s", "0");//front_inst apr_snprintf(front->front_type, sizeof(front->front_type), "%s", front_type);//front_type apr_snprintf(front->mp_num, sizeof(front->mp_num), "%s", mp_num);//mp_num } else { qDebug() << "0.0.0.0 : front_type = " << front_type << "mp_num = " << mp_num << endl; } } else if(function == "frontip"){ if (!front_map->contains("frontip")) { //以"frontip"为key front = new front_list(); front_map->insert("frontip", front); apr_snprintf(front->front_ip, sizeof(front->front_ip), "%s", front_ip);//front_type } else { qDebug() << "front_ip = " << front_ip << endl; } } else if(function == "frontstatus"){ if (!front_map->contains("frontstatus")) { //以"frontstatus"为key front = new front_list(); front_map->insert("frontstatus", front); apr_snprintf(front->front_status, sizeof(front->front_status), "%s", front_status);//front_type } else { qDebug() << "frontstatus = " << front_status << endl; } } } } if (ptr) { free(ptr); } cJSON_Delete(json); return APR_SUCCESS; } catch (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } //完整性web接口-读 int parse_intact_web_test_read(QMap* intact_list_map,const std::vector& codes) { std::cout << "parse_intact_web_test" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; if(function == "deciderecall"){ /*入参初始化 */ std::string time = ""; std::string id = ""; //入参 time = codes[1]; id = codes[2]; std::cout << "param:" << time << id << std::endl; code = std::string("code1=intact&code2=read&code3=deciderecall") + "&code4=" + time + "&code5=" + id; } else if(function == "autorecall"){ /*入参初始化 */ std::string time = ""; std::string id = ""; //入参 time = codes[1]; id = codes[2]; std::cout << "param:" << time << id << std::endl; code = std::string("code1=intact&code2=read&code3=autorecall") + "&code4=" + time + "&code5=" + id; } else if(function == "handlerecall"){ /*入参初始化 */ std::string tmp_time = ""; std::string Monitorid = ""; std::string start_time = ""; std::string end_time = ""; //入参 tmp_time = codes[1]; Monitorid = codes[2]; start_time = codes[3]; end_time = codes[4]; std::cout << "param:" << tmp_time << Monitorid << start_time << end_time << std::endl; code = std::string("code1=intact&code2=read&code3=handlerecall") + "&code4=" + tmp_time + "&code5=" + Monitorid + "&code4=" + start_time + "&code5=" + end_time; } char* exp_num=NULL; char* act_num=NULL; char* valuetime=NULL; char* ptr=NULL; intact_list* intact; try{ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (exp_num != NULL) { // 如果已经分配了内存,则释放内存 free(exp_num); } exp_num = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(exp_num, json_value->valuestring); std::cout << "exp_num:" << exp_num <type == cJSON_String) { if (act_num != NULL) { // 如果已经分配了内存,则释放内存 free(act_num); } act_num = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(act_num, json_value->valuestring); std::cout << "act_num:" << act_num <type == cJSON_String) { if (valuetime != NULL) { // 如果已经分配了内存,则释放内存 free(valuetime); } valuetime = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(valuetime, json_value->valuestring); std::cout << "valuetime:" << valuetime <contains(id)) { intact = new intact_list(); intact_list_map->insert(id, intact); //时间数据会循环多次,id会重复 if(function == "deciderecall"){ apr_snprintf(intact->exp_num, sizeof(intact->exp_num), "%s", exp_num); apr_snprintf(intact->act_num, sizeof(intact->act_num), "%s", act_num); } else if(function == "autorecall" || function == "handlerecall"){ intact->value_time.push_back(valuetime); } } else { intact = intact_list_map->value(id); //找到这个id对应的类 if(function == "deciderecall"){ qDebug() << "exp_num = " << intact->exp_num << "act_num = " << intact->act_num << endl; } else if(function == "autorecall" || function == "handlerecall"){ intact->value_time.push_back(valuetime);//记录到对应id的容器中 } } } } if (ptr) { free(ptr); } cJSON_Delete(json); return APR_SUCCESS; } catch (const std::exception& e) { cout << "Exception caught: " << e.what() << endl; // 这里可以添加其他异常处理逻辑 } } //日志数据库接口 int parse_rationality_write(const std::vector& codes) { std::cout << "parse_rationality_write" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; char* ret=NULL; char* ptr=NULL; if(function == "log"){ /*入参初始化 */ std::string id = ""; std::string time = ""; std::string count = ""; std::string filename = ""; //入参 id = codes[1]; time = codes[2]; count = codes[3]; filename = codes[4]; std::cout << "insert param:" << id << time << count << filename << std::endl; //构造参数 code = std::string("code1=rationality&code2=write&code3=log") + "&code4=" + id + "&code5=" + time + "&code6=" + count + "&code7=" + filename; } try{ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (ret != NULL) { // 如果已经分配了内存,则释放内存 free(ret); } ret = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(ret, json_value->valuestring); std::cout << "ret:" << ret <& codes) { std::cout << "parse_dataintegrity_write" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; char* ret=NULL; char* ptr=NULL; if(function == "log"){ /*入参初始化 */ std::string time = ""; std::string datatime = ""; std::string monitorId = ""; std::string recallflag = ""; std::string msspan = ""; //入参 time = codes[1]; datatime = codes[2]; monitorId = codes[3]; recallflag = codes[4]; msspan = codes[5]; std::cout << "insert param:" << time << datatime << monitorId << recallflag << msspan <3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (ret != NULL) { // 如果已经分配了内存,则释放内存 free(ret); } ret = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(ret, json_value->valuestring); std::cout << "ret:" << ret <& codes) { std::cout << "parse_match_write" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; char* ret=NULL; char* ptr=NULL; if(function == "log"){ /*入参初始化 */ std::string id = ""; std::string time = ""; std::string BASE_MAT_NUM = ""; std::string ADV_MAT_NUM = ""; std::string BASE_ACT_NUM = ""; std::string ADV_ACT_NUM = ""; std::string filename = ""; //入参 id = codes[1]; time = codes[2]; BASE_MAT_NUM = codes[3]; ADV_MAT_NUM = codes[4]; BASE_ACT_NUM = codes[5]; ADV_ACT_NUM = codes[6]; filename = codes[7]; std::cout << "insert param:" << id << time << BASE_MAT_NUM<< ADV_MAT_NUM<< BASE_ACT_NUM<< ADV_ACT_NUM<3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (ret != NULL) { // 如果已经分配了内存,则释放内存 free(ret); } ret = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(ret, json_value->valuestring); std::cout << "ret:" << ret <& codes) { std::cout << "parse_commstatus_write" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; char* ret=NULL; char* ptr=NULL; if(function == "log"){ /*入参初始化 */ std::string id = ""; std::string currenttime = ""; //入参 id = codes[1]; currenttime = codes[2]; std::cout << "insert param:" << id << currenttime <3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (ret != NULL) { // 如果已经分配了内存,则释放内存 free(ret); } ret = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(ret, json_value->valuestring); std::cout << "ret:" << ret <& codes) { std::cout << "parse_commerror_write" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; char* ret=NULL; char* ptr=NULL; if(function == "log"){ /*入参初始化 */ std::string id = ""; std::string time = ""; std::string filename = ""; //入参 id = codes[1]; time = codes[2]; filename = codes[3]; std::cout << "insert param:" << id << time << filename <3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (ret != NULL) { // 如果已经分配了内存,则释放内存 free(ret); } ret = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(ret, json_value->valuestring); std::cout << "ret:" << ret <& codes) { std::cout << "parse_device_web_test_front" << std::endl; std::string code = ""; /*请求界定 */ std::string function = codes[0]; std::cout << "function:" << function << std::endl; if(function == "ontime"){ /*入参初始化 */ std::string time = ""; //入参 time = codes[1]; std::cout << "param:" << time << std::endl; code = std::string("code1=ontime&code2=delete&code3=deletetime") + "&code4=" + time; } char* ret=NULL; char* tablename=NULL; char* ptr=NULL; try{ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); //调试用 printf("ptr:%s\n",ptr); cJSON* json = cJSON_Parse(ptr); //json格式序列化 cJSON* json_node = NULL;; cJSON* json_records = NULL;; cJSON* json_value = NULL; int array_size = 0; int i = 0; if (json == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(json == NULL){ SendWebAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", code.c_str(), &ptr); json = cJSON_Parse(ptr); i++;if(i>3)break; } } else { json_node = cJSON_GetObjectItem(json, "result"); //获取result根节点 json_records = cJSON_GetObjectItem(json_node, "records"); //获取记录节点 array_size = cJSON_GetArraySize(json_records); //获取记录数组大小 for(i = 0;itype == cJSON_String) { if (ret != NULL) { // 如果已经分配了内存,则释放内存 free(ret); } ret = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(ret, json_value->valuestring); std::cout << "ret:" << ret <type == cJSON_String) { if (tablename != NULL) { // 如果已经分配了内存,则释放内存 free(tablename); } tablename = (char*)malloc(strlen(json_value->valuestring) + 1); // 分配内存 strcpy(tablename, json_value->valuestring); std::cout << "tablename:" << tablename <> exp_num >> act_num;*/ std::vector codes;//入参集合 QMap intact_list_map; codes.push_back("deciderecall"); codes.push_back(std::string(time)); codes.push_back(std::string(id)); parse_intact_web_test_read(&intact_list_map,codes); codes.clear(); try { //char exp_num[64]; //char act_num[64]; double exp_num; double act_num; // 遍历终端台账容器 QMap::iterator it; for (it = intact_list_map.begin(); it != intact_list_map.end(); ++it) { intact_list* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 //strncpy(exp_num, value->exp_num.c_str(), sizeof(exp_num) - 1); //strncpy(act_num, value->act_num.c_str(), sizeof(act_num) - 1); exp_num = atof(value->exp_num); act_num = atof(value->exp_num); std::cout << exp_num << " " << act_num << std::endl; if (exp_num * 0.8 <= act_num) { flag = 0; } } } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); flag = 0; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); flag = 0; } return flag; } void OTL_Select_recall_web(char* time, char* id) //数据完整性补招判断 { try { QDateTime dt = QDateTime::fromString(time, "yyyy-MM-dd"); long long starttime = dt.toMSecsSinceEpoch() / 1000; //补招起始时间 long long endtime = starttime + 86399; //补招结束时间 QList timestamp_list; //数据库完整性记录时间点 QList recallinfo_list; //待补招队列 QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 /* int rtState = OTLDbconnected(); //int rtState = db.connected; if (rtState == 0) { int ret = OTLConnect(); } //OTLConnect(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "SELECT unnest(value_time) AS timestamp_value FROM \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_measpoint_intact_tr\" "); str1.append("WHERE \"statistical_date\" = '"); str1.append(time); str1.append("' AND \"monitor_id\" = '"); str1.append(id); str1.append("' ORDER BY timestamp_value"); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> timestamp;*/ std::vector codes;//入参集合 QMap intact_list_map; codes.push_back("autorecall"); codes.push_back(std::string(time)); codes.push_back(std::string(id)); parse_intact_web_test_read(&intact_list_map,codes); codes.clear(); try { otl_datetime timestamp; // 遍历终端台账容器 if (intact_list_map.contains(id)) { intact_list* value = intact_list_map.value(id); // 找到键值为 "id" 的对象 if (value != nullptr) { // 遍历 value_time 容器并输出所有时间字符串 for (std::vector::const_iterator it = value->value_time.begin(); it != value->value_time.end(); ++it) { const std::string& time = *it; std::cout << "Time: " << time << std::endl; timestamp = parseTimestamp(time); struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 timeinfo.tm_mday = timestamp.day; timeinfo.tm_hour = timestamp.hour; timeinfo.tm_min = timestamp.minute; timeinfo.tm_sec = timestamp.second; time_t timestamp = std::mktime(&timeinfo); long long stamp = static_cast(timestamp); timestamp_list.append(stamp); } } } else { std::cout << "No entry found for id: " << id << std::endl; } /* struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 timeinfo.tm_mday = timestamp.day; timeinfo.tm_hour = timestamp.hour; timeinfo.tm_min = timestamp.minute; timeinfo.tm_sec = timestamp.second; time_t timestamp = std::mktime(&timeinfo); long long stamp = static_cast(timestamp); timestamp_list.append(stamp);*/ } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); } if (timestamp_list.size() == 0) //完整性数据表无数据 { RecallInfo info; info.starttime = starttime; info.endtime = endtime; recallinfo_list.append(info); } else if (timestamp_list.size() == 1)//存在1条数据 { long long temptime = timestamp_list[0]; if (temptime != starttime && temptime != endtime) { RecallInfo info1; info1.starttime = starttime; info1.endtime = temptime - 1; RecallInfo info2; info2.starttime = temptime + 1; info2.endtime = endtime; recallinfo_list.append(info1); recallinfo_list.append(info2); } else { RecallInfo info; info.starttime = starttime + 1; info.endtime = endtime - 1; recallinfo_list.append(info); } } else //存在多条数据 { for (int i = 1; i < timestamp_list.size(); i++) { if (i == 1) { timestamp_list[0];//头数据 timestamp_list[timestamp_list.size() - 1];//尾数据 if (timestamp_list[0] - starttime > 600) { RecallInfo info; info.starttime = starttime + 1; info.endtime = timestamp_list[0] - 1; recallinfo_list.append(info); } if (endtime - timestamp_list[timestamp_list.size() - 1] > 600) { RecallInfo info; info.starttime = timestamp_list[timestamp_list.size() - 1] + 1; info.endtime = endtime - 1; recallinfo_list.append(info); } } long long temptime1 = timestamp_list[i - 1]; long long temptime2 = timestamp_list[i]; if (temptime2 - temptime1 > 600) { RecallInfo info; info.starttime = temptime1 + 1; info.endtime = temptime2 - 1; recallinfo_list.append(info); } } } for (int i = 0; i < recallinfo_list.size(); i++) { 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; RecallInfo info; info.starttime = start - 10; info.endtime = end - 10; recallinfo_list_hour.append(info); } else { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].starttime + j + max_interval; RecallInfo info; info.starttime = start - 10; info.endtime = end - 10; recallinfo_list_hour.append(info); } } } LD_info_t* LD_info = find_LD_info_only_from_mp_id(id); if (LD_info == NULL || LD_info->read_flag == 0) { printf("\n Find LD_info == null \n"); } else { for (int j = 0; j < recallinfo_list_hour.size(); j++) { CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); } } bool CheckPG_To_Recall_web_test(long long start, long long end, char* Monitorid) { QDateTime deltime_Qtime = QDateTime::fromTime_t(start); QDateTime deltime_Qtime_end = QDateTime::fromTime_t(end); QString tmp_chr1 = deltime_Qtime.toString("yyyy-MM-dd"); //当前天 QString start_chr1 = deltime_Qtime.toString("yyyy-MM-dd hh:mm:ss"); //当前天 QString end_chr1 = deltime_Qtime_end.toString("yyyy-MM-dd hh:mm:ss"); //当前天 int timespan = 3;//默认时间间隔 try { /*int rtState = OTLDbconnected(); //int rtState = db.connected; if (rtState == 0) { int ret = OTLConnect(); } //printf("\nPostgreSL 1 %s \n", POSTGRES_SCHEMA); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "select \"exp_num\",\"act_num\" from \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_measpoint_intact_tr\" "); str1.append("WHERE \"statistical_date\" = '"); str1.append(tmp_chr1.toAscii().data()); str1.append("' AND \"monitor_id\" = '"); str1.append(Monitorid); str1.append("'"); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); double exp_num; double act_num; while (!i.eof()) { //while not end-of-data i >> exp_num >> act_num;*/ std::vector codes;//入参集合 QMap intact_list_map; codes.push_back("deciderecall"); codes.push_back(tmp_chr1.toStdString()); codes.push_back(std::string(Monitorid)); parse_intact_web_test_read(&intact_list_map,codes); codes.clear(); try { //char exp_num[64]; //char act_num[64]; double exp_num; double act_num; // 遍历终端台账容器 QMap::iterator it; for (it = intact_list_map.begin(); it != intact_list_map.end(); ++it) { intact_list* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 //strncpy(exp_num, value->exp_num.c_str(), sizeof(exp_num) - 1); //strncpy(act_num, value->act_num.c_str(), sizeof(act_num) - 1); exp_num = atof(value->exp_num); act_num = atof(value->act_num); std::cout << exp_num << " " << act_num << std::endl; timespan = 1440 / exp_num; printf("\n %f %f %d \n", exp_num, act_num, timespan); } } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } //OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } try { long long starttime = start; //补招起始时间 long long endtime = starttime + 3599; //补招结束时间 QList timestamp_list; //数据库完整性记录时间点 QList recallinfo_list; //待补招队列 QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 /* int rtState = OTLDbconnected(); //int rtState = db.connected; if (rtState == 0) { int ret = OTLConnect(); } //OTLConnect(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str3 = POSTGRES_TABLEPREFIX;//schame analy std::string str1 = "SELECT unnest(value_time) AS timestamp_value FROM \""; str1.append(str2); str1.append("\".\""); str1.append(str3); str1.append("meas_pq_measpoint_intact_tr\" "); str1.append("WHERE \"statistical_date\" = '"); str1.append(tmp_chr1.toAscii().data()); str1.append("' AND \"monitor_id\" = '"); str1.append(Monitorid); str1.append("' ORDER BY timestamp_value"); std::string str4 = "select b1.timestamp_value from ("; str4.append(str1); str4.append(") b1 where b1.timestamp_value >= '"); str4.append(start_chr1.toAscii().data()); str4.append("' and b1.timestamp_value <= '"); str4.append(end_chr1.toAscii().data()); str4.append("'"); otl_stream i(1, // buffer size str4.c_str(), //SELECT statement db //connect object ); otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> timestamp;*/ std::vector codes;//入参集合 QMap intact_list_map; codes.push_back("handlerecall"); codes.push_back(tmp_chr1.toStdString()); codes.push_back(std::string(Monitorid)); codes.push_back(start_chr1.toStdString()); codes.push_back(end_chr1.toStdString()); parse_intact_web_test_read(&intact_list_map,codes); codes.clear(); try { otl_datetime timestamp; // 遍历终端台账容器 if (intact_list_map.contains(Monitorid)) { intact_list* value = intact_list_map.value(Monitorid); // 找到键值为 "id" 的对象 if (value != nullptr) { // 遍历 value_time 容器并输出所有时间字符串 for (std::vector::const_iterator it = value->value_time.begin(); it != value->value_time.end(); ++it) { const std::string& time = *it; std::cout << "Time: " << time << std::endl; timestamp = parseTimestamp(time); struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 timeinfo.tm_mday = timestamp.day; timeinfo.tm_hour = timestamp.hour; timeinfo.tm_min = timestamp.minute; timeinfo.tm_sec = timestamp.second; time_t timestamp = std::mktime(&timeinfo); long long stamp = static_cast(timestamp); timestamp_list.append(stamp); } } } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } //OTLDisconnect(); if (timestamp_list.size() <= (60 / timespan) * 0.97) //完整性数据表无数据 { printf("\n return ture %d %f\n", timestamp_list.size(), (60 / timespan) * 0.97); return true; } else { printf("\n return false %d %f\n", timestamp_list.size(), (60 / timespan) * 0.97); return false; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } printf("\n>>>error quit!!\n"); return true; } //初始化的web测试接口 int parse_device_cfg_web_test() { qDebug() << "parse_device_cfg_web" << endl; std::vector codes; //多前置判断 if (FRONT_INST == 0 || FRONT_IP[0] == '\0') { MULTIPLE_NODE_FLAG = 0; cout << "set MULTIPLE_NODE_FLAG:0,because do not have FRONT_INST or FRONT_IP" << endl; } char front_type[2] = {""}; int mp_num = 0; //用web接口替换前置表的读写,接口中解析结果,存入容器,从接口直接取出容器,从容器中获取需要的值,写入时直接传参: if (MULTIPLE_NODE_FLAG) { //前置表读取部分替换 /*QString selectFrontSql; selectFrontSql.append(QString("select \"front_type\",\"mp_num\" from \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); selectFrontSql.append(QString("where \"front_ip\" = '0.0.0.0' and \"front_inst\"=0")); cout << selectFrontSql.toStdString().c_str() << endl; try { OTLConnect(); otl_stream i2(1, // buffer size selectFrontSql.toStdString().c_str(), db //connect object ); while (!i2.eof()) { //while not end-of-data i2 >> front_type >> mp_num; break; } OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; }*/ QMap front_map; codes.push_back("info"); parse_device_web_test_front_read(&front_map,codes); codes.clear(); // 遍历 QMap 容器 QMap::iterator it; for (it = front_map.begin(); it != front_map.end(); ++it) { front_list* value = it.value(); // 确保 value 不为空 if (it.key() == "0.0.0.0" && value != nullptr) { // 从 value 中读取 front_type,保留前两个字符 strncpy(front_type, value->front_type, 2); front_type[2] = '\0'; // 确保以空字符结尾 // 将 mp_num 从字符串转换为整数 mp_num = std::atoi(value->mp_num); } } //前置表读取部分 //前置表写入部分 /*QString addFrontSql; addFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); addFrontSql.append(QString("values('%1',10000,%2,'%3','01','%4',200) ").arg(FRONT_IP).arg(FRONT_INST).arg(front_type).arg(PROGRAM_VERSION)); addFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); addFrontSql.append(QString("\"front_type\"= '%1',\"front_version\"='%2'").arg(front_type).arg(PROGRAM_VERSION)); cout << addFrontSql.toStdString().c_str() << endl; OTLConnect(); int rt = write_to_db(addFrontSql.toStdString().c_str()); OTLDisconnect();*/ codes.push_back("insertfront"); codes.push_back(std::string(FRONT_IP)); codes.push_back(intToString(FRONT_INST)); codes.push_back(std::string(front_type)); codes.push_back(std::string(PROGRAM_VERSION)); codes.push_back("01"); //添加状态值 parse_device_web_test_front_write(codes); codes.clear(); //前置表写入部分 } cout << "mp_num:" << mp_num << " front_type:" << front_type << endl; ied_t* ied; ied_usr_t* ied_usr; chnl_usr_t* chnl_usr; int count_cfg = 0; int count_real = 0; //读取终端ext表替换为web接口 QMap terminal_ext_map; //read_terminal_ext_pg(&terminal_ext_map); codes.push_back("info"); parse_device_web_test_ext(&terminal_ext_map,codes); codes.clear(); //读取终端ext表替换为web接口 //读取终端台账表总数替换为web接口 /*try { OTLConnect(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("meas_pq_dev_tr"); str1.append("\" where tmnl_status='20';"); cout << "pg sql1 is:" << str1 << endl; otl_stream i(1, // buffer size str1.c_str(), db //connect object ); int f2; while (!i.eof()) { //while not end-of-data i >> f2; } OTLDisconnect(); count_cfg = f2;;//读数据库 cout << "dev_count=" << count_cfg << endl; } catch (otl_exception& e) { printf("\ndev PostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; }*/ QMap terminal_dev_map; codes.push_back("count_cfg"); parse_device_web_test_dev(&terminal_dev_map,codes); // 遍历 QMap 容器 QMap::iterator it; for (it = terminal_dev_map.begin(); it != terminal_dev_map.end(); ++it) { terminal_dev* value = it.value(); // 确保 value 不为空 if (it.key() == "count_cfg" && value != nullptr) { // 将 count 从字符串转换为整数 count_cfg = std::atoi(value->count_cfg); } //调试用 cout << "count_cfg:" << count_cfg << " value->count_cfg:" << value->count_cfg << endl; } codes.clear(); //取完count——cfg要将容器清0否则影响取台账逻辑 terminal_dev_map.clear(); //读取终端台账表总数替换为web接口 //读取终端台账表替换为web接口 codes.push_back("info"); codes.push_back(intToString(FRONT_INST)); codes.push_back(intToString(mp_num)); codes.push_back(intToString(count_cfg)); codes.push_back(intToString(MULTIPLE_NODE_FLAG)); codes.push_back(intToString(g_front_seg_num)); parse_device_web_test_dev(&terminal_dev_map,codes); codes.clear(); if (MULTIPLE_NODE_FLAG && g_front_seg_num == 0) { if (mp_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * mp_num; } else { count_cfg = mp_num; } } else if (MULTIPLE_NODE_FLAG && g_front_seg_num != 0) { int front_num = (count_cfg / g_front_seg_num) + 1; if (front_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * front_num; } else { count_cfg = front_num; } } g_node->n_clients = count_cfg; //总数读不到后续就会出错 g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); /* std::string strSchame = POSTGRES_SCHEMA;//schame analy std::string strDevSQL = "select \"terminal_id\",\"terminal_code\",\"org_name\",\"maint_name\",\"station_name\",\"tmnl_ip\",\"tmnl_port\",\"tmnl_factory\",\"tmnl_type\",\"tmnl_status\",\"update_time\" from \""; strDevSQL.append(strSchame); strDevSQL.append("\".\""); strDevSQL.append(POSTGRES_TABLEPREFIX); strDevSQL.append("meas_pq_dev_tr"); strDevSQL.append("\" where tmnl_status='20'"); if (MULTIPLE_NODE_FLAG && g_front_seg_num == 0) { strDevSQL.append(" ORDER BY terminal_id OFFSET "); strDevSQL.append(QString::number((FRONT_INST - 1) * mp_num).toStdString()); strDevSQL.append(" LIMIT "); strDevSQL.append(QString::number(mp_num).toStdString()); if (mp_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * mp_num; } else { count_cfg = mp_num; } } else if (MULTIPLE_NODE_FLAG && g_front_seg_num != 0) { int front_num = (count_cfg / g_front_seg_num) + 1; strDevSQL.append(" ORDER BY terminal_code OFFSET "); strDevSQL.append(QString::number((FRONT_INST - 1) * front_num).toStdString()); strDevSQL.append(" LIMIT "); strDevSQL.append(QString::number(front_num).toStdString()); if (front_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * front_num; } else { count_cfg = front_num; } } cout << strDevSQL << endl; g_node->n_clients = count_cfg; g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); for (int k = 0; k < count_cfg; k++) g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t)); //读数据 try { cout << "read dev information." << endl; OTLConnect(); //cout << "pg sql2 is:" << str1 << endl; //int rtState = OTLState(); // 执行长的select语句 otl_stream i(1, // buffer size strDevSQL.c_str(), //SELECT statement db //connect object ); //create select stream 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[64]; char dev_series[64]; char addr_str[64]; char port_char[64]; otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> terminal_id >> terminal_code >> org_name >> maint_name >> station_name >> addr_str >> port_char >> tmnl_factory >> dev_type >> tmnl_status >> timestamp; */ //读取终端台账表替换为web接口 ////////////////////////////////////////////////////////////////////////////////////////////////// //读数据 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[64]; char dev_series[64]; char addr_str[64]; char port_char[64]; //char timestamp[64]; otl_datetime timestamp; // 遍历终端台账容器 QMap::iterator it; for (it = terminal_dev_map.begin(); it != terminal_dev_map.end(); ++it) { terminal_dev* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 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); //strncpy(timestamp, value->timestamp, sizeof(timestamp) - 1); timestamp = parseTimestamp(value->timestamp); } ///////////////////////////////////////////////////////////////////////////////// ied = g_node->clients[count_real++]; ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t)); ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t)); if (ied_usr->LD_info == NULL) return APR_ENOMEM; ied_usr->dev_flag = g_DevFlag; ied->chncount = 1; ied->channel = (channel_t*)apr_pcalloc(g_cfg_pool, sizeof(channel_t) * ied->chncount); 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; } 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; } cout << "code" << ied_usr->terminal_code << endl; if (terminal_ext_map.contains(QString::fromUtf8(ied_usr->terminal_code))) { //terminal_ext* ext = terminal_ext_map.value(ied_usr->terminal_code); terminal_ext* ext = terminal_ext_map.value(QString::fromUtf8(ied_usr->terminal_code)); //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ext->terminal_key);//DEV_Key cout << "dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ext->terminal_identify_code);//DEV_Series cout << "dev_series:" << ied_usr->dev_series << endl; } else { //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Key apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", "");//DEV_Key cout << "defalut dev_key:" << ied_usr->dev_key << endl; //QByteArray ba = QByteArray::fromBase64(devPropVal.toAscii());//DEV_Series apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", "");//DEV_Series cout << "defalut dev_series:" << ied_usr->dev_series << 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)) { // 转换成功,portStr全为数字,并且已经转换为int类型的port 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 cout << "ied_usr->port:" << port_char << ",非合法端口.使用默认端口:" << ied->channel[0].port << endl;//DEV_PortID } } if (timestamp.year != 0) { //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); cout << "ied_usr->time:" << ied_usr->time << endl; } //////////////////////////////// /*// 定义年、月、日、时、分、秒变量 int year, month, day, hour, minute, second; // 使用字符串流进行解析 std::istringstream ss(timestamp); char discard; // 用于丢弃分隔符 // 解析字符串 ss >> year >> discard >> month >> discard >> day >> hour >> discard >> minute >> discard >> second; std::cout << "" << year << "" << month<< "" << day<< "" << hour<< "" << minute<< "" << second<time = static_cast(time); cout << "ied_usr->time:" << ied_usr->time << endl; }*/ ///////////////////////////////////// chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); 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++; //调试用 std::cout << "value:" << terminal_id <<" "<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) { printf("\ndev tr\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } } int parse_line_cfg_web_test() { ied_t* ied; ied_usr_t* ied_usr; int count_cfg = 0; int count_real = 0; LD_info_t line_info; std::vector codes;//入参集合 //监测点数量 /*try { std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select count(*) from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor"); str1.append("\" where status<>'04' and status<>'05' and \"terminal_code\" in ("); int dev_no = 0; cout << "n_clients:" << g_node->n_clients << endl; if (g_node->n_clients <= 0) { cout << "no terminal exist " << endl; return APR_EBADF; } for (dev_no = 0; dev_no < g_node->n_clients; dev_no++) { str1.append("'"); str1.append(((ied_usr_t*)(g_node->clients[dev_no]->usr_ext))->terminal_code); str1.append("'"); if (dev_no < g_node->n_clients - 1) { str1 += ","; } } str1.append(")"); cout << "pg sql1 is:" << str1 << endl; OTLConnect(); otl_stream i(1,str1.c_str(),db); int f2; while (!i.eof()) { i >> f2; } OTLDisconnect(); count_cfg = f2;;//读数据库 cout << "line_count=" << count_cfg << endl; } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; }*/ //前置对应的监测点数量将根据监测点信息中的终端号进行统计,而不是直接从数据库获取 //监测点数量 //检测点数据 QMap ledger_monitor_map; codes.push_back("info"); parse_line_web_test(&ledger_monitor_map,codes); codes.clear(); /*根据终端号整理监测点数量和监测点数据*/ 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; } /*这段处理放在容器处理中 for (dev_no = 0; dev_no < g_node->n_clients; dev_no++) { if(((ied_usr_t*)(g_node->clients[dev_no]->usr_ext))->terminal_code); }*/ //读数据 /*try { OTLConnect(); std::string str2 = POSTGRES_SCHEMA;//schame analy std::string str1 = "select \"monitor_id\",\"terminal_code\",\"monitor_name\",\"logical_device_seq\",\"voltage_level\",\"terminal_connect\",\"update_time\" from \""; str1.append(str2); str1.append("\".\""); str1.append(POSTGRES_TABLEPREFIX); str1.append("pq_ledger_monitor"); str1.append("\" where status<>'04' and status<>'05' and \"terminal_code\" in ("); int dev_no = 0; for (dev_no = 0; dev_no < g_node->n_clients; dev_no++) { str1.append("'"); str1.append(((ied_usr_t*)(g_node->clients[dev_no]->usr_ext))->terminal_code); str1.append("'"); if (dev_no < g_node->n_clients - 1) { str1 += ","; } } str1.append(")"); cout << "pg sql2 is:" << str1 << endl; //int rtState = OTLState(); otl_stream i(1, // buffer size str1.c_str(), //SELECT statement db //connect object ); //create select stream 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]; otl_datetime timestamp; while (!i.eof()) { //while not end-of-data i >> monitor_id >> terminal_code >> monitor_name >> logical_device_seq >> voltage_level >> terminal_connect >> timestamp; cout << "monitor_id=" << monitor_id << " terminal_code=" << terminal_code << " monitor_name=" << monitor_name << " logical_device_seq=" << logical_device_seq; cout << " voltage_level=" << voltage_level << " terminal_connect=" << terminal_connect; cout << " timestamp: " << timestamp.year << "-" << timestamp.month << "-" << timestamp.day << " " << timestamp.hour << ":" << timestamp.minute << ":" << timestamp.second << endl;*/ //读数据 try { 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]; otl_datetime timestamp; // 遍历终端台账容器 QMap::iterator it; for (it = ledger_monitor_map.begin(); it != ledger_monitor_map.end(); ++it) { ledger_monitor* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 strncpy(monitor_id, value->monitor_id, sizeof(monitor_id) - 1); strncpy(terminal_code, value->terminal_code, sizeof(terminal_code) - 1); strncpy(monitor_name, value->monitor_name, sizeof(monitor_name) - 1); strncpy(logical_device_seq, value->logical_device_seq, sizeof(logical_device_seq) - 1); strncpy(voltage_level, value->voltage_level, sizeof(voltage_level) - 1); strncpy(terminal_connect, value->terminal_connect, sizeof(terminal_connect) - 1); //strncpy(timestamp, value->timestamp, sizeof(timestamp) - 1); timestamp = parseTimestamp(value->timestamp); } count_cfg = ledger_monitor_map.size();//获取监测点表的条数 //检测点数据 count_real++; memset(&line_info, 0, sizeof(line_info)); line_info.line_id = count_real; //cout << "line_id:" << line_info.line_id << endl; strcpy(line_info.mp_id, monitor_id); //cout << "mp_id:" << line_info.mp_id << endl; strcpy(line_info.terminal_code, terminal_code); //cout << "terminal_code:" << line_info.terminal_code << endl; if (isCharPtrEmpty(logical_device_seq)) { line_info.cpuno = 1; //cout << "logical_device_seq:is null~"<< line_info.cpuno << endl; } else { line_info.cpuno = std::atoi(logical_device_seq); //cout << "logical_device_seq:"<< logical_device_seq << 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; //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); //cout << "time:" << line_info.time << endl; strcpy(line_info.name, monitor_name); //cout << "name:" << line_info.name << endl; line_info.read_flag = 1; ied = find_ied_from_dev_code(line_info.terminal_code); if (ied && ied->usr_ext && line_info.cpuno && line_info.cpuno < 10) { char str[256]; byte_t cpuno = line_info.cpuno; //cout << "cpuno:" << line_info.cpuno << endl; //cout << "byte_t cpuno:" << cpuno-1 << endl; ied_usr = (ied_usr_t*)ied->usr_ext; ied_usr->LD_info[cpuno - 1] = line_info; ied_usr->LD_info[cpuno - 1].ied = ied; apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].rptcount = 0; //cout << "rptcount:" << ied_usr->LD_info[cpuno - 1].rptcount << endl; if (cpuno > ied->cpucount) { //int c = cpuno; //cout << "cpucount(linecount old):" << (int)(ied->cpucount) << "new:" << c << endl; ied->cpucount = cpuno; //cout << "byte_t cpucount:" << ied->cpucount+1 << endl; } } } OTLDisconnect(); } catch (otl_exception& e) { printf("\nledger monitor\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } if (count_cfg != count_real) return APR_EBADF; return APR_SUCCESS; } int parse_model_cfg_web_test() { std::vector codes;//入参集合 QMap icd_model_map; codes.push_back("info"); parse_model_web_test(&icd_model_map,codes); codes.clear(); try { char model_id[64]; char tmnl_type[64]; char tmnl_factory[64]; char file_name[128]; //char timestamp[64]; otl_datetime timestamp; // 遍历终端台账容器 QMap::iterator it; for (it = icd_model_map.begin(); it != icd_model_map.end(); ++it) { icd_model* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 strncpy(model_id, value->model_id, sizeof(model_id) - 1); strncpy(tmnl_type, value->tmnl_type, sizeof(tmnl_type) - 1); strncpy(tmnl_factory, value->tmnl_factory, sizeof(tmnl_factory) - 1); strncpy(file_name, value->file_name, sizeof(file_name) - 1); //strncpy(timestamp, value->timestamp, sizeof(timestamp) - 1); timestamp = parseTimestamp(value->timestamp); Set_xml_databaseinfo(model_id, tmnl_type, tmnl_factory, file_name, timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second); } } } catch (otl_exception& e) { printf("\nicd model\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } } #if 0 //定时任务的sql修改为web void OnTimerThread::run() { msleep(10000); printf("OnTimerThread::run() is called ...... \n"); static int delectflag = 1;//定时日志清理标记 bool account_update = true; bool asd = true; 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; QMap dic_task_block; // 向QMap中添加键值对 dic_task_block.insert("account", false); dic_task_block.insert("recruit ", false); dic_task_block.insert("log", false); dic_task_block.insert("multi_node", false); int ip_count = 0; int telnet_count = 0; // 查找键值对 if (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) { init_ping_telnet(ip_count, telnet_count); Cout_account_information(); } if (g_onlyIP[0] != 0) { printf("g_onlyIP[0]=!0 ontimer--%s--\n", g_onlyIP); add_comm_log(const_cast("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; int recall_flag1 = 1; //添加入参容器 std::vector codes; //char recalllllll[256] = "0923000982"; //CheckPG_To_Recall(1705168800, 1705168800 + 3599, recalllllll); while (1) { /*cout << "ip_count:" << ip_count << " telnet_count:" << telnet_count << endl; msleep(1000);*/ //进入线程时间 previousTime = apr_time_now(); apr_time_exp_gmt(&localTime, previousTime); //apr_time_t elapsedTime = currentTime - previousTime; //apr_time_as_msec(elapsedTime); //cout << "front num:" << FRONT_MP_NUM << endl; if (strcmp(subdir, "cfg_stat_data") == 0 || strcmp(subdir, "cfg_newhis_data") == 0) {//台账更新,多节点,通讯 //读取上次台账更新时间 //判断间隔执行 if (false) { //执行台账任务; } //记录现在时间 // //判断执行此任务时间段内是否有 任务被堵塞 if (MULTIPLE_NODE_FLAG && pgflag) { if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { //修改为web接口更新前置表 /*QString updateFrontSql;//待组装的pgsql语句 updateFrontSql.append(QString("update \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("set \"mp_num\"= %1,front_version='%2' ").arg(FRONT_MP_NUM).arg(PROGRAM_VERSION)); updateFrontSql.append(QString("where \"front_ip\" = '%1' and \"front_inst\"=%2;").arg(FRONT_IP).arg(FRONT_INST)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(updateFrontSql); Sql_data_list_mutex.unlock(); //解锁*/ codes.push_back("updatefront"); codes.push_back(std::string(FRONT_IP)); codes.push_back(intToString(FRONT_INST)); codes.push_back(intToString(FRONT_MP_NUM)); codes.push_back(std::string(PROGRAM_VERSION)); parse_device_web_test_front_write(codes); codes.clear(); } pgflag = 0; } else if (MULTIPLE_NODE_FLAG && pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } if (mp_num_hour != localTime.tm_hour) { std::string mp_num_str = ""; mp_num_str.append("connected device count:"); mp_num_str.append(QString::number(FRONT_MP_NUM).toStdString()); mp_num_str.append(",g_node clients:"); mp_num_str.append(QString::number(g_node->n_clients).toStdString()); add_comm_log(const_cast(mp_num_str.c_str())); mp_num_hour = localTime.tm_hour; } //2023-10-17 zw新增 定期obs oss和sql数据库记录删除 if (delectflag == 1 && localTime.tm_hour == 16) { delectflag = 0; //time_t timestamp = apr_time_as_time_t(previousTime); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; if (FILE_FLAG == 1) //阿里云 oss 文件删除 { //PutOSS("comtrade/not def/20231111/temp2.log", "/FeProject/dat/9D3AAA2BDCE430BA7E3E1302F132B880.xml"); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); long long deltime = stamp - (60 * 60 * 24 * 30);//减去30天 QDateTime deltime_Qtime = QDateTime::fromTime_t(deltime); QString tmp_chr1 = deltime_Qtime.toString("yyyyMMdd"); QString Oss_Del_Path = NULL; Oss_Del_Path.append("comtrade/"); Oss_Del_Path.append(LD_info->mp_id).append("/"); Oss_Del_Path.append(tmp_chr1).append("/"); //cout << Oss_Del_Path.toAscii().data() << endl; DelOSS(Oss_Del_Path.toAscii().data()); cpuno++; } i++; } //PutOSS("comtrade/not def/20231111/temp.log","/FeProject/dat/6A5C8A2A7BBC1A61D9EC3F1AE2A25A03.xml"); //PutOSS("comtrade/not def/20231111/temp2.log", "/FeProject/dat/6A5C8A2A7BBC1A61D9EC3F1AE2A25A03.xml"); //PutOSS("comtrade/not def/20231111/temp3.log", "/FeProject/dat/6A5C8A2A7BBC1A61D9EC3F1AE2A25A03.xml"); //DelOSS("comtrade/not def/20231111/temp3.log"); } else if (FILE_FLAG == 2)//华为云 obs 文件删除 { //OBSFile("/FeProject/dat/67BC249C13B5EC819CF4DF0307DB71C5.xml", "comtrade/not def/20231111/temp3.log", "putObject"); //OBSFile_del("comtrade/not def/20231111/temp3.log", "deleteObject"); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); long long deltime = stamp - (60 * 60 * 24 * 30);//减去30天 QDateTime deltime_Qtime = QDateTime::fromTime_t(deltime); QString tmp_chr1 = deltime_Qtime.toString("yyyyMMdd"); QString Oss_Del_Path = NULL; Oss_Del_Path.append("comtrade/"); Oss_Del_Path.append(LD_info->mp_id).append("/"); Oss_Del_Path.append(tmp_chr1).append("/"); //cout << Oss_Del_Path.toAscii().data() << endl; OBSFile_del(Oss_Del_Path.toAscii().data(), "deleteObject"); cpuno++; } i++; } } //pgsql删除记录 long long deltime = stamp - (60 * 60 * 24 * 30);//减去30天 QDateTime deltime_Qtime = QDateTime::fromTime_t(deltime); QString tmp_chr1 = deltime_Qtime.toString("yyyy-MM-dd"); //替换成web接口 /*QString pgsql0; pgsql0.append(QString("DELETE FROM \"%1\".\"%2meas_pq_comm_status_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql1; pgsql1.append(QString("DELETE FROM \"%1\".\"%2meas_pq_comm_error_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql2; pgsql2.append(QString("DELETE FROM \"%1\".\"%2meas_pq_measpoint_rationality_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql3; pgsql3.append(QString("DELETE FROM \"%1\".\"%2meas_pq_measpoint_intact_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); QString pgsql4; pgsql4.append(QString("DELETE FROM \"%1\".\"%2meas_pq_measpoint_match_tr\ WHERE \"statistical_data\" < '%3';").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(tmp_chr1)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(pgsql0); Sql_data_list.append(pgsql1); Sql_data_list.append(pgsql2); Sql_data_list.append(pgsql3); Sql_data_list.append(pgsql4); Sql_data_list_mutex.unlock(); //解锁*/ codes.push_back("delete"); codes.push_back(tmp_chr1.toStdString()); parse_database_delete(codes); codes.clear(); } if (delectflag == 0 && localTime.tm_hour != 16) { delectflag = 1; } //2023-10-17 zw新增 定期obs oss和sql数据库记录删除 end } if (strcmp(subdir, "cfg_newhis_data") == 0) {//上海定时招装置日志 static int hour_time = 0; if (localTime.tm_hour != hour_time) { hour_time = localTime.tm_hour; printf(">>>cfg_newhis_data is run!!!\n"); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; long long start = stamp - (stamp % 3600) - 3600 - 3600;//开始时间 当前整点值往前推两小时 long long end = start + 3599;//结束时间 QList recallinfo_list_hour; RecallInfo info; info.starttime = start - 10; info.endtime = end; recallinfo_list_hour.append(info); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) { while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; if (LD_info->logcount <= 0 || LD_info->read_flag == 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { for (int j = 0; j < recallinfo_list_hour.size(); j++) { CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } i++; } } } if (strcmp(subdir, "cfg_recallall_data") == 0) { static int recall_xml_time = 0; if (localTime.tm_min != recall_xml_time) { recall_xml_time = localTime.tm_min; //补招开始与截止时间 static long long recall_start_time = 0; static long long recall_end_time = 0; static int flag = 0; if (recall_start_time == 0 && recall_end_time == 0) {//无缓存数据 //查询一条 -1状态(代补招)的记录 char front_ip[42]; cout << "start select:" << endl; //替换为web接口 /*QString selectFrontSql; selectFrontSql.append(QString("select \"front_ip\" from \"%1\".\"%2meas_pq_front_list_tr\" ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); selectFrontSql.append(QString("where front_inst=%1 and \"front_status\" = '-1' LIMIT 1;").arg(g_front_seg_index)); cout << selectFrontSql.toStdString().c_str() << endl; try { otl_stream i(1, // buffer size selectFrontSql.toStdString().c_str(), db //connect object ); //create select stream while (!i.eof()) { //while not end-of-data i >> front_ip; break; //cout << "count=" << f2 << endl; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); continue; }*/ QMap front_map; codes.push_back("frontip"); codes.push_back("g_front_seg_index"); codes.push_back("-1"); parse_device_web_test_front_read(&front_map,codes); codes.clear(); // 遍历 QMap 容器 QMap::iterator it; for (it = front_map.begin(); it != front_map.end(); ++it) { front_list* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 从 value 中读取 front_ip strncpy(front_ip, value->front_ip, sizeof(front_ip) - 1); //应该只有一条记录 std::cout << "front_ip:" <> front_status; break; //cout << "count=" << f2 << endl; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); continue; }*/ QMap front_map; codes.push_back("frontstatus"); codes.push_back(dateRange.toStdString()); //ip codes.push_back("g_front_seg_index"); //inst parse_device_web_test_front_read(&front_map,codes); codes.clear(); // 遍历 QMap 容器 QMap::iterator it; for (it = front_map.begin(); it != front_map.end(); ++it) { front_list* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 从 value 中读取 front_ip strncpy(front_status, value->front_status, sizeof(front_status) - 1); //应该只有一条记录 std::cout << "front_status:" < duration) { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].endtime; RecallInfo info; info.starttime = start; info.endtime = end; recallinfo_list_hour.append(info); } else { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].starttime + j + max_interval; RecallInfo info; info.starttime = start; info.endtime = end - 1; recallinfo_list_hour.append(info); } } } int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; printf("/home/pq mpid=%s %d\n", LD_info->mp_id, LD_info->read_flag); if (LD_info->logcount <= 0 || LD_info->read_flag == 0) { continue; } printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { g_StatisticLackList_list_mutex.lock(); for (int j = 0; j < recallinfo_list_hour.size(); j++) { //替换成web接口 2024-10-21 lnk // if (CheckPG_To_Recall(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { // printf("CheckPG_To_Recall == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); if (CheckPG_To_Recall_web(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { printf("CheckPG_To_Recall_web == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); continue; } CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList.push_back(jr); } g_StatisticLackList_list_mutex.unlock(); } } i++; } } } } if (strcmp(subdir, "cfg_his_data") == 0) { if (pgflag) { if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { //替换为web接口 /*QString updateFrontSql; updateFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("values('his',10000,1,'02','01','%1',200) ").arg(PROGRAM_VERSION)); updateFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); updateFrontSql.append(QString("\"mp_num\"= '%1',front_version='%2'").arg(FRONT_MP_NUM).arg(PROGRAM_VERSION)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(updateFrontSql); Sql_data_list_mutex.unlock(); //解锁 */ codes.push_back("his"); codes.push_back("his"); //ip codes.push_back(std::string(PROGRAM_VERSION)); codes.push_back(intToString(FRONT_MP_NUM)); //检测点数 parse_device_web_test_front_write(codes); codes.clear(); } pgflag = 0; } else if (pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } static int cfg_his_data_hour_time = 0; if (localTime.tm_hour != cfg_his_data_hour_time) { cfg_his_data_hour_time = localTime.tm_hour; printf(">>>cfg_his_data is run!!!\n"); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; long long start = stamp - (stamp % 3600) - 3600 - 3600;//开始时间 当前整点值往前推两小时 long long end = start + 3599;//结束时间 QList recallinfo_list_hour; RecallInfo info; info.starttime = start - 10; info.endtime = end; recallinfo_list_hour.append(info); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) { while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; if (LD_info->logcount <= 0 || LD_info->read_flag == 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { for (int j = 0; j < recallinfo_list_hour.size(); j++) { //替换成web接口 2024-10-21 lnk //if (CheckPG_To_Recall(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { //printf("CheckPG_To_Recall == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); if (CheckPG_To_Recall_web(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { printf("CheckPG_To_Recall_web == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); continue; } CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } i++; } } } if (strcmp(subdir, "cfg_recallhis_data") == 0) { if (pgflag) { if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { //替换为web接口 /*QString updateFrontSql; updateFrontSql.append(QString("insert into \"%1\".\"%2meas_pq_front_list_tr\"(\"front_ip\",\"front_port\",\"front_inst\",\"front_type\",\"front_status\",\"front_version\",\"mp_num\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); updateFrontSql.append(QString("values('recallhis',10000,1,'02','01','%1',200) ").arg(PROGRAM_VERSION)); updateFrontSql.append(QString("on conflict(\"front_ip\",\"front_inst\") do update set ")); updateFrontSql.append(QString("\"mp_num\"= '%1',front_version='%2'").arg(FRONT_MP_NUM).arg(PROGRAM_VERSION)); Sql_data_list_mutex.lock(); //加锁 Sql_data_list.append(updateFrontSql); Sql_data_list_mutex.unlock(); //解锁 */ codes.push_back("his"); codes.push_back("recallhis"); //ip codes.push_back(std::string(PROGRAM_VERSION)); codes.push_back(intToString(FRONT_MP_NUM)); //检测点数 parse_device_web_test_front_write(codes); codes.clear(); } pgflag = 0; } else if (pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } } //g_node_id == HIS_DATA_BASE_NODE_ID && //printf("/home/pq hour=%d\n", localTime.tm_hour); if (0 && g_node_id == HIS_DATA_BASE_NODE_ID && (localTime.tm_hour <= 12 || localTime.tm_hour >= 20) && recall_flag1 == 1) { recall_flag1 = 0; QString MyKafkaIniFilename = QString("../etc/") + QString("mykafka.ini"); //+QString::fromAscii(subdir) QSettings settings(MyKafkaIniFilename, QSettings::IniFormat); QString dateString = settings.value("Recall/select_day").toString(); QList recallinfo_list_hour; QByteArray byteArray = dateString.toUtf8(); // 使用 UTF-8 编码 char* charArray = byteArray.data(); Get_Recall_Time(charArray, recallinfo_list_hour); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); if (LD_info->logcount <= 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 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->autorecallflag = 0; LD_info->autorecallcount = recallinfo_list_hour.size(); LD_info->autorecall = new autorecall_t * [recallinfo_list_hour.size()]; printf("/home/pq recall mpid=%s\n", LD_info->mp_id); for (int j = 0; j < recallinfo_list_hour.size(); j++) { printf("\n %lld ===== %11d\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime); LD_info->autorecall[j] = new autorecall_t[1]; LD_info->autorecall[j]->start = recallinfo_list_hour[j].starttime; LD_info->autorecall[j]->end = recallinfo_list_hour[j].endtime; } } cpuno++; } i++; } QDate date = QDate::fromString(dateString, "yyyy-MM-dd"); date.addDays(-1); // 一天 settings.setValue("Recall/select_day", date.toString("yyyy-MM-dd")); // 重新写入日期字符串 } if (localTime.tm_hour > 12 && localTime.tm_hour < 20 && recall_flag1 == 0) { recall_flag1 = 1; } msleep(1000); } printf(">>>OnTimerThread::run() is end!!!\n"); } #endif #endif /*/////////////////////////////////////////////////////////lnk10-11移除pg库sql的测试代码/////////////////////////////////////////////////////////////*/ /*/////////////////////////////////////////////////////////lnk10-24根据web接口修改/////////////////////////////////////////////////////////////*/ //添加了json字符串的入参 // 回调函数,将数据直接追加到 *ptr 中 size_t req_reply_http(void* contents, size_t size, size_t nmemb, void* userp) { size_t realsize = size * nmemb; char** ptr = (char**)userp; // 动态扩展 *ptr 的内存 char* temp = (char*)realloc(*ptr, strlen(*ptr) + realsize + 1); if (temp == NULL) { printf("Memory allocation failed!\n"); return 0; // 返回 0 以通知 curl 停止数据接收 } *ptr = temp; // 追加数据到 *ptr strncat(*ptr, (char*)contents, realsize); 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; // 初始化 *ptr 并分配空字符串 *ptr = (char*)malloc(1); if (*ptr == NULL) { printf("Memory allocation failed!\n"); return; } (*ptr)[0] = '\0'; // 为空字符串以便 strncat 操作 if (curl) { char url[256]; snprintf(url, sizeof(url), "%s?%s", strUrl.c_str(), code); //printf(">>>json %s\n", url);//减少不必要的打印 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) { // curl 初始化 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); // 设置 URL curl_easy_setopt(curl, CURLOPT_URL, url); // 设置数据接收和写入函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web); // 数据接收 std::string resPost0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); // 设置超时时间 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); if(json != ""){ // 设置 HTTP 方法为 POST curl_easy_setopt(curl, CURLOPT_POST, 1L); // 设置 JSON 格式的 body 数据 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", resPost0.c_str()); // 分配内存并复制返回结果 *ptr = (char*)malloc(resPost0.size() + 1); // 分配足够的内存空间 if (*ptr != NULL) { strcpy(*ptr, resPost0.c_str()); } else { printf("Memory allocation failed!\n"); } } // 清理请求头 curl_slist_free_all(headers); } else { printf(">>> web curl init failed"); } curl_easy_cleanup(curl); }*/ // 打印 terminal_dev_map 中所有内容的函数 void printTerminalDevMap(const QMap& terminal_dev_map) { QMap::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) << ", Device processNo:" << QString(dev->processNo) << ", Address:" << QString(dev->addr_str) << ", Port:" << QString(dev->port) << ", Timestamp:" << QString(dev->timestamp); // 打印监测点信息 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"; } } } //打印当前进程的台账////////////////////////////////////////////////////////////////////////// // 打印结构体信息的递归函数 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; // 打印每个LD_info的内容 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; //count暂不打印数组 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) { ied_t* ied; ied = find_ied_from_dev_idx(ied_usr.dev_idx); 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"); char portStr[20]; // 用于存放端口号的字符串 sprintf(portStr, "%u", ied->channel[0].port); // 将端口号转为字符串 outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_port: " + QByteArray(portStr) + "\n"); char statusStr[20]; // 用于存放状态的字符串 sprintf(statusStr, "%u", ied->channel[0].status); // 将连接状态转为字符串 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"); // 打印每个LD_info的内容 for (int i = 0; i < 10; ++i) { if (strcmp(ied_usr.LD_info[i].mp_id, "") != 0) { outputDevice->write("\r\x1B[K");outputDevice->write("|-- LD_info[" + QByteArray::number(i) + "]:\n"); // name 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: " + (strlen(ied_usr.LD_info[i].LD_name) == 0 ? QByteArray("NA") : QByteArray(ied_usr.LD_info[i].LD_name)) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write(" |-- read_flag: " + QByteArray::number(ied_usr.LD_info[i].read_flag) + "\n"); // index outputDevice->write("\r\x1B[K");outputDevice->write(" |-- line_id: " + QByteArray::number(ied_usr.LD_info[i].line_id) + "\n"); // monitorledger 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"); // count暂不打印数组 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"); //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"); for (int j = 0; j < ied_usr.LD_info[i].autorecallcount && ied_usr.LD_info->autorecall[j] != NULL; j++){ outputDevice->write("\r\x1B[K");outputDevice->write(" |-- autorecall_t[" + QByteArray::number(j) + "]:\n"); outputDevice->write("\r\x1B[K");outputDevice->write(" |-- start_time: " + QByteArray::number(ied_usr.LD_info->autorecall[j]->start) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write(" |-- end_time: " + QByteArray::number(ied_usr.LD_info->autorecall[j]->end) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write(" |-- need_steady: " + QByteArray::number(ied_usr.LD_info->autorecall[j]->need_steady) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write(" |-- need_voltage: " + QByteArray::number(ied_usr.LD_info->autorecall[j]->need_voltage) + "\n"); } // rpt 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"); // rtdata 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"); // RDRE outputDevice->write("\r\x1B[K");outputDevice->write(" |-- RDRE_FltNum: " + QByteArray::number(ied_usr.LD_info[i].RDRE_FltNum) + "\n"); for (int j = 0; j < 256; ++j) { if (ied_usr.LD_info[i].FltNum[j] != 0) { outputDevice->write("\r\x1B[K");outputDevice->write(" |-- FltNum[" + QByteArray::number(j) + "]: " + QByteArray::number(ied_usr.LD_info[i].FltNum[j]) + "\n"); } } // QVVR 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"); for (int j = 0; j < 256; ++j) { if (ied_usr.LD_info[i].qvvr[j].used_status != QVVR_DATA_NOT_USED) { 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"); } } } } outputDevice->write("\r\x1B[K");outputDevice->write("------------------------------------\n"); } // 打印所有设备信息或特定终端信息 void ledger(const char* terminal_id, QIODevice* outputDevice) { outputDevice->write("\r\x1B[K"); outputDevice->write("print ledger in shell"); pthread_mutex_lock(&mtx); std::cout << "ledger()hold lock !!!!!!!!!!!" << std::endl; 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)) { printLedgerinshell(*ied_usr, outputDevice); // 使用 QIODevice 输出 //std::cout << "!!! print to log !!!"<< std::endl; //printLedger(*ied_usr); if(terminal_id != NULL && strcmp(ied_usr->terminal_id, terminal_id) == 0){ found = true; } } } } 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"); outputDevice->write(msg); // 输出到 QIODevice } } //lnk20250210打印指定的变量名 void value_print(const char *variableName, QTcpSocket *clientSocket) { char buffer[256]; // 用于存储变量值的缓冲区 pthread_mutex_lock(&mtx); std::cout << "value_print hold lock !!!!!!!!!!!" << std::endl; // 打印变量值 if (strcmp(variableName, "frontindex") == 0) { sprintf(buffer, "frontindex = %d", g_front_seg_index); // 将 int 转换为字符串 clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); // 发送字符串到客户端 } else if (strcmp(variableName, "remtable") == 0) { sprintf(buffer, "remtable = %d",g_pt61850app->chnl_counts); clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); } else if (strcmp(variableName, "iedcount") == 0) { sprintf(buffer, "g_node->n_clients = %d, ied config count = %d",g_node->n_clients ,IED_COUNT); clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); } else if (strcmp(variableName, "frontfun") == 0) { sprintf(buffer, "frontfun = %s", subdir); clientSocket->write("\r\x1B[K"); 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); clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); }else if (strcmp(variableName, "init") == 0) { sprintf(buffer, "INITFLAG = %d",INITFLAG); clientSocket->write("\r\x1B[K"); clientSocket->write(buffer); }else { clientSocket->write("\r\x1B[K"); clientSocket->write("Unknown variable name\n> "); } pthread_mutex_unlock(&mtx); std::cout << "value_print free lock !!!!!!!!!!!" << std::endl; clientSocket->flush(); } std::list* 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) { clientSocket->write("\r\x1B[K"); clientSocket->write("Usage: viewlog [ERROR|WARN|NORMAL|DEBUG]\n> "); clientSocket->flush(); return; } QString logLevel = parts[1].toUpper(); std::list* logList = getLogList(logLevel); pthread_mutex_t* logMutex = getLogMutex(logLevel); if (!logList || !logMutex) { clientSocket->write("\r\x1B[K"); clientSocket->write("Invalid log level! Use ERROR, WARN, NORMAL, or DEBUG.\n> "); clientSocket->flush(); return; } stopViewLog = false; activeClient = clientSocket; // 记录当前 shell socket clientSocket->write("\r\x1B[K"); clientSocket->write(QString("Viewing logs for level: %1 (Press '`' to exit)\n> ").arg(logLevel).toUtf8()); clientSocket->flush(); while (!stopViewLog) { // **1. 监听输入,用户输入 ``` 退出** if (clientSocket->waitForReadyRead(500)) { // ? 监听输入 QByteArray input = clientSocket->readAll().trimmed(); if (input == "`") { // ? 用户输入 ```,退出日志模式 std::cout << "Received '`' from shell socket! Exiting viewlog...\n"; stopViewLog = true; showinshellflag = false; break; } } // **2. 获取日志内容并发送** pthread_mutex_lock(logMutex); if (!logList->empty()) { std::string logEntry = logList->front(); logList->pop_front(); pthread_mutex_unlock(logMutex); if (!logEntry.empty()) { clientSocket->write("\r\x1B[K"); clientSocket->write((logEntry + "\n").c_str()); clientSocket->flush(); } } else { pthread_mutex_unlock(logMutex); usleep(500000); // ? 防止 CPU 100% 占用 } } // **3. 退出 `viewlog`,返回 Shell** clientSocket->write("\r\x1B[K"); clientSocket->write("\nLog view stopped. Returning to shell.\n> "); clientSocket->flush(); } ////////////////////////////////////////////////////////////////////////////////////////////////// // 解析 JSON 的函数 多前置动态均分 int terminal_ledger_web(QMap* terminal_dev_map, const std::vector& codes, int index, int num) { //后续修改为根据index来获取对应的台账,num就没有作用了,index用来均分的也没有作用了 if(1 == MULTIPLE_NODE_FLAG){ // 参数验证 if (num <= 0) { std::cerr << "Error: 'num' must be greater than 0." << std::endl; return 1; // 返回适当的错误码 } index = index - 1; if (index < 0 || index >= num) { std::cerr << "Error: 'index' must be in the range [0, num-1]." << std::endl; return 1; // 返回适当的错误码 } } // 获取参数 if (codes.empty()) { std::cerr << "Error: 'codes' vector is empty." << std::endl; return 1; } std::string parm = codes[0]; char* ptr = NULL; // 发送 API 请求 SendJsonAPI_web(WEB_DEVICE, "",parm.c_str(), &ptr); if (ptr == NULL) { std::cerr << "Error: Received NULL response from SendJsonAPI_web." << std::endl; return 1; } // 调试用 printf("ptr:%s\n", ptr); cJSON* root = cJSON_Parse(ptr); //json格式序列化 int retry = 0; if (root == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(root == NULL){ // 在重试前释放之前的 ptr 以避免内存泄漏 if (ptr != NULL) { free(ptr); ptr = NULL; } //测试用url参数 //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; } // 如果重试后仍然失败,确保退出前释放任何已分配的内存 if (root == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); return 1; // 根据需要返回适当的错误码 } } // 获取 "code" 和 "msg" cJSON* codeItem = cJSON_GetObjectItem(root, "code"); cJSON* msgItem = cJSON_GetObjectItem(root, "msg"); // 使用 std::string 获取值 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"; // 打印结果 std::cout << "code: " << code << std::endl; std::cout << "msg: " << msg << std::endl; // 获取 "data" 数组 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; } //后续修改为根据index来获取对应的台账,将不再均分,获取所有台账并判断进程号 #if 0 int base_size = 0; int remainder = 0; int start_index = 0; int end_index = data_size; if(1 == MULTIPLE_NODE_FLAG){ // 计算每份的大小 base_size = data_size / num; remainder = data_size % num; // 计算当前份的起始和结束索引 start_index = index * base_size + (index < remainder ? index : remainder); end_index = start_index + base_size + (index < remainder ? 1 : 0); // 确保结束索引不超过数组大小 if (end_index > data_size) { end_index = data_size; } } #endif int start_index = 0; int end_index = data_size; // 遍历指定范围内的元素 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; continue; // 跳过无效的项 } terminal_dev* dev = new terminal_dev(); memset(dev, 0, sizeof(terminal_dev)); // 初始化结构体 // 解析各个字段 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); //lnk20250210台账进程号 cJSON* processNo = cJSON_GetObjectItem(item, "processNo"); // processNo转为字符串 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); 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); // 解析 monitorData 数组 cJSON* monitorData = cJSON_GetObjectItem(item, "monitorData"); if (monitorData && monitorData->type == cJSON_Array) { int j = 0; cJSON* monitorItem; cJSON_ArrayForEach(monitorItem, monitorData) { if (j >= 10){ std::cout << "一个终端最多只能有十个监测点" << std::endl; break; // 限制为最多10个 } 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); // 添加监测点状态 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++; } } // 准备键 QString key = QString(dev->terminal_id);//用id而不是code区分:有的code存在乱码 // 检查是否存在重复键 if (terminal_dev_map->contains(key)) { std::cerr << "Duplicate terminal_code found: " << key.toStdString() << std::endl; // 删除旧的 terminal_dev 对象以避免内存泄漏 delete terminal_dev_map->value(key); // 移除旧的键值对 terminal_dev_map->remove(key); // 插入新的 terminal_dev 对象 if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号 //调试用 std::cout<< "process num match" << std::endl; terminal_dev_map->insert(key, dev);}//后续修改为只有进程号匹配上index才录入当前进程 } else { // 插入新的 terminal_dev 对象 if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号 //调试用 std::cout<< "process num match" << std::endl; terminal_dev_map->insert(key, dev);}//后续修改为只有进程号匹配上index才录入当前进程 //调试用 //std::cout << "i = " << i << std::endl; //std::cout << "terminal_dev_map.size:" << terminal_dev_map->size() << std::endl; }//如果出现重复项,日志要有体现方便排查 } // 释放资源 cJSON_Delete(root); free(ptr); return 0; // 确保函数有返回值 } int parse_device_cfg_web() { std::cout << "parse_device_cfg_web" << endl; std::vector codes; //入参集合 /*//多前置判断 if (FRONT_INST == 0 || FRONT_IP[0] == '\0') { MULTIPLE_NODE_FLAG = 0; cout << "set MULTIPLE_NODE_FLAG:0,because do not have FRONT_INST or FRONT_IP" << endl; } char front_type[2] = {""}; int mp_num = 0; //用web接口替换前置表的读写,接口中解析结果,存入容器,从接口直接取出容器,从容器中获取需要的值,写入时直接传参: if (MULTIPLE_NODE_FLAG) { //前置表读取部分替换 QMap front_map; codes.push_back("info"); parse_device_web_test_front_read(&front_map,codes); codes.clear(); // 遍历 QMap 容器 QMap::iterator it; for (it = front_map.begin(); it != front_map.end(); ++it) { front_list* value = it.value(); // 确保 value 不为空 if (it.key() == "0.0.0.0" && value != nullptr) { // 从 value 中读取 front_type,保留前两个字符 strncpy(front_type, value->front_type, 2); front_type[2] = '\0'; // 确保以空字符结尾 // 将 mp_num 从字符串转换为整数 mp_num = std::atoi(value->mp_num); } } //前置表读取部分 //前置表写入部分 codes.push_back("insertfront"); codes.push_back(std::string(FRONT_IP)); codes.push_back(intToString(FRONT_INST)); codes.push_back(std::string(front_type)); codes.push_back(std::string(PROGRAM_VERSION)); codes.push_back("01"); //添加状态值 parse_device_web_test_front_write(codes); codes.clear(); //前置表写入部分 } cout << "mp_num:" << mp_num << " front_type:" << front_type << endl;*/ //当前前置不需要多前置,前置从配置文件(mykafka.ini)获取到ip后,将ip作为参数传送给web接口获取台账 ied_t* ied; ied_usr_t* ied_usr; chnl_usr_t* chnl_usr; int count_cfg = 0; //终端台账总数 int count_real = 0; //遍历终端台账的计数器 ///////////////////////////////////////////////////////////////////////////////// /*//读取终端ext表替换为web接口 QMap terminal_ext_map; //read_terminal_ext_pg(&terminal_ext_map); codes.push_back("info"); parse_device_web_test_ext(&terminal_ext_map,codes); codes.clear(); //读取终端ext表替换为web接口 //读取终端台账表总数替换为web接口 QMap terminal_dev_map; codes.push_back("count_cfg"); parse_device_web_test_dev(&terminal_dev_map,codes); // 遍历 QMap 容器 QMap::iterator it; for (it = terminal_dev_map.begin(); it != terminal_dev_map.end(); ++it) { terminal_dev* value = it.value(); // 确保 value 不为空 if (it.key() == "count_cfg" && value != nullptr) { // 将 count 从字符串转换为整数 count_cfg = std::atoi(value->count_cfg); } //调试用 cout << "count_cfg:" << count_cfg << " value->count_cfg:" << value->count_cfg << endl; } codes.clear(); //取完count——cfg要将容器清0否则影响取台账逻辑 terminal_dev_map.clear(); //读取终端台账表总数替换为web接口 //读取终端台账表替换为web接口 codes.push_back("info"); codes.push_back(intToString(FRONT_INST)); codes.push_back(intToString(mp_num)); codes.push_back(intToString(count_cfg)); codes.push_back(intToString(MULTIPLE_NODE_FLAG)); codes.push_back(intToString(g_front_seg_num)); parse_device_web_test_dev(&terminal_dev_map,codes); codes.clear(); if (MULTIPLE_NODE_FLAG && g_front_seg_num == 0) { if (mp_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * mp_num; } else { count_cfg = mp_num; } } else if (MULTIPLE_NODE_FLAG && g_front_seg_num != 0) { int front_num = (count_cfg / g_front_seg_num) + 1; if (front_num * FRONT_INST > count_cfg) { count_cfg = count_cfg - (FRONT_INST - 1) * front_num; } else { count_cfg = front_num; } }*/ //////////////////////////////////////////////////////////////////////////////// //接口合并,只用一个web接口获取终端台账和监测点台账 QMap terminal_dev_map; ////////////////////////////////////////////////////////////////////////////// //测试用 //codes.push_back("code1=ledger"); //填FRONT_IP和状态(可不填) //构造入参json std::string input_jstr = "{"; input_jstr += "\"ip\":\"" + std::string(FRONT_IP) + "\","; input_jstr += "\"runFlag\":" + TERMINAL_STATUS + ""; input_jstr += "}"; std::cout << "input_jstr: " << input_jstr << std::endl; // 输出结果 codes.push_back(input_jstr); //是否需要筛选状态直接在配置文件控制 /////////////////////////////////////////////////////////////////////////////// terminal_ledger_web(&terminal_dev_map,codes,g_front_seg_index,g_front_seg_num); codes.clear(); //调试用 //printTerminalDevMap(terminal_dev_map); count_cfg = terminal_dev_map.size();//容器的数量就是台账的数量 std::cout << "terminal_ledger_num:" << count_cfg << std::endl; g_node->n_clients = count_cfg; //这里开辟的ied的空间由配置文件中的终端台账数量决定lnk20250121 if(IED_COUNT < count_cfg){ //申请数至少是初始化能读取到的台账数,防止设置失误导致的崩溃。 //如果是多进程,IED_COUNT应该设置为大于平均数, //如果是单进程则应该设置为大于终端总数, //单进程多进程同时存在则单进程应该大于终端总数,否则添加台账时单进程部分就无法同步添加。 g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, count_cfg * sizeof(ied_t*)); //添加提示 std::cout << "!!!!!!!!!!single process can not add any ledger unless reboot!!!!!!!"<< std::endl; } else{ g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, IED_COUNT * sizeof(ied_t*));//g_node->clients 这块大内存空间存储了 count_cfg 个 ied_t* 类型的指针(即一个指针数组)这是(指向内存块的指针)的指针数组 } //把ied放入数组 for (int k = 0; k < count_cfg; k++){ //调试用 std::cout << "!!!!!!!!!!gnodeindex:" << k << std::endl; g_node->clients[k] = (ied_t*)apr_pcalloc(g_cfg_pool, sizeof(ied_t));}//每个 g_node->clients[k] 指向的内存块是独立的(每个 ied_t 结构体占用的内存块)这是指向内存块的指针 //读取终端台账表替换为web接口 ////////////////////////////////////////////////////////////////////////////////////////////////// //读数据 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]; //lnk20250210添加进程号 char processNo[64]; otl_datetime timestamp; // 遍历终端台账容器 QMap::iterator it; for (it = terminal_dev_map.begin(); it != terminal_dev_map.end(); ++it) { terminal_dev* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 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); strncpy(processNo, value->processNo, sizeof(processNo) - 1);//进程号 timestamp = parseTimestamp(value->timestamp); //处理终端台账 ied = g_node->clients[count_real++]; //这里申请的空间基于ied的数量,挂载到ied上 ied_usr = (ied_usr_t*)apr_pcalloc(g_init_pool, sizeof(ied_usr_t));//终端台账在initpool中申请空间 ied->usr_ext = ied_usr; if (ied_usr == NULL) return APR_ENOMEM; ied_usr->last_call_wavelist_time = sGetMsTime() + g_pt61850app->giTime * 1000; //这里申请的空间基于ied的数量,挂载到ied上 ied_usr->LD_info = (LD_info_t*)apr_pcalloc(g_init_pool, MAX_CPUNO * sizeof(LD_info_t));//监测点台账在initpool中申请空间 if (ied_usr->LD_info == NULL) return APR_ENOMEM; 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端口等 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; } /*不需要这三个信息 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; } //lnk20250210台账进程号 if (processNo != NULL) { apr_snprintf(ied_usr->processNo, sizeof(ied_usr->processNo), "%s", processNo);//processNo cout << "ied_usr->processNo:" << ied_usr->processNo << endl; } 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; } //lnk20241125实时数据用 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)) { // 转换成功,portStr全为数字,并且已经转换为int类型的port 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 cout << "ied_usr->port:" << port_char << ",非合法端口.使用默认端口:" << ied->channel[0].port << endl;//DEV_PortID } } if (timestamp.year != 0) { //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); cout << "ied_usr->time:" << ied_usr->time << endl; } //这里申请的空间基于ied的数量,挂载到ied上 chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t));//拓展定义的通信结构在g_init_pool中申请空间:拓展记录一些开关时间信息 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++; //调试用 //std::cout << "value:" << terminal_id <<" "<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; //for (int j = 0; j < 10; ++j) { // 假设最多有10个监测点 for (int j = 0; value->line[j].monitor_id[0] != '\0'; ++j){ ledger_monitor& monitor = value->line[j]; // 检查监测点 ID 是否为空以避免访问无效数据 /*if (monitor.monitor_id[0] != '\0') { std::cout << " Monitor ID: " << monitor.monitor_id << std::endl; std::cout << " Terminal Code: " << monitor.terminal_code << std::endl; //应该为空,json不带 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; std::cout << " Timestamp: " << monitor.timestamp << std::endl; //应该为空json不带 std::cout << " monitor_status: " << monitor.status << std::endl;*/ strncpy(monitor_id, monitor.monitor_id, sizeof(monitor_id) - 1); //strncpy(terminal_code, monitor.terminal_code, sizeof(terminal_code) - 1); //从上级获取 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); //timestamp = parseTimestamp(monitor.timestamp); //从上级获取 strncpy(monitor_status, monitor.status, sizeof(monitor_status) - 1);//添加监测点状态 //监测点台账处理 count_real_monitor++; memset(&line_info, 0, sizeof(line_info)); line_info.line_id = count_real_monitor; //监测点排号 cout << "line_id:" << line_info.line_id << endl; strcpy(line_info.mp_id, monitor_id); cout << "mp_id:" << line_info.mp_id << endl; strcpy(line_info.terminal_code, terminal_code); //从上级获取的终端号 cout << "terminal_code:" << line_info.terminal_code << endl; if (isCharPtrEmpty(logical_device_seq)) { line_info.cpuno = 1; //默认监测点实例号1 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; //lnk2024-8-14记录接线标志 if (strcmp(line_info.v_wiring_type, "02") == 0) { isdelta_flag = 1; //存在一个监测点为角型接线则这个前置就要启动第二个配置列表 cout << "monitor_id" << monitor_id << "v_wiring_type:" << line_info.v_wiring_type << "is delta wiring:" << isdelta_flag << endl; } strcpy(line_info.monitor_status, monitor_status); cout << "monitor_status:" << line_info.monitor_status << endl; //// 构造struct tm对象 struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 //从上级获取的timestamp timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 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(time); cout << "time:" << line_info.time << endl; strcpy(line_info.name, monitor_name); cout << "name:" << line_info.name << endl; line_info.read_flag = ENABLE; //监测点有效 //ied = find_ied_from_dev_code(line_info.terminal_code); //不需要再找上级终端了,已经在终端里了 if (ied && ied->usr_ext && line_info.cpuno && (static_cast(line_info.cpuno) < 10)) { char str[256]; //256大小 byte_t cpuno = line_info.cpuno; cout << "cpuno:" << (int)line_info.cpuno << endl; cout << "index cpuno:" << cpuno-1 << endl; ied_usr = (ied_usr_t*)ied->usr_ext; ied_usr->LD_info[cpuno - 1] = line_info; //cpuno默认是1 ied_usr->LD_info[cpuno - 1].ied = ied; apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno);//将监测点逻辑号转为PQMonitorPQM+逻辑号 //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 字节的内存 ied_usr->LD_info[cpuno - 1].LD_name = (char *)apr_palloc(g_init_pool, 256); // 清空内存,防止残留数据 memset(ied_usr->LD_info[cpuno - 1].LD_name, 0, 256); // 将 str 中的内容复制到预先分配的内存中,最多复制 256 字节(包含结束符) apr_cpystrn(ied_usr->LD_info[cpuno - 1].LD_name, str, 256); //这里申请的空间基于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 在后续的代码中可能会被填充 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; } } //} } } } ////////////////////////////////////////////////////////////////////////////////////////////////// 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) { printf("\ndev tr\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } } int parse_model_web(QMap* icd_model_map,const std::vector& codes) { std::string parm = codes[0]; //装置型号列表,格式["型号1","型号2"...] char* ptr=NULL; //测试用url参数 //SendJsonAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", parm.c_str(), "",&ptr); SendJsonAPI_web(WEB_ICD,"",parm.c_str(),&ptr); // 检查 ptr 是否为 NULL,避免 std::string 初始化失败 if (ptr == NULL) { // 处理 ptr 为 NULL 的情况,例如日志记录或错误处理 std::cout << "Error: Received NULL response"<< std::endl; return 1; } //调试用 printf("ptr:%s\n",ptr); cJSON* root = cJSON_Parse(ptr); //json格式序列化 int retry = 0; if (root == NULL) { printf("web error %s\n", cJSON_GetErrorPtr()); //重发多次 while(root == NULL){ // 在重试前释放之前的 ptr 以避免内存泄漏 if (ptr != NULL) { free(ptr); ptr = NULL; } //测试用url参数 //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"); // 使用 std::string 获取值 std::string code = (codeItem != NULL) ? codeItem->valuestring : "not found"; std::string msg = (msgItem != NULL) ? msgItem->valuestring : "not found"; // 打印结果 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); cJSON* filePath = cJSON_GetObjectItem(item, "filePath");//新增 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); // 添加到 QMap icd_model_map->insert(model->model_id, model); } } cJSON_Delete(root); free(ptr); // 如果 SendJsonAPI_web 分配了内存,记得释放 return 0; // 确保函数有返回值 } int parse_model_cfg_web() { std::vector codes;//入参集合 QMap icd_model_map; ///////////////////////////////////////////////////////////////////////// //测试用 //codes.push_back("code1=model1"); //填入终端型号列表 //使用中端型号列表构建入参json字符串 // 遍历前置所有监测点 ied_t* ied; ied_usr_t* ied_usr; std::cout << "g_node->n_clients" << g_node->n_clients << std::endl; std::set devTypes; // 用于去重的集合set 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; // 假设 dev_type 是一个字符串类型,加入集合 ,这里会去重 if (strlen(ied_usr->dev_type) > 0) { devTypes.insert(std::string(ied_usr->dev_type)); } } // 手动构建 JSON 字符串 std::string input_jstr = "["; bool first = true; // 用于处理逗号 for (std::set::iterator it = devTypes.begin(); it != devTypes.end(); ++it) { if (!first) { input_jstr += ","; // 添加逗号 } first = false; // 第一次之后设置为 false input_jstr += "\"" + *it + "\""; // 添加字符串 } input_jstr += "]"; // 结束 JSON 数组 std::cout << "input_jstr: " << input_jstr << std::endl; // 输出结果 if(ICD_FLAG == "1"){ codes.push_back(input_jstr); //填入终端型号列表-获取指定的icd配置文件 } else{ codes.push_back("[]"); //不填-获取所有的icd配置文件 } ///////////////////////////////////////////////////////////////////////// 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; // 遍历终端台账容器 QMap::iterator it; for (it = icd_model_map.begin(); it != icd_model_map.end(); ++it) { icd_model* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 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; //lnk20241125测试用 //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) { printf("\nicd model\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return e.code; } } ////////////////////////////////////////////////////////////icd模型重构函数lnk20250116 char* parse_model_cfg_web_one(ied_t* ied) { std::vector codes;//入参集合 QMap icd_model_map; ied_usr_t* ied_usr; ied_usr = (ied_usr_t*)ied->usr_ext; // 手动构建 JSON 字符串 std::string input_jstr = "["; input_jstr += "\"" + std::string(ied_usr->dev_type) + "\""; input_jstr += "]"; // 结束 JSON 数组 std::cout << "input_jstr: " << input_jstr << std::endl; // 输出结果 codes.push_back(input_jstr); //填入终端型号列表-获取指定的icd配置文件 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;//不使用 // 遍历终端台账容器 QMap::iterator it; for (it = icd_model_map.begin(); it != icd_model_map.end(); ++it) { icd_model* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 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; //lnk20241125测试用 //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 model_id; } catch (otl_exception& e) { printf("\nicd model\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return NULL; } } //////////////////////////////////////////////////////////// //自动补招接口,暂不修改,可能不使用 #if 0 bool CheckPG_To_Recall_web(long long start, long long end, char* Monitorid) { QDateTime deltime_Qtime = QDateTime::fromTime_t(start); QDateTime deltime_Qtime_end = QDateTime::fromTime_t(end); QString tmp_chr1 = deltime_Qtime.toString("yyyy-MM-dd"); //当前天 QString start_chr1 = deltime_Qtime.toString("yyyy-MM-dd hh:mm:ss"); //当前天 QString end_chr1 = deltime_Qtime_end.toString("yyyy-MM-dd hh:mm:ss"); //当前天 int timespan = 3;//默认时间间隔 try { std::vector codes;//入参集合 QMap intact_list_map; codes.push_back("deciderecall"); codes.push_back(tmp_chr1.toStdString()); codes.push_back(std::string(Monitorid)); parse_intact_web_test_read(&intact_list_map,codes); codes.clear(); try { double exp_num; double act_num; // 遍历终端台账容器 QMap::iterator it; for (it = intact_list_map.begin(); it != intact_list_map.end(); ++it) { intact_list* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 找到容器中对应名称并取值 exp_num = atof(value->exp_num); act_num = atof(value->act_num); std::cout << exp_num << " " << act_num << std::endl; timespan = 1440 / exp_num; printf("\n %f %f %d \n", exp_num, act_num, timespan); } } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } //OTLDisconnect(); } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } try { long long starttime = start; //补招起始时间 long long endtime = starttime + 3599; //补招结束时间 QList timestamp_list; //数据库完整性记录时间点 QList recallinfo_list; //待补招队列 QList recallinfo_list_hour; //待补招队列-以小时为最大间隔 std::vector codes;//入参集合 QMap intact_list_map; codes.push_back("handlerecall"); codes.push_back(tmp_chr1.toStdString()); codes.push_back(std::string(Monitorid)); codes.push_back(start_chr1.toStdString()); codes.push_back(end_chr1.toStdString()); parse_intact_web_test_read(&intact_list_map,codes); codes.clear(); try { otl_datetime timestamp; // 遍历终端台账容器 if (intact_list_map.contains(Monitorid)) { intact_list* value = intact_list_map.value(Monitorid); // 找到键值为 "id" 的对象 if (value != nullptr) { // 遍历 value_time 容器并输出所有时间字符串 for (std::vector::const_iterator it = value->value_time.begin(); it != value->value_time.end(); ++it) { const std::string& time = *it; std::cout << "Time: " << time << std::endl; timestamp = parseTimestamp(time); struct tm timeinfo; timeinfo.tm_year = timestamp.year - 1900; // 年份需要减去1900 timeinfo.tm_mon = timestamp.month - 1; // 月份需要减去1 timeinfo.tm_mday = timestamp.day; timeinfo.tm_hour = timestamp.hour; timeinfo.tm_min = timestamp.minute; timeinfo.tm_sec = timestamp.second; time_t timestamp = std::mktime(&timeinfo); long long stamp = static_cast(timestamp); timestamp_list.append(stamp); } } } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } //OTLDisconnect(); if (timestamp_list.size() <= (60 / timespan) * 0.97) //完整性数据表无数据 { printf("\n return ture %d %f\n", timestamp_list.size(), (60 / timespan) * 0.97); return true; } else { printf("\n return false %d %f\n", timestamp_list.size(), (60 / timespan) * 0.97); return false; } } catch (otl_exception& e) { printf("\nPostgreSL\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); return false; } printf("\n>>>error quit!!\n"); return true; } #endif //定时任务不需要定时日志清理和其他一些功能,统一放在这里修改 void OnTimerThread::run() { msleep(10000); printf("OnTimerThread::run() is called ...... \n"); bool account_update = true; bool asd = true; //当前时间获取 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; /* //web手动补招的进程,测试前置所有连接的终端连接情况 int ip_count = 0; int telnet_count = 0; if (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) { //在测试连接时给台账加锁lnk20250114 pthread_mutex_lock(&mtx); std::cout << "testping hold lock !!!!!!!!!!!" << std::endl; init_ping_telnet(ip_count, telnet_count); Cout_account_information(); pthread_mutex_unlock(&mtx); std::cout << "testping free lock !!!!!!!!!!!" << std::endl; } *///放入testsheell //单联模式 if (g_onlyIP[0] != 0) { printf("g_onlyIP[0]=!0 ontimer--%s--\n", g_onlyIP); add_comm_log(const_cast("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; int recall_flag1 = 1; //补招标志 //添加入参容器 std::vector codes; while (1) { //进入线程时间 previousTime = apr_time_now(); apr_time_exp_gmt(&localTime, previousTime); if (strcmp(subdir, "cfg_stat_data") == 0 || strcmp(subdir, "cfg_newhis_data") == 0) {//台账更新,多节点,通讯 //不需要更新前置表 /*//判断执行此任务时间段内是否有 任务被堵塞 if (MULTIPLE_NODE_FLAG && pgflag) { if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { codes.push_back("updatefront"); codes.push_back(std::string(FRONT_IP)); codes.push_back(intToString(FRONT_INST)); codes.push_back(intToString(FRONT_MP_NUM)); codes.push_back(std::string(PROGRAM_VERSION)); parse_device_web_test_front_write(codes); codes.clear(); } pgflag = 0; } else if (MULTIPLE_NODE_FLAG && pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; }*/ //日志记录 if (mp_num_hour != localTime.tm_hour) { pthread_mutex_lock(&mtx); std::cout << "ontime hold lock !!!!!!!!!!!" << std::endl; std::string mp_num_str = ""; mp_num_str.append("connected device count:"); mp_num_str.append(QString::number(FRONT_MP_NUM).toStdString());//记录连接的检测点数 mp_num_str.append(",g_node clients:"); mp_num_str.append(QString::number(g_node->n_clients).toStdString()); add_comm_log(const_cast(mp_num_str.c_str())); mp_num_hour = localTime.tm_hour; pthread_mutex_unlock(&mtx); std::cout << "ontime free lock !!!!!!!!!!!" << std::endl; } } //不使用的代码lnk20241206 #if 0 if (strcmp(subdir, "cfg_newhis_data") == 0) {//上海定时招装置日志 static int hour_time = 0; if (localTime.tm_hour != hour_time) { hour_time = localTime.tm_hour; printf(">>>cfg_newhis_data is run!!!\n"); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; long long start = stamp - (stamp % 3600) - 3600 - 3600;//开始时间 当前整点值往前推两小时 long long end = start + 3599;//结束时间 QList recallinfo_list_hour; RecallInfo info; info.starttime = start - 10; info.endtime = end; recallinfo_list_hour.append(info); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) { while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; if (LD_info->logcount <= 0 || LD_info->read_flag == 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { for (int j = 0; j < recallinfo_list_hour.size(); j++) { CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } i++; } } } //全量补招将通过web下发,而不是手动操作数据库 if (strcmp(subdir, "cfg_recallall_data") == 0) { static int recall_xml_time = 0; if (localTime.tm_min != recall_xml_time) { recall_xml_time = localTime.tm_min; //补招开始与截止时间 static long long recall_start_time = 0; static long long recall_end_time = 0; static int flag = 0; if (recall_start_time == 0 && recall_end_time == 0) {//无缓存数据 //查询一条 -1状态(代补招)的记录 char front_ip[42]; cout << "start select:" << endl; QMap front_map; codes.push_back("frontip"); codes.push_back("g_front_seg_index"); codes.push_back("-1"); parse_device_web_test_front_read(&front_map,codes); codes.clear(); // 遍历 QMap 容器 QMap::iterator it; for (it = front_map.begin(); it != front_map.end(); ++it) { front_list* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 从 value 中读取 front_ip strncpy(front_ip, value->front_ip, sizeof(front_ip) - 1); //应该只有一条记录 std::cout << "front_ip:" <::iterator it; for (it = front_map.begin(); it != front_map.end(); ++it) { front_list* value = it.value(); // 确保 value 不为空 if (value != nullptr) { // 从 value 中读取 front_ip strncpy(front_status, value->front_status, sizeof(front_status) - 1); //应该只有一条记录 std::cout << "front_status:" < duration) { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].endtime; RecallInfo info; info.starttime = start; info.endtime = end; recallinfo_list_hour.append(info); } else { long long start = recallinfo_list[i].starttime + j; long long end = recallinfo_list[i].starttime + j + max_interval; RecallInfo info; info.starttime = start; info.endtime = end - 1; recallinfo_list_hour.append(info); } } } int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; printf("/home/pq mpid=%s %d\n", LD_info->mp_id, LD_info->read_flag); if (LD_info->logcount <= 0 || LD_info->read_flag == 0) { continue; } printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { g_StatisticLackList_list_mutex.lock(); for (int j = 0; j < recallinfo_list_hour.size(); j++) { //替换成web接口 2024-10-21 lnk // if (CheckPG_To_Recall(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { // printf("CheckPG_To_Recall == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); if (CheckPG_To_Recall_web(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { printf("CheckPG_To_Recall_web == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); continue; } CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList.push_back(jr); } g_StatisticLackList_list_mutex.unlock(); } } i++; } } } } //自动补招可能改为web轮询下发 if (strcmp(subdir, "cfg_his_data") == 0) { if (pgflag) { //当前不需要实时更新前置表对应的监测点 /*if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { codes.push_back("his"); codes.push_back("his"); //ip codes.push_back(std::string(PROGRAM_VERSION)); codes.push_back(intToString(FRONT_MP_NUM)); //检测点数 parse_device_web_test_front_write(codes); codes.clear(); }*/ pgflag = 0; } else if (pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } static int cfg_his_data_hour_time = 0; if (localTime.tm_hour != cfg_his_data_hour_time) { cfg_his_data_hour_time = localTime.tm_hour; printf(">>>cfg_his_data is run!!!\n"); long long stamp = static_cast(previousTime) / 1000000; cout << ">>>>>>>>>The Time is: " << stamp << endl; long long start = stamp - (stamp % 3600) - 3600 - 3600;//开始时间 当前整点值往前推两小时 long long end = start + 3599;//结束时间 QList recallinfo_list_hour; RecallInfo info; info.starttime = start - 10; info.endtime = end; recallinfo_list_hour.append(info); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); //if (chnl_usr->m_state == CHANNEL_CONNECTED) { while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); cpuno++; if (LD_info->logcount <= 0 || LD_info->read_flag == 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 0) { for (int j = 0; j < recallinfo_list_hour.size(); j++) { //替换成web接口 2024-10-21 lnk //if (CheckPG_To_Recall(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { //printf("CheckPG_To_Recall == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); if (CheckPG_To_Recall_web(recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id) == false) { printf("CheckPG_To_Recall_web == false %d-%d %s\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime, LD_info->mp_id); continue; } CJournalRecall jr; jr.MonitorID = QString(LD_info->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"); jr.STEADY = QString::number(1, 10); jr.VOLTAGE = QString::number(1, 10); g_StatisticLackList_list_mutex.lock(); g_StatisticLackList.push_back(jr); g_StatisticLackList_list_mutex.unlock(); } } } i++; } } } #endif //单条补招由web触发,cfg_recallhis_data进程启动时会分配一个专用的端口,其他进程没有 if (strcmp(subdir, "cfg_recallhis_data") == 0) { if (pgflag) { //当前不需要实时更新前置表对应的监测点 /*if (FRONT_INST != 0 && FRONT_IP[0] != '\0') { codes.push_back("his"); codes.push_back("recallhis"); //ip codes.push_back(std::string(PROGRAM_VERSION)); codes.push_back(intToString(FRONT_MP_NUM)); //检测点数 parse_device_web_test_front_write(codes); codes.clear(); }*/ pgflag = 0; } else if (pgmin != localTime.tm_min) { pgmin = localTime.tm_min; pgflag = 1; } } //不使用的代码lnk20241206 #if 0 //自动补招处理 if (0 && g_node_id == HIS_DATA_BASE_NODE_ID && (localTime.tm_hour <= 12 || localTime.tm_hour >= 20) && recall_flag1 == 1) { recall_flag1 = 0; QString MyKafkaIniFilename = QString("../etc/") + QString("mykafka.ini"); //+QString::fromAscii(subdir) QSettings settings(MyKafkaIniFilename, QSettings::IniFormat); QString dateString = settings.value("Recall/select_day").toString(); QList recallinfo_list_hour; QByteArray byteArray = dateString.toUtf8(); // 使用 UTF-8 编码 char* charArray = byteArray.data(); Get_Recall_Time(charArray, recallinfo_list_hour); int i = 0; while (i < g_pt61850app->chnl_counts) { chnl_usr_t* chnl_usr; ied_t* ied; ied_usr_t* ied_usr; LD_info_t* LD_info; int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; ied = chnl_usr->chnl->ied; ied_usr = GET_IEDEXT_ADDR(ied); while (cpuno < ied->cpucount) { LD_info = &(ied_usr->LD_info[cpuno]); if (LD_info->logcount <= 0) continue; printf("/home/pq mpid=%s\n", LD_info->mp_id); printf("\n %d ===== %d\n", recallinfo_list_hour.size(), LD_info->autorecallflag); if (recallinfo_list_hour.size() != 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->autorecallflag = 0; LD_info->autorecallcount = recallinfo_list_hour.size(); LD_info->autorecall = new autorecall_t * [recallinfo_list_hour.size()]; printf("/home/pq recall mpid=%s\n", LD_info->mp_id); for (int j = 0; j < recallinfo_list_hour.size(); j++) { printf("\n %lld ===== %11d\n", recallinfo_list_hour[j].starttime, recallinfo_list_hour[j].endtime); LD_info->autorecall[j] = new autorecall_t[1]; LD_info->autorecall[j]->start = recallinfo_list_hour[j].starttime; LD_info->autorecall[j]->end = recallinfo_list_hour[j].endtime; } } cpuno++; } i++; } QDate date = QDate::fromString(dateString, "yyyy-MM-dd"); date.addDays(-1); // 一天 settings.setValue("Recall/select_day", date.toString("yyyy-MM-dd")); // 重新写入日期字符串 } #endif if (localTime.tm_hour > 12 && localTime.tm_hour < 20 && recall_flag1 == 0) { recall_flag1 = 1; } msleep(1000); } printf(">>>OnTimerThread::run() is end!!!\n"); } //补招web处理函数 /*int HandleRecall_http(const httplib::Request& req, httplib::Response& res) //接收并处理Web客户端发来的信息 { // 打印请求的查询参数 std::cout << "Query parameters: " << std::endl; if (req.body.empty()) { res.status = 400; // 返回 400 Bad Request 错误 res.set_content("Missing code or parameter", "application/json"); return 10000; } std::cout << "Received code: " << req.body<< std::endl; try { printf("来自web客户端消息:\n"); cJSON* json_root = cJSON_Parse(req.body.c_str()); //json格式序列化 //第一个参数 if (json_root == NULL) { return 10000; }*/ int recall_json_handle(const char* jstr) { //不指定稳态/暂态则全部补招 int stat = 0; //都不补 int voltage= 0; try{ std::vector recallParams; cJSON* json_root = cJSON_Parse(jstr); //json格式序列化 //第一个参数 if (json_root == NULL) { std::cout << "json root解析错误"<< std::endl; return 10000; } /*cJSON* json_code = NULL; cJSON* json_msg = NULL; std::vector recallParams; json_code = cJSON_GetObjectItem(json_root, "code"); //获取code if (json_code != NULL) { std::cout << "Received code: " << json_code->valuestring << std::endl; } else { return 10000; } json_msg = cJSON_GetObjectItem(json_root, "msg"); //获取msg if (json_code != NULL) { std::cout << "Received msg: " << json_msg->valuestring << std::endl; } else { return 10000; }*/ // 获取 "data" 数组 //cJSON* dataArray = cJSON_GetObjectItem(json_root, "data"); // 遍历数组的每个对象 if (json_root->type == cJSON_Array) { for (cJSON* item = json_root->child; item != nullptr; item = item->next) { // 获取 monitorId 数组 cJSON* monitorIdArray = cJSON_GetObjectItem(item, "monitorId"); cJSON* timeIntervalArray = cJSON_GetObjectItem(item, "timeInterval"); //判断dataType是否为空 cJSON* datatype = cJSON_GetObjectItem(item, "dataType"); //添加异常判断防止崩溃 if(monitorIdArray == NULL || timeIntervalArray == NULL || datatype == NULL ){ std::cout << "json内容解析错误 "<< std::endl; return 10000; } if(strcmp(datatype->valuestring, "") != 0)//非空 { stat = (strcmp(datatype->valuestring, "0") == 0) ? 1 : 0;//稳态 voltage= (strcmp(datatype->valuestring, "1") == 0) ? 1 : 0;//暂态 } else //空或其他 { stat = 1; voltage= 1; } //调试用 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; //monitorIdArray有数据的情况 if (monitorIdArray != nullptr && monitorIdArray->type == cJSON_Array && timeIntervalArray->type == cJSON_Array && monitorIdArray->child != nullptr) { // 遍历 monitorId 数组 for (cJSON* idItem = monitorIdArray->child; idItem != nullptr; idItem = idItem->next) { QString monitorId = QString(idItem->valuestring); //添加判断数组中当前监测点是否属于本进程20241230,防止出现非本进程的监测点触发补招 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; for (int m = 0; m<10; m++){//最多10个 if(strcmp(ied_usr->LD_info[m].mp_id,"") == 0)continue;//跳过空的 if(strcmp(ied_usr->LD_info[m].mp_id,monitorId.toStdString().c_str()) == 0){//匹配上了 mppair = 1; break;//找到就退出监测点循环 } } if(mppair == 1)break;//找到就退出终端循环 } if(mppair == 0)continue;//当前进程的监测点都没有找到这个检测点号,说明不是本进程的监测点,处理数组的下一个监测点 //调试用 std::cout << "find mpid:" << monitorId.toStdString() << "in this process,mppair=" << mppair <child; timeItem != nullptr; timeItem = timeItem->next) { QString timeInterval = QString(timeItem->valuestring); QString start = timeInterval.left(timeInterval.indexOf("~")); QString end = timeInterval.mid(timeInterval.indexOf("~") + 1); // 创建 RecallParam 对象并添加到列表中 RecallParam param; param.mp_id = monitorId; param.start = start; param.end = end; param.stat = stat; param.voltage = voltage; recallParams.push_back(param); } } } //monitorIdArray为空的情况 else if (monitorIdArray != nullptr && monitorIdArray->type == cJSON_Array && monitorIdArray->child == nullptr) { // monitorIdArray 为空 std::cout << "monitorIdArray is null" << std::endl; //所有监测点补招 // 遍历前置所有监测点 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); // 遍历 timeInterval 数组 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); // 创建 RecallParam 对象并添加到列表中 RecallParam param; param.mp_id = monitorId; param.start = start; param.end = end; param.stat = stat; param.voltage = voltage; recallParams.push_back(param); } } } } else{ std::cout << "monitorIdArray 不存在或类型不正确" << std::endl; } } } cJSON_Delete(json_root); //web入参处理结束 //遍历容器取出所有补招 for (std::vector::iterator it = recallParams.begin(); it != recallParams.end(); ++it) { QList 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"); //现在暂态稳态根据web获取 //jr.STEADY = QString::number(1, 10); // 将整数 1 转换为字符串并赋值 //jr.VOLTAGE = QString::number(1, 10);// 将整数 1 转换为字符串并赋值 //调试用 //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) { printf("处理客户端发送的消息错误,原因:%s\n", e.what()); return 10004; } return 000000; } int rtdata_http(const char* jstr) { } // 声明外部函数,http功能用库链接,单独编译 #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; // 创建 JSON 对象 cJSON* json_response = cJSON_CreateObject(); // 添加字段 if(result == 000000){ cJSON_AddStringToObject(json_response, "code", "A0000"); cJSON_AddStringToObject(json_response, "msg", "数据补招执行成功"); } else{ cJSON_AddStringToObject(json_response, "code", "A0002"); cJSON_AddStringToObject(json_response, "msg", "数据补招执行失败"); } cJSON_AddNullToObject(json_response, "data"); // 设置为 null // 将 JSON 对象转换为字符串 char* json_string = cJSON_Print(json_response); std::cout << json_string << std::endl; //发送回复给对方,只发一次 SendJsonAPI_web("调用方", "", json_string ,&ptr); // 清理 cJSON_Delete(json_response); free(json_string); // 释放打印字符串的内存 } #endif void WebhttpThread::run() { int ret = 1; printf("WebhttpThread::run() is called ...... \n"); while(1){ //补招进程 if (!threadmsghttp(1) && g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) {//http处理一条消息,状态变为false,不再处理消息(http此时可能有消息来但是不处理)后这个线程开始读取数据 const char* data = getReceivedData(1);//从http中取数据,指针 std::cout << "recall data cfg:" << data <= 0) { // 将 val 的高 6 位转化为 Base64 字符,并添加到输出中 out.push_back(base64_chars[(val >> valb) & 0x3F]); valb -= 6; // 每次编码后,位偏移量减少 6 位 } } // 如果还有剩余的位数,补充 '=' 字符 while (valb > -6) { out.push_back('='); valb -= 6; // 每次添加一个 '=',位偏移量减少 6 位 } return out; // 返回编码后的字符串 } void handleUploadResponse(const std::string& response, char* wavepath) { // 解析 JSON 响应 cJSON* json_data = cJSON_Parse(response.c_str()); if (json_data == nullptr) { std::cerr << "Error parsing response: " << cJSON_GetErrorPtr() << std::endl; return; } // 提取字段 cJSON* codeItem = cJSON_GetObjectItem(json_data, "code"); cJSON* msgItem = cJSON_GetObjectItem(json_data, "msg"); cJSON* dataItem = cJSON_GetObjectItem(json_data, "data"); if (codeItem && 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; // 输出信息 std::cout << "File Path: " << name << std::endl; std::cout << "Uploaded File Name: " << fileName << std::endl; std::cout << "File URL: " << url << std::endl; // 找到最后一个 '.' size_t pos = fileName.find_last_of('.'); std::string nameWithoutExt; if (pos != std::string::npos) { // 截取去掉后缀的部分 nameWithoutExt = fileName.substr(0, pos); } else { // 如果没有后缀,直接使用原文件名 nameWithoutExt = fileName; } // 拷贝到 wavepath strcpy(wavepath, nameWithoutExt.c_str()); std::cout << "wavepath: " << wavepath << std::endl; } } else { std::cerr << "Error: Missing expected fields in JSON response." << std::endl; } // 释放 JSON 对象 cJSON_Delete(json_data); } //这是json结构发送的方式 /*void SendFileWeb(const std::string& strUrl, const char* localpath, const char* cloudpath, char* wavepath) { // 从本地路径读取文件内容 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(); std::string fileContent = ss.str();//文件流 std::string encodedFile = base64_encode(fileContent);//文件流编码 // 创建 JSON 对象 实现入参要求 cJSON* json_root = cJSON_CreateObject(); cJSON_AddItemToObject(json_root, "multipartFile", cJSON_CreateString(encodedFile.c_str())); cJSON_AddItemToObject(json_root, "path", cJSON_CreateString(cloudpath));//远端路径 cJSON_AddItemToObject(json_root, "isReserveName", cJSON_CreateBool(true)); // 布尔值 char* szjson = cJSON_Print(json_root); std::cout << ">>> json: " << szjson << std::endl; // curl 初始化 CURL* curl = curl_easy_init(); if (curl) { // 设置请求为 POST 请求 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")); // 设置超时时间 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); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web); // 设置数据接收和写入函数 // 执行请求 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; handleUploadResponse(resPost0,wavepath); // 处理响应 } // 清理 free(szjson); } else { std::cerr << ">>> curl init failed" << std::endl; } curl_easy_cleanup(curl); cJSON_Delete(json_root); }*/ //这是dataform发送方式 void SendFileWeb(const std::string& strUrl, const char* localpath, const char* cloudpath, char* wavepath) { // 初始化 curl CURL* curl = curl_easy_init(); if (curl) { // 设置请求 URL 和 POST 请求 curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); curl_easy_setopt(curl, CURLOPT_POST, 1); // 创建表单数据 curl_httppost* formpost = nullptr; curl_httppost* lastptr = nullptr; // 添加文件字段,直接从本地路径读取文件内容 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "file", CURLFORM_FILE, localpath, CURLFORM_END); // 添加 `path` 字段 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "path", CURLFORM_COPYCONTENTS, cloudpath, CURLFORM_END); // 添加 `isReserveName` 字段 curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "isReserveName", CURLFORM_COPYCONTENTS, "true", CURLFORM_END); // 设置表单数据到请求 curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); // 设置头信息 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); // 设置超时时间 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); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web); // 执行请求 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; handleUploadResponse(resPost0, wavepath); // 处理响应 } // 清理 curl_formfree(formpost); // 释放表单数据 curl_slist_free_all(header_list); // 释放头部列表 curl_easy_cleanup(curl); } else { std::cerr << ">>> curl init failed" << std::endl; } } void SOEFileWeb(char* localpath,char* cloudpath, char* wavepath) { //示例ip,更换为实际ip即可 SendFileWeb(WEB_FILEUPLOAD,localpath,cloudpath,wavepath); } void SOEFileWeb_test() { char localpath[128] = {"/FeProject/comtrade/his/PQMonitor_PQM1_000420_20250310_151030_923.cfg"}; char cloudpath[128] = {"/comtrade/192.168.1.105/"}; char wavepath[128] = {""}; SOEFileWeb(localpath,cloudpath,wavepath); std::cout << "wavepath:" << wavepath << std::endl; } /*/////////////////////////////////////////////////////////lnk10-24根据web接口修改/////////////////////////////////////////////////////////////*/ /*封装C可调用的台账更新函数 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index,int ied_take) { chnl_usr_t* chnl_usr = NULL; ied_usr_t* ied_usr = NULL; ied_usr = (ied_usr_t*)ied->usr_ext; // 将 update[i] 中的数据写入到 ied_usr 中 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); } 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); } 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 { apr_snprintf(ied_usr->dev_series, sizeof(ied_usr->dev_series), "%s", ""); // 默认为空字符串 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 { apr_snprintf(ied_usr->dev_key, sizeof(ied_usr->dev_key), "%s", ""); // 默认为空字符串 printf("ied_usr->dev_key (default): %s\n", ied_usr->dev_key); } ied_usr->dev_idx = terminal_index; //终端排号,g_node下标 printf("dev_idx: %d\n", ied_usr->dev_idx); 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)) { // 转换成功,portStr全为数字,并且已经转换为int类型的port 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 printf("ied_usr->port: %s, 非合法端口. 使用默认端口: %d\n", update[i].port, ied->channel[0].port); // DEV_PortID } } if (update[i].timestamp != NULL && strlen(update[i].timestamp) > 0) { // 构造struct tm对象 struct tm timeinfo = {0}; // 初始化为0 // 假设时间字符串格式为 "YYYY-MM-DD HH:MM:SS" // 使用sscanf从字符串中提取各个时间字段 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) { // 将年份从1900开始计算 timeinfo.tm_year -= 1900; // 月份从0开始计算,减去1 timeinfo.tm_mon -= 1; // 对tm_isdst进行初始化,通常可以设置为-1,由mktime自动判断 timeinfo.tm_isdst = -1; // 使用mktime将struct tm转换为time_t time_t raw_time = mktime(&timeinfo); // 判断mktime是否成功 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; } } //如果是使用已有空间则不需要再申请 if(!ied_take){ chnl_usr = (chnl_usr_t*)apr_pcalloc(g_init_pool, sizeof(chnl_usr_t)); ied->channel[0].connect = chnl_usr; g_pt61850app->chnl_counts++; //新增的需要添加 } else{ chnl_usr = (chnl_usr_t*)ied->channel[0].connect; } chnl_usr->chnl = &(ied->channel[0]);//如果是已有的ied,这个值是原本就存在的,再赋值一次 chnl_usr->chnl_id = 0; chnl_usr->m_state = CHANNEL_DISCONNECTED; chnl_usr->m_ClosedMsTime = NEXT_CONNECT_TIME * (-1); // 将 monitorData 中的数据写入到 LD_info 中 int count_real_monitor = 0; //遍历监测点台账的计数器 int j; for (j = 0; j < 10 && update[i].line[j].monitor_id[0] != '\0'; ++j) { monitor monitor_data = update[i].line[j]; //监测点计数 count_real_monitor++; // 初始化用于值拷贝的 LD_info,里面涉及指针的部分都为空 LD_info_t line_info; memset(&line_info, 0, sizeof(line_info)); char logical_device_seq[64]; // 填充监测点信息 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)) { line_info.cpuno = 1; // 默认监测点实例号1 printf("logical_device_seq: is null, set cpuno: %d\n", (int)line_info.cpuno); } else { line_info.cpuno = atoi(logical_device_seq); printf("logical_device_seq: %d\n", (int)line_info.cpuno); } line_info.line_id = count_real_monitor; // 记录终端排号 printf("line_id: %d\n", line_info.line_id); printf("mp_id: %s\n", line_info.mp_id); printf("terminal_code: %s\n", line_info.terminal_code); 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); printf("name: %s\n", line_info.name); //lnk20250214角形 if (strcmp(line_info.v_wiring_type, "02") == 0) { isdelta_flag = 1; //存在一个监测点为角型接线则这个前置就要启动第二个配置列表 cout << "monitor_id" << line_info.mp_id << "v_wiring_type:" << line_info.v_wiring_type << "is delta wiring:" << isdelta_flag << endl; } // 填充时间戳 if (update[i].timestamp[0] != '\0') { struct tm timeinfo; char timestamp[64]; // 假设update[i].timestamp格式为 "YYYY-MM-DD HH:MM:SS" // 例如:"2023-01-14 12:34:56" 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); // 将年份从1900年开始计算 timeinfo.tm_year -= 1900; // 月份从0开始,减1 timeinfo.tm_mon -= 1; // 对tm_isdst进行初始化,通常可以设置为-1,由mktime自动判断 timeinfo.tm_isdst = -1; // 使用mktime将struct tm转换为time_t time_t raw_time = mktime(&timeinfo); // 判断mktime是否成功 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; } } line_info.read_flag = 1; //监测点有效 // 填充 LD_info if (ied && ied->usr_ext && line_info.cpuno && ((int)line_info.cpuno < 10)) { char str[256]; byte_t cpuno = line_info.cpuno; //使用新台账的逻辑序列号,在使用原有ied的情况下,如果序列号数量小于原有数量,那么新的部分会被覆盖,如果删除时没有清理,原有的其他部分会仍存在内存中,但不会被使用 printf("cpuno: %d\n", (int)line_info.cpuno); printf("index cpuno: %d\n", cpuno - 1); ied_usr = (ied_usr_t*)ied->usr_ext; //ied_usr->LD_info[cpuno - 1] = line_info;//这个放在后面,因为需要先判断原有的指针 //ied_usr->LD_info[cpuno - 1].ied = ied; //这个放在后面,因为需要先判断原有的指针 //用来记录可能的已有的ldname char *ldname = NULL; //用来记录可能已有的报告、日志数组 loginfo_t **loginfo = NULL; rptinfo_t **rptinfo = NULL; //调试 //printf("check error111 !!!!!!!!!!!!!!\n"); ///////// //清空已有的补招数组占用空间 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]; } } if(NULL != ied_usr->LD_info[cpuno - 1].autorecall){ delete ied_usr->LD_info[cpuno - 1].autorecall; } ied_usr->LD_info[cpuno - 1].autorecallcount = 0; } //调试 //printf("check error112 !!!!!!!!!!!!!!\n"); //////// //记录原有的报告和日志数组 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; //调试 //printf("check error113 !!!!!!!!!!!!!!\n"); //避免重复分配内存,如果使用已存在的ied,那么它之前初始化就分配了哈希表,如果在删除台账时没有清除,则需要将原来的清除 if (ied_usr->LD_info[cpuno - 1].ht_fcd != NULL) { apr_hash_clear(ied_usr->LD_info[cpuno - 1].ht_fcd); } if (ied_usr->LD_info[cpuno - 1].ht_full_fcda != NULL) { apr_hash_clear(ied_usr->LD_info[cpuno - 1].ht_full_fcda); } //调试 //printf("check error116 !!!!!!!!!!!!!!\n"); //这些可能是已有的内存,如果存在则需要清除,(在台账删除时就应该清除) apr_snprintf(str, sizeof(str), "PQMonitorPQM%d", cpuno); // 仅在没有值时更新 LD_name,避免重复分配内存 if (ied_usr->LD_info[cpuno - 1].LD_name == NULL) { //lnk20250208调试用 std::cout << "new space for LD_name" << std::endl; //lnk20250208不使用apr_pstrdup,使用固定大小,后续都在这块内存上直接复用 //ied_usr->LD_info[cpuno - 1].LD_name = apr_pstrdup(g_init_pool, str); // 从 g_init_pool 内存池中分配固定 256 字节的内存 ied_usr->LD_info[cpuno - 1].LD_name = (char *)apr_palloc(g_init_pool, 256); // 清空内存,防止残留数据 memset(ied_usr->LD_info[cpuno - 1].LD_name, 0, 256); // 将 str 中的内容复制到预先分配的内存中,最多复制 256 字节(包含结束符) apr_cpystrn(ied_usr->LD_info[cpuno - 1].LD_name, str, 256); } else {//已有则替换,在原有空间上覆盖 //lnk20250208调试用 std::cout << "old space for LD_name:" << ied_usr->LD_info[cpuno - 1].LD_name <LD_info[cpuno - 1].LD_name, 0, 256); //printf("check error333 !!!!!!!!!!!!!!\n"); apr_cpystrn(ied_usr->LD_info[cpuno - 1].LD_name, str, 256); //原有空间覆盖 //printf("check error222 !!!!!!!!!!!!!!\n"); } ldname = ied_usr->LD_info[cpuno - 1].LD_name; //调试 //printf("check error114 !!!!!!!!!!!!!!\n"); ied_usr->LD_info[cpuno - 1] = line_info;//这个放在后面,因为需要先判断原有的指针 ied_usr->LD_info[cpuno - 1].ied = ied; //这个放在后面,因为需要先判断原有的指针 //调试 //printf("check error115 !!!!!!!!!!!!!!\n"); ied_usr->LD_info[cpuno - 1].LD_name = ldname;//记录原有的或者新的ldname //调试 printf("ledger ied_usr->LD_info[cpuno - 1].LD_name: %s\n", ied_usr->LD_info[cpuno - 1].LD_name); ied_usr->LD_info[cpuno - 1].ht_fcd = apr_hash_make(g_init_pool); //重新创建哈希表 ied_usr->LD_info[cpuno - 1].ht_full_fcda = apr_hash_make(g_init_pool); ied_usr->LD_info[cpuno - 1].rptcount = 0; //报告数清零,这个值在ied_usr->LD_info[cpuno - 1] = line_info;时应该就已清0,报告的空间会在报告块初始化时分配 printf("rptcount: %d\n", ied_usr->LD_info[cpuno - 1].rptcount); //使用原有的报告日志空间 ied_usr->LD_info[cpuno - 1].loginfo = loginfo; //不管是新的还是旧的空间,后续初始化报告都会将它覆盖 ied_usr->LD_info[cpuno - 1].rptinfo = rptinfo; if (cpuno > ied->cpucount) {//新台账的逻辑号大于ied原有的cpu数(初始化是0),则更新cpu数,用来记录有多少个监测点 ied->cpucount = cpuno; } } printf("Monitor Info [ID: %s, Name: %s] saved in LD_info\n", line_info.mp_id, line_info.name); } return 0; } ////////////////////////////////////////////////////////////////////////台账更新记录日志 // 获取当前时间并格式化为 "YYYY-MM-DD HH:MM:SS" 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); } // 写入日志条目 void write_log_entry(std::ofstream &log_file, const std::string &action, const std::string &terminal_id, const std::string ¤t_time) { log_file << terminal_id << "\t" << action << "time:" << current_time << "\n"; } // 创建台账更新日志 void create_ledger_log(trigger_update_xml_t* ledger_update_xml) { std::cout << "create_ledger_log." << std::endl; std::string log_filename = "../etc/" + std::string(LEDGER_UPDATE_FN); std::ofstream log_file(log_filename.c_str(), std::ios::app); // 以追加模式打开文件 if (!log_file.is_open()) { std::cerr << "Failed to open log file: " << log_filename << std::endl; return; } std::vector > new_entries; // 用于存储new的terminal_id和时间 std::vector > modify_entries; // 用于存储modify的terminal_id和时间 std::vector > delete_entries; // 用于存储delete的terminal_id和时间 std::string current_time = get_current_time(); // 获取当前时间 // 处理 new_updates 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)); } // 处理 modify_updates 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)); } // 处理 delete_updates 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)); } // 写入日志文件 if (!new_entries.empty()) { log_file << "\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 << "\n"; } if (!modify_entries.empty()) { log_file << "\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 << "\n"; } if (!delete_entries.empty()) { log_file << "\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 << "\n"; } log_file.close(); std::cout << "Ledger log has been updated." << std::endl; } ///////////////////////////////////////////////////////////////////////////台账内存分配部分功能代码:未使用 // 删除指定的子池 void delete_sub_pool(const char* terminal_id) { std::list >::iterator it; for (it = pool_list.begin(); it != pool_list.end(); ++it) { if (it->first == terminal_id) { apr_pool_destroy(it->second); // 销毁子池 pool_list.erase(it); // 从容器中移除 break; } } } //找对应的子池 apr_pool_t* find_sub_pool(const char* terminal_id) { std::list >::iterator it; for (it = pool_list.begin(); it != pool_list.end(); ++it) { if (it->first == terminal_id) { return it->second; // 找到对应的子池 } } return NULL; // 没有找到对应的子池 } // 创建子池并添加到容器 apr_pool_t* create_sub_pool(apr_pool_t* parent_pool, const char* terminal_id) { apr_pool_t* new_sub_pool = NULL; // 在父池中创建一个子池 apr_pool_create(&new_sub_pool, parent_pool); if (new_sub_pool == NULL) { return NULL; // 创建失败 } // 将子池和终端 ID 存储在容器中 pool_list.push_back(std::make_pair(std::string(terminal_id), new_sub_pool)); return new_sub_pool; } ////////////////////////////////////////////////////////////////////////////////////////////////// //台账变更的报告块初始化 int parse_rpt_log_ini_one(ied_t* ied) { QMap rpt_cfg_strlists; QMap 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(); rpt_cfg_strlists.insert(type, rpt_temp);//报告控制列表 log_cfg_strlists.insert(type, log_temp);//日志控制列表 //g_DevFlag没有使用 parse_one_rpt_log_ini(g_DevFlag, rpt_cfg_strlists[type], log_cfg_strlists[type], ied_usr->dev_type); } //lnk20250208调试用 std::cout << "ied->cpucount:" << (int)(ied->cpucount) <cpucount; cpuno++) {//根据ied实际的检测点数遍历 //lnk20250208调试用 std::cout << "cpuno:" << cpuno << "log init !!!!!!" <LD_info[cpuno]); //这些可能是已有的内存,经过判断才能从g_init_pool中分配内存,lnk20250122 char str[256]; char* tmp = Get_IED(ied_usr->dev_type); qDebug() << tmp << endl; apr_snprintf(str, sizeof(str), tmp, cpuno + 1); //ied_usr->LD_info[cpuno].LD_name = apr_pstrdup(g_init_pool, str);//lnk20250122 //lnk20250212重复申请删除 #if 0 // 仅在没有值时更新 LD_name,避免重复分配内存 if (ied_usr->LD_info[cpuno].LD_name == NULL) { //lnk20250208调试用 std::cout << "cpuno:" << cpuno << "apr_pstrdup" <LD_info[cpuno].LD_name = apr_pstrdup(g_init_pool, str); // 从 g_init_pool 内存池中分配固定 256 字节的内存 ied_usr->LD_info[cpuno].LD_name = (char *)apr_palloc(g_init_pool, 256); // 清空内存,防止残留数据 memset(ied_usr->LD_info[cpuno].LD_name, 0, 256); // 将 str 中的内容复制到预先分配的内存中,最多复制 256 字节(包含结束符) apr_cpystrn(ied_usr->LD_info[cpuno].LD_name, str, 256); } else {//已有则替换,在原有空间上覆盖 // 调试用 std::cout << "strlen(str):" << strlen(str) << "strlen(ied_usr->LD_info[cpuno].LD_name)" << strlen(ied_usr->LD_info[cpuno].LD_name) <LD_info[cpuno].LD_name, 0, 256); apr_cpystrn(ied_usr->LD_info[cpuno].LD_name, str, 256);//apr_palloc 只是分配了一个固定大小的内存块,而没有提供直接的机制来跟踪或验证它的空间是否已被使用或填充到最大值,直接覆盖即可 } #endif //调试 printf("logini ied_usr->LD_info[cpuno - 1].LD_name: %s\n", ied_usr->LD_info[cpuno].LD_name); delete[] tmp;//Get_IED中分配了内存,使用后删除 //lnk20250208调试用 std::cout << "cpuno:" << cpuno << " fill report control" <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); } //初始化监测点的日志控制 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); fill_logctrl_by_cfg(LD_info, i, buf, tmp); delete[] tmp; } } //报告控制块和日志控制块处理结束后清理容器 for (QMap::iterator it1 = log_cfg_strlists.begin(); it1 != log_cfg_strlists.end(); ++it1) { delete it1.value(); } for (QMap::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; //插入的位置和g_node一样 ied_usr = (ied_usr_t*)ied->usr_ext; pos = ied_usr->dev_idx - 1; std::cout << "!!!!!!!!!rem_dib_table pos is " << pos << std::endl; for(chnl_no=0 ; chnl_nochncount; chnl_no++) { chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect;//初始化时已根据最大数量申请空间 g_pt61850app->chnl_usr[pos] = chnl_usr; std::cout << "!!!!!!!!!g_pt61850app pos " << pos << "is " << ied_usr->terminal_id << "is" << (chnl_usr == NULL?"NULL":"NOTNULL") << std::endl; 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 ); add_rem_dib_table (pos++,chnl_usr->ip_str,ied->channel[chnl_no].port );//当前终端的IP端口记录到表中,这里要注意添加的下标,如果删除终端,这个表内的内容仍存在,再次使用时会被替换 { 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; } ///////////////////////////////////////////////////////////////////////////////////////////////////清理ied void clearLogInfo(loginfo_t *loginfo) { if (loginfo == nullptr) { return; // 如果传入的指针为空,直接返回 } // 清空字符数组 memset(loginfo->logName, 0, sizeof(loginfo->logName)); // 清空其他非指针成员 loginfo->IntgPd = 0; loginfo->reasonCode = 0; loginfo->TrgOpt = 0; loginfo->start_time = 0; loginfo->end_time = 0; loginfo->need_steady = 0; loginfo->need_voltage = 0; // 对指针成员进行清理,但不释放内存 if (loginfo->lcbName != nullptr) { memset(loginfo->lcbName, 0, strlen(loginfo->lcbName)); // 清空字符串内容 } if (loginfo->datasetName != nullptr) { memset(loginfo->datasetName, 0, strlen(loginfo->datasetName)); // 清空字符串内容 } // 由于 LD_info 是指针,它不清理,仍指向上级 } void clearRptInfo(rptinfo_t *rptinfo) { if (rptinfo == nullptr) { return; // 如果传入的指针为空,直接返回 } // 清空字符数组和非指针成员 rptinfo->instanceNeedSuffix = 0; rptinfo->TrgOpt = 0; memset(rptinfo->OptFlds, 0, sizeof(rptinfo->OptFlds)); rptinfo->IntgPd = 0; rptinfo->report_PQ_type = 0; rptinfo->rpt_registered = 0; rptinfo->chnl_id = 0; rptinfo->m_LastDataTime = 0; rptinfo->m_LastGITime = 0; rptinfo->m_LastRegisterFailedTime = 0; rptinfo->m_LastUnRegisterFailedTime = 0; memset(rptinfo->m_EntryID, 0, sizeof(rptinfo->m_EntryID)); rptinfo->m_curRptSuffix = 0; rptinfo->count = 0; rptinfo->rptNo = 0; rptinfo->flickerflag = 0; rptinfo->pstflag = 0; // 对指针成员进行清理,但不释放内存 if (rptinfo->rptID != nullptr) { memset(rptinfo->rptID, 0, strlen(rptinfo->rptID)); // 清空字符串内容 } // 由于 LD_info 是指针,它不需要清理,仍指向父级 //rptinfo->LD_info = nullptr; // 对 RCBC_INFO 结构体指针进行处理 if (rptinfo->m_rcb_info != nullptr) { // 如果需要,可以选择清理结构体内部内容,但不释放内存 rptinfo->m_rcb_info = nullptr;//这里可以清空,因为这个指针指向的区域在连接通道关闭时会被清理 } } void clearLDInfo(LD_info_t *ld_info) { if (ld_info == nullptr) { std::cout << "ldinfo is null" << std::endl; return; } //保留原来的ied指向 //清空报告 if (ld_info->rptinfo != nullptr) { for (int i = 0; i < ld_info->rptcount; ++i) { if (ld_info->rptinfo[i] != nullptr) { clearRptInfo(ld_info->rptinfo[i]); //清空报告控制块 } } } std::cout << "clean RptInfo!!!" << std::endl; //清空日志 if (ld_info->loginfo != nullptr) { for (int i = 0; i < ld_info->logcount; ++i) { if (ld_info->loginfo[i] != nullptr) { clearLogInfo(ld_info->loginfo[i]); //清空日志控制块 } } } std::cout << "clean loginfo_t!!!" << std::endl; //清空补招 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)); delete ld_info->autorecall[i]; //删除数组元素空间,如果有正在补招的内容,则已经申请空间,需要释放 } } delete ld_info->autorecall; //删除数组空间 } 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); } // 清空其他指针成员 if (ld_info->name != nullptr) { memset(ld_info->name, 0, sizeof(char) * 256); } 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); } ld_info->cpuno = 0; //清空逻辑序列号 ld_info->time = 0; //台账更新时间清0 ld_info->update_flag = 0; //监测点更新标志,暂不使用 ld_info->rptRecvFlag = 0;//重置报告标志 ld_info->rptRecvCheckFlag = 0; ld_info->rptPstRecvFlag = 0; ld_info->rptPstRecvCheckFlag = 0; ld_info->read_flag = 0;//监测点无效 ld_info->rptcount = 0; ld_info->logcount = 0; ld_info->autorecallflag = 0; ld_info->autorecallcount = 0; //ld_info->group = 0; //不使用 //清空实时数据部分 ld_info->line_id = 0; ld_info->real_data = 0; ld_info->soe_data = 0; ld_info->limit = 0; ld_info->count = 0; //ld_info->SubV_Index = 0; //不使用 //ld_info->Dev_Index = 0; //不使用 //ld_info->Sub_Index = 0; //不使用 //ld_info->GD_Index = 0; //不使用 //清空暂态结构 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; memset(ld_info->qvvr[i].QVVR_Rptname, 0, sizeof(ld_info->qvvr[i].QVVR_Rptname)); // 清空字符数组 ld_info->qvvr[i].timestamp = 0; } ld_info->qvvr_idx = 0; memset(ld_info->FltNum, 0, sizeof(ld_info->FltNum)); ld_info->RDRE_FltNum = 0; //录波号清零 } void clearIedUsr(ied_usr_t *ied_usr) { if (ied_usr == nullptr) { std::cout << "ied_usr is null" << std::endl; return; } // 清空 ied_usr_t 中的非指针部分 //ied_usr->dev_idx = 0;//保留index ied_usr->dev_flag = UNUSED; ied_usr->last_call_wavelist_time = 0; ied_usr->time = 0; //台账更新时间 ied_usr->update_flag = 0; //台账更新标志暂不使用 // 清空指针部分,但不清理非空指针 if (ied_usr->LD_info != nullptr) { // 如果 LD_info 不为空,清理它内部的内容 for (int i = 0; i < MAX_CPUNO; ++i) { LD_info_t * ld =NULL; ld = (LD_info_t *)&ied_usr->LD_info[i]; if (ld != NULL) { clearLDInfo(ld); } } } if (ied_usr->cookie != nullptr) { //不使用 std::cout << "cookie not null" << std::endl; } // 清空其他非指针部分,也可以不清0,后续都会覆盖 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)); } // 清空 channel 和 cpuinfo 的非指针部分 void clear_channel_and_cpuinfo(byte_t chncount, channel_t *channel, byte_t cpucount, cpuinfo_t *cpuinfo) { // 清空 channel 数组中的每个元素的非指针字段 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; // 清理 channel 里的 chnl_usr_t 部分 // 关闭连接时已清理,保留指针本身 } // 清空 cpuinfo 数组中的每个元素的非指针字段 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; } } void clearIed(ied_t *ied) { if (ied == nullptr) { return; } // 清空 ied_t 的id ied->id = 0; //ied->flags = 0; //未使用 //ied->type = 0; //未使用 //清理channel //清理cpuinfo clear_channel_and_cpuinfo(ied->chncount,ied->channel,ied->cpucount,ied->cpuinfo); ied->chncount = 0; //清空通道数 ied->cpucount = 0; //清空检测点数 //名称清理 memset(ied->name, 0, LONGNAME); //ied->station = 0; //未使用 //ied->node = 0; //未使用 //ied->frequency = 0; //未使用 //ied->delay = 0; //未使用 //ied->count = 0; //未使用 //数据组定义部分未使用 //ied->groups = NULL; //ied->htgroups = NULL; //系统令牌未使用 //ied->systoken_st = 0; //ied->index = 0; //未使用 ied->status = STATUS_NOINIT; //设备状态设为未初始化 //ied->last_ticks = 0; //未使用 //ied->last_gi = 0; //未使用 // 清空指针部分 if (ied->usr_ext != nullptr) { ied_usr_t *ied_usr = (ied_usr_t*)ied->usr_ext; clearIedUsr(ied_usr); } if (ied->sys_ext != nullptr) { //不使用 } if (ied->app_ext != nullptr) { //不使用 } } /*封装C可调用的台账更新函数 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //测试函数 std::string to_string(long long value) { std::stringstream ss; ss << value; return ss.str(); } void rocketmq_test_300(int mpnum,int front_index) { Ckafka_data_t data; data.strTopic = QString::fromStdString(G_ROCKETMQ_TOPIC); data.mp_id = "0"; // 读取文件内容 std::ifstream file("long_string.txt"); // 文件中存储长字符串 std::stringstream buffer; buffer << file.rdbuf(); std::string file_contents = buffer.str(); // 获取文件内容 std::string base_strText = file_contents; // 获取当前时间作为开始时间 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; // 清零毫秒位(如果需要更精确,使用高精度时间) // 获取当前的时间戳(秒) std::time_t base_time_t = std::mktime(time_info);//将 std::tm 结构(本地时间)转换回 std::time_t(时间戳) // 计算每条消息的时间戳,精确到分钟,毫秒和秒清零 long long current_time_ms = static_cast(base_time_t) * 1000; // 每分钟递增,单位毫秒 // 设定总的消息数量 int total_messages = mpnum; ied_t* ied; ied_usr_t* ied_usr; // 循环发送 300 条消息 for (int i = 0; (total_messages != 0 && g_front_seg_index == 1 && g_node_id == 100) && i < g_node->n_clients; ++i) { ied = (ied_t*)g_node->clients[i]; if(ied != NULL){ ied_usr = (ied_usr_t*)ied->usr_ext; //跳过正常的终端 if(strcmp(ied_usr->terminal_id, "8499c5ae999d392b4e73112ca0d2d778") == 0){ std::cout << "8499c5ae999d392b4e73112ca0d2d778 use true message " << std::endl; continue; } for (int j = 0; j < 10 && ied_usr->LD_info[j].mp_id[0] != '\0'; j++){ // 修改 Monitor 值 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; std::string modified_time = to_string(current_time_ms); // 时间转换为整数类型(Unix时间戳) // 替换消息中的 Monitor 和 TIME 字段(只匹配字段名,不匹配具体数值) std::string modified_strText = base_strText; // 替换 Monitor 字段 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()); } } // 替换 TIME 字段 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); } } // 更新数据 data.strText = QString::fromStdString(modified_strText); // 发送数据 my_rocketmq_send(data); // 输出调试信息 std::cout << "Sent message " << (i + 1) << " with Monitor " << data.monitor_id << " and TIME " << modified_time << std::endl; // 等待下一条消息的发送(固定为1分钟) //QThread::sleep(60); // 每次发送间隔1分钟 } } } std::cout << "Finished sending " << total_messages << " messages." << std::endl; } ///////////////////////////////////////////////////////////////////////////////lnk实时日志部分20250205 // ------------------ 全局日志列表和锁 ------------------ std::list errorList; std::list warnList; std::list normalList; std::list debugList; // 新增 debugList pthread_mutex_t errorListMutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t warnListMutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t normalListMutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t debugListMutex = PTHREAD_MUTEX_INITIALIZER; // 新增 debugList 互斥锁 // ------------------ 输出开关 ------------------ bool errorOutputEnabled = false; // 是否将 error 级别写入 errorList bool warnOutputEnabled = false; // 是否将 warn 级别写入 warnList bool normalOutputEnabled = false; // 是否将 normal 级别写入 normalList bool debugOutputEnabled = false; // 新增 debug 开关 // ------------------ 用于恢复原始缓冲区 ------------------ static std::streambuf* g_originalCoutBuf = NULL; static std::streambuf* g_originalClogBuf = NULL; static std::streambuf* g_originalCerrBuf = NULL; // ------------------ 日志级别枚举(C++98) ------------------ enum LogLevel { LOGERROR, LOGWARN, LOGNORMAL, LOGDEBUG // 新增 debug 级别 }; // ------------------------------------------------------------------ // TeeStreamBuf: 先写到原始buf(保持终端输出),再拷贝到list里 // ------------------------------------------------------------------ class TeeStreamBuf : public std::streambuf { public: // 默认构造:先把指针设为NULL TeeStreamBuf() : m_originalBuf(NULL), m_level(LOGNORMAL) { pthread_mutex_init(&m_mutex, NULL); } // 带参构造:直接初始化 TeeStreamBuf(std::streambuf* originalBuf, LogLevel level) : m_originalBuf(originalBuf), m_level(level) { pthread_mutex_init(&m_mutex, NULL); } // 析构函数:销毁互斥锁 virtual ~TeeStreamBuf() { pthread_mutex_destroy(&m_mutex); } // 自定义 init(...) 函数:在同一个对象上重新设置 void init(std::streambuf* originalBuf, LogLevel level) { m_originalBuf = originalBuf; m_level = level; pthread_mutex_lock(&m_mutex); m_buffer.clear(); pthread_mutex_unlock(&m_mutex); } protected: // 当 flush 或 std::endl 时会调用 sync() virtual int sync() { // 先让原始缓冲区执行同步 if (m_originalBuf) { m_originalBuf->pubsync(); } // 再将自身的缓存 flush flushBuffer(); return 0; // 成功 } // 当写入一个新字符时,overflow() 被调用 virtual int_type overflow(int_type ch) { if (ch == traits_type::eof()) { return ch; } // 1) 写到原始缓冲区 → 保留终端输出 if (m_originalBuf) { if (m_originalBuf->sputc(static_cast(ch)) == traits_type::eof()) { return traits_type::eof(); } } // 2) 存到我们的临时缓存,注意加锁保护 pthread_mutex_lock(&m_mutex); //防止多线程推入崩溃lnk20250305 m_buffer.push_back(static_cast(ch)); // 3) 遇到换行就 flushBuffer() if (ch == '\n') { flushBuffer_locked(); } pthread_mutex_unlock(&m_mutex); return ch; } private: // 内部版本:假定互斥锁已经被加锁 void flushBuffer_locked() { if (m_buffer.empty()) { return; } // 根据等级和对应开关,将 m_buffer 写入相应的 list switch (m_level) { case LOGERROR: if (debugOutputEnabled) { pthread_mutex_lock(&debugListMutex); debugList.push_back(m_buffer); pthread_mutex_unlock(&debugListMutex); } else if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(m_buffer); pthread_mutex_unlock(&normalListMutex); } else if (warnOutputEnabled) { pthread_mutex_lock(&warnListMutex); warnList.push_back(m_buffer); pthread_mutex_unlock(&warnListMutex); } else if (errorOutputEnabled) { pthread_mutex_lock(&errorListMutex); errorList.push_back(m_buffer); pthread_mutex_unlock(&errorListMutex); } break; case LOGWARN: if (debugOutputEnabled) { pthread_mutex_lock(&debugListMutex); debugList.push_back(m_buffer); pthread_mutex_unlock(&debugListMutex); } else if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(m_buffer); pthread_mutex_unlock(&normalListMutex); } else if (warnOutputEnabled) { pthread_mutex_lock(&warnListMutex); warnList.push_back(m_buffer); pthread_mutex_unlock(&warnListMutex); } break; case LOGNORMAL: if (debugOutputEnabled) { pthread_mutex_lock(&debugListMutex); debugList.push_back(m_buffer); pthread_mutex_unlock(&debugListMutex); } else if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(m_buffer); pthread_mutex_unlock(&normalListMutex); } break; } m_buffer.clear(); } // 对外接口,内部对 m_buffer 加锁 void flushBuffer() { pthread_mutex_lock(&m_mutex); flushBuffer_locked(); pthread_mutex_unlock(&m_mutex); } private: // 禁止自动生成的赋值函数 TeeStreamBuf& operator=(const TeeStreamBuf&); private: std::streambuf* m_originalBuf; LogLevel m_level; std::string m_buffer; pthread_mutex_t m_mutex; }; // ------------------ 全局Tee对象(避免重复赋值) ------------------ static TeeStreamBuf g_errorTeeBuf; static TeeStreamBuf g_warnTeeBuf; static TeeStreamBuf g_normalTeeBuf; // ------------------ 我们另外提供一个全局的 debug 输出流 ------------------ // 其原始buf默认为 NULL(不输出到终端),只存到 debugList(若开关开) //static std::ostream g_debug(&g_debugTeeBuf); // 让 qDebug() 映射到这个全局流 //#define qDebug() g_debug // ------------------ 重定向函数 ------------------ // 只在第一次启用时,用 init(...) 初始化 TeeStreamBuf; // 之后再启用时,不再 new 或 赋值,而是直接用之前构造好的对象。 void redirectErrorOutput(bool enabled) { errorOutputEnabled = enabled; if (enabled) { if (g_originalCerrBuf == NULL) { g_originalCerrBuf = std::cerr.rdbuf(); g_errorTeeBuf.init(g_originalCerrBuf, LOGERROR); } std::cerr.rdbuf(&g_errorTeeBuf); } else { if (g_originalCerrBuf) { std::cerr.rdbuf(g_originalCerrBuf); } } } void redirectWarnOutput(bool enabled) { warnOutputEnabled = enabled; if (enabled) { if (g_originalClogBuf == NULL) { g_originalClogBuf = std::clog.rdbuf(); g_warnTeeBuf.init(g_originalClogBuf, LOGWARN); } std::clog.rdbuf(&g_warnTeeBuf); } else { if (g_originalClogBuf) { std::clog.rdbuf(g_originalClogBuf); } } } void redirectNormalOutput(bool enabled) { normalOutputEnabled = enabled; if (enabled) { if (g_originalCoutBuf == NULL) { g_originalCoutBuf = std::cout.rdbuf(); g_normalTeeBuf.init(g_originalCoutBuf, LOGNORMAL); } std::cout.rdbuf(&g_normalTeeBuf); } else { if (g_originalCoutBuf) { std::cout.rdbuf(g_originalCoutBuf); } } } // ------------------ 重定向函数 ------------------ void redirectDebugOutput(bool enable) { debugOutputEnabled = enable; // 不去改 clog.rdbuf() // 不去 install 任何 msg handler } // ------------------ Qt4 消息处理函数 ------------------ void myQtMsgHandler(QtMsgType type, const char *msg) { // 不论消息类型如何,都写入 debugList if (debugOutputEnabled) { pthread_mutex_lock(&debugListMutex); debugList.push_back(msg); pthread_mutex_unlock(&debugListMutex); } // 根据消息类型选择输出流 FILE* output = nullptr; const char* typeStr = ""; switch (type) { case QtDebugMsg: typeStr = "Debug"; output = stdout; // Debug 走标准输出 break; case QtWarningMsg: typeStr = "Warning"; output = stderr; // Warning 走标准错误 break; case QtCriticalMsg: typeStr = "Critical"; output = stderr; // Critical 走标准错误 break; case QtFatalMsg: typeStr = "Fatal"; output = stderr; // Fatal 走标准错误 break; } fprintf(output, "[%s] %s\n", typeStr, msg); fflush(output); // Fatal 时进程退出 if (type == QtFatalMsg) { abort(); } } // ------------------ 自定义 printf 输出 ------------------ // 这里示例:把它当成 normal 级别 => 最终会进入normalList(若开关开) // 定义一个全局静态的互斥锁,名称为 printfmtx static pthread_mutex_t printfmtx = PTHREAD_MUTEX_INITIALIZER; // 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; }; int customPrintf(const char* format, ...) { // 在进入函数时自动加锁,退出时自动解锁 LockGuard lock(printfmtx); va_list args; va_start(args, format); char buffer[1024]; int written = vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); if (written < 0) { return -1; } // 将格式化后的字符串输出到 std::cout std::cout << buffer << std::endl; return written; } /////////////////////////////////////////////////////////////////////////////// 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); // 终端输出 printf("[ERROR] rv=%d %s:%d => %s", rv, file_name, line_no, __buf); fflush(stdout); // 写入 errorList 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); // 终端输出 printf("[WARN ] %s:%d => %s", file_name, line_no, __buf); fflush(stdout); // 写入 warnList 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); // 终端输出 printf("[DEBUG] %s:%d => %s", file_name, line_no, __buf); fflush(stdout); // 写入 normalList if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(std::string(__buf)); pthread_mutex_unlock(&normalListMutex); } } /////////////////////////////////////////////////////////////////////////////// void Worker::telnetetst(QTcpSocket* clientSocket) { int ip_count = 0; int telnet_count = 0; //在测试连接时给台账加锁lnk20250114 pthread_mutex_lock(&mtx); std::cout << "testping hold lock !!!!!!!!!!!" << std::endl; Worker::init_ping_telnet(clientSocket,ip_count, telnet_count); Cout_account_information(); pthread_mutex_unlock(&mtx); std::cout << "testping free lock !!!!!!!!!!!" << std::endl; }