diff --git a/cfg_parse/SimpleProducer.cpp b/cfg_parse/SimpleProducer.cpp index 64e4abf..c6e0657 100644 --- a/cfg_parse/SimpleProducer.cpp +++ b/cfg_parse/SimpleProducer.cpp @@ -1,6 +1,3 @@ -/* -* Description: Simple Producer demo -*/ #include // 用于 std::ifstream #include // 用于 std::stringstream #include @@ -12,7 +9,6 @@ #include "../include/rocketmq/CProducer.h" #include "../include/rocketmq/CMessage.h" #include "../include/rocketmq/CSendResult.h" - #include "../include/rocketmq/SimpleProducer.h" //测试300数据用lnk20241202 @@ -135,13 +131,7 @@ RocketMQConsumer::RocketMQConsumer(const std::string& consumerName, const std::s std::cout << "error setting groupId"<< std::endl; throw std::runtime_error("Failed to set Consumer Group ID."); } -/* - // 设置消费模式为广播模式 - if (SetPushConsumerMessageModel(consumer_, BROADCASTING) != 0) { - DestroyPushConsumer(consumer_); - std::cout << "error setting messagemodel"<< std::endl; - } -*/ + //调试用 std::string consumerlog = "./mqconsumer/" + consumerName +".log"; if ( (SetPushConsumerLogPath(consumer_,consumerlog.c_str()) || SetPushConsumerLogFileNumAndSize(consumer_,10,100) || SetPushConsumerLogLevel(consumer_,E_LOG_LEVEL_DEBUG) ) != 0) {//记录消费日志 @@ -365,7 +355,6 @@ void rocketmq_consumer_receive( } } - // 消费逻辑已通过回调处理,无需额外操作 } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //封装生产者类 @@ -465,19 +454,6 @@ public: RoundRobinSelector, // 队列选择器回调函数 &queueNum // 传递给选择器的额外参数(队列数量) ); - - //调试用 - /*int sendResult = SendMessageSync( - producer_, - msg, - &result - ); - int ret = SendMessageSync(producer_, msg, &result); - if (ret == 0) { - printSendResult(result); - } else { - std::cerr << "SendMessageSync failed with ret=" << ret << std::endl; - }*/ if (sendResult == 0) { // 假设返回 0 表示成功 std::cout << "Message sent successfully.topic:" << topic <= 1024 - queueNum) { - currentQueueId = 0; - } - return queueId; -} -void StartSendMessage_queue(CProducer* producer, const char* strbody, const char* topic) -{ - CSendResult result; - - // 创建消息并设置一些属性 - CMessage* msg = CreateMessage(topic); - SetMessageTags(msg, G_ROCKETMQ_TAG.c_str()); - SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str()); - SetMessageBody(msg, strbody); - - // 动态获取队列数量和 Broker 名称 - int queueNum = QUEUENUM; // 假设这个是配置的队列数量,比如5 - - // 使用 SendMessageOnewayOrderly 发送消息,传递回调函数 - int sendResult = SendMessageOnewayOrderly( - producer, - msg, - RoundRobinSelector, // 传递符合 QueueSelectorCallback 签名的函数 - &queueNum // 传递给选择器的额外参数(队列数量) - ); - - if (sendResult == 0) { // 假设返回 0 表示成功 - std::cout << "Message sent successfully: " << std::endl; - } else { - std::cout << "Failed to send message: " << std::endl; - } - - // 销毁消息 - DestroyMessage(msg); -} -#endif ////////////////////////////////////////////////////////////////////////////////////////////////////////// // producer_send0测试用 void StartSendMessage(CProducer* producer) @@ -716,60 +642,6 @@ void producer_send(const char* strbody) } /////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if 0 -void rocketmq_StartSendMessage(CProducer* producer,const char* strbody,const char* topic) -{ - CSendResult result; - - // create message and set some values for it - CMessage* msg = CreateMessage(topic); - - //多前置区分消息tag,一个进程 - - SetMessageTags(msg, G_ROCKETMQ_TAG.c_str()); - SetMessageKeys(msg, G_ROCKETMQ_KEY.c_str()); - - SetMessageBody(msg, strbody); - // send message - SendMessageSync(producer, msg, &result); - - //cout << "rocketmq_result status:" << result.sendStatus << ", msgBody:" << strbody << endl; - - // destroy message - DestroyMessage(msg); -} - -void rocketmq_producer_send(const char* strbody,const char* topic) -{ - cout << "rocketmq_Producer Initializing....." << endl; - - // create producer and set some values for it - CProducer* producer = CreateProducer(G_ROCKETMQ_PRODUCER.c_str()); - if (producer == NULL) { - std::cerr << "Failed to create producer." << std::endl; - return; - } - - // nameserver - SetProducerNameServerAddress(producer, G_ROCKETMQ_IPPORT.c_str()); - - // start producer - StartProducer(producer); - - cout << "rocketmq_Producer start....." << endl; - // send message - //rocketmq_StartSendMessage(producer,strbody,topic); - //根据队列发消息 - StartSendMessage_queue(producer,strbody,topic); - // shutdown producer - ShutdownProducer(producer); - // destroy producer - DestroyProducer(producer); - cout << "rocketmq_Producer Shutdown!" << endl; -} -#endif - - extern "C" { extern std::string G_MQCONSUMER_TOPIC_RT; @@ -862,84 +734,3 @@ void rocketmq_test_log() } - -#if 0 -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; - - // 循环发送 300 条消息 - for (int i = 0; i < total_messages; ++i) { - // 修改 Monitor 值 - data.monitor_id = front_index *10000 + 1 + i; - - data.mp_id = QString::number(data.monitor_id); - - std::string modified_time = my_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, my_to_string(data.monitor_id)); - } - } - - // 替换 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; -} -#endif - - diff --git a/cfg_parse/base64.cpp b/cfg_parse/base64.cpp index c06ed5c..f484789 100644 --- a/cfg_parse/base64.cpp +++ b/cfg_parse/base64.cpp @@ -111,8 +111,6 @@ extern "C" { return encoded_data; } - - /// /// жַǷΪpower{}ʽ /// @@ -152,38 +150,6 @@ extern "C" { return true; // ȡɹ } - //int testbase64(char ** decoded_text) { - // unsigned char text[] = "power{SGVsbG8sIFdvcmxkIWV3ZA==}"; - // size_t encoded_length, decoded_length; - - // char encoded_text[100]; - - // if (extract_if_power((char*)text, encoded_text, sizeof(encoded_text), &encoded_length)) { - // // ַ - // long decodedLen = strlen(encoded_text) * 3 / 4; - // * decoded_text = (char*)malloc(decodedLen + 1); - // // Base64 - // int success = base64_decode(encoded_text, strlen(encoded_text), *decoded_text, &decodedLen); - // if (decoded_text) { - // printf("Decoded: %s\n", (char*)decoded_text); // ע⣺Ҫȷınullַֹ - // free(decoded_text); // ע⣺ʵϲӦʹdecoded_textΪַӡΪunsigned char* - // // ʵӦУҪתΪchar*nullֹ - // } - // } - // else { - // printf(" no Decoded: %s\n", text); // ע⣺Ҫȷınullַֹ - // } - // - - - // // ע⣺decoded_textӡDz׼ȷģΪdecoded_textunsigned char*ҿܲnullַֹ - // // ȷǽdecoded_textתΪַıݣʽ - - // return 0; - //} - - - #ifdef __cplusplus } #endif diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index 31b0640..72e45d6 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -62,8 +62,6 @@ extern "C" { std::list > pool_list; /////////////////////////////////////////////////// - - //ZW 2023-10-10 нṹ class RecallInfo { @@ -250,11 +248,6 @@ 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; @@ -358,9 +351,6 @@ 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ݿû @@ -390,235 +380,6 @@ void parse_log_switch_ini(unsigned int* error, unsigned int* warn, unsigned int* 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="; // ҪҵеĿͷ @@ -777,8 +538,6 @@ void init_config() { 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()); @@ -1003,84 +762,7 @@ void init_config() { 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); // ڴ - // ʹsprintfintֵΪַ - 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; @@ -1324,2173 +1006,6 @@ int stringToInt(const char* str, int* result) { 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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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\":\"00B78D00DC23\",\"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() //ȡǰ÷ { @@ -3931,8 +1446,7 @@ 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; @@ -3942,8 +1456,7 @@ int parse_rpt_log_ini() 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); @@ -3959,10 +1472,6 @@ int parse_rpt_log_ini() 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]); @@ -3973,17 +1482,6 @@ int parse_rpt_log_ini() 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()); @@ -3992,7 +1490,7 @@ int parse_rpt_log_ini() apr_snprintf(buf, sizeof(buf), "%s", rpt_cfg_strlists[type]->at(i).toAscii().constData()); - fill_rptctrl_by_cfg(LD_info, i, buf);// + fill_rptctrl_by_cfg(LD_info, i, buf); } @@ -4138,8 +1636,6 @@ std::list find_xml_belong_to_this_process() 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; @@ -4151,9 +1647,6 @@ std::list find_xml_belong_to_this_process() 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") { @@ -4716,58 +2209,7 @@ int extract_timestamp_from_cfg_file(char* comtrade_fn, long long* start_tm, long 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) @@ -5715,1247 +3157,6 @@ bool CheckPG_To_Recall(long long start, long long end, char* Monitorid) 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 osssqlݿ¼ɾ - 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 osssqlݿ¼ɾ 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ȻtokenAPI -//http://172.40.237.145:30010/psr-auth/oauth/accessToken -//ȨϢ -//client_id : 2a78ecf0074111ed806c7a5cabbedfb4 -// client_secret : 58nOklQlP0SGEuXbrd0wgcVO7HX7IODAgvzHiCm + mAgWSadcX0we2wffjyTUYGsK -// grant_type : credentials -//getpostӦ -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; -} -//getpostӦ -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()); - - //postIJ - - 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()); - //postIJ - 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 -//getpostӦ -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()); - //postIJ - 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()); - //postIJ - 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ģݿȡ @@ -7351,16 +3552,6 @@ void CreateRecallXml() 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) { @@ -7535,3949 +3726,6 @@ void SendWebAPI_web(const string strUrl, const char* code, char** ptr) 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ȡն̨ˣIJֱΪ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(); - - //ȡcountcfgҪ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 osssqlݿ¼ɾ - 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 osssqlݿ¼ɾ 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ƳpgsqlIJԴ/////////////////////////////////////////////////////////////*/ /*/////////////////////////////////////////////////////////lnk10-24webӿ޸/////////////////////////////////////////////////////////////*/ //jsonַ @@ -12300,131 +4548,15 @@ int parse_device_cfg_web() 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(); - - //ȡcountcfgҪ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) + "\","; @@ -12434,7 +4566,6 @@ int parse_device_cfg_web() 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(); @@ -13023,10 +5154,8 @@ char* parse_model_cfg_web_one(ied_t* ied) 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;//ʹ // ն̨ @@ -13041,16 +5170,12 @@ char* parse_model_cfg_web_one(ied_t* ied) 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); } } @@ -13063,145 +5188,6 @@ char* parse_model_cfg_web_one(ied_t* ied) } } //////////////////////////////////////////////////////////// -//Զнӿڣݲ޸ģܲʹ -#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() { @@ -13220,17 +5206,6 @@ void OnTimerThread::run() << 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) { @@ -13245,7 +5220,6 @@ void OnTimerThread::run() int pgflag = 0; int pgmin = 0; int mp_num_hour = 0; - int recall_flag1 = 1; //б־ // std::vector codes; @@ -13257,29 +5231,6 @@ void OnTimerThread::run() 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) { @@ -13295,502 +5246,13 @@ void OnTimerThread::run() 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 - //webcfg_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ͻ˷Ϣ -{ - // ӡIJѯ - 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) { //ָ̬/̬ȫ @@ -13804,27 +5266,6 @@ int recall_json_handle(const char* jstr) 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) { @@ -14801,40 +6242,7 @@ int parse_rpt_log_ini_one(ied_t* ied) if(tmp == NULL){std::cerr << "front read ied config error!" << std::endl;continue;} 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); diff --git a/cfg_parse/datahub.cpp b/cfg_parse/datahub.cpp index aea5396..2cfb208 100644 --- a/cfg_parse/datahub.cpp +++ b/cfg_parse/datahub.cpp @@ -14,10 +14,8 @@ using namespace std; #include - #include #include - #include "../mms/db_interface.h" #include "../json/cjson.h"//WW 2023-08-27json #include "../include/curl/curl.h" @@ -29,11 +27,8 @@ extern "C" { size_t req_reply_datahub(void* ptr, size_t size, size_t nmemb, void* stream) { - //ע͵ԴӡcookieϢ string* str = (string*)stream; (*str).append((char*)ptr, size * nmemb); - //printf(">>>GetDevice in reply %s\n", (char*)ptr); - //GetCJson(ptr); return size * nmemb; } @@ -42,6 +37,7 @@ void SendWebAPI_Datahub(const string strUrl,char* topic,char* data) // curlʼ CURL* curl = curl_easy_init(); + // curlֵ CURLcode res; if (curl) @@ -60,18 +56,15 @@ void SendWebAPI_Datahub(const string strUrl,char* topic,char* data) //URLַ curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); + //postIJ cJSON* json_root = cJSON_CreateObject(); - //cJSON_AddItemToObject(json_root, "topic", cJSON_CreateString("ems_pq_mmxu_stat")); - //cJSON_AddItemToObject(json_root, "data", cJSON_CreateString("{\"DATA_TYPE\": \"04\",\"Monitor\": \"4563\",\"Value\": {\"FLAG\": 1,\"TIME\": 1512097260000,\"VOLTAGE\": {\"MAG\": 56.23,\"DUR\": 23,\"STARTTIME\": 1512097260000,\"ENDTIME\": 1512097283000,\"DISKIND\": \"01\",\"WAVEFILE\": \"PQMonitor_PQM1_000001_20230707_103916_596\",\"PHASIC\": \"unknow\"}}}")); cJSON_AddItemToObject(json_root, "topic", cJSON_CreateString(topic)); cJSON_AddItemToObject(json_root, "data", cJSON_CreateString(data)); 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֤ @@ -86,7 +79,6 @@ void SendWebAPI_Datahub(const string strUrl,char* topic,char* data) //ݽպд뺯 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_datahub); - string resPost0; curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); @@ -97,8 +89,10 @@ void SendWebAPI_Datahub(const string strUrl,char* topic,char* data) curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); printf(">>>Testaliyun datahub Post in curl post\n"); + // post res = curl_easy_perform(curl); + // Ƿɹ if (res != CURLE_OK) { printf("aliyun datahub failed res code: "); @@ -119,14 +113,11 @@ void SendWebAPI_Datahub(const string strUrl,char* topic,char* data) curl_easy_cleanup(curl); } - void DataHub_Send_Datahub(char* topic,char* data) { SendWebAPI_Datahub("http://127.0.0.1:8091/powerQuality/PQDATAHUB",topic,data); - } - #ifdef __cplusplus } #endif diff --git a/cfg_parse/httprun.cpp b/cfg_parse/httprun.cpp index a1b53be..5c9b2f0 100644 --- a/cfg_parse/httprun.cpp +++ b/cfg_parse/httprun.cpp @@ -4,20 +4,9 @@ #include #include "../json/cjson.h" -//#include - -//#include - -//std::mutex data_mutex; // 用来保护 receivedData 变量 - -//#include -//std::atomic isrunning(false); // 使用原子变量保证 isrunning 的内存可见性 - -//std::queue receivedData; // 用于存储接收到的数据 bool isrunning = true; //用于线程同步 std::string receivedData; -//std::queue receivedData2; // 用于存储接收到的数据 bool isrunning2 = true; //用于线程同步 std::string receivedData2; @@ -32,10 +21,6 @@ std::string rtdata_fail = "{\"code\":\"A0002\", \"msg\":\"3s数据执行失败\" // 处理补招请求的函数 std::string HandleRecall_http(const httplib::Request& req, httplib::Response& res) { - // 打印请求的查询参数 - //std::cout << "Query parameters: " << std::endl; - - //std::lock_guard lock(data_mutex); if(isrunning == true){ //收到前置信号,收到信息可以处理消息 if (req.body.empty()) { //消息体为空 @@ -180,21 +165,11 @@ std::string Handleupdate_http(const httplib::Request& req, httplib::Response& re //extern "C" std::string getReceivedData() { extern "C" const char* getReceivedData(int fun) { if(1 == fun){ - /*if (!receivedData.empty()) { - std::string msg = receivedData.front(); // 获取队列中的第一条消息 - receivedData.pop(); // 从队列中移除这条消息 - return msg.c_str(); - } - return "recall queue empty";*/ + return receivedData.c_str(); } if(2 == fun){ - /*if (!receivedData2.empty()) { - std::string msg = receivedData2.front(); // 获取队列中的第一条消息 - receivedData2.pop(); // 从队列中移除这条消息 - return msg.c_str(); - } - return "rtdata queue empty";*/ + return receivedData2.c_str(); } return "all queue empty"; @@ -223,7 +198,6 @@ extern "C" bool threadmsghttp(int fun) { // 启动 HTTP 服务器的函数 extern "C" void httprun() { - //std::cout << "WebhttpThread::run() is called ...... " << std::endl; // 创建 HTTP 服务器对象 httplib::Server svr; @@ -237,11 +211,8 @@ extern "C" void httprun() { // 监听路径 /powerQuality/update,绑定处理函数 svr.Post("/powerQuality/update", Handleupdate_http); // 使用 POST 方法处理请求 - // 监听端口 10004 - //std::cout << "Server started at http://0.0.0.0:10004" << std::endl; if (!svr.listen(HTTP_IP, HTTP_PORT)) { // 监听所有 IP std::cerr << "Error: Unable to start server on port 10004" << std::endl; } - //std::cout << "WebhttpThread::run() is end ...... " << std::endl; } \ No newline at end of file diff --git a/cfg_parse/nacos.cpp b/cfg_parse/nacos.cpp index 227c46d..8277f09 100644 --- a/cfg_parse/nacos.cpp +++ b/cfg_parse/nacos.cpp @@ -14,13 +14,9 @@ using namespace std; #include - -/*lnk10-12*/ #include - #include #include - #include "../mms/db_interface.h" #include "../json/cjson.h"//WW 2023-08-27json #include "../include/curl/curl.h" @@ -30,712 +26,632 @@ extern "C" { #endif /* __cplusplus */ - size_t req_reply_nacos(void* ptr, size_t size, size_t nmemb, void* stream) - { - //((std::string*)userp)->append((char*)contents, size * nmemb); - //ע͵ԴӡcookieϢ - string* str = (string*)stream; - (*str).append((char*)ptr, size * nmemb); - //printf(">>>GetDevice in reply %s\n", (char*)ptr); - - //GetCJson(ptr); - return size * nmemb; +size_t req_reply_nacos(void* ptr, size_t size, size_t nmemb, void* stream) +{ + string* str = (string*)stream; + (*str).append((char*)ptr, size * nmemb); + return size * nmemb; +} +void read_nacos_param(const char* ptr, char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret) { + //cout << ">>>GetDevice in reply" << (char*)ptr; + int flag = 1; + cJSON* json = cJSON_Parse((char*)ptr); //jsonʽл + cJSON* json_node; + cJSON* json_param; + if (json == NULL) { + printf("nacos error %s\n", cJSON_GetErrorPtr()); } - - void read_nacos_param(const char* ptr, char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret) { - //cout << ">>>GetDevice in reply" << (char*)ptr; - int flag = 1; - cJSON* json = cJSON_Parse((char*)ptr); //jsonʽл - cJSON* json_node; - cJSON* json_param; - - if (json == NULL) { - printf("nacos 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()); + flag = 0; + } + json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult + if (json_node == NULL || json_node->valuestring == NULL || json_node->valuestring == "/0" || json_node->valuestring == "" || strcmp(json_node->valuestring, "success") != 0) { + printf("errors get falie: %s\n", cJSON_GetErrorPtr()); + flag = 0; + } + if (flag) { + printf("read nacos success\n"); + json_param = cJSON_GetObjectItem(json, "param"); //ȡresult + json_node = cJSON_GetObjectItem(json_param, "postgres_uid"); //ȡresult + if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { + strcpy(postgres_uid, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "postgres_pwd"); //ȡresult + if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { + strcpy(postgres_pwd, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "web_clientid"); //ȡresult + if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { + strcpy(web_clientid, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "web_clientsecret"); //ȡresult + if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { + strcpy(web_clientsecret, json_node->valuestring); + } + } + } + cJSON_Delete(json); +} +void releaseMemory(char** ptr) { + if (*ptr != NULL) { + free(*ptr); // ͷڴ + } +} +void SendWebAPI_Nacos(const string strUrl, const char* code, char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret) +{ + // curlʼ + CURL* curl = curl_easy_init(); + // curlֵ + CURLcode res; + if (curl) + { + //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, strUrl.c_str()); + //postIJ + cJSON* json_root = cJSON_CreateObject(); + cJSON_AddItemToObject(json_root, "code", cJSON_CreateString(code)); + char* szjson = cJSON_Print(json_root); + printf(">>>json %s\n", szjson); + 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_nacos); + 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(">>>Test nacos Post in curl post\n"); + // post + res = curl_easy_perform(curl); + // Ƿɹ + if (res != CURLE_OK) { + printf("nacos failed res code: "); } 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()); - flag = 0; - } - json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult - if (json_node == NULL || json_node->valuestring == NULL || json_node->valuestring == "/0" || json_node->valuestring == "" || strcmp(json_node->valuestring, "success") != 0) { - printf("errors get falie: %s\n", cJSON_GetErrorPtr()); - flag = 0; - } - if (flag) { - printf("read nacos success\n"); - - json_param = cJSON_GetObjectItem(json, "param"); //ȡresult - json_node = cJSON_GetObjectItem(json_param, "postgres_uid"); //ȡresult - if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { - strcpy(postgres_uid, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "postgres_pwd"); //ȡresult - if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { - //***postgres_pwd = json_node->valuestring; - strcpy(postgres_pwd, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "web_clientid"); //ȡresult - if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { - strcpy(web_clientid, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "web_clientsecret"); //ȡresult - if (json_node != NULL && strcmp(json_node->valuestring, "null") != 0) { - strcpy(web_clientsecret, json_node->valuestring); - } - - } + printf("nacos success,string %s", resPost0.c_str()); + //webapiֵж + read_nacos_param(resPost0.c_str(), postgres_uid, postgres_pwd, web_clientid, web_clientsecret); } - cJSON_Delete(json); + curl_slist_free_all(header_list); + free(szjson); + cJSON_Delete(json_root); } - - void releaseMemory(char** ptr) { - if (*ptr != NULL) { - free(*ptr); // ͷڴ - } - } - - void SendWebAPI_Nacos(const string strUrl, const char* code, char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret) + else { - - // curlʼ - CURL* curl = curl_easy_init(); - // curlֵ - CURLcode res; - if (curl) - { - //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, strUrl.c_str()); - //postIJ - cJSON* json_root = cJSON_CreateObject(); - - cJSON_AddItemToObject(json_root, "code", cJSON_CreateString(code)); - - 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_nacos); - - - 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(">>>Test nacos Post in curl post\n"); - // post - res = curl_easy_perform(curl); - // Ƿɹ - if (res != CURLE_OK) { - printf("nacos failed res code: "); + printf(">>> nacos curl init failed"); + } + curl_easy_cleanup(curl); +} +void SendWebAPI_Nacos_Ptr(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?code=%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_nacos); + string resPost0; + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); + //óʱʱ + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); + + // post + res = curl_easy_perform(curl); + // Ƿɹ + if (res != CURLE_OK) { + printf("nacos failed res code: "); + } + else { + printf(">>> nacos 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("nacos success,string %s", resPost0.c_str()); - //webapiֵж - read_nacos_param(resPost0.c_str(), postgres_uid, postgres_pwd, web_clientid, web_clientsecret); + printf("Memory allocation failed!\n"); } - - curl_slist_free_all(header_list); - free(szjson); - cJSON_Delete(json_root); } - else - { - printf(">>> nacos curl init failed"); - } - curl_easy_cleanup(curl); } - - void SendWebAPI_Nacos_Ptr(const string strUrl, const char* code, char** ptr) + else { - // curlʼ - CURL* curl = curl_easy_init(); - // curlֵ - CURLcode res; - if (curl) - { - char url[100]; - sprintf(url, "%s?code=%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_nacos); - - - string resPost0; - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0); - //óʱʱ - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); + printf(">>> nacos curl init failed"); + } + curl_easy_cleanup(curl); +} +void Nacos_GetParam(char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret) +{ + SendWebAPI_Nacos("http://127.0.0.1:8091/powerQuality/PQNACOS", "200", postgres_uid, postgres_pwd, web_clientid, web_clientsecret); +} +void Nacos_GetParam_Ptr(const char* code, char** ptr) +{ + SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", code, ptr); +} +void Read_Nacos_Param_Postgres(char** database_ip, char** database_port, char** postgres_database, char** postgres_username, char** postgres_password, char** postgres_schema, char** postgres_dnsname, char** postgres_tableprefix) { + char* ptr=NULL; + SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "postgres", &ptr); + int flag = 1; + cJSON* json = cJSON_Parse(ptr); //jsonʽл + cJSON* json_node; + cJSON* json_param; + if (json == NULL) { + printf("nacos error %s\n", cJSON_GetErrorPtr()); + } + else { + json_node = cJSON_GetObjectItem(json, "status"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { + printf("status error :%s\n", cJSON_GetErrorPtr()); + flag = 0; + } + json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { + printf("errors get falie: %s\n", cJSON_GetErrorPtr()); + flag = 0; + } + if (flag) { + printf("read nacos success\n"); + json_param = cJSON_GetObjectItem(json, "param"); //ȡresult + json_node = cJSON_GetObjectItem(json_param, "ip"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*database_ip != NULL) { + // Ѿڴ棬ͷڴ + free(*database_ip); + } + *database_ip = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*database_ip, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "port"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*database_port != NULL) { + // Ѿڴ棬ͷڴ + free(*database_port); + } + *database_port = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*database_port, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "database"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*postgres_database != NULL) { + // Ѿڴ棬ͷڴ + free(*postgres_database); + } + *postgres_database = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*postgres_database, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "username"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*postgres_username != NULL) { + // Ѿڴ棬ͷڴ + free(*postgres_username); + } + *postgres_username = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*postgres_username, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "password"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*postgres_password != NULL) { + // Ѿڴ棬ͷڴ + free(*postgres_password); + } + *postgres_password = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*postgres_password, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "schema"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*postgres_schema != NULL) { + // Ѿڴ棬ͷڴ + free(*postgres_schema); + } + *postgres_schema = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*postgres_schema, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "dnsname"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*postgres_dnsname != NULL) { + // Ѿڴ棬ͷڴ + free(*postgres_dnsname); + } + *postgres_dnsname = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*postgres_dnsname, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "tablePrefix"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*postgres_tableprefix != NULL) { + // Ѿڴ棬ͷڴ + free(*postgres_tableprefix); + } + *postgres_tableprefix = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*postgres_tableprefix, json_node->valuestring); + } + } + } + if (ptr) { + free(ptr); + } + cJSON_Delete(json); +} +void Read_Nacos_Param_Kafka(char** broker_list, char** topic_stat, char** topic_pst, char** topic_plt, char** topic_event, char** topic_alarm, char** topic_sng,char** protocol ,char** mechanisms, char** service_name, char** principal, char** domain_name) { + char* ptr = NULL; + SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "kafka", &ptr); + int flag = 1; + cJSON* json = cJSON_Parse(ptr); //jsonʽл + cJSON* json_node; + cJSON* json_param; + if (json == NULL) { + printf("nacos error %s\n", cJSON_GetErrorPtr()); + } + else { + json_node = cJSON_GetObjectItem(json, "status"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { + printf("status error :%s\n", cJSON_GetErrorPtr()); + flag = 0; + } + json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { + printf("errors get falie: %s\n", cJSON_GetErrorPtr()); + flag = 0; + } + if (flag) { + printf("read nacos success\n"); + json_param = cJSON_GetObjectItem(json, "param"); //ȡresult + json_node = cJSON_GetObjectItem(json_param, "brokerList"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*broker_list != NULL) { + // Ѿڴ棬ͷڴ + free(*broker_list); + } + *broker_list = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*broker_list, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "hisTopic"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*topic_stat != NULL) { + // Ѿڴ棬ͷڴ + free(*topic_stat); + } + *topic_stat = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*topic_stat, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "pstTopic"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*topic_pst != NULL) { + // Ѿڴ棬ͷڴ + free(*topic_pst); + } + *topic_pst = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*topic_pst, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "pltTopic"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*topic_plt != NULL) { + // Ѿڴ棬ͷڴ + free(*topic_plt); + } + *topic_plt = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*topic_plt, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "eventTopic"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*topic_event != NULL) { + // Ѿڴ棬ͷڴ + free(*topic_event); + } + *topic_event = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*topic_event, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "almTopic"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*topic_alarm != NULL) { + // Ѿڴ棬ͷڴ + free(*topic_alarm); + } + *topic_alarm = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*topic_alarm, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "sngTopic"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*topic_sng != NULL) { + // Ѿڴ棬ͷڴ + free(*topic_sng); + } + *topic_sng = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*topic_sng, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "protocol"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*protocol != NULL) { + // Ѿڴ棬ͷڴ + free(*protocol); + } + *protocol = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*protocol, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "mechanisms"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*mechanisms != NULL) { + // Ѿڴ棬ͷڴ + free(*mechanisms); + } + *mechanisms = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*mechanisms, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "serviceName"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*service_name != NULL) { + // Ѿڴ棬ͷڴ + free(*service_name); + } + *service_name = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*service_name, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "principal"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*principal != NULL) { + // Ѿڴ棬ͷڴ + free(*principal); + } + *principal = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*principal, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "domainName"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*domain_name != NULL) { + // Ѿڴ棬ͷڴ + free(*domain_name); + } + *domain_name = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*domain_name, json_node->valuestring); + } + } + } + cJSON_Delete(json); +} +void Read_Nacos_Param_Web(char** client_id, char** client_secret, char** token_url, char** device_url, char** grant_type) { + char* ptr = NULL; + SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "web", &ptr); + int flag = 1; + cJSON* json = cJSON_Parse(ptr); //jsonʽл + cJSON* json_node; + cJSON* json_param; + if (json == NULL) { + printf("nacos error %s\n", cJSON_GetErrorPtr()); + } + else { + json_node = cJSON_GetObjectItem(json, "status"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { + printf("status error :%s\n", cJSON_GetErrorPtr()); + flag = 0; + } + json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { + printf("errors get falie: %s\n", cJSON_GetErrorPtr()); + flag = 0; + } + if (flag) { + printf("read nacos success\n"); + json_param = cJSON_GetObjectItem(json, "param"); //ȡresult + json_node = cJSON_GetObjectItem(json_param, "clientId"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*client_id != NULL) { + // Ѿڴ棬ͷڴ + free(*client_id); + } + *client_id = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*client_id, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "clientSecret"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*client_secret != NULL) { + // Ѿڴ棬ͷڴ + free(*client_secret); + } + *client_secret = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*client_secret, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "tokenUrl"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*token_url != NULL) { + // Ѿڴ棬ͷڴ + free(*token_url); + } + *token_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*token_url, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "deviceUrl"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*device_url != NULL) { + // Ѿڴ棬ͷڴ + free(*device_url); + } + *device_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*device_url, json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "grantType"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*grant_type != NULL) { + // Ѿڴ棬ͷڴ + free(*grant_type); + } + *grant_type = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*grant_type, json_node->valuestring); + } - - // post - res = curl_easy_perform(curl); - - // Ƿɹ - if (res != CURLE_OK) { - printf("nacos failed res code: "); - } - else { - printf(">>> nacos return str:%s \n", resPost0.c_str()); - //*ptr = strdup(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"); - } - //printf(">>>json %s\n", *ptr); - //webapiֵж - } - - //free(url); } - else - { - printf(">>> nacos curl init failed"); - } - curl_easy_cleanup(curl); } - - - void Nacos_GetParam(char* postgres_uid, char* postgres_pwd, char* web_clientid, char* web_clientsecret) - { - SendWebAPI_Nacos("http://127.0.0.1:8091/powerQuality/PQNACOS", "200", postgres_uid, postgres_pwd, web_clientid, web_clientsecret); + cJSON_Delete(json); +} +void Read_Nacos_Param_Flag(int* file_flag, int* send_flag, int* front_inst, char** front_ip) { + char* ptr = NULL; + SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "flag", &ptr); + int flag = 1; + cJSON* json = cJSON_Parse(ptr); //jsonʽл + cJSON* json_node; + cJSON* json_param; + if (json == NULL) { + printf("nacos error: %s\n", ptr); } - - void Nacos_GetParam_Ptr(const char* code, char** ptr) - { - SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", code, ptr); + else { + json_node = cJSON_GetObjectItem(json, "status"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { + printf("status error :%s\n", cJSON_GetErrorPtr()); + flag = 0; + } + json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { + printf("errors get falie: %s\n", cJSON_GetErrorPtr()); + flag = 0; + } + if (flag) { + printf("read nacos success\n"); + json_param = cJSON_GetObjectItem(json, "param"); //ȡresult + json_node = cJSON_GetObjectItem(json_param, "fileFlag"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + *file_flag= atoi(json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "sendFlag"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + *send_flag = atoi(json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "frontInst"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + *front_inst = atoi(json_node->valuestring); + } + json_node = cJSON_GetObjectItem(json_param, "frontIP"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + //***postgres_pwd = json_node->valuestring; + if (*front_ip != NULL) { + // Ѿڴ棬ͷڴ + free(*front_ip); + } + *front_ip = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*front_ip, json_node->valuestring); + } + + } } - - void Read_Nacos_Param_Postgres(char** database_ip, char** database_port, char** postgres_database, char** postgres_username, char** postgres_password, char** postgres_schema, char** postgres_dnsname, char** postgres_tableprefix) { - char* ptr=NULL; - SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "postgres", &ptr); - //cout << ">>>GetDevice in reply" << (char*)ptr; - int flag = 1; - cJSON* json = cJSON_Parse(ptr); //jsonʽл - cJSON* json_node; - cJSON* json_param; - - if (json == NULL) { - printf("nacos error %s\n", cJSON_GetErrorPtr()); - } - else { - json_node = cJSON_GetObjectItem(json, "status"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { - printf("status error :%s\n", cJSON_GetErrorPtr()); - flag = 0; - } - json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { - printf("errors get falie: %s\n", cJSON_GetErrorPtr()); - flag = 0; - } - if (flag) { - printf("read nacos success\n"); - - json_param = cJSON_GetObjectItem(json, "param"); //ȡresult - json_node = cJSON_GetObjectItem(json_param, "ip"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*database_ip != NULL) { - // Ѿڴ棬ͷڴ - free(*database_ip); - } - *database_ip = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*database_ip, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "port"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*database_port != NULL) { - // Ѿڴ棬ͷڴ - free(*database_port); - } - *database_port = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*database_port, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "database"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*postgres_database != NULL) { - // Ѿڴ棬ͷڴ - free(*postgres_database); - } - *postgres_database = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*postgres_database, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "username"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - //***postgres_pwd = json_node->valuestring; - if (*postgres_username != NULL) { - // Ѿڴ棬ͷڴ - free(*postgres_username); - } - *postgres_username = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*postgres_username, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "password"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*postgres_password != NULL) { - // Ѿڴ棬ͷڴ - free(*postgres_password); - } - *postgres_password = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*postgres_password, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "schema"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*postgres_schema != NULL) { - // Ѿڴ棬ͷڴ - free(*postgres_schema); - } - *postgres_schema = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*postgres_schema, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "dnsname"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*postgres_dnsname != NULL) { - // Ѿڴ棬ͷڴ - free(*postgres_dnsname); - } - *postgres_dnsname = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*postgres_dnsname, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "tablePrefix"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*postgres_tableprefix != NULL) { - // Ѿڴ棬ͷڴ - free(*postgres_tableprefix); - } - *postgres_tableprefix = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*postgres_tableprefix, json_node->valuestring); - } - - } - } - if (ptr) { - free(ptr); - } - cJSON_Delete(json); + cJSON_Delete(json); +} +void Read_Nacos_Param_Recall(int* recall_len, int* recall_sta, int* recall_daily) { + char* ptr = NULL; + SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "recall", &ptr); + int flag = 1; + cJSON* json = cJSON_Parse(ptr); //jsonʽл + cJSON* json_node; + cJSON* json_param; + if (json == NULL) { + printf("nacos error %s\n", cJSON_GetErrorPtr()); } - - void Read_Nacos_Param_Kafka(char** broker_list, char** topic_stat, char** topic_pst, char** topic_plt, char** topic_event, char** topic_alarm, char** topic_sng,char** protocol ,char** mechanisms, char** service_name, char** principal, char** domain_name) { - char* ptr = NULL; - SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "kafka", &ptr); - //cout << ">>>GetDevice in reply" << (char*)ptr; - int flag = 1; - cJSON* json = cJSON_Parse(ptr); //jsonʽл - cJSON* json_node; - cJSON* json_param; - if (json == NULL) { - printf("nacos error %s\n", cJSON_GetErrorPtr()); + else { + json_node = cJSON_GetObjectItem(json, "status"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { + printf("status error :%s\n", cJSON_GetErrorPtr()); + flag = 0; } - else { - json_node = cJSON_GetObjectItem(json, "status"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { - printf("status error :%s\n", cJSON_GetErrorPtr()); - flag = 0; + json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { + printf("errors get falie: %s\n", cJSON_GetErrorPtr()); + flag = 0; + } + if (flag) { + printf("read nacos success\n"); + json_param = cJSON_GetObjectItem(json, "param"); //ȡresult + json_node = cJSON_GetObjectItem(json_param, "recall_lenth"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + *recall_len = atoi(json_node->valuestring); } - json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { - printf("errors get falie: %s\n", cJSON_GetErrorPtr()); - flag = 0; + json_node = cJSON_GetObjectItem(json_param, "recall_start"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + *recall_sta = atoi(json_node->valuestring); } - if (flag) { - printf("read nacos success\n"); - json_param = cJSON_GetObjectItem(json, "param"); //ȡresult - json_node = cJSON_GetObjectItem(json_param, "brokerList"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*broker_list != NULL) { - // Ѿڴ棬ͷڴ - free(*broker_list); - } - *broker_list = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*broker_list, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "hisTopic"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*topic_stat != NULL) { - // Ѿڴ棬ͷڴ - free(*topic_stat); - } - *topic_stat = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*topic_stat, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "pstTopic"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*topic_pst != NULL) { - // Ѿڴ棬ͷڴ - free(*topic_pst); - } - *topic_pst = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*topic_pst, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "pltTopic"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*topic_plt != NULL) { - // Ѿڴ棬ͷڴ - free(*topic_plt); - } - *topic_plt = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*topic_plt, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "eventTopic"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*topic_event != NULL) { - // Ѿڴ棬ͷڴ - free(*topic_event); - } - *topic_event = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*topic_event, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "almTopic"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*topic_alarm != NULL) { - // Ѿڴ棬ͷڴ - free(*topic_alarm); - } - *topic_alarm = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*topic_alarm, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "sngTopic"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*topic_sng != NULL) { - // Ѿڴ棬ͷڴ - free(*topic_sng); - } - *topic_sng = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*topic_sng, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "protocol"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*protocol != NULL) { - // Ѿڴ棬ͷڴ - free(*protocol); - } - *protocol = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*protocol, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "mechanisms"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*mechanisms != NULL) { - // Ѿڴ棬ͷڴ - free(*mechanisms); - } - *mechanisms = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*mechanisms, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "serviceName"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*service_name != NULL) { - // Ѿڴ棬ͷڴ - free(*service_name); - } - *service_name = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*service_name, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "principal"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*principal != NULL) { - // Ѿڴ棬ͷڴ - free(*principal); - } - *principal = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*principal, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "domainName"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*domain_name != NULL) { - // Ѿڴ棬ͷڴ - free(*domain_name); - } - *domain_name = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*domain_name, json_node->valuestring); - } - + json_node = cJSON_GetObjectItem(json_param, "recall_dailytime"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + *recall_daily = atoi(json_node->valuestring); } } - cJSON_Delete(json); } - - void Read_Nacos_Param_Web(char** client_id, char** client_secret, char** token_url, char** device_url, char** grant_type) { - char* ptr = NULL; - SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "web", &ptr); - //cout << ">>>GetDevice in reply" << (char*)ptr; - int flag = 1; - cJSON* json = cJSON_Parse(ptr); //jsonʽл - cJSON* json_node; - cJSON* json_param; - - if (json == NULL) { - printf("nacos error %s\n", cJSON_GetErrorPtr()); - } - else { - json_node = cJSON_GetObjectItem(json, "status"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { - printf("status error :%s\n", cJSON_GetErrorPtr()); - flag = 0; - } - json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { - printf("errors get falie: %s\n", cJSON_GetErrorPtr()); - flag = 0; - } - if (flag) { - printf("read nacos success\n"); - - json_param = cJSON_GetObjectItem(json, "param"); //ȡresult - json_node = cJSON_GetObjectItem(json_param, "clientId"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*client_id != NULL) { - // Ѿڴ棬ͷڴ - free(*client_id); - } - *client_id = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*client_id, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "clientSecret"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*client_secret != NULL) { - // Ѿڴ棬ͷڴ - free(*client_secret); - } - *client_secret = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*client_secret, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "tokenUrl"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*token_url != NULL) { - // Ѿڴ棬ͷڴ - free(*token_url); - } - *token_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*token_url, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "deviceUrl"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - //***postgres_pwd = json_node->valuestring; - if (*device_url != NULL) { - // Ѿڴ棬ͷڴ - free(*device_url); - } - *device_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*device_url, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "grantType"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*grant_type != NULL) { - // Ѿڴ棬ͷڴ - free(*grant_type); - } - *grant_type = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*grant_type, json_node->valuestring); - } - - - } - } - cJSON_Delete(json); + cJSON_Delete(json); +} +void Read_Nacos_Param_Uds(char** uds_upload_url, char** uds_download_url, char** uds_delete_url) { + char* ptr = NULL; + SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "uds", &ptr); + int flag = 1; + cJSON* json = cJSON_Parse(ptr); //jsonʽл + cJSON* json_node; + cJSON* json_param; + if (json == NULL) { + printf("nacos error %s\n", cJSON_GetErrorPtr()); } - - void Read_Nacos_Param_Flag(int* file_flag, int* send_flag, int* front_inst, char** front_ip) { - char* ptr = NULL; - SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "flag", &ptr); - //cout << ">>>GetDevice in reply" << (char*)ptr; - int flag = 1; - cJSON* json = cJSON_Parse(ptr); //jsonʽл - cJSON* json_node; - cJSON* json_param; - - if (json == NULL) { - printf("nacos error: %s\n", ptr); + else { + json_node = cJSON_GetObjectItem(json, "status"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { + printf("status error :%s\n", cJSON_GetErrorPtr()); + flag = 0; } - else { - json_node = cJSON_GetObjectItem(json, "status"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { - printf("status error :%s\n", cJSON_GetErrorPtr()); - flag = 0; + json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult + if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { + printf("errors get falie: %s\n", cJSON_GetErrorPtr()); + flag = 0; + } + if (flag) { + printf("read nacos success\n"); + json_param = cJSON_GetObjectItem(json, "param"); //ȡresult + json_node = cJSON_GetObjectItem(json_param, "udsUploadUrl"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*uds_upload_url != NULL) { + // Ѿڴ棬ͷڴ + free(*uds_upload_url); + } + *uds_upload_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*uds_upload_url, json_node->valuestring); } - json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { - printf("errors get falie: %s\n", cJSON_GetErrorPtr()); - flag = 0; + json_node = cJSON_GetObjectItem(json_param, "udsDownloadUrl"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*uds_download_url != NULL) { + // Ѿڴ棬ͷڴ + free(*uds_download_url); + } + *uds_download_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*uds_download_url, json_node->valuestring); } - if (flag) { - printf("read nacos success\n"); - - json_param = cJSON_GetObjectItem(json, "param"); //ȡresult - json_node = cJSON_GetObjectItem(json_param, "fileFlag"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - *file_flag= atoi(json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "sendFlag"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - *send_flag = atoi(json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "frontInst"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - *front_inst = atoi(json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "frontIP"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - //***postgres_pwd = json_node->valuestring; - if (*front_ip != NULL) { - // Ѿڴ棬ͷڴ - free(*front_ip); - } - *front_ip = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*front_ip, json_node->valuestring); + json_node = cJSON_GetObjectItem(json_param, "UdsDeleteUrl"); //ȡresult + if (json_node && json_node->type == cJSON_String) { + if (*uds_delete_url != NULL) { + // Ѿڴ棬ͷڴ + free(*uds_delete_url); } + *uds_delete_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ + strcpy(*uds_delete_url, json_node->valuestring); + } - - } } - cJSON_Delete(json); } - - void Read_Nacos_Param_Recall(int* recall_len, int* recall_sta, int* recall_daily) { - char* ptr = NULL; - SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "recall", &ptr); - //cout << ">>>GetDevice in reply" << (char*)ptr; - int flag = 1; - cJSON* json = cJSON_Parse(ptr); //jsonʽл - cJSON* json_node; - cJSON* json_param; - - if (json == NULL) { - printf("nacos error %s\n", cJSON_GetErrorPtr()); - } - else { - json_node = cJSON_GetObjectItem(json, "status"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { - printf("status error :%s\n", cJSON_GetErrorPtr()); - flag = 0; - } - json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { - printf("errors get falie: %s\n", cJSON_GetErrorPtr()); - flag = 0; - } - if (flag) { - printf("read nacos success\n"); - - json_param = cJSON_GetObjectItem(json, "param"); //ȡresult - json_node = cJSON_GetObjectItem(json_param, "recall_lenth"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - *recall_len = atoi(json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "recall_start"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - *recall_sta = atoi(json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "recall_dailytime"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - *recall_daily = atoi(json_node->valuestring); - } - - } - } - cJSON_Delete(json); - } - - void Read_Nacos_Param_Uds(char** uds_upload_url, char** uds_download_url, char** uds_delete_url) { - char* ptr = NULL; - SendWebAPI_Nacos_Ptr("http://127.0.0.1:8091/powerQuality/getProperties", "uds", &ptr); - //cout << ">>>GetDevice in reply" << (char*)ptr; - int flag = 1; - cJSON* json = cJSON_Parse(ptr); //jsonʽл - cJSON* json_node; - cJSON* json_param; - - if (json == NULL) { - printf("nacos error %s\n", cJSON_GetErrorPtr()); - } - else { - json_node = cJSON_GetObjectItem(json, "status"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "000000") != 0) { - printf("status error :%s\n", cJSON_GetErrorPtr()); - flag = 0; - } - json_node = cJSON_GetObjectItem(json, "errors"); //ȡresult - if (json_node == NULL || strcmp(json_node->valuestring, "success") != 0) { - printf("errors get falie: %s\n", cJSON_GetErrorPtr()); - flag = 0; - } - if (flag) { - printf("read nacos success\n"); - - json_param = cJSON_GetObjectItem(json, "param"); //ȡresult - json_node = cJSON_GetObjectItem(json_param, "udsUploadUrl"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*uds_upload_url != NULL) { - // Ѿڴ棬ͷڴ - free(*uds_upload_url); - } - *uds_upload_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*uds_upload_url, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "udsDownloadUrl"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*uds_download_url != NULL) { - // Ѿڴ棬ͷڴ - free(*uds_download_url); - } - *uds_download_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*uds_download_url, json_node->valuestring); - } - json_node = cJSON_GetObjectItem(json_param, "UdsDeleteUrl"); //ȡresult - if (json_node && json_node->type == cJSON_String) { - if (*uds_delete_url != NULL) { - // Ѿڴ棬ͷڴ - free(*uds_delete_url); - } - *uds_delete_url = (char*)malloc(strlen(json_node->valuestring) + 1); // ڴ - strcpy(*uds_delete_url, json_node->valuestring); - } - - } - } - cJSON_Delete(json); - } - - - - + cJSON_Delete(json); +} #ifdef __cplusplus } diff --git a/cfg_parse/obs_huaweiyun.cpp b/cfg_parse/obs_huaweiyun.cpp index ae4ba3f..18f9b18 100644 --- a/cfg_parse/obs_huaweiyun.cpp +++ b/cfg_parse/obs_huaweiyun.cpp @@ -32,11 +32,8 @@ char BUCKET_NAME_OBS[2048] = { "test-8601" }; size_t req_reply_device(void* ptr, size_t size, size_t nmemb, void* stream) { - //ע͵ԴӡcookieϢ string* str = (string*)stream; (*str).append((char*)ptr, size * nmemb); - //printf(">>>GetDevice in reply %s\n", (char*)ptr); - //GetCJson(ptr); return size * nmemb; } @@ -162,8 +159,6 @@ void SendWebAPI(const string strUrl, char* localpath, char* cloudpath,const char 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֤ @@ -245,12 +240,10 @@ void SendWebAPI_del(const string strUrl, char* cloudpath, const char* code) //param cJSON_AddItemToObject(json_param, "object_name", cJSON_CreateString(cloudpath)); cJSON_AddNullToObject(json_param, "localfile_name"); - //cJSON_AddItemToObject(json_param, "localfile_name", cJSON_CreateString(localpath)); 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֤ diff --git a/cfg_parse/oss_aliyun.cpp b/cfg_parse/oss_aliyun.cpp index d62fc12..01124c7 100644 --- a/cfg_parse/oss_aliyun.cpp +++ b/cfg_parse/oss_aliyun.cpp @@ -23,19 +23,14 @@ using namespace std; #include "../mms/db_interface.h" #include - char* OSS_ENDPOINT; - char* ACCESS_KEY_ID; - char* ACCESS_KEY_SECRET; +char* OSS_ENDPOINT; +char* ACCESS_KEY_ID; +char* ACCESS_KEY_SECRET; char* BUCKET_NAME; -//const char OSS_ENDPOINT[] = "oss-cn-nanjing.aliyuncs.com"; -//const char ACCESS_KEY_ID[] = "LTAI5tER4bgJxT6Ptie7t2X7"; -//const char ACCESS_KEY_SECRET[] = "dSYIC5hD3flhTNoLMAxCoKjSPdWFSz"; -//const char BUCKET_NAME[] = "cn-pq-test"; const char OBJECT_NAME[] = "comtrade/temp.json"; void init_sample_request_options(oss_request_options_t *options, int is_cname); - void put_object_from_buffer(); void put_object_from_buffer_new(char* File_Name, char* data); void put_object_from_file(); @@ -52,27 +47,19 @@ void TestOSS() aos_pool_t *pool = NULL; apr_status_t ret; - // initialize http io system, call it olny once /* ڳڵaos_http_io_initializeʼ硢ڴȫԴ*/ printf(">>>TestOSS ini Start"); if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { return; } - printf(">>>TestOSS put Start"); - // run samples - //put_object_from_buffer(); - //put_object_from_file(); + put_object_from_buffer(); get_object_to_file(); - //get_object_to_buffer(); - //get_object_to_file(); - //delete_object(); + printf(">>>TestOSS put End"); - - // deinitialize http io system, call it olny once aos_http_io_deinitialize(); return ; @@ -84,7 +71,6 @@ void PutOSS(char* File_Name,char* data) //zw aos_pool_t* pool = NULL; apr_status_t ret; - // initialize http io system, call it olny once /* ڳڵaos_http_io_initializeʼ硢ڴȫԴ*/ printf(">>>PutOSS ini Start"); printf(File_Name); @@ -100,8 +86,6 @@ void PutOSS(char* File_Name,char* data) //zw printf(">>>PutOSS put End"); - - // deinitialize http io system, call it olny once aos_http_io_deinitialize(); return; @@ -113,22 +97,18 @@ void GetOSS(char* File_Name,char* savepath) //zw aos_pool_t* pool = NULL; apr_status_t ret; - // initialize http io system, call it olny once /* ڳڵaos_http_io_initializeʼ硢ڴȫԴ*/ printf(">>>GetOSS ini Start"); if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { return; } - printf(">>>GetOSS put Start"); get_object_to_file_new(File_Name,savepath);//ʹbufferļ printf(">>>GetOSS put End"); - - // deinitialize http io system, call it olny once aos_http_io_deinitialize(); return; @@ -140,32 +120,29 @@ void DelOSS(char* File_Name) aos_pool_t* pool = NULL; apr_status_t ret; - // initialize http io system, call it olny once /* ڳڵaos_http_io_initializeʼ硢ڴȫԴ*/ printf(">>>DelOSS ini Start"); if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { return; } - printf(">>>DelOSS put Start"); + delete_object_new(File_Name);//ʹbufferļ printf(">>>DelOSS put End"); - - // deinitialize http io system, call it olny once aos_http_io_deinitialize(); return; } -void coutTest() { +void coutTest() +{ std:: cout << "OSS_ENDPOINT:" << OSS_ENDPOINT << std::endl; std::cout << "ACCESS_KEY_ID:" << ACCESS_KEY_ID << std::endl; std::cout << "ACCESS_KEY_SECRET:" << ACCESS_KEY_SECRET << std::endl; std::cout << "BUCKET_NAME:" << BUCKET_NAME << std::endl; - } void init_sample_request_options(oss_request_options_t *options, int is_cname) @@ -175,7 +152,6 @@ void init_sample_request_options(oss_request_options_t *options, int is_cname) aos_str_set(&options->config->access_key_id, ACCESS_KEY_ID); aos_str_set(&options->config->access_key_secret, ACCESS_KEY_SECRET); options->config->is_cname = is_cname; - options->ctl = aos_http_controller_create(options->pool, 0); } @@ -231,7 +207,6 @@ void put_object_from_buffer_new(char* File_Name,char* data)//zw aos_buf_t* content = NULL; char* str = data; aos_status_t* s = NULL; - aos_pool_create(&p, NULL); options = oss_request_options_create(p); init_sample_request_options(options, is_cname); @@ -323,10 +298,8 @@ void put_object_from_file_new(char* File_Name, char* path) printf("put object from file succeeded\n"); } else { - printf("put object from file failed, code:%d, error_code:%s, error_msg:%s, request_id:%s\n", - s->code, s->error_code, s->error_msg, s->req_id); + printf("put object from file failed, code:%d, error_code:%s, error_msg:%s, request_id:%s\n",s->code, s->error_code, s->error_msg, s->req_id); } - aos_pool_destroy(p); } diff --git a/cfg_parse/uds_huaweiyun.cpp b/cfg_parse/uds_huaweiyun.cpp index 4974d06..229f411 100644 --- a/cfg_parse/uds_huaweiyun.cpp +++ b/cfg_parse/uds_huaweiyun.cpp @@ -14,10 +14,8 @@ using namespace std; #include - #include #include - #include "../mms/db_interface.h" #include "../json/cjson.h"//WW 2023-08-27json #include "../include/curl/curl.h" @@ -26,293 +24,243 @@ using namespace std; extern "C" { #endif /* __cplusplus */ - - - - 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); - //printf(">>>GetDevice in reply %s\n", (char*)ptr); - //GetCJson(ptr); - return size * nmemb; - } - - /** - * @brief Get_Uuid json,õuuid - * @param ptr - * @param uuid ݴС - * @return int 0ɹ -1Ч - * ע⣺ݵĴС44ı - */ - int Get_Uuid(const char* ptr, char* uuid,char* filename) { - int result = 0; - //cout << ">>>GetDevice in reply" << (char*)ptr; - cJSON* json = cJSON_Parse((char*)ptr); //jsonʽл - cJSON* json_code; - cJSON* json_data; - cJSON* json_msg; - - - if (json) { - json_code = cJSON_GetObjectItem(json, "code"); //ȡsuccess - json_msg = cJSON_GetObjectItem(json, "msg"); //ȡsuccess - json_data = cJSON_GetObjectItem(json, "data"); //ȡdata - if (json_code && json_code->type == cJSON_Number && json_code->valueint==0) { - printf("upload uds success\n"); - cJSON* json_uuid; - cJSON* json_filename; - json_uuid = cJSON_GetObjectItem(json_data, "storeId"); //ȡdata - if (json_uuid && json_uuid->type == cJSON_String) { - strcpy(uuid, json_uuid->valuestring); - printf("read uds uuid success:%s\n", uuid); - } - json_filename = cJSON_GetObjectItem(json_data, "fileName"); //ȡdata - if (json_filename && json_filename->type == cJSON_String) { - strcpy(filename, json_filename->valuestring); - printf("read uds filename success:%s\n", filename); - } - result = 1; +size_t req_reply(void* ptr, size_t size, size_t nmemb, void* stream) +{ + string* str = (string*)stream; + (*str).append((char*)ptr, size * nmemb); + return size * nmemb; +} +/** +* @brief Get_Uuid json,õuuid +* @param ptr +* @param uuid ݴС +* @return int 0ɹ -1Ч +* ע⣺ݵĴС44ı +*/ +int Get_Uuid(const char* ptr, char* uuid,char* filename) +{ + int result = 0; + cJSON* json = cJSON_Parse((char*)ptr); //jsonʽл + cJSON* json_code; + cJSON* json_data; + cJSON* json_msg; + if (json) { + json_code = cJSON_GetObjectItem(json, "code"); //ȡsuccess + json_msg = cJSON_GetObjectItem(json, "msg"); //ȡsuccess + json_data = cJSON_GetObjectItem(json, "data"); //ȡdata + if (json_code && json_code->type == cJSON_Number && json_code->valueint==0) { + printf("upload uds success\n"); + cJSON* json_uuid; + cJSON* json_filename; + json_uuid = cJSON_GetObjectItem(json_data, "storeId"); //ȡdata + if (json_uuid && json_uuid->type == cJSON_String) { + strcpy(uuid, json_uuid->valuestring); + printf("read uds uuid success:%s\n", uuid); } - else if (json_msg && json_msg->valuestring != NULL) - { - printf("uuid get falie msg: %s\n", json_msg->valuestring); - result = 0; - } - else - { - printf("get uds uuid error :do not get msg\n"); - result = 0; + json_filename = cJSON_GetObjectItem(json_data, "fileName"); //ȡdata + if (json_filename && json_filename->type == cJSON_String) { + strcpy(filename, json_filename->valuestring); + printf("read uds filename success:%s\n", filename); } + result = 1; } - else { - printf("get uds uuid error:do not get json and %s\n", cJSON_GetErrorPtr()); + else if (json_msg && json_msg->valuestring != NULL) + { + printf("uuid get falie msg: %s\n", json_msg->valuestring); + result = 0; + } + else + { + printf("get uds uuid error :do not get msg\n"); result = 0; } - cJSON_Delete(json); - return result; } - + else { + printf("get uds uuid error:do not get json and %s\n", cJSON_GetErrorPtr()); + result = 0; + } + cJSON_Delete(json); + return result; +} +// ֽдļ +void Write_Byte_Array_To_File(char* local_path, char* data_array, long size) +{ // ֽдļ - void Write_Byte_Array_To_File(char* local_path, char* data_array, long size) { - // ֽдļ - FILE* outFile = fopen(local_path, "wb"); - if (outFile != NULL) { - fwrite(data_array, sizeof(char), size, outFile); - fclose(outFile); - printf("File saved successfully.\n"); - } - else { - printf("Failed to open file for writing\n"); - } + FILE* outFile = fopen(local_path, "wb"); + if (outFile != NULL) { + fwrite(data_array, sizeof(char), size, outFile); + fclose(outFile); + printf("File saved successfully.\n"); } - - void Save_File(const char* ptr, char* local_path) { - //cout << ">>>GetDevice in reply" << (char*)ptr; - cJSON* json = cJSON_Parse((char*)ptr); //jsonʽл - cJSON* json_success; - cJSON* json_data; - cJSON* json_msg; - if (json) { - json_success = cJSON_GetObjectItem(json, "sucess"); //ȡsuccess - json_msg = cJSON_GetObjectItem(json, "msg"); //ȡsuccess - json_data = cJSON_GetObjectItem(json, "data"); //ȡdata - if (json_success && json_success->type == cJSON_True) { - printf("save uds file success\n"); - if (json_data && json_data->type == cJSON_String) { - // ַ - long decodedLen = strlen(json_data->valuestring) * 3 / 4; - char* decodedStr = (char*)malloc(decodedLen + 1); - // Base64 - int success = base64_decode(json_data->valuestring, strlen(json_data->valuestring), decodedStr, &decodedLen); - Write_Byte_Array_To_File(local_path, decodedStr, decodedLen); - free(decodedStr); - } - } - else if (json_msg && json_msg->valuestring != NULL) - { - printf("save uds file falie msg: %s\n", json_msg->valuestring); - } - else - { - printf("save uds file error :do not get msg\n"); - } - } - else { - printf("save uds file error:do not get json and %s\n", cJSON_GetErrorPtr()); - - } - cJSON_Delete(json); + else { + printf("Failed to open file for writing\n"); } - - int WebAPI_Uds_Upload(char* strUrl, char* loacl_path, char* uuid,char* filename) - { - int result = 0; - printf("loaclpath: %s\n", loacl_path); - /*char json_buf[] = "{\"code\":0,\"msg\":\"success\",\"data\":\"0903d01092381283918391312131awe\",\"encrypt_data\":null,\"other\":null,\"sucess\":true}"; - Get_Uuid(json_buf, uuid); - printf("loaclpath: %s\n", uuid);*/ - // curlʼ - CURL* curl = curl_easy_init(); - // curlֵ - CURLcode res; - if (curl) +} +void Save_File(const char* ptr, char* local_path) +{ + cJSON* json = cJSON_Parse((char*)ptr); //jsonʽл + cJSON* json_success; + cJSON* json_data; + cJSON* json_msg; + if (json) { + json_success = cJSON_GetObjectItem(json, "sucess"); //ȡsuccess + json_msg = cJSON_GetObjectItem(json, "msg"); //ȡsuccess + json_data = cJSON_GetObjectItem(json, "data"); //ȡdata + if (json_success && json_success->type == cJSON_True) { + printf("save uds file success\n"); + if (json_data && json_data->type == cJSON_String) { + // ַ + long decodedLen = strlen(json_data->valuestring) * 3 / 4; + char* decodedStr = (char*)malloc(decodedLen + 1); + // Base64 + int success = base64_decode(json_data->valuestring, strlen(json_data->valuestring), decodedStr, &decodedLen); + Write_Byte_Array_To_File(local_path, decodedStr, decodedLen); + free(decodedStr); + } + } + else if (json_msg && json_msg->valuestring != NULL) { - //curlͷ - struct curl_slist* header_list = NULL; - //Content-TypeΪmultipart/form-data - header_list = curl_slist_append(header_list, "Content-Type: multipart/form-data"); - - 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); - //postIJ - - - struct curl_httppost* formpost = NULL; - struct curl_httppost* lastptr = NULL; - // form-dataֶ - curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "file", CURLFORM_FILE, loacl_path, CURLFORM_END); - //curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "password", CURLFORM_COPYCONTENTS, "secretpassword", CURLFORM_END); - curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); - - //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(">>>uds upload Post in curl post\n"); - // post - res = curl_easy_perform(curl); - // Ƿɹ - if (res != CURLE_OK) { - printf("uds upload failed res code: "); - result = 0; - } - else { - printf("uds upload success,string %s", resPost0.c_str()); - //webapiֵж - result=Get_Uuid(resPost0.c_str(), uuid,filename); - } - // ͷԴ - curl_slist_free_all(header_list); - curl_formfree(formpost); + printf("save uds file falie msg: %s\n", json_msg->valuestring); } else { - printf(">>> uds upload init failed"); + printf("save uds file error :do not get msg\n"); + } + } + else { + printf("save uds file error:do not get json and %s\n", cJSON_GetErrorPtr()); + } + cJSON_Delete(json); +} +int WebAPI_Uds_Upload(char* strUrl, char* loacl_path, char* uuid,char* filename) +{ + int result = 0; + printf("loaclpath: %s\n", loacl_path); + // curlʼ + CURL* curl = curl_easy_init(); + // curlֵ + CURLcode res; + if (curl) + { + //curlͷ + struct curl_slist* header_list = NULL; + //Content-TypeΪmultipart/form-data + header_list = curl_slist_append(header_list, "Content-Type: multipart/form-data"); + 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); + //postIJ + struct curl_httppost* formpost = NULL; + struct curl_httppost* lastptr = NULL; + // form-dataֶ + curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "file", CURLFORM_FILE, loacl_path, CURLFORM_END); + //curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "password", CURLFORM_COPYCONTENTS, "secretpassword", CURLFORM_END); + curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); + //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(">>>uds upload Post in curl post\n"); + // post + res = curl_easy_perform(curl); + // Ƿɹ + if (res != CURLE_OK) { + printf("uds upload failed res code: "); result = 0; - } - - curl_easy_cleanup(curl); - return result; + else { + printf("uds upload success,string %s", resPost0.c_str()); + //webapiֵж + result=Get_Uuid(resPost0.c_str(), uuid,filename); + } + // ͷԴ + curl_slist_free_all(header_list); + curl_formfree(formpost); } - - void WebAPI_Uds_Download(char* strUrl, char* uuid, char* local_path,char* filename) + else { - //const char json_buf[] = "{\"code\":0,\"msg\":\"success\",\"data\":\"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCASHBBIDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+2iiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA9J8CEf6SM846fjXo9eE6Hqsml3iSAnymYCROxzxkjvgfj6EV7LZapaXyBopVz3UsAQfTBOf8g9xQBo0U3en95f8Avof40b0/vL/30P8AGgB1FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXPeJiP7Kn5Hbv71utNEud0sYx1y6jtnuR2rynxNrpv1ksLNztLc8+hxknpjjGCeCwIPTIBxA6D6ClpACoCnqAAe/I4PP1paACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAp6ySIQVkdSOhVmUj6EEYplFAE/wBquf8An4n/AO/0n/xVH2q5/wCfif8A7/Sf/FVBRQBN9ouP+e83/f1//iqPtFx/z3m/7+v/APFVDRQBN9ouP+e83/f1/wD4qj7Rcf8APeb/AL+v/wDFVDRQBN9ouP8AnvN/39f/AOKo+0XH/Peb/v6//wAVUNFAE32i4/57zf8Af1//AIqj7Rcf895v+/r/APxVQ0UATfaLj/nvN/39f/4qj7Rcf895v+/r/wDxVQ0UATfaLj/nvN/39f8A+Ko+0XH/AD3m/wC/r/8AxVQ0UATfaLj/AJ7zf9/X/wDiqPtFx/z3m/7+v/8AFVDRQBN9ouP+e83/AH9f/wCKo+0XH/Peb/v6/wD8VUNFAE32i4/57zf9/X/+Ko+0XH/Peb/v6/8A8VUNFAE32i4/57zf9/X/APiqPtFx/wA95v8Av6//AMVUNFAEpnnbrNKfrI5/maj3NnO45HQ5OfzpKKADr1ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACilwcbsHb6446469OvH1puRzyOOuOaALfkJ6t+Y/wo8hPVvzH+FUjcEHBZv++m/wpPtJ/vN/303+FAF7yE9W/Mf4UeQnq35j/CqP2k/3m/76b/Cj7Sf7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P1+0W5guLP5DLIhu1IJ6kZGD0wen5dmP9oSmnKuqjpSm1rZt3jpZyl/Ja122l6I/q3hHBZZiFCeBoKlGcKbb0d+WLf2qcb6Ss7pLXXXR/JFnaS6XqmreEWSaa2Mf+iC6hBWGIRyRSAQyb44RJ/HtGCfvcjNegfCPw14V8Barpeq6d4QtNPthrejS64YoY9uqOLjzHZnVAVYk884J61ufEvQvEHguz0PxDrdvb3Gtf2SU1xoFBR3jkMTmIgHJBzgg8gcda89/4TyPTdNfTizpZa3d6dPbu4y9qwG7CuQSoBJwADg8HOTXCszzGk172lNx051tC2zvfVW1s2faVsryuKqKUYXtNNNbvqttd0tF17tH+jt8APGnwy1T4V/C2PwXe6Ppmm+IfC+lXmk6LaKqOJHs7aS4tYIY1VJGtp3e2dEVAht2OOcD6TCAL5bHcBwScjOD16kj6Z9q/jf/AOCUPxf8VX/7SPwV0/WfFFzL4fj0DWNLtLPUdUufskf2Oy1ZbfZDPNNbxuJrYMTHDG20qp4HH9jKzbwGVwwcBgRypDDcCpxggg5BGMiv07IcypY/Dy9nTVKVKNP2i9oqjlOakt1GNuXktbW116v+eOKMmqZLmXLKv7WOLpRrwfLyct5TvCynJO3MmmuV2dnFWMq6sDLPE+3OxicgDqeMEdB2OSeeoIr8of8AgqVqLR/D7SNBjckyXI1IqGIbBJstoGcBck8E/ez3ya/XZWwwbrg56/15r8Uv+CkOorqetyWTPlNLsIVZecc3XnMMDJHBJz17cYr26nT5/oLhhOebUb621/8AJo3s16dz2H9hdNv7P2iowIxf6htBJ4+ewb/0HJ/+vivslQAoA6YFfJn7F6iP4KaUuNq/2pqWBz0+zWDD1PUZr6zXoPoP5VmcvE//ACPcX/ipr5q916q6uhaKKKDxgooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArz34u/8iDrf/XH/ANmSvQq89+Lv/Ig63/1x/wDZ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wX4nnNnpW6yL6LeH7Sd2chjnnOcOMEgjBB5r428Z/BD4n+KPCF/a/wDCvvGkF6TljJomrA/6WCbv7KfsYPy54+pOMkV/Y1RXMvDDALX+0sS3dP8AhLW1nZ/vurWpp/rbiWrexltb/ePK2q9jr59+p/Bdov7On7QcWpppupfDPxbremCR0TVLnwprHnrFkbYkdrVWuijAj74ZQyAOVCqv1h+zn8HvjR4XvPFvhvxH4C8bSW2rKuoW1wPCeqW1vFHCXVUdJoxuZY2UHBHBzx0r+yGivSwvAmHwlnSx0ns3zYa7fK9Hf6xe9tHe9+vZ8tDiTE0Zubg53/6euL+/2cr+d1q+y0P4y/iv+y18R9blupI/hv4ruG+cjydAvQVILYBDICecnOASODjpXinw1+DXx/8Ah5450S90r4c+PrSOHVbRZJYvDOtRReWjsVG+O0ZHL425EgUgncclcf3P0V70cgoxt+9va2vslfT/ALiaGsuKMRJSUqF+ZNP99prbo6TW6XbZdj8+f2u4vHPiv9m74caZHoF3qviTxDZ6Kus2MIkujZFbb/TdysRglgc5HJ6etfNf7LnwG+O/hz4gaFqnhq1vvA/hvSbxBeh8D7ZabSDZfYmPS8Oe3IyMjGK/ZvJIAJJA4AzwB6D0pU+8Px/ka7auWwrKkp1H+6TStG17uP8AedrKNlvv5H2fDfivi+GuG824dweQ5ZiXnEa1Kvjsfy4mVKlWSThRoPDx5XpeUvb3m409I8nvBMpCNMxebaFkds5Z14JIPQ7snHXnmm1JJ2/H+lR16KVkl2Vj8iqO9abfWVN/epBRRRTKCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigB25j1Yn6kn/APV+FNoop3fd/ewWl7aX3tpf1CiiikAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUVrGV9Hv0ff/g/n67gUUUVkAUUUUAFFFFABRRRQAUUUUAFOT7w/H+RptFA07NPs7hRRRQLrf0/C/wDmFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRR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SxSlzKS+GmrW5fJ7qV/l5nFS4FySs5SeElBJp255NNS10slpo7fI/pr/AOIhr4cD/m1zx4T6/wDCyNBAP4f8I3j9K7jwt/wX5+C2t3kcGvfA3x74U0/CfadUk8RafrEdqrZG4wWeixPKBjI+ZMjp0r+WD7Gv939T/wDFVILckBTyowADgjH4k15y41z1yX+22Te3LF9VpuvP8NDb/iH2RyaXsJLmdubmmrXsr2621drrtfqv9CP4MfHz4XfH7wpZeMPhf4s0zxFpl3bxzSwW1xE19YO/DQ3tsGMkTo/yk4K5KjIY7R7QQQSDwQcEehFfyBf8Eb/it4g8DftMaZ4Gj1S6h8P/ABH0+fTLnTjNIYGudOtrzVIrqFTtMEsUVvPt8s+UXZZXjZ443H9gn0z+PJ/E8ZP4Cv2HhjNp5tgI1Ksozq0o041JQVk5SjLf3pK/u30turo/JeK8hXD+aVMLCU5UZuU6TmtVH3W0n1iuZJO7e6ewUUUV9IfMBRRRQAUUUUAFFFFABRVa7u7ewge7vJPItIRuuLgjKwqejMMjOTkYyOlYPg/xn4Y8faJH4j8IatBrejS3NzZpqFp81q11ZsqXUCSgkPJAzqsoGNhZQevAB09FFFABRRRQAUUUUAFFFFABRWTrmu6P4a0u81vXtQt9M0qwhee7vLqRY4oYo1LOxLEZIUE7QegJOFBIXQNc0jxRo1l4g0HUbTU9I1GMzWN5azxyx3EHGJFKMwGTuG3J+7wTkUAatFFFABRRRQAUUUUAFFFFABRXEXPxO+HNl43svhvd+LLODxvqNol7YaDIgW4uYCN0zRu0yqTChRmH8QkXGBzXallHf+dADqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/NpGjwg5Ab/P/AavyaNF8o2HnOB82e3tmur/ALNb1b9P8KuNpWSpCtgHnk+o69/881/GVPHS1vFrR/Ya+y/L+vmf3HUytKK91y1WnK10fk166Hcfs7ab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rKQfSpaKAI4oYoI0hgjjhijUJHFEipGiqAFVUUBVUAAAAAADFSUUUAFJgZJ7nGfw6UtFABRRRQBn/wBmWP2v7b9jsvtWP+Pv7Hb/AGzP/Xzs34xxjGfetD9f8+1FFADDGjdR7ZHWq8lsrqyMFkRwVdJACrKeqspyGU9CCOat0UAVYLK1tgBBbW0AHAEMCRjj0CBQPwFWgMen4DFFFAFWaOOdJIZo0mifIeKVVkjcZzhkcFWGQDggjIB7UkcccKJFCiRRxjCRxKI40HoqIAqjnoABUjdT9T/OkoAsUUUUAIABkgYycn3OAMn8AB9BS0UUAFGAeozRRQAmB6D8hS0UUAFFFFAB/n86CAeDRRQAYHHsMD6f5FIABnAxk5P1PelooAQqCQSMkcj2/wA4oIB6/wCen+ApaKACkIB6ilooAKKKKAGd3+g/ka4Tx7/x52f/AF2f/wBBWu77v9B/I1wnj3/jzs/+uz/+grQB5bRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSgkEEDJBBx9D9R/OkpQCSADgkgZ+p+h/lQB6P4DB23jgnGARknHBA6cY7+vr3xXow5CnPT9T0/n/X1ryHwfqAt7l7b7qycfXJJ6k+xxyO3bNeuqcKg65A5684yeee/9fSgB9FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFV6sVEyY5HT09P6mgBlSquOT1/l1/OhVxyev8uv50+gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK4Hx7/AMedn/12f/0EV31eR+MdRF5KYYzmK1wg95Cw3nqR2x68YPQUAcXRSL0H0H8qWgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAo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F0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k/Mf/ABdHP95PzH/xdAHA/wDCEXf/AEHL/wDNP/jNH/CEXf8A0HL/APNP/jNd9z/eT8x/8XRz/eT8x/8AF0AcD/whF3/0HL/80/8AjNH/AAhF3/0HL/8ANP8A4zXfc/3k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uxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr1yuxPf8AL/7KjYnv+X/2VAHVf2xb+/5f/Xo/ti39/wAv/r1yuxPf8v8A7KjYnv8Al/8AZUAdV/bFv7/l/wDXo/ti39/y/wDr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wHi/+IoA/wAtT/h2D+3x/wBGyfE3/wAJjX//AJUUf8Owf2+P+jZPib/4TGv/APyor/Ur+w2X/Pna/wDgPF/8RR9hsv8Anztf/AeL/wCIoA/y1P8Ah2D+3x/0bJ8Tf/CY1/8A+VFH/DsH9vj/AKNk+Jv/AITGv/8Ayor/AFK/sNl/z52v/gPF/wDEUfYbL/nztf8AwHi/+IoA/wAtT/h2D+3x/wBGyfE3/wAJjX//AJUUf8Owf2+P+jZPib/4TGv/APyor/Ur+w2X/Pna/wDgPF/8RR9hsv8Anztf/AeL/wCIoA/y1P8Ah2D+3x/0bJ8Tf/CY1/8A+VFH/DsH9vj/AKNk+Jv/AITGv/8Ayor/AFK/sNl/z52v/gPF/wDEUfYbL/nztf8AwHi/+IoA/wAtT/h2D+3x/wBGyfE3/wAJjX//AJUUf8Owf2+P+jZPib/4TGv/APyor/Ur+w2X/Pna/wDgPF/8RR9hsv8Anztf/AeL/wCIoA/y1P8Ah2D+3x/0bJ8Tf/CY1/8A+VFH/DsH9vj/AKNk+Jv/AITGv/8Ayor/AFK/sNl/z52v/gPF/wDEUfYbL/nztf8AwHi/+IoA/wAtT/h2D+3x/wBGyfE3/wAJjX//AJUUf8Owf2+P+jZPib/4TGv/APyor/Ur+w2X/Pna/wDgPF/8RR9hsv8Anztf/AeL/wCIoA/y1P8Ah2D+3x/0bJ8Tf/CY1/8A+VFH/DsH9vj/AKNk+Jv/AITGv/8Ayor/AFK/sNl/z52v/gPF/wDEUfYbL/nztf8AwHi/+IoA/wAtT/h2D+3x/wBGyfE3/wAJjX//AJUUf8Owf2+P+jZPib/4TGv/APyor/Ur+w2X/Pna/wDgPF/8RR9hsv8Anztf/AeL/wCIoA/y1P8Ah2D+3x/0bJ8Tf/CY1/8A+VFH/DsH9vj/AKNk+Jv/AITGv/8Ayor/AFK/sNl/z52v/gPF/wDEUfYbL/nztf8AwHi/+IoA/wAtT/h2D+3x/wBGyfE3/wAJjX//AJUUf8Owf2+P+jZPib/4TGv/APyor/Ur+w2X/Pna/wDgPF/8RR9hsv8Anztf/AeL/wCIoA/y1P8Ah2D+3x/0bJ8Tf/CY1/8A+VFf0of8G9f/AATU/aN/Z5+Mnj39pD47eFtU+G+lzeAtQ+H2h+EPEFrJaavrcut6rp2oTao1s06vBBYro1uYmubPcxuXjjcEyCv62/sNl/z52v8A4Dxf/EVZVVQBUVVUdFUBQPoBgCgABBGRwO1LRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB/9n7LkULAAAAAMmgYjTsXjQVGow4AIccHXk=\",\"encrypt_data\":null,\"other\":null,\"sucess\":true}"; - //Save_File1(json_buf, local_path); - // curlʼ - CURL* curl = curl_easy_init(); - // curlֵ - CURLcode res; - if (curl) - { - //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, strUrl); - //postIJ - cJSON* json_root = cJSON_CreateObject(); - cJSON_AddItemToObject(json_root, "isWrap", cJSON_CreateString("1")); - cJSON_AddItemToObject(json_root, "storeId", cJSON_CreateString(uuid)); - cJSON_AddItemToObject(json_root, "filename", cJSON_CreateString(filename)); - char* szjson = cJSON_Print(json_root); - printf(">>>json %s\n", szjson); - - 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(">>>uds download Post in curl post\n"); - // post - res = curl_easy_perform(curl); - // Ƿɹ - if (res != CURLE_OK) { - printf("uds download failed res code: "); - } - else { - printf("uds download success,string %s", resPost0.c_str()); - //webapiֵж - Save_File(resPost0.c_str(), local_path); - } - curl_slist_free_all(header_list); - free(szjson); - cJSON_Delete(json_root); - } - else - { - printf(">>> uds download init failed"); - } - curl_easy_cleanup(curl); + printf(">>> uds upload init failed"); + result = 0; } - + curl_easy_cleanup(curl); + return result; +} +void WebAPI_Uds_Download(char* strUrl, char* uuid, char* local_path,char* filename) +{ + // curlʼ + CURL* curl = curl_easy_init(); + // curlֵ + CURLcode res; + if (curl) + { + //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, strUrl); + //postIJ + cJSON* json_root = cJSON_CreateObject(); + cJSON_AddItemToObject(json_root, "isWrap", cJSON_CreateString("1")); + cJSON_AddItemToObject(json_root, "storeId", cJSON_CreateString(uuid)); + cJSON_AddItemToObject(json_root, "filename", cJSON_CreateString(filename)); + char* szjson = cJSON_Print(json_root); + printf(">>>json %s\n", szjson); + 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(">>>uds download Post in curl post\n"); + // post + res = curl_easy_perform(curl); + // Ƿɹ + if (res != CURLE_OK) { + printf("uds download failed res code: "); + } + else { + printf("uds download success,string %s", resPost0.c_str()); + //webapiֵж + Save_File(resPost0.c_str(), local_path); + } + curl_slist_free_all(header_list); + free(szjson); + cJSON_Delete(json_root); + } + else + { + printf(">>> uds download init failed"); + } + curl_easy_cleanup(curl); +} #ifdef __cplusplus } diff --git a/json/create_json.cpp b/json/create_json.cpp index 3ceecb5..42dffb3 100644 --- a/json/create_json.cpp +++ b/json/create_json.cpp @@ -33,11 +33,6 @@ extern std::string G_CONNECT_TOPIC; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// using namespace std; -extern int parse_commerror_write(const std::vector& codes); -extern int parse_commstatus_write(const std::vector& codes); -extern int parse_match_write(const std::vector& codes); -extern int parse_dataintegrity_write(const std::vector& codes); -extern int parse_rationality_write(const std::vector& codes); extern std::string intToString(int number); QString JSON_CONFIG_FN = QString("JiangSu_Config.xml"); @@ -195,8 +190,7 @@ public: //-------------------------------------------------------------------------------------*/ //Ѷñ -//extern QMutex kafka_data_list_mutex; //Kafka -//extern QList kafka_data_list; //kafka + extern int FILE_FLAG; QMutex kafka_data_list_mutex; //Kafka @@ -210,8 +204,7 @@ QMutex Sql_data_list_mutex; //Sqlִ QList Sql_data_list; //Sqlִ //////////////////////////////////////WW 2023-08-22 end -//QMap > error_data_list;//zw޸ 2023 - 8 - 22 ‰ݲԼ¼map -//QMap > error_datamatch_list;//zw޸ 2023-8-28 ƥȱֶμ¼map + QMap data_timespan_list;//zw޸ 2023 - 8 - 29 ʱ QMap xmlinfo_list;//zw޸ ͺŶӦxml-ݿ Ľڵ kafka @@ -226,851 +219,11 @@ extern int isdelta_flag;//lnk2024-8-16 ///////////////////////////////////////////////lnk20241021滻webӿ////////////////////////////////// void connectlog_pgsql(char* id,char* datetime,int status); -void errorlog_pgsql(char* id, QString time, QString filename); -void SoeRptSql(char* id, int state,char* rpt); -QString errorlog_num_pgsql(QString monitorId, QString datatime, QString filename, int count); -QString errorlog_dataintegrity_pgsql(QString time, QString datatime,QString monitorId,bool recallflag); -QString errorlog_datamatch_pgsql(QString id, QString time, int BASE_MAT_NUM,int ADV_MAT_NUM,int BASE_ACT_NUM,int ADV_ACT_NUM,QString filename); - -#if 0 -void connectlog_pgsql(char* id) -{ - QString pgsql; - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_status_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',1) ").arg(id).arg(QDateTime::currentDateTime().toString("yyyyMMdd"))); - pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\") do update set ")); - pgsql.append(QString("\"comm_status\"= \"%1\".\"%2meas_pq_comm_status_tr\".\"comm_status\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // - //cout << pgsql.toAscii().data() << endl; -} -//zw޸ 2023 - 8 - 24 쳣¼ pgsqlװ նid ʱ 洢ļ· -void errorlog_pgsql(char* id, QString time, QString filename) -{ - QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',1,'%3') ").arg(id).arg(time).arg(filename)); - pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\") do update set ")); - pgsql.append(QString("\"comm_status\"= \"%1\".\"%2meas_pq_comm_error_tr\".\"comm_status\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // - cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << pgsql.toAscii().data() << endl; -} -//zw޸ 20240115 ݽ¼ -void SoeRptSql(char* id, int state,char* rpt) -{ - QDateTime savetime = QDateTime::currentDateTime(); - - QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(id).arg(savetime.toString("yyyyMMdd")).arg(state).arg(rpt)); - pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\",\"file_name\") do update set ")); - pgsql.append(QString("\"comm_status\"= %1;").arg(state)); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // -} -#endif - -//zw޸ 2023 - 8 - 18 쳣¼ jsonװ նid նip ն˶˿ ־Դ 쳣 -void errorlog_json(char* id,char* ip,int port,int type,char* error_type,char* ERROR_DES,char* ERROR_PARAM) -{ - if (id == NULL || ip == NULL || port == NULL || type == NULL || error_type == NULL) { - cout << "Function errorlog_json Error!" << endl; - } - QString json;//װjson־ - json.append("{"); - json.append(QString("\"TERMINAL_ID\": \"%1\",").arg(id));//װID - json.append(QString("\"COMM_TIME\": \"%1\",").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")));//ʱ - json.append(QString("\"TMNL_IP\": \"%1\",").arg(ip));//նIP - json.append(QString("\"TMNL_PORT\": \"%1\",").arg(port));//ն˶˿ں - json.append(QString("\"COMM_TYPE\": \"%1\",").arg(type));//־Դ - json.append(QString("\"ERROR_TYPE\": \"%1\",").arg(error_type));//쳣 - json.append(QString("\"ERROR_DES\": \"%1\",").arg(ERROR_DES));// - json.append(QString("\"ERROR_PARAM\": \"%1\"").arg(ERROR_PARAM));//ؼ - json.append("}"); - cout << json.toAscii().data() << endl; - - QDateTime savetime = QDateTime::currentDateTime(); - QString Qfilename, Qsavename; - Qfilename.append("comtrade/").append(id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_COMM.log"); - Qsavename.append("/FeProject/dat/").append(id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_COMM.log"); - char file_name[256]; - memset(file_name, 0, 256); - sprintf(file_name, "%s", Qfilename.toAscii().data()); - char save_name[256]; - memset(save_name, 0, 256); - sprintf(save_name, "%s", Qsavename.toAscii().data()); - //cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; - - oss_data_t OssData; - OssData.filename = file_name; - OssData.savename = save_name; - OssData.data = json; - - OssData.id = QString(id); - OssData.time = savetime.toString("yyyyMMdd"); //ʱ - OssData.log_name = "comm"; - - oss_data_list_mutex.lock(); // - oss_data_list.append(OssData); // kafka - oss_data_list_mutex.unlock(); // - //std::ofstream file(save_name); // һļ󣬴ļ example.txt - //if (file.is_open()) { // жļǷɹ - // file << json.toAscii().data() << "\n"; - // file.close(); // رļ - //} - //else { - // std::cerr << "Unable to open file\n"; - //} - - //PutOSS(file_name, save_name); - //std::remove(save_name); - - //errorlog_pgsql(id, savetime.toString("yyyyMMdd"), Qfilename); -} -//zw޸ 2023 - 8 - 23 ֵжϺ ڵ ʵֵ ѹȼ 洢map -void errorlog_num(CDataValue* pDataValue, double value, double UL, QMap *map_list,long long time) -{ - if(pDataValue == NULL) - { - cout << "Function errorlog_num Error!" <LimitUp.toAscii().data() << pDataValue->LimitDown.toAscii().data() << endl; - if (pDataValue->LimitUp != "not define" && pDataValue->LimitDown != "not define" && UL != 0)//zw޸ 2023-8-23 ݺж - { - double limitup = 0, limitdown = 0; - if (pDataValue->LimitUp.indexOf("*%UN") != -1) - { - QString tmp = pDataValue->LimitUp; - float temp = tmp.replace("*%UN", "").toFloat(); - limitup = temp * UL; - } - else if (pDataValue->LimitUp.indexOf("*%U") != -1) - { - QString tmp = pDataValue->LimitUp; - float temp = tmp.replace("*%U", "").toFloat(); - limitup = (temp * UL) / 1.732f; - } - else - { - limitup = pDataValue->LimitUp.toFloat(); - } - if (pDataValue->LimitDown.indexOf("*%UN") != -1) - { - QString tmp = pDataValue->LimitDown; - float temp = tmp.replace("*%UN", "").toFloat(); - limitdown = temp * UL; - } - else if (pDataValue->LimitDown.indexOf("*%U") != -1) - { - QString tmp = pDataValue->LimitDown; - float temp = tmp.replace("*%U", "").toFloat(); - limitdown = (temp * UL) / 1.732f; - } - else - { - limitdown = pDataValue->LimitDown.toFloat(); - } - //cout << limitdown << "||||" << limitup << "||||" << UL << endl; - if (pDataValue->LimitUp != "0" || pDataValue->LimitDown != "0") - { - if (value < limitdown || value >limitup)//ж - { - if (!map_list->contains(pDataValue->strFullName)) - { - MP_RATIONALITY* tmp_data = new MP_RATIONALITY(); - tmp_data->fValue = value; - tmp_data->over_time = 0; - tmp_data->dtvalue = QDateTime::fromTime_t(time / 1000); - - map_list->insert(pDataValue->strFullName, tmp_data); - } - map_list->value(pDataValue->strFullName)->over_time++; - } - } - } -} -//zw޸ 2023 - 8 - 23 ֵж 쳣ֵתjsonpgsql -QString errorlog_num_json(QString monitorId, QMap map_list) -{ - int count = 0; - QString log_json;//ɵjsonַ - QMap tmp = map_list; - for (QMap::iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) - { - count++; - QString key2 = it2.key(); - MP_RATIONALITY* value2 = it2.value(); - - log_json.append("{"); - log_json.append(QString("\"strFullName\":\"%1\", ").arg(key2));//ֵȫ - log_json.append(QString("\"value\":\"%1\", ").arg(value2->fValue));//ֵ - log_json.append(QString("\"datetime\":\"%1\"").arg(value2->dtvalue.toString("yyyy-MM-dd hh:mm:ss")));//ֵʱ - log_json.append("}"); - } - - return log_json; -} - ///////////////////////////////////////////////lnk20241021滻webӿ////////////////////////////////// -#if 0 -//2023 9-18 pgsql -QString errorlog_num_pgsql(QString monitorId, QString datatime, QString filename, int count) -{ - QString log_pqsql;//ɵpgsql - log_pqsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_rationality_tr\"(\"monitor_id\",\"statistical_date\",\"irrat_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - log_pqsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(monitorId).arg(datatime).arg(count).arg(filename)); - log_pqsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(log_pqsql); - Sql_data_list_mutex.unlock(); // - return log_pqsql; -} -//zw޸ 2023 - 8 - 24 ֵж pgsql նid 2023-08-15 ʱ2023-08-15 19:15:00 -QString errorlog_dataintegrity_pgsql(QString time, QString datatime,QString monitorId,bool recallflag) -{ - int num = 480; - if (data_timespan_list[monitorId]->msspan != 0) { - num = 1440 / data_timespan_list[monitorId]->msspan; - } - QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_intact_tr\"(\"monitor_id\",\"statistical_date\",\"exp_num\",\"act_num\",\"value_time\",\"last_value_time\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',480,1,array[TIMESTAMP'%3'],'%4') ").arg(monitorId).arg(time).arg(datatime).arg(datatime)); - pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do update set ")); - //pgsql.append(QString("\"value_time\"=(array_cat(EXCLUDED.\"value_time\", \"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\"))[:1440] , \"exp_num\" = %3 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - if (recallflag == true) { - if (data_timespan_list[monitorId]->msspan != 0) { - pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - } - else { - pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - } - } - else { - pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - } - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // - return pgsql; -} -#endif -//zw޸ 2023-8-24 ֵж ʱ -void errorlog_dataintegrity_timespanlist(QString monitorId,long long time) -{ - if (!data_timespan_list.contains(monitorId))//zw޸ ʱ - { - Mn_Timespan* mn_tmp = new Mn_Timespan(); - mn_tmp->timespan.append(time); - data_timespan_list.insert(monitorId, mn_tmp); - } - else - { - if (data_timespan_list[monitorId]->timespan.count() <= 8) { - data_timespan_list[monitorId]->timespan.append(time); - } - } -} -//zw޸ 2023-8-24 ֵж ʱ -void errorlog_dataintegrity_timespanlist_2(QString monitorId) -{ - if (data_timespan_list[monitorId]->msspan == 0 && data_timespan_list[monitorId]->timespan.count() >= 8) //Լ - { - int count[10] = {0,0,0,0,0,0,0,0,0,0}; - int tmp_sp = 0; - qSort(data_timespan_list[monitorId]->timespan.begin(), data_timespan_list[monitorId]->timespan.end()); - for (int i = 1; i < data_timespan_list[monitorId]->timespan.size(); i++) { - int tmp_ms = data_timespan_list[monitorId]->timespan[i] - data_timespan_list[monitorId]->timespan[i - 1]; - if (tmp_ms >= 30000 && tmp_ms <= 90000) { - count[0]++; - } - else if (tmp_ms >= 90000 && tmp_ms <= 150000) { - count[1]++; - } - else if (tmp_ms >= 150000 && tmp_ms <= 210000) { - count[2]++; - } - else if (tmp_ms >= 210000 && tmp_ms <= 270000) { - count[3]++; - } - else if (tmp_ms >= 270000 && tmp_ms <= 330000) { - count[4]++; - } - else if (tmp_ms >= 330000 && tmp_ms <= 390000) { - count[5]++; - } - else if (tmp_ms >= 390000 && tmp_ms <= 450000) { - count[6]++; - } - else if (tmp_ms >= 450000 && tmp_ms <= 510000) { - count[7]++; - } - else if (tmp_ms >= 510000 && tmp_ms <= 570000) { - count[8]++; - } - else if (tmp_ms >= 570000 && tmp_ms <= 630000) { - count[9]++; - } - } - for (int i = 0; i < 10; i++) { - if (count[i] != 0 && count[i] > tmp_sp) { - tmp_sp = count[i]; - data_timespan_list[monitorId]->msspan = i+1; - } - } - - } -} - -//zw޸ 2023 - 8 - 28 ƥ map¼ ȫ 洢map -void errorlog_datamatch(QString fullname, QMap *map_list) -{ - if(!map_list->contains(fullname)) - { - map_list->insert(fullname, QDateTime::currentDateTime()); - } -} - -///////////////////////////////////////////////lnk20241021滻webӿ////////////////////////////////// -#if 0 -//zw޸ 2023 - 8 - 25 ֵƥж pgsql նid 2023-08-15 Ӧ Ӧ ʵ ʵ -QString errorlog_datamatch_pgsql(QString id, QString time, int BASE_MAT_NUM,int ADV_MAT_NUM,int BASE_ACT_NUM,int ADV_ACT_NUM,QString filename) -{ - QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_match_tr\"(\"monitor_id\",\"statistical_date\",\"base_mat_num\",\"adv_mat_num\",\"base_act_num\",\"adv_act_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',%3,%4,%5,%6,'%7') ").arg(id).arg(time).arg(BASE_MAT_NUM).arg(ADV_MAT_NUM).arg(BASE_ACT_NUM).arg(ADV_ACT_NUM).arg(filename)); - pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); - //pgsql.append(QString("\"BASE_ACT_NUM\"= %1 , \"ADV_ACT_NUM\"= %2;").arg(BASE_ACT_NUM).arg(ADV_ACT_NUM)); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // - return pgsql; -} -#endif - - -//zw޸ 2023-8-29 ֵƥjsonʽ -QString errorlog_datamatch_json(QMap data_match_map_1, QMap data_match_map_2,long long time) -{ - QString log_json,fullnamelist;//ɵjsonַ - if (data_match_map_1.count() != 0) { - for (QMap::iterator it2 = data_match_map_1.begin(); it2 != data_match_map_1.end(); ++it2) { - - QString key2 = it2.key(); - QDateTime value2 = it2.value(); - - fullnamelist.append("\""); - fullnamelist.append(key2);//ƥֵȫ - fullnamelist.append("\","); - } - } - if (data_match_map_2.count() != 0) { - for (QMap::iterator it2 = data_match_map_2.begin(); it2 != data_match_map_2.end(); ++it2) { - - QString key2 = it2.key(); - QDateTime value2 = it2.value(); - - fullnamelist.append("\""); - fullnamelist.append(key2);//ƥֵȫ - fullnamelist.append("\","); - } - } - fullnamelist.chop(1); - log_json.append(QString("{ \"datetime\": \"%1\",").arg(QDateTime::fromTime_t(time / 1000).toString("yyyy-MM-dd hh:mm:ss"))); - log_json.append(QString(" \"LackDataName\": [%1] ").arg(fullnamelist)); - log_json.append("}"); - return log_json; -} - -#if 0 -bool ParseXMLConfig2(XmlConfig *cfg, list *ctopiclist,QString path) //JiangSu_Config.xmlļ -{ - //cfg = new XmlConfig(); - //ע#7#ͨͨ 8421룬8-CP95 4-Сֵ 2-ֵ 1-ƽֵ - // %2,50%ͨͨгݣ÷Χ룬һֱʾгʼţڶг - // SEQ=ֵ8421 8-T 4-C 2-B 1-A - //עtypeͣ0-DataType 1- 2-޳ 3-ʱ̣ 4- 5-λ 6-ֵ 9-ʵʱSOE¼ 11-ʵʱSOE¼ - QString strPhasic[4] = { "A", "B", "C", "T" }; //ö (A-T) - int nStart = 1, nEnd = 1; //гֹ - QString strValueTemp; //ʱгַ %0,49% %2,50% - - //JiangSu_Config.xmlļ - //QString xml_dir = QString("D:/")+QString("PQD-9k/config/"); //·ȡxmlʧܣ˴þ· zl 2018-11-14 15:43:34 - QDomDocument doc; //½QDomDocumentһXMLĵ - if ("not define" == path) { - QString xml_dir = QString("../") + QString("etc/"); //Linuxµ· - QFile file(xml_dir + JSON_CONFIG_FN); - if (!file.open(QIODevice::ReadOnly | QFile::Text)) //ֻʽxml - { - std::cout << "can't open not define config file" << std::endl;//lnk20250208 - return 0; - } - if (!doc.setContent(&file)) //ļݶdoc - { - std::cout << "can't read not define config file" << std::endl;//lnk20250208 - file.close(); - return 0; - } - file.close(); - cout << "not define xml" << endl; - } - else { - QString tmppath; - tmppath.append("/FeProject/dat/").append(path).append(".xml"); - QFile file(tmppath); - if (!file.open(QIODevice::ReadOnly | QFile::Text)) //ֻʽxml - { - std::cout << "can't open config file" << tmppath.toStdString() <strTopic = e.attribute("name"); // - ctopiclist->push_back(topic); // Kafka - - //zw޸ 2023 - 8 - 14 Ϊʷݲ Valueڵָ-BaseFlag LimitUp LimitDown - if ("Topic" == strTag && ("HISDATA" == topic->strTopic || "RTDATA" == topic->strTopic)) //ٶȡTopicHISDATARTDATA--------------------------------------------------- - { - QDomNodeList list = e.childNodes(); //ԪTopicӽڵб - for (int i = 0; i < list.count(); i++) // DataTypeб - { - QDomNode node = list.at(i); //node1 - if (node.isElement()) - { - CDataType* dt = new CDataType(); //ָ - dt->iDataType = node.toElement().attribute("value").toInt(); //ֵ(1-ʵʱ/ʷ̬2-ʵʱ/ʷ䡢3-ʵʱ/ʷ̬4-̬5-䡢6-̬) - dt->type = node.toElement().attribute("type"); //ȼ - dt->BaseFlag0 = 0; - dt->BaseFlag1 = 0; - topic->DataTypeList.push_back(dt); // - - QString strTag2 = node.toElement().tagName(); //DataTypeڵ - if ("DataType" == strTag2) //ڶȡDataType - { - QDomNodeList list2 = node.childNodes(); //ԪDataTypeӽڵб - for (int i2 = 0; i2 < list2.count(); i2++) // Monitorб - { - QDomNode node2 = list2.at(i2); //node2 - if (node2.isElement()) - { - CMonitor* mt = new CMonitor(); //ָ - mt->strMonitor = node2.toElement().attribute("name"); // עֵҪRptлȡ - mt->type = node2.toElement().attribute("type"); //ȼ - dt->MonitorList.push_back(mt); // - - QString strTag3 = node2.toElement().tagName(); //Monitorڵ - if ("Monitor" == strTag3) //۶ȡMonitor - { - QDomNodeList list3 = node2.childNodes(); //ԪMonitorӽڵб - for (int i3 = 0; i3 < list3.count(); i3++) // Itemб - { - QDomNode node3 = list3.at(i3); //node3 - if (node3.isElement()) - { - CItem* it = new CItem(); //ָ - it->strItemName = node3.toElement().attribute("name"); //FLAGTIMEVIPQ - it->type = node3.toElement().attribute("type"); //ȼ - if ("FLAG" == it->strItemName) //޳(1޳0޳Ĭ޳) - it->strItemValue = node3.toElement().attribute("value"); //ֵ - mt->ItemList.push_back(it); // - - QString strTag4 = node3.toElement().tagName(); //Itemڵ - if ("Item" == strTag4) //ܶȡItem - { - QDomNodeList list4 = node3.childNodes(); //ԪItemӽڵб - for (int i4 = 0; i4 < list4.count(); i4++) // Sequenceб - { - QDomNode node4 = list4.at(i4); //node4 - if (node4.isElement()) - { - QString strPhase = node4.toElement().attribute("value"); // - if ("7" == strPhase) //-ٶȡABC - { - for (int n = 0; n < 3; n++) // (ABC) - { - CSequence* sq = new CSequence(); //ABCָ - sq->strSValue = node4.toElement().attribute("value"); //ֵ(7ABCࡢ8T) - sq->type = node4.toElement().attribute("type"); //ȼ - sq->strSeq = strPhasic[n]; //ֵ ABC - it->SequenceList.push_back(sq); // - - QString strTag5 = node4.toElement().tagName(); //Sequenceڵ - if ("Sequence" == strTag5) //ݶȡSequence - { - QDomNodeList list5 = node4.childNodes(); //ԪSequenceӽڵб - for (int i5 = 0; i5 < list5.count(); i5++) // ABCValueб - { - QDomNode node5 = list5.at(i5); //node5 - if (node5.isElement()) - { - QDomElement e_Value = node5.toElement(); //תΪԪ - QString strTag6 = e_Value.tagName(); //Sequence DataValueӽڵ - if ("Value" == strTag6) //޶ȡABCValue - { - QString strDVName = e_Value.attribute("name"); // - QString strDAName = e_Value.attribute("DA"); // - if (strDAName.indexOf("phs*") >= 0) //DA"phs*" - strDAName = strDAName.replace("*", sq->strSeq); //DA*滻Ϊ(ABC) phsA$cVal$mag$f - //-гݶȡ(ABC)------------------------------------- - if (strDVName.indexOf("%") >= 0 && strDAName.indexOf("%-") >= 0) //% DA%- V_%0,49%_MAX - { - QStringList strHarm1 = strDVName.split('%'); - if (strHarm1.count() >= 2) //V_ | 0,49 | _MAX - { - strValueTemp = "%" + strHarm1.at(1) + "%"; //%0,49% - QStringList strHarm2 = strHarm1.at(1).split(','); //0,49 - if (strHarm2.count() >= 2) - { - nStart = (strHarm2.at(0)).toInt(); //гʼ 0 - nEnd = (strHarm2.at(1)).toInt(); //г 49 - } - } - - QString substring = strDAName.mid(strDAName.indexOf("[") + 1, strDAName.indexOf("]") - strDAName.indexOf("[") - 1); - QStringList strDAList1 = substring.split('-'); - int strDAoffset = (strDAList1.at(1)).toInt(); - - for (int i = nStart; i <= nEnd; i++) // ABCг - { - QString strDVNameTemp = strDVName; //ʱ - QString strDANameTemp = strDAName; //ʱ - CDataValue* dv1 = new CDataValue(); //ABCгֵָ - dv1->type = e_Value.attribute("type"); //ȼ - if (e_Value.attributes().contains("Coefficient")) { - dv1->strCoefficient = e_Value.attribute("Coefficient"); //ϵ(ַ) - dv1->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //ϵ() - } - dv1->strOffset = e_Value.attribute("Offset"); //ʼƫ(ַ) - dv1->iOffset = e_Value.attribute("Offset").toInt(); //ʼƫ() = յԺʼ - װʵʼ - dv1->DO = e_Value.attribute("DO"); //ݶ - dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //%0,49%滻Ϊ SI_%0,49%ΪSI_1 - dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //DA%-2滻Ϊ phs*Har[1]$mag$f - //cout << dv1->strName.toAscii().data() << "--" << dv1->DA.toAscii().data() << " (" << dv1->iOffset << endl; - //zw޸ 2023 - 8 - 14 Ϊʷݲ Valueڵָ-BaseFlag LimitUp LimitDown - if (e_Value.attributes().contains("BaseFlag")) - { - dv1->BaseFlag = e_Value.attribute("BaseFlag"); - if (dv1->BaseFlag == "1") { - dt->BaseFlag1++; - } - else { - dt->BaseFlag0++; - } - } - else - { - dt->BaseFlag0++; - dv1->BaseFlag = "0"; - } - if (e_Value.attributes().contains("LimitUp")) - { - dv1->LimitUp = e_Value.attribute("LimitUp"); - } - else - { - dv1->LimitUp = "not define"; - } - if (e_Value.attributes().contains("LimitDown")) - { - dv1->LimitDown = e_Value.attribute("LimitDown"); - } - else - { - dv1->LimitDown = "not define"; - } - if (!dv1->DO.isEmpty() && !dv1->DA.isEmpty()) //ݶΪ - dv1->strFullName = dv1->DO + "$" + dv1->DA; - else - dv1->strFullName = "not define"; - sq->DataValueList.push_back(dv1); // (ABC) - } //ABCг - //continue; //ABCгɺ󣬼ȡһڵ - } - else //-ڷгݶȡ(ABC)------------------------------- - { - CDataValue* dv2 = new CDataValue(); //ABCгֵָ - dv2->strName = e_Value.attribute("name"); // - dv2->type = e_Value.attribute("type"); //ȼ - if (e_Value.attributes().contains("Coefficient")) { - dv2->strCoefficient = e_Value.attribute("Coefficient"); //ϵ(ַ) - dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //ϵ() - } - dv2->DO = e_Value.attribute("DO"); //ݶ - dv2->DA = strDAName; // - - //zw޸ 2023 - 8 - 14 Ϊʷݲ Valueڵָ-BaseFlag LimitUp LimitDown - if (e_Value.attributes().contains("BaseFlag")) - { - dv2->BaseFlag = e_Value.attribute("BaseFlag"); - if (dv2->BaseFlag == "1") { - dt->BaseFlag1++; - } - else { - dt->BaseFlag0++; - } - } - else - { - dt->BaseFlag0++; - dv2->BaseFlag = "0"; - } - if (e_Value.attributes().contains("LimitUp")) - { - dv2->LimitUp = e_Value.attribute("LimitUp"); - } - else - { - dv2->LimitUp = "not define"; - } - if (e_Value.attributes().contains("LimitDown")) - { - dv2->LimitDown = e_Value.attribute("LimitDown"); - } - else - { - dv2->LimitDown = "not define"; - } - if (!e_Value.attribute("PltFlag").isEmpty() && e_Value.attribute("PltFlag") == "True") //ʱʶ - dv2->bPlt = true; //ʱʶ - else - dv2->bPlt = false; //ʱ - - if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //ݶΪ - dv2->strFullName = dv2->DO + "$" + dv2->DA; - else - dv2->strFullName = "not define"; - sq->DataValueList.push_back(dv2); // (ABC) - } - } //ȡABCValue - } //жnode5ΪԪ - } //ABCValueб - } // ABC - } - } //-ٶȡABC - - if ("8" == strPhase) //-ڶȡT - { - CSequence* sq = new CSequence(); //Tָ - sq->strSValue = node4.toElement().attribute("value"); //ֵ - sq->type = node4.toElement().attribute("type"); //ȼ - sq->strSeq = strPhasic[3]; //ֵ - it->SequenceList.push_back(sq); // (T) - - QDomNodeList list5 = node4.childNodes(); //ԪSequenceӽڵб - for (int i5 = 0; i5 < list5.count(); i5++) // TValueб - { - QDomNode node5 = list5.at(i5); //node5 - if (node5.isElement()) - { - QDomElement e_Value = node5.toElement(); //תΪԪ - QString strTag6 = e_Value.tagName(); //Sequence DataValueӽڵ - if ("Value" == strTag6) //޶ȡTValue - { - //-гݶȡ(T) עTûг - //-ڷгݶȡ(T) - CDataValue* dv2 = new CDataValue(); //Tгֵָ - dv2->strName = e_Value.attribute("name"); // - dv2->type = e_Value.attribute("type"); //ȼ - if (e_Value.attributes().contains("Coefficient")) { - dv2->strCoefficient = e_Value.attribute("Coefficient"); //ϵ(ַ) - dv2->fCoefficient = e_Value.attribute("Coefficient").toFloat(); //ϵ() - } - dv2->DO = e_Value.attribute("DO"); //ݶ - dv2->DA = e_Value.attribute("DA"); // - - //zw޸ 2023 - 8 - 14 Ϊʷݲ Valueڵָ-BaseFlag LimitUp LimitDown - if (e_Value.attributes().contains("BaseFlag")) - { - dv2->BaseFlag = e_Value.attribute("BaseFlag"); - if (dv2->BaseFlag == "1") { - dt->BaseFlag1++; - } - else { - dt->BaseFlag0++; - } - } - else - { - dt->BaseFlag0++; - dv2->BaseFlag = "0"; - } - if (e_Value.attributes().contains("LimitUp")) - { - dv2->LimitUp = e_Value.attribute("LimitUp"); - } - else - { - dv2->LimitUp = "not define"; - } - if (e_Value.attributes().contains("LimitDown")) - { - dv2->LimitDown = e_Value.attribute("LimitDown"); - } - else - { - dv2->LimitDown = "not define"; - } - - if (!dv2->DO.isEmpty() && !dv2->DA.isEmpty()) //ݶΪ - dv2->strFullName = dv2->DO + "$" + dv2->DA; - else - dv2->strFullName = "not define"; - sq->DataValueList.push_back(dv2); // (ABC) - } //ȡTValue - } //жnode5ΪԪ - } //TValueб - } //-ڶȡT - } //жnode4ΪԪ - } //Sequenceб - } //ȡItem - } //жnode3ΪԪ - } //Itemб - } //ȡMonitorڵ - } //жnode2ΪԪ - } //Monitorб - } //ȡDataType - } //жnodeΪԪ - } //DataTypeб - } //ȡTopicڵHISDATARTDATA - else if ("Topic" == strTag && "RTDATASOE" == topic->strTopic) //SOE¼------------------------------------------------------- - { - QDomNodeList list = e.childNodes(); //ԪTopicӽڵб - for (int i = 0; i < list.count(); i++) // DataTypeб - { - QDomNode node = list.at(i); //node1 - if (node.isElement()) - { - CDataType* dt = new CDataType(); //ָ - dt->iDataType = node.toElement().attribute("value").toInt(); //ֵ(1-̬SOE2-SOE3-̬SOE) - dt->type = node.toElement().attribute("type"); //ȼ - topic->DataTypeList.push_back(dt); // - - QString strTag2 = node.toElement().tagName(); //DataTypeڵ - if ("DataType" == strTag2) //ڶȡDataType - { - QDomNodeList list2 = node.childNodes(); //ԪDataTypeӽڵб - for (int i2 = 0; i2 < list2.count(); i2++) // SOEб - { - QDomNode node2 = list2.at(i2); //node2 - if (node2.isElement()) - { - CEventData* ed = new CEventData(); //SOE¼ָ - ed->triggerFlag = node2.toElement().attribute("TriggerFlag"); //SOEʶ - ed->DO = node2.toElement().attribute("DO"); //ݶ - ed->DA = node2.toElement().attribute("DA"); // - ed->type = node2.toElement().attribute("type"); //ȼtypeͣ0-DataType 1- 2-޳ 3-ʱ̣ 4- 5-λ 6-ֵ 9-ʵʱSOE¼ - if (!ed->DO.isEmpty() && !ed->DA.isEmpty()) //ݶΪ - ed->strFullName = ed->DO + "$" + ed->DA; - else - ed->strFullName = "not define"; - dt->SOEList.push_back(ed); // SOE¼ - } //жnode2ΪԪ - } //SOEб - } //ȡDataTypeڵ - } //жnodeΪԪ - } //DataTypeб - } //TopicڵRTDATASOE - else if ("Topic" == strTag && "SOEDATA" == topic->strTopic) - { - QDomNodeList list = e.childNodes(); //ԪTopicӽڵб - for (int i = 0; i < list.count(); i++) // DataTypeб - { - QDomNode node = list.at(i); //node1 - if (node.isElement()) - { - CEventData* ed = new CEventData(); //SOE¼ָ - ed->triggerFlag = node.toElement().attribute("name"); //SOE - ed->DO = node.toElement().attribute("DO"); //ݶ - ed->DA = node.toElement().attribute("DA"); // - ed->type = node.toElement().attribute("type"); //ȼtypeͣ0-DataType 1- 2-޳ 3-ʱ̣ 4- 5-λ 6-ֵ 9-ʵʱSOE¼ - if (!ed->DO.isEmpty() && !ed->DA.isEmpty()) //ݶΪ - ed->strFullName = ed->DO + "$" + ed->DA; - else - ed->strFullName = "not define"; - //cout << ed->triggerFlag.toAscii().data() << "=====" << ed->strFullName.toAscii().data() << endl; - cfg->SOEList.push_back(ed); - } - } - } - } - if ("ReportMap" == strTag)//zw޸ 2023 - 8 - 15 ж ĽXML ԭRptLogCfg.iniȡ - { - //cout << "ReportMap" << endl; - } - if ("Topic" != strTag && "ReportMap" != strTag)//zw޸ 2023 - 8 - 14 ж ֽڵ - { - if ("WavePhasic" == strTag) - { - cfg->WavePhasicFlag.append(e.attribute("Flag")); - if (cfg->WavePhasicFlag == "1") { - cfg->WavePhasicA.append(e.attribute("A")); - cfg->WavePhasicB.append(e.attribute("B")); - cfg->WavePhasicC.append(e.attribute("C")); - } - - } - if ("UnitOfTime" == strTag) - { - cfg->UnitOfTimeUnit.append(e.attribute("Unit")); - } - if ("ValueOfTime" == strTag) - { - cfg->ValueOfTimeUnit.append(e.attribute("Unit")); - } - if ("ComtradeFile" == strTag) - { - cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag")); - //cout << xmlcfg->WaveTimeFlag.toAscii().data() << endl; - } - if ("IED" == strTag) - { - cfg->IEDname.append(e.attribute("name")); - //cout << xmlcfg->IEDname.toAscii().data() << endl; - } - if ("LDevice" == strTag) - { - cfg->LDevicePrefix.append(e.attribute("Prefix")); - //cout<LDevicePrefix.toAscii().data() < RTDATA > RTDATASOE) - } //while (!n.isNull) - - return true; -} -#endif //lnk2024-8-16 ͽ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QString path) //JiangSu_Config.xmlļ { - //cfg = new XmlConfig(); //ע#7#ͨͨ 8421룬8-CP95 4-Сֵ 2-ֵ 1-ƽֵ // %2,50%ͨͨгݣ÷Χ룬һֱʾгʼţڶг // SEQ=ֵ8421 8-T 4-C 2-B 1-A @@ -1217,7 +370,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt if (strDAName.indexOf("l_phs*") >= 0){ //DA"l_phs*"//lnk20250221νҲԽPPV strDAName = strDAName.replace("l_phs", "phs"); strDAName = strDAName.replace("*", strLine[n]); - //qDebug() << "strDAName:" << strDAName << endl;// + } //DA*滻Ϊ(ABBCCA) phsAB$cVal$mag$f else if (strDAName.indexOf("phs*") >= 0) {//DA"phs*" @@ -1257,7 +410,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt dv1->DO = e_Value.attribute("DO"); //ݶ dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //%0,49%滻Ϊ SI_%0,49%ΪSI_1 dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //DA%-2滻Ϊ phs*Har[1]$mag$f - //cout << dv1->strName.toAscii().data() << "--" << dv1->DA.toAscii().data() << " (" << dv1->iOffset << endl; + //zw޸ 2023 - 8 - 14 Ϊʷݲ Valueڵָ-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { @@ -1296,7 +449,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt dv1->strFullName = "not define"; sq->DataValueList.push_back(dv1); // (ABC) } //ABCг - //continue; //ABCгɺ󣬼ȡһڵ + } else //-ڷгݶȡ(ABC)------------------------------- { @@ -1426,7 +579,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt dv1->strName = strDVNameTemp.replace(strValueTemp, QString::number(i + e_Value.attribute("Offset").toInt())); //%0,49%滻Ϊ SI_%0,49%ΪSI_1 dv1->DA = strDANameTemp.replace(substring, QString::number(i - strDAoffset)); //DA%-2滻Ϊ phs*Har[1]$mag$f - //cout << dv1->strName.toAscii().data() << "--" << dv1->DA.toAscii().data() << " (" << dv1->iOffset << endl; + //zw޸ 2023 - 8 - 14 Ϊʷݲ Valueڵָ-BaseFlag LimitUp LimitDown if (e_Value.attributes().contains("BaseFlag")) { @@ -1465,7 +618,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt dv1->strFullName = "not define"; sq->DataValueList.push_back(dv1); // (ABBCCA) } //ABCг - //continue; //ABBCCAгɺ󣬼ȡһڵ + } else //-ڷгݶȡ(ABBCCA)------------------------------- { @@ -1672,7 +825,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt ed->strFullName = ed->DO + "$" + ed->DA; else ed->strFullName = "not define"; - //cout << ed->triggerFlag.toAscii().data() << "=====" << ed->strFullName.toAscii().data() << endl; + cfg->SOEList.push_back(ed); } } @@ -1680,7 +833,7 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt } if ("ReportMap" == strTag)//zw޸ 2023 - 8 - 15 ж ĽXML ԭRptLogCfg.iniȡ { - //cout << "ReportMap" << endl; + } if ("Topic" != strTag && "ReportMap" != strTag)//zw޸ 2023 - 8 - 14 ж ֽڵ { @@ -1705,17 +858,17 @@ bool ParseXMLConfig2(int xml_flag, XmlConfig *cfg, list *ctopiclist,QSt if ("ComtradeFile" == strTag) { cfg->WaveTimeFlag.append(e.attribute("WaveTimeFlag")); - //cout << xmlcfg->WaveTimeFlag.toAscii().data() << endl; + } if ("IED" == strTag) { cfg->IEDname.append(e.attribute("name")); - //cout << xmlcfg->IEDname.toAscii().data() << endl; + } if ("LDevice" == strTag) { cfg->LDevicePrefix.append(e.attribute("Prefix")); - //cout<LDevicePrefix.toAscii().data() < ctopic_list; -#if 0 - if (xmlinfo_list.contains(data->dev_type)) { - cout << "transfer_json_block_data contain data->dev_type" << endl; - ctopic_list = xmlinfo_list[data->dev_type]->topicList; - } - else { - cout << "transfer_json_block_data not contain data->dev_type" << endl; - ctopic_list = topicList; - } -#endif - - ////lnk2024-8-15 ,ͽ if (strcmp(v_wiring_type, "0") == 0) //lnk2024-8-15 ͽ { @@ -1810,18 +951,12 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json } } - //list* tmp; bool shortjumpflag = false; bool longjumpflag = false; - //zw޸ 2023-8-28 ־ж - //bool data_match_flag = false, data_integrity_flag = true, data_reason_flag = false;//ƥ ־¼־ - QMap data_reason_map;//ݺmap - QMap data_match_map_1;//ƥmap - QMap data_match_map_2;//ƥmap ǻ + //zw޸ end if (!inited) //ʼ JiangSu_Config.xml { - //ParseXMLConfig(); // ParseXMLConfig() JiangSu_Config.xmlļ inited = true; } @@ -1887,7 +1022,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; - //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //ƴ json ABC + KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //ƴ json ABCT list::iterator dv = pSequence->DataValueList.begin(); //ޱ DataValueList @@ -2092,7 +1227,6 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json if (longjumpflag == true || shortjumpflag == true) { return 1; } - //return 1; //úִֹͣ } //-ʷݽ-------------------------------- if (1 == pDataType->iDataType) //-ʷ̬----------------------------------------------------------- @@ -2148,7 +1282,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; - //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //ƴ json ABCT + KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //ƴ json ABCT list::iterator dv = pSequence->DataValueList.begin(); //ޱ DataValueList @@ -2169,12 +1303,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //ƴ - if (pDataValue->BaseFlag == "1") { - //errorlog_datamatch(pDataValue->strFullName, &data_match_map_1);//lnkɾ - } - else { - //errorlog_datamatch(pDataValue->strFullName, &data_match_map_2);//lnkɾ - } + continue; } @@ -2188,8 +1317,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //ƴ jsonֵ(Ƕֵ) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //ƴ jsonֵ(Ƕֵ) - //zw޸ 2023 - 8 - 23 ֵжϺ ڵ ʵֵ ѹȼ - //errorlog_num(pDataValue, dAngleTemp, data->voltage_level, &data_reason_map, data->time); + } else { @@ -2198,8 +1326,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //ƴ jsonֵ(ǽǶֵ) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //ƴ jsonֵ(ǽǶֵ) - //zw޸ 2023 - 8 - 23 ֵжϺ ڵ ʵֵ ѹȼ - //(pDataValue, dTemp, data->voltage_level, &data_reason_map, data->time); + } } catch (exception& e) @@ -2238,136 +1365,6 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json kafka_data_list.append(KafkaData); // kafka kafka_data_list_mutex.unlock(); // - //lnk20241122¼Щ - if(false)//zw޸ 2023-8-28 ƥ ־¼ִж߼ - { - cout << "!!!!!!!!!!!!!!!!!!!!!!===============" << data_match_map_1.count() << "--------" << data_match_map_2.count() << endl; - cout << "!!!!!!!!!!!!!!!!!!!!!!---------------" << data_reason_map.count() << endl; - if(data_match_map_1.count() + data_match_map_2.count() <= 1200)//Լ¼ ĬΪtrue ֻҪkafka¼ִ - { - errorlog_dataintegrity_timespanlist(data->mp_id,data->time); - errorlog_dataintegrity_timespanlist_2(data->mp_id); - QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time/1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - QString tmp_chr2 = dataintegrity_time.toString("yyyy-MM-dd hh:mm:ss"); - //ҪԼ¼lnk202411-6 - //cout << errorlog_dataintegrity_pgsql(tmp_chr1, tmp_chr2, data->mp_id,false).toAscii().data() << endl; - } - if(data_reason_map.count() != 0)//Լ¼ ֻҪmapԪ ¼־ - { - QString reasonlog = errorlog_num_json(data->mp_id, data_reason_map); - - QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); - QString Qfilename, Qsavename; - Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); - Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); - char file_name[256]; - memset(file_name, 0, 256); - sprintf(file_name, "%s", Qfilename.toAscii().data()); - char save_name[256]; - memset(save_name, 0, 256); - sprintf(save_name, "%s", Qsavename.toAscii().data()); - //cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; - //cout << reasonlog.toAscii().data() << endl; - - oss_data_t OssData; - OssData.filename = file_name; - OssData.savename = save_name; - OssData.data = reasonlog; - - QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - OssData.id = data->mp_id; - OssData.time = tmp_chr1; //ʱ - OssData.list_num = data_reason_map.size(); - OssData.log_name = "reason"; - - if (data->time % 3600000 == 0) { - oss_data_list_mutex.lock(); // - oss_data_list.append(OssData); // kafka - oss_data_list_mutex.unlock(); // - } - - //std::ofstream file(save_name); // һļ󣬴ļ example.txt - //if (file.is_open()) { // жļǷɹ - // file << reasonlog.toAscii().data() << "\n"; - // file.close(); // رļ - //} - //else { - // cout << "Unable to open file\n" << endl; - //} - - //PutOSS(file_name, save_name); - //std::remove(save_name); - - /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - QString pgsql; - pgsql.append(errorlog_num_pgsql(data->mp_id, tmp_chr1, Qfilename, data_reason_map.size())); - cout << pgsql.toAscii().data() << endl;*/ - } - if(data_match_map_1.count() != 0 || data_match_map_2.count() != 0)//ƥʼ¼ ֻҪmapԪ ¼ƥֵ - { - QString matchlog = errorlog_datamatch_json(data_match_map_1, data_match_map_2,data->time); - //cout << matchlog.toAscii().data() << endl; - - QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); - QString Qfilename,Qsavename; - Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); - Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); - char file_name[256]; - memset(file_name,0,256); - sprintf(file_name,"%s",Qfilename.toAscii().data()); - char save_name[256]; - memset(save_name, 0, 256); - sprintf(save_name,"%s", Qsavename.toAscii().data()); - cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; - - oss_data_t OssData; - OssData.filename = file_name; - OssData.savename = save_name; - OssData.data = matchlog; - - QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - OssData.id = data->mp_id; - OssData.time= tmp_chr1; //ʱ - //match_log - OssData.base_mat_num= pDataType->BaseFlag1; - OssData.adv_mat_num= pDataType->BaseFlag1 + pDataType->BaseFlag0; - OssData.base_act_num= pDataType->BaseFlag1 - data_match_map_1.count(); - OssData.adv_act_num= pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(); - OssData.log_name = "match"; - - if (data->time % 3600000 == 0) { - oss_data_list_mutex.lock(); // - oss_data_list.append(OssData); // kafka - oss_data_list_mutex.unlock(); // - } - //std::ofstream file(save_name); // һļ󣬴ļ example.txt - //if (file.is_open()) { // жļǷɹ - // file << matchlog.toAscii().data() << "\n"; - // file.close(); // رļ - //} - //else { - // cout << "Unable to open file\n" << endl; - //} - - //PutOSS(file_name, save_name); - //std::remove(save_name); - //GetOSS(file_name, savename); - /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - - QString pqsql; - pqsql.append(errorlog_datamatch_pgsql(data->mp_id, tmp_chr1, pDataType->BaseFlag1, pDataType->BaseFlag1 + pDataType->BaseFlag0, pDataType->BaseFlag1 - data_match_map_1.count(), pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(), Qfilename)); - cout << pqsql.toAscii().data() << endl;*/ - - } - QMap().swap(data_match_map_1); - QMap().swap(data_match_map_2); - QMap().swap(data_reason_map); - } return 1; //úִֹͣ } //-ʷ̬ݽ-------------------------------- } //DataTypeList @@ -2428,7 +1425,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; - //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //ƴ json ABCT + KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //ƴ json ABCT list::iterator dv = pSequence->DataValueList.begin(); //ޱ DataValueList @@ -2542,7 +1539,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json while (sq != pItem->SequenceList.end()) { CSequence* pSequence = *sq++; - //KafkaData.strText.append(QString("{\"SEQ\":\"%1\", ").arg(pSequence->strSeq)); //ƴ json ABC + KafkaData.strText.append(QString("\"%1\":{ ").arg(line_to_phasic(pSequence->strSeq))); //ƴ json ABCT list::iterator dv = pSequence->DataValueList.begin(); //ޱ DataValueList @@ -3111,12 +2108,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json else KafkaData.strText.append(QString("\"%1\":%2 ").arg(pDataValue->strName).arg("null")); //ƴ - if (pDataValue->BaseFlag == "1") { - //errorlog_datamatch(pDataValue->strFullName, &data_match_map_1);//lnkɾ - } - else { - //errorlog_datamatch(pDataValue->strFullName, &data_match_map_2);//lnkɾ - } + continue; } @@ -3130,8 +2122,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //ƴ jsonֵ(Ƕֵ) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dAngleTemp, 10, 6))); //ƴ jsonֵ(Ƕֵ) - //zw޸ 2023 - 8 - 23 ֵжϺ ڵ ʵֵ ѹȼ - //errorlog_num(pDataValue, dAngleTemp, data->voltage_level, &data_reason_map, data->time); + } else { @@ -3140,8 +2131,7 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json KafkaData.strText.append(QString("\"%1\":\"%2\", ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //ƴ jsonֵ(ǽǶֵ) else KafkaData.strText.append(QString("\"%1\":\"%2\" ").arg(pDataValue->strName).arg(QString::number(dTemp, 10, 6))); //ƴ jsonֵ(ǽǶֵ) - //zw޸ 2023 - 8 - 23 ֵжϺ ڵ ʵֵ ѹȼ - //errorlog_num(pDataValue, dTemp, data->voltage_level, &data_reason_map, data->time); + } } catch (exception& e) @@ -3180,134 +2170,6 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json kafka_data_list.append(KafkaData); // kafka kafka_data_list_mutex.unlock(); // - //lnk20241122¼Щ - if (false)//zw޸ 2023-8-28 ƥ ־¼ִж߼ - { - cout << "!!!!!!!!!!!!!!!!!!!!!!===============" << data_match_map_1.count() << "--------" << data_match_map_2.count() << endl; - cout << "!!!!!!!!!!!!!!!!!!!!!!---------------" << data_reason_map.count() << endl; - if (data_match_map_1.count() + data_match_map_2.count() <= 1200)//Լ¼ ĬΪtrue ֻҪkafka¼ִ - { - errorlog_dataintegrity_timespanlist(data->mp_id, data->time); - errorlog_dataintegrity_timespanlist_2(data->mp_id); - QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - QString tmp_chr2 = dataintegrity_time.toString("yyyy-MM-dd hh:mm:ss"); - //ҪԼ¼lnk202411-6 - //cout << errorlog_dataintegrity_pgsql(tmp_chr1, tmp_chr2, data->mp_id,true).toAscii().data() << endl; - } - if (data_reason_map.count() != 0)//Լ¼ ֻҪmapԪ ¼־ - { - QString reasonlog = errorlog_num_json(data->mp_id, data_reason_map); - - QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); - QString Qfilename, Qsavename; - Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); - Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_reason.log"); - char file_name[256]; - memset(file_name, 0, 256); - sprintf(file_name, "%s", Qfilename.toAscii().data()); - char save_name[256]; - memset(save_name, 0, 256); - sprintf(save_name, "%s", Qsavename.toAscii().data()); - cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; - - oss_data_t OssData; - OssData.filename = file_name; - OssData.savename = save_name; - OssData.data = reasonlog; - - - QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - OssData.id = data->mp_id; - OssData.time = tmp_chr1; //ʱ - OssData.list_num = data_reason_map.size(); - OssData.log_name = "reason"; - - if (data->time % 3600000 == 0) { - oss_data_list_mutex.lock(); // - oss_data_list.append(OssData); // kafka - oss_data_list_mutex.unlock(); // - } - //std::ofstream file(save_name); // һļ󣬴ļ example.txt - //if (file.is_open()) { // жļǷɹ - // file << reasonlog.toAscii().data() << "\n"; - // file.close(); // رļ - //} - //else { - // cout << "Unable to open file\n" << endl; - //} - - //PutOSS(file_name, save_name); - //std::remove(save_name); - - /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - QString pgsql; - pgsql.append(errorlog_num_pgsql(data->mp_id, tmp_chr1, Qfilename, data_reason_map.size())); - cout << pgsql.toAscii().data() << endl;*/ - } - if (data_match_map_1.count() != 0 || data_match_map_2.count() != 0)//ƥʼ¼ ֻҪmapԪ ¼ƥֵ - { - QString matchlog = errorlog_datamatch_json(data_match_map_1, data_match_map_2, data->time); - //cout << matchlog.toAscii().data() << endl; - - QDateTime savetime = QDateTime::fromTime_t(data->time / 1000); - QString Qfilename, Qsavename; - Qfilename.append("comtrade/").append(data->mp_id).append("/").append(savetime.toString("yyyyMMdd")).append("/").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); - Qsavename.append("/FeProject/dat/").append(data->mp_id).append("_").append(savetime.toString("yyyyMMddhhmmss")).append("_match.log"); - char file_name[256]; - memset(file_name, 0, 256); - sprintf(file_name, "%s", Qfilename.toAscii().data()); - char save_name[256]; - memset(save_name, 0, 256); - sprintf(save_name, "%s", Qsavename.toAscii().data()); - cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; - - oss_data_t OssData; - OssData.filename = file_name; - OssData.savename = save_name; - OssData.data = matchlog; - - QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - OssData.id = data->mp_id; - OssData.time = tmp_chr1; //ʱ - //match_log - OssData.base_mat_num = pDataType->BaseFlag1; - OssData.adv_mat_num = pDataType->BaseFlag1 + pDataType->BaseFlag0; - OssData.base_act_num = pDataType->BaseFlag1 - data_match_map_1.count(); - OssData.adv_act_num = pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(); - OssData.log_name = "match"; - - if (data->time % 3600000 == 0) { - oss_data_list_mutex.lock(); // - oss_data_list.append(OssData); // kafka - oss_data_list_mutex.unlock(); // - } - //std::ofstream file(save_name); // һļ󣬴ļ example.txt - //if (file.is_open()) { // жļǷɹ - // file << matchlog.toAscii().data() << "\n"; - // file.close(); // رļ - //} - //else { - // cout << "Unable to open file\n" << endl; - //} - - /*PutOSS(file_name, save_name); - std::remove(save_name);*/ - //GetOSS(file_name, savename); - /*QDateTime dataintegrity_time = QDateTime::fromTime_t(data->time / 1000); - QString tmp_chr1 = dataintegrity_time.toString("yyyy-MM-dd"); - QString pqsql; - pqsql.append(errorlog_datamatch_pgsql(data->mp_id, tmp_chr1, pDataType->BaseFlag1, pDataType->BaseFlag1 + pDataType->BaseFlag0, pDataType->BaseFlag1 - data_match_map_1.count(), pDataType->BaseFlag1 + pDataType->BaseFlag0 - data_match_map_1.count() - data_match_map_2.count(), Qfilename)); - cout << pqsql.toAscii().data() << endl;*/ - - } - QMap().swap(data_match_map_1); - QMap().swap(data_match_map_2); - QMap().swap(data_reason_map); - } return 1; //úִֹͣ } //-ʷ̬ݽ-------------------------------- } //DataTypeList @@ -3486,91 +2348,6 @@ int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json return 1; } - - -/*//json̬Ϣ zw޸ 2023-8-25 jsonṹ -int transfer_json_qvvr_data(unsigned int func_type, int monitor_id, float mag, float dur, long long start_tm, long long end_tm, int dis_kind, char* uuid_cfg,char* uuid_dat,char* mp_id,char* Qvvr_rptname,char* devtype) //json̬Ϣ > MMS_Wave -{ - XmlConfig c_xmlcfg; - if (xmlinfo_list.contains(devtype)) { - c_xmlcfg = xmlinfo_list[devtype]->xmlcfg; - } - else { - c_xmlcfg = xmlcfg; - } - - //if (0 == monitor_id) //jsonƴӼΪ - // return 0; - if (strlen(mp_id) == 0) { - return 0; - } - - Ckafka_data_t KafkaData; //kafkaݽṹ - KafkaData.monitor_id = monitor_id; - KafkaData.mp_id = mp_id; - -// if (400 == func_type) //ʷ > MMS_Recall -// KafkaData.strTopic = "HISDATA"; //kafka -// else -// KafkaData.strTopic = "RTDATA"; - - KafkaData.strTopic = "Event"; //kafka - - KafkaData.strText.append("{"); //ƴ jsonʼ - - if (400 == func_type || 500 == func_type || 600 == func_type || 700 == func_type) //ʷ > MMS_Recall - KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //ƴ - else - KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //ƴ - - KafkaData.strText.append(QString("\"Monitor\":\"%1\", ").arg(mp_id)); //ƴ json - - KafkaData.strText.append(QString("\"Value\":{")); //ƴ json - KafkaData.strText.append(QString("\"FLAG\":%1,").arg(1)); //ƴ ޳ - KafkaData.strText.append(QString("\"TIME\":%1,").arg(start_tm)); //ƴ ʱ - KafkaData.strText.append("\"VOLTAGE\":{"); //ƴ VOLTAGE - KafkaData.strText.append(QString("\"MAG\":%1").arg(mag)); //ƴ ѹֵ - KafkaData.strText.append(QString(", \"DUR\":%1").arg(dur * 1000)); //ƴ ʱ() - KafkaData.strText.append(QString(", \"STARTTIME\":%1").arg(start_tm )); //ƴ ʼʱ() - KafkaData.strText.append(QString(", \"ENDTIME\":%1").arg(end_tm)); //ƴ ʱ() - KafkaData.strText.append(QString(", \"DISKIND\":\"%1%2\"").arg("0").arg(dis_kind)); //ƴ ݽ(1210001- 1210002-ݽ 1210004-ж 1210003-) - KafkaData.strText.append(QString(", \"CFG_FILE\":\"%1\"").arg(uuid_cfg)); //ƴ cfgļ - KafkaData.strText.append(QString(", \"DAT_FILE\":\"%1\"").arg(uuid_dat)); //ƴ datļ - if (c_xmlcfg.WavePhasicFlag == "1") { - QString Qvvr_Rptname; - Qvvr_Rptname.append(Qvvr_rptname); - if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicA) != -1) { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("A")); //ƴ - } - else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicB) != -1) { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("B")); //ƴ - } - else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicC) != -1) { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("C")); //ƴ - } - else { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //ƴ - } - } - else { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //ƴ - } - - KafkaData.strText.append("}"); //ƴ json - KafkaData.strText.append("}}"); //ƴ json - - printf("transfer json qvvr data: %s==%s \n",KafkaData.strText.toStdString().c_str(), Qvvr_rptname); - - kafka_data_list_mutex.lock(); // - kafka_data_list.append(KafkaData); // kafka - //if (400 != func_type) { //Dzʷ - // KafkaData.strTopic = "Event"; - // kafka_data_list.append(KafkaData); - //} - kafka_data_list_mutex.unlock(); // - return 1; -}*/ - void processGGIO_start_data_end(char* mp_id,char* fullname,double v,long long time,char* devtype,int monitor_id) { XmlConfig c_xmlcfg; @@ -3750,25 +2527,6 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char std::cerr << "Error: Unable to download file." << std::endl; } - /*if (FILE_FLAG == 1) { - GetOSS(file_name, save_name); - } - else if (FILE_FLAG == 2) { - OBSFile(save_name, file_name, "getObject"); - } - else if (FILE_FLAG == 3) { - //OBSFile(save_name, file_name, "getObject"); - } - else { - - }*/ - // - if (xmlinfo_list.contains(type)) { - std::cout << "xmlinfo_list.contains" << type.toStdString() < codes; - codes.push_back("log"); - codes.push_back(std::string(id)); - codes.push_back(QDateTime::currentDateTime().toString("yyyyMMdd").toStdString()); - parse_commstatus_write(codes); - codes.clear();*/ - //״̬µķʽ //Ӧ char* ptr=NULL; @@ -4037,11 +2777,7 @@ void connectlog_pgsql(char* id,char* datetime,int status) } cJSON_AddItemToObject(jsonObject, "status", status_item); - // ӵ - //cJSON_AddItemToArray(jsonArray, jsonObject); - // תΪַ - //char* jsonString = cJSON_PrintUnformatted(jsonArray); char* jsonString = cJSON_Print(jsonObject); if (jsonString == NULL) { std::cerr << "Failed to print JSON object." << std::endl; @@ -4049,20 +2785,7 @@ void connectlog_pgsql(char* id,char* datetime,int status) return; } - //std::cout << "jsonString: " << jsonString << std::endl;////ٶĴӡ - //ݵԶ - - /*SendJsonAPI_web(WEB_COMFLAG, "", jsonString,&ptr);//ʹýӿlnk20250310 - //ص - // ptr ǷΪ NULL std::string ʼʧ - if (ptr != NULL) { - //handleCommentResponse(std::string(ptr));//ٶĴӡ - free(ptr); // SendJsonAPI_web ڴ棬ǵͷ - } else { - // ptr Ϊ NULL ־¼ - std::cout << "Error: Received NULL response" << std::endl; - }*/ //ʹmq Ckafka_data_t connect_info; @@ -4081,176 +2804,6 @@ void connectlog_pgsql(char* id,char* datetime,int status) } -//쳣¼ pgsqlװ նid ʱ 洢ļ· -void errorlog_pgsql(char* id, QString time, QString filename) -{ - /*QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',1,'%3') ").arg(id).arg(time).arg(filename)); - pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\") do update set ")); - pgsql.append(QString("\"comm_status\"= \"%1\".\"%2meas_pq_comm_error_tr\".\"comm_status\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // - cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << pgsql.toAscii().data() << endl;*/ - /*std::vector codes; - codes.push_back("log"); - codes.push_back(std::string(id)); - codes.push_back(time.toStdString()); - codes.push_back(filename.toStdString()); - parse_commerror_write(codes); - codes.clear();*/ -} - -//ݽ¼ -void SoeRptSql(char* id, int state,char* rpt) -{ - /*QDateTime savetime = QDateTime::currentDateTime(); - - QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_comm_error_tr\"(\"terminal_id\",\"statistical_date\",\"comm_status\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(id).arg(savetime.toString("yyyyMMdd")).arg(state).arg(rpt)); - pgsql.append(QString("on conflict(\"terminal_id\",\"statistical_date\",\"file_name\") do update set ")); - pgsql.append(QString("\"comm_status\"= %1;").arg(state)); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); //*/ - /*std::vector codes; - codes.push_back("soe"); - codes.push_back(std::string(id)); - codes.push_back(QDateTime::currentDateTime().toString("yyyyMMdd").toStdString()); - codes.push_back(intToString(state)); - codes.push_back(std::string(rpt)); - parse_commerror_write(codes); - codes.clear();*/ -} -//lnk 20241210ɾҪĴ -#if 0 -// pgsql -QString errorlog_num_pgsql(QString monitorId, QString datatime, QString filename, int count) -{ - /*QString log_pqsql;//ɵpgsql - log_pqsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_rationality_tr\"(\"monitor_id\",\"statistical_date\",\"irrat_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - log_pqsql.append(QString("values('%1',date'%2',%3,'%4') ").arg(monitorId).arg(datatime).arg(count).arg(filename)); - log_pqsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(log_pqsql); - Sql_data_list_mutex.unlock(); // - return log_pqsql;*/ - /*std::vector codes; - codes.push_back("log"); - codes.push_back(monitorId.toStdString()); - codes.push_back(datatime.toStdString()); - codes.push_back(intToString(count)); - codes.push_back(filename.toStdString()); - parse_rationality_write(codes); - codes.clear();*/ -} - -//ֵж pgsql նid -QString errorlog_dataintegrity_pgsql(QString time, QString datatime,QString monitorId,bool recallflag) -{ - /*int num = 480; - if (data_timespan_list[monitorId]->msspan != 0) { - num = 1440 / data_timespan_list[monitorId]->msspan; - } - QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_intact_tr\"(\"monitor_id\",\"statistical_date\",\"exp_num\",\"act_num\",\"value_time\",\"last_value_time\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',480,1,array[TIMESTAMP'%3'],'%4') ").arg(monitorId).arg(time).arg(datatime).arg(datatime)); - pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do update set ")); - //pgsql.append(QString("\"value_time\"=(array_cat(EXCLUDED.\"value_time\", \"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\"))[:1440] , \"exp_num\" = %3 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - if (recallflag == true) { - if (data_timespan_list[monitorId]->msspan != 0) { - pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - } - else { - pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%4\".\"%5meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - } - } - else { - pgsql.append(QString("\"value_time\"= ARRAY_APPEND(\"%1\".\"%2meas_pq_measpoint_intact_tr\".\"value_time\", '%3') , \"exp_num\" = %4 , \"last_value_time\" = EXCLUDED.\"last_value_time\" ,\"act_num\"= \"%5\".\"%6meas_pq_measpoint_intact_tr\".\"act_num\" + 1;").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX).arg(datatime).arg(num).arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - } - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // - return pgsql;*/ - - //Ҫô202411-1lnkֻҪidʱ㣬ֲк̬Ҫʱ - /*std::vector codes; - codes.push_back("log"); - codes.push_back(time.toStdString()); - codes.push_back(datatime.toStdString()); - codes.push_back(monitorId.toStdString()); - codes.push_back(boolToString(recallflag)); - codes.push_back(intToString(data_timespan_list[monitorId]->msspan)); - parse_dataintegrity_write(codes); - codes.clear();*/ - - //Ӧ - char* ptr=NULL; - - // cJSON - cJSON* jsonArray = cJSON_CreateArray(); - - // JSON - cJSON* jsonObject = cJSON_CreateObject(); - cJSON_AddStringToObject(jsonObject, "id", monitorId.toStdString().c_str()); - cJSON_AddStringToObject(jsonObject, "date", datatime.toStdString().c_str()); - - // ӵ - cJSON_AddItemToArray(jsonArray, jsonObject); - - // תΪַ - char* jsonString = cJSON_PrintUnformatted(jsonArray); - - //ݵԶ - SendJsonAPI_web(WEB_INTEGRITY,"", jsonString,&ptr); - - //ص - // ptr ǷΪ NULL std::string ʼʧ - if (ptr != NULL) { - handleCommentResponse(std::string(ptr)); - free(ptr); // SendJsonAPI_web ڴ棬ǵͷ - } else { - // ptr Ϊ NULL ־¼ - std::cout << "Error: Received NULL response" << std::endl; - } - - // תΪ QString - QString result = QString::fromStdString(jsonString); - - // ͷڴ - cJSON_Delete(jsonArray); - free(jsonString); // cJSON_PrintUnformattedʹmallocڴ - - return result; //jsonӡ -} - -//ֵƥж pgsql նid Ӧ Ӧ ʵ ʵ -QString errorlog_datamatch_pgsql(QString id, QString time, int BASE_MAT_NUM,int ADV_MAT_NUM,int BASE_ACT_NUM,int ADV_ACT_NUM,QString filename) -{ - /*QString pgsql;//װpgsql - pgsql.append(QString("insert into \"%1\".\"%2meas_pq_measpoint_match_tr\"(\"monitor_id\",\"statistical_date\",\"base_mat_num\",\"adv_mat_num\",\"base_act_num\",\"adv_act_num\",\"file_name\") ").arg(POSTGRES_SCHEMA).arg(POSTGRES_TABLEPREFIX)); - pgsql.append(QString("values('%1',date'%2',%3,%4,%5,%6,'%7') ").arg(id).arg(time).arg(BASE_MAT_NUM).arg(ADV_MAT_NUM).arg(BASE_ACT_NUM).arg(ADV_ACT_NUM).arg(filename)); - pgsql.append(QString("on conflict(\"monitor_id\",\"statistical_date\") do nothing;")); - //pgsql.append(QString("\"BASE_ACT_NUM\"= %1 , \"ADV_ACT_NUM\"= %2;").arg(BASE_ACT_NUM).arg(ADV_ACT_NUM)); - Sql_data_list_mutex.lock(); // - Sql_data_list.append(pgsql); - Sql_data_list_mutex.unlock(); // - return pgsql;*/ - /*std::vector codes; - codes.push_back("log"); - codes.push_back(id.toStdString()); - codes.push_back(time.toStdString()); - codes.push_back(intToString(BASE_MAT_NUM)); - codes.push_back(intToString(ADV_MAT_NUM)); - codes.push_back(intToString(BASE_ACT_NUM)); - codes.push_back(intToString(ADV_ACT_NUM)); - codes.push_back(filename.toStdString()); - parse_match_write(codes); - codes.clear();*/ -} -#endif //lnk202411-5 ̬ݲʹkafkaͣijhttpӿ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////̬¼ļ // ⲿҪԭСܡĸ @@ -4568,154 +3121,7 @@ char* mp_id,char* Qvvr_rptname,char* devtype) return 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////̬¼ļ -#if 0 -int transfer_json_qvvr_data(unsigned int func_type, int monitor_id, -double mag, double dur, long long start_tm, long long end_tm, int dis_kind, //ֵʱ䣬ʼʱ䣬ʱ䣬̬ -char* uuid_cfg,char* uuid_dat, //¼ļ -char* mp_id,char* Qvvr_rptname,char* devtype) //ţ̬豸 -{ - XmlConfig c_xmlcfg; - if (xmlinfo_list.contains(devtype)) { - c_xmlcfg = xmlinfo_list[devtype]->xmlcfg;//ӳ - } - else { - c_xmlcfg = xmlcfg; - } - if (strlen(mp_id) == 0) { - std::cout << "mp_id is null" << std::endl; - return 0; - } - - // 洢 uuid_cfg uuid_dat - //const char wave_paths[] = {"/comtrade/"}; - - // ʼ cJSON - cJSON* root = cJSON_CreateObject(); - // ƴ JSON - - // - //printf("Inside function: &mag = %p, &dur = %p\n", &mag, &dur); - //printf("~~~~~~~send QVVR_PerTime after record is %f~~~~~~~~~~ \n",dur); - //printf("~~~~~~~send QVVR_Amg after record is %f~~~~~~~~~~ \n",mag); - - //ҪͣΪhttpӿڲݶ - cJSON_AddStringToObject(root, "monitorId", mp_id); - cJSON_AddNumberToObject(root, "amplitude", mag); - cJSON_AddNumberToObject(root, "duration", dur); - cJSON_AddNumberToObject(root, "eventType", dis_kind); - // ʽʱΪַʱΪ룩 - char start_time_str[25]; - time_t start_sec = start_tm / 1000; - struct tm* time_info = localtime(&start_sec); - strftime(start_time_str, sizeof(start_time_str), "%Y-%m-%d %H:%M:%S", time_info); - // Ӻ벿 - snprintf(start_time_str + strlen(start_time_str), sizeof(start_time_str) - strlen(start_time_str), ".%03lld", start_tm % 1000); - cJSON_AddStringToObject(root, "startTime", start_time_str); - //cJSON_AddStringToObject(root, "wavePathcfg", uuid_cfg); // ̬òļ·Ҫļ - //cJSON_AddStringToObject(root, "wavePathdat", uuid_dat); // ̬òļ· - cJSON_AddStringToObject(root, "wavePath", uuid_dat); - //𲿷 - if (c_xmlcfg.WavePhasicFlag == "1") { - QString Qvvr_Rptname;//תΪqstringʽ - Qvvr_Rptname.append(Qvvr_rptname); - if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicA) != -1) { //ӳǷڱг - cJSON_AddStringToObject(root, "phase", "A"); //ƴ - } - else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicB) != -1) { - cJSON_AddStringToObject(root, "phase", "B"); //ƴ - } - else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicC) != -1) { - cJSON_AddStringToObject(root, "phase", "C"); //ƴ - } - else { - cJSON_AddStringToObject(root, "phase", "unknow"); //ƴ - } - } - else { - cJSON_AddStringToObject(root, "phase", "unknow"); //ƴ - } - // cJSON תΪַ - char* json_string = cJSON_Print(root); - printf("%s\n", json_string); // JSON ַ - // ͵̬ӿ - char* ptr = NULL; - SendJsonAPI_web(WEB_EVENT, "", json_string, &ptr); - // ص - // ptr ǷΪ NULL std::string ʼʧ - if (ptr != NULL) { - handleCommentResponse(std::string(ptr)); - free(ptr); // SendJsonAPI_web ڴ棬ǵͷ - } else { - // ptr Ϊ NULL ־¼ - std::cout << "Error: Received NULL response" << std::endl; - // ͷڴ - cJSON_Delete(root); - free(json_string); - return 0; - } - // ͷڴ - cJSON_Delete(root); - free(json_string); - - /*Ckafka_data_t KafkaData; //kafkaݽṹ - KafkaData.monitor_id = monitor_id; - KafkaData.mp_id = mp_id; - - KafkaData.strTopic = "Event"; //kafka - - KafkaData.strText.append("{"); //ƴ jsonʼ - - if (400 == func_type || 500 == func_type || 600 == func_type || 700 == func_type) //ʷ > MMS_Recall - KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //ƴ - else - KafkaData.strText.append("\"DATA_TYPE\":\"04\", "); //ƴ - - KafkaData.strText.append(QString("\"Monitor\":\"%1\", ").arg(mp_id)); //ƴ json - - KafkaData.strText.append(QString("\"Value\":{")); //ƴ json - KafkaData.strText.append(QString("\"FLAG\":%1,").arg(1)); //ƴ ޳ - KafkaData.strText.append(QString("\"TIME\":%1,").arg(start_tm)); //ƴ ʱ - KafkaData.strText.append("\"VOLTAGE\":{"); //ƴ VOLTAGE - KafkaData.strText.append(QString("\"MAG\":%1").arg(mag)); //ƴ ѹֵ - KafkaData.strText.append(QString(", \"DUR\":%1").arg(dur * 1000)); //ƴ ʱ() - KafkaData.strText.append(QString(", \"STARTTIME\":%1").arg(start_tm )); //ƴ ʼʱ() - KafkaData.strText.append(QString(", \"ENDTIME\":%1").arg(end_tm)); //ƴ ʱ() - KafkaData.strText.append(QString(", \"DISKIND\":\"%1%2\"").arg("0").arg(dis_kind)); //ƴ ݽ(1210001- 1210002-ݽ 1210004-ж 1210003-) - KafkaData.strText.append(QString(", \"CFG_FILE\":\"%1\"").arg(uuid_cfg)); //ƴ cfgļ - KafkaData.strText.append(QString(", \"DAT_FILE\":\"%1\"").arg(uuid_dat)); //ƴ datļ - if (c_xmlcfg.WavePhasicFlag == "1") { - QString Qvvr_Rptname; - Qvvr_Rptname.append(Qvvr_rptname); - if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicA) != -1) { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("A")); //ƴ - } - else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicB) != -1) { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("B")); //ƴ - } - else if (Qvvr_Rptname.indexOf(c_xmlcfg.WavePhasicC) != -1) { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("C")); //ƴ - } - else { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //ƴ - } - } - else { - KafkaData.strText.append(QString(", \"PHASIC\":\"%1\"").arg("unknow")); //ƴ - } - - KafkaData.strText.append("}"); //ƴ json - KafkaData.strText.append("}}"); //ƴ json - - printf("transfer json qvvr data: %s==%s \n",KafkaData.strText.toStdString().c_str(), Qvvr_rptname); - - kafka_data_list_mutex.lock(); // - kafka_data_list.append(KafkaData); // kafka - kafka_data_list_mutex.unlock(); //*/ - - return 1; -} -#endif void qvvr_test() { char uuid_cfg[] = {"/comtrade/"}; @@ -4751,18 +3157,6 @@ void Set_xml_nodeinfo_one(char* dev_type) { bool ret = false; -//̨˲dzʼҪٽһĬ -/* - //޶ӦxmlļʱĬϽ - if (!inited) //ʼ JiangSu_Config.xml - { - QString path; - path.append("not define"); - ParseXMLConfig2(&xmlcfg, &topicList, path); // ParseXMLConfig() JiangSu_Config.xmlļ - inited = true; - } -*/ - if(xmlinfo_list[QString::fromUtf8(dev_type)] != NULL){ //ԭѴ͵Ľڵ if(xmlinfo_list[QString::fromUtf8(dev_type)]->updataflag == true){ //Ҫ @@ -4802,4 +3196,4 @@ void Set_xml_nodeinfo_one(char* dev_type) } } - //4-ӳļ/////////////////////////////////// + diff --git a/json/kafka_producer.cpp b/json/kafka_producer.cpp index 9630f35..43b037f 100644 --- a/json/kafka_producer.cpp +++ b/json/kafka_producer.cpp @@ -33,12 +33,6 @@ public: } private: - //static inline unsigned int djb_hash (const char *str, size_t len) { - // unsigned int hash = 5381; - // for (size_t i = 0 ; i < len ; i++) - // hash = ((hash << 5) + hash) + str[i]; - // return hash; - //} }; class ProducerDeliveryReportCb : public RdKafka::DeliveryReportCb { @@ -88,8 +82,6 @@ bool FeKafkaProducer::init(const std::string &brokerlist, const bool &async, con } #endif - //std::string broker(host); - //broker.append(":").append(std::to_string((long long)port)); conf_->set("metadata.broker.list", brokerlist, errstr); if (strcmp(PROTOCOL, "sasl_plaintext") == 0) { conf_->set("security.protocol", PROTOCOL, errstr); @@ -114,17 +106,10 @@ bool FeKafkaProducer::init(const std::string &brokerlist, const bool &async, con { char size_str[256]; conf_->set("producer.type", "async", errstr); - //conf_->set("queue.buffering.max.messages", std::to_string((long long)size).c_str(), errstr); memset(size_str,0,256); apr_snprintf(size_str,sizeof(size_str),"%i",size); conf_->set("queue.buffering.max.messages", size_str, errstr); - { - //const char* api_version_request = "false"; - //const char* api_version_fallback = "0.8.2.0"; - //conf_->set("api.version.request", api_version_request, errstr) ; - //conf_->set("broker.version.fallback", api_version_fallback, errstr); - } } else { @@ -146,7 +131,7 @@ int FeKafkaProducer::send(const char *data, const int &size, const std::string & const int &partition, const std::string *key,const int &timeout) { RdKafka::Topic *tpk = get_topic(topic); - //std::cout<<"send data "<(data), size, key->c_str(),key->size(), NULL); - ///*NULL*/ key, NULL); if (resp != RdKafka::ERR_NO_ERROR) { diff --git a/json/mms_json_inter.h b/json/mms_json_inter.h index 0920a64..17bb8cf 100644 --- a/json/mms_json_inter.h +++ b/json/mms_json_inter.h @@ -39,35 +39,6 @@ public: QString dev_type;//豸 QMap mms_str_map; //ֵ(61850, ֵ) - -/* - json_block_data() //ʹã zl 2018-11-22 09:03:30 ----ԲԳֵ - { - monitorId = 7501; //ID - partitionSize = 3; //kafkaͷ - func_type = 100; //Ӧ(#define궨100 400)ѡ - data_type = 1; // - flag = 0; //޳ - time = 1546099200000; //ʱ() 2018-12-30??00:00:00 - //connectLineCount = 1; //· - //triggerLineCount = 1; //Ѵ· - - mms_str_map.insert("MMXU4$MX$PhVDev$phsA$cVal$mag$f", 123.4567890); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsAHar[0]$ang$f", 200.1234567); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsAHar[47]$ang$f", 300.1234567); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsAHar[48]$ang$f", 300.1234567); //ʹã zl 2018-11-22 10:46:15 - - mms_str_map.insert("MMXU4$MX$PhVDev$phsB$cVal$mag$f", 123.4567890); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsBHar[0]$ang$f", 200.1234567); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsBar[47]$ang$f", 300.1234567); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsBar[48]$ang$f", 300.1234567); //ʹã zl 2018-11-22 10:46:15 - - mms_str_map.insert("MMXU4$MX$PhVDev$phsC$cVal$mag$f", 123.4567890); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsCHar[0]$ang$f", 200.1234567); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsCHar[47]$ang$f", 300.1234567); //ʹã zl 2018-11-22 10:46:15 - mms_str_map.insert("MHAI2$MX$HRPhV$phsCHar[48]$ang$f", 300.1234567); //ʹã zl 2018-11-22 10:46:15 - } -*/ }; class Ckafka_data_t //kafkaݽṹ @@ -91,30 +62,14 @@ public: QString log_name; //նidid QString id; //նidid QString time; //ʱ - //match_log int base_mat_num; int adv_mat_num; int base_act_num; int adv_act_num; - //reason_log int list_num; }; -//extern QMutex kafka_data_list_mutex; -//extern QList kafka_data_list; -/* ʹʾ룺 - Ckafka_data_t data; - data.patition_id = 0; - data.strText = QString("{a=1,b=2}"); - kafka_data_list_mutex.lock(); - kafka_data_list.append(data); - kafka_data_list_mutex.unlock(); -*/ int transfer_json_block_data(char v_wiring_type[], json_block_data* data);//lnk2024-8-16Ӳ -//int transfer_json_block_data(json_block_data *data); -void errorlog_pgsql(char* id, QString time, QString filename); -QString errorlog_num_pgsql(QString monitorId, QString datatime, QString filename, int count); -QString errorlog_datamatch_pgsql(QString id, QString time, int BASE_MAT_NUM, int ADV_MAT_NUM, int BASE_ACT_NUM, int ADV_ACT_NUM, QString filename); #endif /* __cplusplus */ @@ -125,15 +80,11 @@ extern "C" { int transfer_json_qvvr_data(unsigned int func_type,int monitor_id,double mag,double dur,long long start_tm,long long end_tm,int dis_kind, char* uuid_cfg, char* uuid_dat, char* mp_id, char* Qvvr_rptname, char* devtype); void processGGIO_start_data_end(char* mp_id, char* fullname, double v,long long time,char* devtype,int monitor_id); -//void errorlog_num(CDataValue* pDataValue, double value, int monitorId, double UL, int maxcount); -//void errorlog_num_json(int monitorId); void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* TMNL_FACTORY, char* FILE_NAME, int year, int month, int day, int hour, int minute, int second);//zw޸ ú void Set_xml_nodeinfo();//zw޸ char* Get_xmlpath(char* devtype); char* Get_IED(char* devtype); char* Get_LDevice(char* devtype); -void errorlog_json(char* id, char* ip, int port, int type, char* error_type, char* ERROR_DES, char* ERROR_PARAM); -void SoeRptSql(char* id, int state, char* rpt); void connectlog_pgsql(char* id,char* datetime,int status); #ifdef __cplusplus } diff --git a/json/save2json.cpp b/json/save2json.cpp index 4477d91..92d7d09 100644 --- a/json/save2json.cpp +++ b/json/save2json.cpp @@ -32,8 +32,6 @@ using namespace std; #include "../json/save2json.h" #include "../json/mms_json_inter.h" #include "kafka_producer.h" -/*lnk10-11 */ -//#include "../include/rocketmq/SimpleProducer.h" #include "../include/rocketmq/CPushConsumer.h" #include #include "../json/cjson.h" //json @@ -42,7 +40,6 @@ using namespace std; bool createXmlFile(int devindex, int mpindex, bool realData, bool soeData, int limit,std::string type); extern int recall_json_handle(const char* jstr); extern std::string intToString(int number); -//extern int stringToInt(const char* str, int* result); int StringToInt(const std::string& str); extern pthread_mutex_t mtx;//lnk20250115 @@ -78,13 +75,10 @@ extern QList oss_data_list; extern int FILE_FLAG; KafkaSendThread myThrd; //WW 2023-08-22 ݿ̺߳WebSokcet߳ -SQLExcuteThread sqlThrd; //Sqlִ߳ WebSocketThread socketThrd; //Web Socket߳ WebhttpThread webhttpThrd; //Web http߳ lnk202411 httpThread httpThrd; //Web http߳ lnk202411 -//mqtestThread mqtestThrd; //mqtest߳ lnk202412 -//mqtestThread mqtestThrd(nullptr); //mqtest߳ lnk202412 mqconsumerThread mqconsumerThrd;//mq߳lnk20241213 OnTimerThread onTimerThrd;//ʱ߳ @@ -253,45 +247,6 @@ void add_stat_kafka_json_log(char* log_str) QTextStream out(&file); out << (now.toString("yyyy-MM-dd hh:mm:ss") + " " + level_str + " " + QString::fromAscii(log_str)) << endl; } -//////////////////////////////////////////////////////////////////////////// - -/*void TrimLeft(std::string &s) -{ - const std::string &space =" \f\n\t\r\v"; - s.erase(0, s.find_first_not_of(space)); -} - -void TrimRight(std::string &s) -{ - const std::string &space =" \f\n\t\r\v"; - s.erase(s.find_last_not_of(space) + 1); -} - -void Trim(std::string &s) -{ - const std::string &space =" \f\n\t\r\v"; - s.erase(0, s.find_first_not_of(space)); - s.erase(s.find_last_not_of(space) + 1); -} - - -int is_rpt_Time_exact_hour() -{ - apr_time_t hour_time_t = g_db_info->TimeID[RPT_IDX]/APRTIME_8H*APRTIME_8H; - if (g_db_info->TimeID[RPT_IDX]==hour_time_t) - return TRUE; - else - return FALSE; -} */ - -//char uuid_str[APR_UUID_FORMATTED_LENGTH+1]; -//int iii; -//for (iii=0;iii<10;iii++) { -// apr_uuid_t uuid; -// apr_uuid_get(&uuid); -// apr_uuid_format(uuid_str,&uuid); -// printf("uuid_str=%s \n",uuid_str); -//} ////////////////////////////////////////////////////////////////////////// /*rocketmqlnk10-10*/ @@ -355,7 +310,6 @@ void my_rocketmq_send(Ckafka_data_t& data) } rocketmq_producer_send(const_cast(senddata.c_str()),const_cast(topic.c_str())); - //printf("\nrocketmq send, monitor_id:[%s] topic:[%s] Success\n", key.c_str(), topic.c_str()); } @@ -383,13 +337,10 @@ void my_kafka_send(Ckafka_data_t& data) cfg_Alm_tp = TOPIC_ALARM; cfg_Sng_tp = TOPIC_SNG; - //QString topic_cfg = settings.value("Kafka/topic","").toString(); - //printf("!!!!!!!!!kafka producer init Failed(%s)\n", cfg_tp); cout << cfg_His_tp << endl; - //std::string brokerlist = brl_cfg.toStdString();//"10.240.16.145:6667,10.240.16.146:6667,10.240.16.147:6667,10.240.16.148:6667,10.240.16.149:6667"; - std::string brokerlist = BROKER_LIST; - //topic = topic_cfg.toStdString();//"test"; + std::string brokerlist = BROKER_LIST; + #ifdef __GNUC__ if (kafkaProducer.init(brokerlist)) { @@ -410,9 +361,6 @@ void my_kafka_send(Ckafka_data_t& data) apr_snprintf(tmp_str, sizeof(tmp_str), "%d", data.monitor_id); std::string key = std::string(tmp_str); - //std::string key_mp_id = data.mp_id.toStdString(); - - //key = data.monitor_id; std::string senddata = data.strText.toStdString(); if (data.strTopic == "HISDATA") { @@ -439,29 +387,12 @@ void my_kafka_send(Ckafka_data_t& data) { topic = data.strTopic.toStdString(); } - //QDateTime currentTime = QDateTime::currentDateTime(); - //QTime time = currentTime.time(); - //if (time >= QTime(23, 30) || time < QTime(01, 00)) { - // // The current time is between 23:00 and 00:30 - // add_sng_log(data.strText.toAscii().data()); - //} - //add_sng_log(data.strText.toAscii().data()); if (g_onlyIP[0] != 0) { - //ģʽ - //topic = cfg_Evt_tp; - //key = "2606L20071"; - //senddata = "{\"DATA_TYPE\":\"02\" , \"Monitor\":\"2606123456\" , \"Value\":{\"TIME\":\"1699576200000\", \"F_S\":{\"A\":{ \"PST\":\"0.000000\",\"FLUC\":\"343917.750000\",\"FLUCF\":\"374275.000000\" }, \"B\":{ \"PST\":\"0.000000\",\"FLUC\":\"222171.156250\",\"FLUCF\":\"369039.000000\" }, \"C\":{ \"PST\":\"0.000000\",\"FLUC\":\"208060.968750\",\"FLUCF\":\"369239.000000\" }}}}"; - //senddata = "{\"DATA_TYPE\":\"04\",\"Monitor\":\"2606L20071\",\"Value\":{\"FLAG\":1,\"TIME\":1700193136480,\"VOLTAGE\":{\"MAG\":95.181,\"DUR\":54,\"STARTTIME\":1700193136480,\"ENDTIME\":1700193136634,\"DISKIND\":\"01\",\"WAVEFILE\":\"PQ_PQLD1_000392_20231117_115216_580\",\"PHASIC\":\"B\"}}}"; add_sng_log(data.strText.toAscii().data()); - //char* cstr = new char[senddata.length() + 1]; - //std::strcpy(cstr, senddata.c_str()); - //add_sng_log(cstr); - //delete[] cstr; // ͷڴռ } #ifdef __GNUC__ - //send data retsize = kafkaProducer.send(senddata.c_str(), senddata.length(), topic, RdKafka::Topic::PARTITION_UA, &key); #endif @@ -471,7 +402,6 @@ void my_kafka_send(Ckafka_data_t& data) else printf("\nFailed kafka send, monitor_id:[%s] topic:[%s]\n", key.c_str(), topic.c_str()); - //printf("\n--------------------------------------\n%s\n--------------------------------------\n",senddata.c_str() ); // WW 2023-08-16 } void my_datahub_send(Ckafka_data_t& data) @@ -484,21 +414,6 @@ void my_datahub_send(Ckafka_data_t& data) static std::string cfg_Alm_tp; static bool init = false; if (!init) { - //QString MyKafkaIniFilename = QString("../etc/") + QString("mykafka.ini"); //+QString::fromAscii(subdir) - //QSettings settings(MyKafkaIniFilename, QSettings::IniFormat); - - //QString brl_cfg = settings.value("Kafka/brokerlist", "").toString(); - //QString topic_his = settings.value("Kafka/HisTopic", "").toString(); - //QString topic_plt = settings.value("Kafka/PLTTopic", "").toString(); - //QString topic_pst = settings.value("Kafka/PSTTopic", "").toString(); - //QString topic_evt = settings.value("Kafka/EventTopic", "").toString(); - //QString topic_alm = settings.value("Kafka/AlmTopic", "").toString(); - - //cfg_His_tp = topic_his.toStdString(); - //cfg_PLT_tp = topic_plt.toStdString(); - //cfg_PST_tp = topic_pst.toStdString(); - //cfg_Evt_tp = topic_evt.toStdString(); - //cfg_Alm_tp = topic_alm.toStdString(); cfg_His_tp = TOPIC_STAT; cfg_PLT_tp = TOPIC_PLT; @@ -580,7 +495,6 @@ void KafkaSendThread::run() else if (SEND_FLAG == 2)//datahub { my_datahub_send(data); - //DataHub_Send_Datahub(); } else if (SEND_FLAG == 3)//rocketmqlnk10-11 { @@ -625,8 +539,6 @@ void KafkaSendThread::run() pthread_mutex_lock(&normalListMutex); if (!normalList.empty()) { - //qDebug() << "flag of list:" << normalOutputEnabled << " " << warnOutputEnabled << " " << errorOutputEnabled << " " << "warnList size: " << warnList.size() << "normalList size: " << normalList.size() << "errorList size: " << errorList.size()<>>>>>>>>>>> %s \n", count,QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toAscii().data()); my_rocketmq_send(log_send); } QThread::msleep(1); // CPU תlnk20250326 - /*if (data_gotten) { - LD_info_t* LD_info = find_LD_info_only_from_mp_id(data.mp_id.toAscii().data()); - ied_t* ied; - ied = find_ied_from_dev_code(LD_info->terminal_code); - ied_usr_t* ied_usr = GET_IEDEXT_ADDR(ied); - int cpuno; - for (cpuno = 0; cpuno < ied->cpucount; cpuno++) { - LD_info = &(ied_usr->LD_info[cpuno]); - data.mp_id.clear(); - data.mp_id.append(LD_info->mp_id); - - static uint32_t count = 0; - printf("BEGIN my_kafka_send no.%i -------->>>>>>>>>>>> %s \n", count, - QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toAscii().data()); - my_kafka_send(data); - printf("END my_kafka_send no.%i -------->>>>>>>>>>>> %s \n\n", count++, - QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toAscii().data()); - } - }*/ -//lnk 20241031 ټ¼ƥʡԡ쳣 -/* - oss_data_t ossdata; - bool oss_data_gotten; - - oss_data_gotten = false; - oss_data_list_mutex.lock(); - if (!oss_data_list.isEmpty()) { - oss_data_gotten = true; - ossdata = oss_data_list.takeFirst(); - } - oss_data_list_mutex.unlock(); - - if (oss_data_gotten) { - - char file_name[256]; - memset(file_name, 0, 256); - sprintf(file_name, "%s", ossdata.filename.toAscii().data()); - char save_name[256]; - memset(save_name, 0, 256); - sprintf(save_name, "%s", ossdata.savename.toAscii().data()); - QString uuid_file_name; - - std::ofstream file(save_name); // һļ󣬴ļ example.txt - if (file.is_open()) { // жļǷɹ - file << ossdata.data.toAscii().data() << "\n"; - file.close(); // رļ - } - else { - cout << "Unable to open file\n" << endl; - } - - if (FILE_FLAG == 1) { - PutOSS(file_name, save_name); - char* file; - // ʹstrrchrҵһ'/'λ - char* last_slash = strrchr(file_name, '/'); - if (last_slash != NULL) { - // һ'/'֮IJ־ļ - file = last_slash + 1; - } - else { - // û'/'ַļ - file = file_name; - } - concatenate_and_separate(file_name, file, &uuid_file_name); - } - else if (FILE_FLAG == 2) { - OBSFile(save_name, file_name, "putObject"); - char* file; - // ʹstrrchrҵһ'/'λ - char* last_slash = strrchr(file_name, '/'); - if (last_slash != NULL) { - // һ'/'֮IJ־ļ - file = last_slash + 1; - } - else { - // û'/'ַļ - file = file_name; - } - concatenate_and_separate(file_name, file, &uuid_file_name); - } - else if (FILE_FLAG == 3) { - char* fileName = (char*)malloc(65 * sizeof(char)); - char* uuid = (char*)malloc(65 * sizeof(char)); - WebAPI_Uds_Upload(UDS_UPLOAD_URL, save_name, uuid, fileName); - concatenate_and_separate(uuid, fileName, &uuid_file_name); - free(fileName); - free(uuid); - } - else { - - } -*/ -//lnk 20241031 ټ¼ƥʡԡ쳣 -/* - if (ossdata.log_name=="comm") { - char tnml_code[128]; - memset(tnml_code, 0, 128); - sprintf(tnml_code, "%s", ossdata.id.toAscii().data()); - errorlog_pgsql(tnml_code, ossdata.time, uuid_file_name); - } - else if (ossdata.log_name == "reason") { - QString pgsql; - pgsql.append(errorlog_num_pgsql(ossdata.id, ossdata.time, uuid_file_name, ossdata.list_num)); - cout << pgsql.toAscii().data() << endl; - } - else if (ossdata.log_name == "match") { - QString pqsql; - pqsql.append(errorlog_datamatch_pgsql(ossdata.id, ossdata.time, ossdata.base_mat_num, ossdata.adv_mat_num, ossdata.base_act_num, ossdata.adv_act_num, uuid_file_name)); - cout << pqsql.toAscii().data() << endl; - } - - - - std::remove(save_name); - } - else { - msleep(1); - }*/ - } //while(1) { + } //߳̽ݻ @@ -1637,9 +1428,6 @@ void parse_control(const std::string& json_str, const std::string& output_dir) { //жDzԼ̺ţ int index_value = index->valueint; - //string index_value_str = index->valuestring; - //int index_value = StringToInt(index_value_str); - //̺Ϊ0Ľ̴̨˸Ϣ if (index_value != g_front_seg_index && g_front_seg_index !=0) { @@ -1975,7 +1763,6 @@ int myMessageCallbackupdate(CPushConsumer* consumer, CMessageExt* msg) } else{ // - // Ϣ磬ӡϢݣ std::cout << "ledger update Callback received message: " << body << std::endl; if (key) { std::cout << "Message Key: " << key << std::endl; @@ -2011,7 +1798,6 @@ int myMessageCallbackset(CPushConsumer* consumer, CMessageExt* msg) } else{ // - // Ϣ磬ӡϢݣ std::cout << "process Callback received message: " << body << std::endl; if (key) { std::cout << "Message Key: " << key << std::endl; @@ -2046,7 +1832,6 @@ int myMessageCallbacklog(CPushConsumer* consumer, CMessageExt* msg) } else{ // - // Ϣ磬ӡϢݣ std::cout << "process Callback received message: " << body << std::endl; if (key) { std::cout << "Message Key: " << key << std::endl; @@ -2108,8 +1893,6 @@ int myMessageCallbackrecall(CPushConsumer* consumer, CMessageExt* msg) } - - // ҵ߼״̬ return E_CONSUME_SUCCESS; } @@ -2153,12 +1936,8 @@ void mqconsumerThread::run() } // У߻ͨصϢ - - // ģ std::cout << "Consumer is running. " << std::endl; - //̵߳ - //ShutdownAndDestroyConsumer(); } //CZY 2023-08-23 get double class voltage level, if false will return 0; @@ -2308,22 +2087,11 @@ void try_start_mqconsumer_thread() ///////////////////////////////////////////////////////////////////////// json_block_data json_blkd; -//void init_json_block_data() -//{ -// json_blkd.monitorId = -1; -// json_blkd.func_type = g_node_id; -// //flag Ʒʣ 쳣1 0 -// json_blkd.flag = 0; // //޳ǣ1޳0޳Ĭ޳ -// json_blkd.mms_str_map.clear(); -//} - //CZY 2023-08-17 WW 202212614:09:08 ӶICD֧ //json_block_data json_blkd; //jsonƴӲ,ԭеһݶڶICD»ݴλ //ǽݷLDInfoṹд洢֤һ·һjsonƴӲ void init_json_block_data(char mp_id[], char voltage_level[], int flicker_flag)//WW 202331316:38:41 ICD޸ { - // char[] תΪ std::string - //QString keyString(mp_id); json_block_data* pdata; if (flicker_flag == 1) { @@ -2364,23 +2132,11 @@ void init_json_block_data(char mp_id[], char voltage_level[], int flicker_flag)/ pdata->voltage_level = get_voltage_level(voltage_level); //CZY 2023-08-23 add voltage_level } -//0. jsonɿʼ -//int json_block_create_start(int MonitorId ) -//{ -// try_start_kafka_thread(); -// -// init_json_block_data(); -// json_blkd.monitorId = MonitorId; -// printf("\n\n---------- json_block_create_start: MonitorId=%d \n",MonitorId); -// return TRUE; -//} + int json_block_create_start(char voltage_level[], char monid_char[], int flicker_flag, char temcode[], int line_id)//WW 202331316:38 : 41 ICD޸ { try_start_kafka_thread(); - //WW 2023-08-22 ݿ߳ - //try_start_sql_thread();//lnk2024118Ҫsql߳ - //WW end init_json_block_data(monid_char, voltage_level, flicker_flag); json_block_data* pdata; @@ -2423,13 +2179,7 @@ int json_block_create_start(char voltage_level[], char monid_char[], int flicker return TRUE; } -//1. jsonɿʼ -//int json_block_create_time(int MonitorId , long long Time) -//{ -// json_blkd.time = Time; -// printf("\njson_block_create_time: MonitorId=%d,Time=%lld \n",MonitorId,Time); -// return TRUE; -//} + int json_block_create_time(char monid_char[], long long Time, int flicker_flag)//WW 202331316:38:41 ICD޸ { json_block_data* pdata; @@ -2457,12 +2207,6 @@ int json_block_create_time(char monid_char[], long long Time, int flicker_flag)/ return TRUE; } -//int json_block_create_flag(int MonitorId , int flag) -//{ -// json_blkd.flag = flag; -// printf("\njson_block_create_flag: MonitorId=%d,flag=%d \n",MonitorId,flag); -// return TRUE; -//} int json_block_create_flag(char monid_char[], int flag, int flicker_flag)//WW 202331316:38:41 ICD޸ { @@ -2491,18 +2235,7 @@ int json_block_create_flag(char monid_char[], int flag, int flicker_flag)//WW 20 return TRUE; } -//2. jsonݻص -//int json_block_create_data(int MonitorId , char* mms_str , double v ) -//{ -// static int count = 0; -// //WW2023-08-16 ȥlogע -// //printf("#"); -// //if ( ((count++ %1000)==0) || (count <2000) ) -// // printf("\n%d:json_block_create_data: MonitorId=%d,mms_str=%s,v=%f \n",count,MonitorId,mms_str,v); -// -// json_blkd.mms_str_map.insert(QString::fromAscii(mms_str), v); -// return TRUE; -//} + int json_block_create_data(char monid_char[], char* mms_str, double v, int flicker_flag)//WW 202331316:38:41 ICD޸ { @@ -2535,13 +2268,6 @@ int json_block_create_data(char monid_char[], char* mms_str, double v, int flick return TRUE; } -//3. jsonɽ -//int json_block_create_end(int MonitorId ) -//{ -// printf("\n---------- json_block_create_end: MonitorId=%d \n\n\n",MonitorId); -// -// return transfer_json_block_data(&json_blkd); -//} //lnk2024-8-16ӽ߲ int json_block_create_end(char v_wiring_type[], char monid_char[], int flicker_flag)//WW 202331316:38:41 ICD޸ @@ -2574,8 +2300,6 @@ int json_block_create_end(char v_wiring_type[], char monid_char[], int flicker_f pdata = json_pst_data_map.value(monid_char); } - - //int ret = transfer_json_block_data(pdata, DevKind);//CZY 2023-08-17 Ҫ if (pdata->mms_str_map.count() == 0) { if (flicker_flag == 1) { json_flicker_data_map.remove(monid_char); @@ -2639,18 +2363,6 @@ void prcess_monitor_comm_2_json(int monitor_id, int status, long long tm) } ////////////////////////////////////////////////////////////////////////////// -//int transfer_json_block_data(json_block_data *data) -//{ -// Ckafka_data_t kafka_data; -// kafka_data.patition_id = 0; -// kafka_data.strText = QString("Time=%1").arg(data->time); -// -// kafka_data_list_mutex.lock(); -// kafka_data_list.append(kafka_data); -// kafka_data_list_mutex.unlock(); -// return TRUE; -//} - void clear_old_comtrade_files() { if (g_node_id != SOE_COMTRADE_BASE_NODE_ID) @@ -2670,12 +2382,8 @@ void clear_old_comtrade_files() } } - - - ///////////////////////////////////////////// -//using namespace std; int process_login_verify() { int length = 64; @@ -2683,7 +2391,6 @@ int process_login_verify() char* p = NULL; int count = 0; char encode_password[256]; - //password = "njcnpqs@2018" const char* passwordConfirm = "1c0e4e104de596846648ba495bd32601"; memset(password, 0, sizeof(password)); @@ -2694,131 +2401,23 @@ int process_login_verify() system("stty -echo"); std::cin.getline(password, 64); system("stty echo"); - //while (((*p = getch()) != 13) && count < length) { - // //putch('*'); - // //fflush(stdin); - // p++; - // count++; - //} password[length] = '\0'; - //printf("input typed password : %s \n",password); MyGetSM4Code(password, (unsigned char*)"epri.sgcc.com.cn", encode_password); - //printf("encode_password : %s ,should be %s \n",encode_password,passwordConfirm); return (strcmp(encode_password, passwordConfirm)); } -//////////////////////////////////////////// - /////////////////////////////////////////// -//WW 2023-08-22 ݿ̺߳WebSokcet߳ - -void SQLExcuteThread::run() -{ - //if (THREE_SECS_DATA_BASE_NODE_ID == g_node_id)//3ݴ䲻Ҫд - //return; - - if (1 != g_iOTLFlag) { - Sql_data_list.clear(); - return; - } - - static uint32_t connect_state = 0; - static uint32_t sql_count = 0;//2024-04-01 - const char* pSql = nullptr; - printf("SqlExcuteThread::run() is called ...... \n\n"); - - while (1) - { - msleep(1); - if (!Sql_data_list.isEmpty()) - { - if (0 == sql_count++ % 300) - { - //db.connected - int rtState = OTLDbconnected(); - //int rtState = db.connected; - if (rtState == 0 || connect_state != 0) { - OTLDisconnect(); - int ret = OTLConnect(); - if (ret != 0 && ret != 32031) { - bool bExit = false; - for (int i = 0; i < 3; i++) { - OTLDisconnect(); - ret = OTLConnect(); - if (ret != 0 && ret != 32031) { - if (2 == i) - bExit = true; - else - printf(">>>Postgresql reconnect %d times,errorcode= %d \n", i + 1, ret); - } - } - if (bExit) { - printf(">>>Postgresql reconnect 3 times,errorcode= %d,end thread!\n", ret); - sleep(30); - continue; - //return; - } - } - } - } - // printf("(д)SqlִSql_data_listԪظ= %dʵԪظ= %d \n", g_iSqlListSize, Sql_data_list.size()); - - Sql_data_list_mutex.lock(); - - std::string strSql = Sql_data_list.takeFirst().toStdString(); - printf("get one sql \n"); - if (strSql.length() < 11) - { - // printf("(д)SqlִSql_data_listʣԪظ= %dǰִSql= %scontinueһ䣡\n", Sql_data_list.count(), strSql.c_str()); - continue; - } - pSql = strSql.c_str(); - Sql_data_list_mutex.unlock(); - - //printf("BEGIN my_sql_excute no.%i -------->>>>>>>> %s \n", count, QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toAscii().data()); - /*if (2 == Log_Enable) - printf("(д)SqlִSql_data_listʣԪظ= %iǰִSql.%i= %s \n", Sql_data_list.count(), count, pSql);*/ - printf("write one sql %s \n", pSql); - int rt = write_to_db(pSql); - connect_state = rt; - printf("connect state %d \n", connect_state); - //if (0 == rt) - //{ - // if (1 == Log_Enable) - // printf("(д)Sqlִгɹ.%i \n", count); - // else - // printf("(д)Sqlִгɹ.%iSql= %s \n", count, pSql); - //} - //printf("END my_sql_excute no.%i -------->>>>>>>> %s \n\n", count++, QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toAscii().data()); - } - } - - printf(">>>SqlExcuteThread::run() is end!!!\n"); -} - -void try_start_sql_thread() -{ - static int sql_thread_created = 0; - if (!sql_thread_created) { - //if (2 == Log_Enable) - // printf(">>>Sqḷִ߳\n"); - sqlThrd.start(); - sql_thread_created = 1; - } -} void try_start_socket_thread() { static int socket_thread_created = 0; if (!socket_thread_created) { - //if (2 == Log_Enable) - // printf(">>>Web Sockeṭ߳\n"); socketThrd.start(); socket_thread_created = 1; } @@ -2876,8 +2475,6 @@ void try_start_ontimer_thread() { static int ontimer_thread_created = 0; if (!ontimer_thread_created) { - //if (2 == Log_Enable) - // printf(">>>Web Sockeṭ߳\n"); onTimerThrd.start(); ontimer_thread_created = 1; } @@ -2888,18 +2485,13 @@ void try_start_ontimer_thread() //ZW 2024-01-31 ģʽŻ static QMap mvl_type_ctrl_map;//ZW 2024-01-31 ڱ浥λȡģ static int mvl_type_ctrl_map_size;// -//static std::map myMap; //donameӦģ void add_mvl_type_ctrl(char doname[], int ctrl) { - //printf("\nadd_mvl_type_ctrl: %s\n", doname); - //printf("\nadd_mvl_type_ctrl: %p////%p\n", &ctrl,©); if (!mvl_type_ctrl_map.contains(doname)) { - //MVL_TYPE_CTRL* copy = ctrl; mvl_type_ctrl_map.insert(doname, ctrl); } - //printf("\nadd_mvl_type_ctrl: %p\n", &doname); } //ɾmapģ diff --git a/json/save2json.h b/json/save2json.h index 1fa88d0..542d4f2 100644 --- a/json/save2json.h +++ b/json/save2json.h @@ -57,38 +57,13 @@ extern void redirectErrorOutput(bool enable); extern void redirectWarnOutput(bool enable); extern void redirectNormalOutput(bool enable); extern void redirectDebugOutput(bool enable); - - -////////////////////////////////////////////////////////////////////////////// -//struct json_pair_info -//{ -// string topic; // "RTDATA" ʵʱ "RTDATASOE"ʵʱSOE¼ -// string data_type; //ͣ01/04:̬/ٲ̬02/05:/ٲ䣬03/06:̬/ٲ̬ -// string item; // "I" "PQ" -// string sequence; //"A" "B" "C" "T" -// string name; //jsonkey -// int type; //6-ֵ9-ʵʱSOE¼ -// string mms_ref; //mmsַַ -// float coeff; //Coefficient:ϵ -// unsigned short PltFlag; //0xffff -//}; - -///////////////////////////////////////////////////////////////////////////// class KafkaSendThread : public QThread { -// Q_OBJECT -//public: - protected: void run(); }; //WW 2023-08-22 ݿ̺߳WebSocket߳ -class SQLExcuteThread : public QThread -{ -protected: - void run(); -}; class WebSocketThread : public QThread { @@ -107,12 +82,7 @@ class httpThread : public QThread protected: void run(); }; -//lnk20241202 -/*class mqtestThread : public QThread -{ -protected: - void run(); -};*/ + //lnk20250106 extern bool showinshellflag; @@ -644,12 +614,9 @@ protected: //WW 2023-08-22 end ///////////////////////////////////////////////////////////////////////// - - extern "C" { #endif - //lnk20250106̨˽ṹ typedef struct terminal terminal; typedef struct monitor monitor; diff --git a/mms/db_interface.h b/mms/db_interface.h index 97874f8..a384e8b 100644 --- a/mms/db_interface.h +++ b/mms/db_interface.h @@ -74,7 +74,6 @@ int json_block_create_data(char monid_char[], char* mms_str , double v, int flic //3. jsonɽ //lnk2024-8-16Ӳ int json_block_create_end(char v_wiring_type[], char monid_char[], int flicker_flag); //CZY 2023-08-17 -//int json_block_create_end(int MonitorId,int devkind);//CZY 2023-08-17 //zw 2024-01-31 ģʽŻ void add_mvl_type_ctrl(char doname[], int ctrl); @@ -88,15 +87,6 @@ typedef struct LD_info_t LD_info_t; int urcbRealDataHasReceived(int dev_index, LD_info_t* LD_info, long long Time); //lnk20241223 #endif -//void set_log_LineID(int id); -//void set_rpt_LineID(int id); - -//void set_log_TimeID(apr_time_t time); -//void set_rpt_TimeID(apr_time_t time); - -//void set_log_QualityFlag(int QualityFlag); -//void set_rpt_QualityFlag(int QualityFlag); - int is_rpt_Time_exact_hour() ; apr_status_t app_get_private_config(const char *myfilename); @@ -165,7 +155,6 @@ int testbase64(); //////////////////////////////WW 20230822ݿWebSocket߳ -void try_start_sql_thread(); //Sqlִ߳ void try_start_socket_thread(); //Web Socket߳ void try_start_ontimer_thread();//ʱ߳s /////////////////////////////WW end @@ -202,24 +191,11 @@ int parse_device_web_test_front_read(); int parse_device_web_test_front_write(); int parse_device_cfg_web(); -//int parse_line_cfg_web(); int parse_model_cfg_web(); void SOEFileWeb(char* localpath,char* cloudpath,char* wavepath); - -void OTL_Select_recall_web(char* time, char* id); -int OTL_Select_DecideRecall_web(char* time, char* id); -bool CheckPG_To_Recall_web(long long start, long long end, char* Monitorid); ////////////////////////////////////////////////////////////////////////////////////// - -/*int parse_database_delete(const std::vector& codes); -int parse_commerror_write(const std::vector& codes); -int parse_commstatus_write(const std::vector& codes); -int parse_match_write(const std::vector& codes); -int parse_dataintegrity_write(const std::vector& codes); -int parse_rationality_write(const std::vector& codes);*/ - #ifdef __cplusplus } #endif diff --git a/mms/main.c b/mms/main.c index 7675461..2b53c72 100644 --- a/mms/main.c +++ b/mms/main.c @@ -26,9 +26,8 @@ extern pthread_mutex_t mtx; extern pt61850app_t *g_pt61850app; extern node_t *g_node; char g_my_conf_fname[256]; -//extern byte_t g_Master; + char g_onlyIP[255]; //ֱijIPΪ -//extern byte_t g_protect_file; //0:ٻ¼ļ 1:ٻ¼ļ apr_pool_t *g_root_pool; apr_pool_t *g_rdb_pool; @@ -122,7 +121,6 @@ void init_daemon(void) //"--subdir, set the subdir of /CloudForward/ as the working directory, \n" int usage() { - // fprintf(stderr,"\n\n******** IEC61850 Protocol ********\n"); fprintf(stderr,"\nUsage : pt61850netd_pqfe -d [subdir] \n"); exit(-1); @@ -179,16 +177,9 @@ int prepare_entironment_2() return (-1); } - //g_fun_pool = 0; - - //rv = apr_thread_mutex_create(&g_rdb_mutex, APR_THREAD_MUTEX_NESTED,g_root_pool);//RDB - //if ( rv != APR_SUCCESS) { - // return rv; - //} /* Initialize the register table. Call these functions first! */ echo_msg1("%-60s","Initialize system register......"); - //init_default_dbparser_table(); //ݸXMLļRDBʼ - //load_driver_library(); //ø˿ + echo_msg("OK\n\n"); initTimezoneOffset(); @@ -211,11 +202,8 @@ void printf_cur_user() int main(int argc, const char **argv) { -// ipcclient_t *ipcclient = NULL; -// void *cookie = NULL; uint32_t stimer = 1; apr_status_t rv; -// int pid; /* Prepare the system context */ rv=prepare_entironment_2(); @@ -225,22 +213,6 @@ int main(int argc, const char **argv) getVersion(argc,argv); - //////////////////// - //WW json - //TestJson(NULL); - //WW 2023-08-31 end - /////////////////// - //TestSMSPost();//WW 2023-08-28Թ˾post - //TestBodyPost(); - //TestToken();//Դҵ̨ - - //////////////////// - //WW json - //TestOSS(); - //TestOBS(); - //WW 2023-09-01 end - /////////////////// - /* Parse the command-line parameter */ rv=parse_param(argc, argv); if (rv!=APR_SUCCESS){ return rv; @@ -280,9 +252,6 @@ int main(int argc, const char **argv) return rv; } -//lnk20241024ȥݿ - //OTLConnect(); - rv = run_protocol(); if (rv!=APR_SUCCESS){ return rv; @@ -360,10 +329,8 @@ int parse_param(int argc, const char **argv) char *p; char temp[128]; - //int g_front_seg_index, g_front_seg_num; - /* Set default command-line parameter */ + g_node_id = 0; - //g_protect_file = 0; echo_warn2("================= compiled@ %s %s =================\n",__DATE__ , __TIME__ ); @@ -383,18 +350,7 @@ int parse_param(int argc, const char **argv) break; case 'R': case 'r': - // if (opt_arg[0] >= '0' && opt_arg[0] <= '9' ) - // { - // g_client_id = atoi(opt_arg); - // if (g_client_id>2||g_client_id<0) - // { - // printf("Do not support triple or above clients \n "); - // return (usage()); - // } - ////g_auto_client_id = FALSE; - // } - // else - // return (usage()); + break; case 's': case 'S': @@ -413,11 +369,6 @@ int parse_param(int argc, const char **argv) printf("g_front_seg_num:%d",g_front_seg_num); - //echo_warn2("================= compiled@ %d %d =================\n", g_front_seg_index, g_front_seg_num); - //lnk20241206Ҫ¼subdirʹ - //echo_warn1("subdir %s ", opt_arg + 6); - //strcpy(subdir, opt_arg + 6); - break; break; case 'a': @@ -433,14 +384,7 @@ int parse_param(int argc, const char **argv) break; case 'f': case 'F': - //if (opt_arg[strlen(opt_arg)-1] == '/' - // || opt_arg[strlen(opt_arg)-1] == '\\') { - // echo_errg( "Error: Bad or invalid file name"); - // return (usage()); - // } - // //g_my_conf_fname = SHR_GetPrivateFileName(opt_arg,g_root_pool); - // echo_warn1("using config file %s!\n", g_my_conf_fname); - // break; + break; case 'P': case 'p': if (opt_arg[0] >= '0' && opt_arg[0] <= '9' ) { @@ -459,7 +403,6 @@ int parse_param(int argc, const char **argv) return 0; } - ///////////////////////////////////////////////////////////////ӲԽ̵ļغlnk20250304 void doMonitorTaskmain(void) { static int stimer = 0; diff --git a/mms/mms_process.c b/mms/mms_process.c index 75f8232..a757836 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -81,39 +81,6 @@ extern char* UDS_UPLOAD_URL; /////////////////////////////////////////////////////////////////// //lnk20250122start -#if 0 -apr_status_t init_rem_dib_table() -{ - int pos = 0; - int iedno,chnl_no; - ied_t *ied; - struct in_addr ip; - chnl_usr_t *chnl_usr; - - set_rem_dib_table_size( g_pt61850app->chnl_counts ); - g_pt61850app->chnl_usr = apr_pcalloc( g_init_pool,g_pt61850app->chnl_counts*sizeof(chnl_usr_t*) ); - printf( "set_rem_dib_table_size %d \n",g_pt61850app->chnl_counts ); - for(iedno=0 ; iednon_clients; iedno++) { - ied = g_node->clients[iedno]; - for(chnl_no=0 ; chnl_nochncount; chnl_no++) { - chnl_usr = ied->channel[chnl_no].connect; - g_pt61850app->chnl_usr[pos] = chnl_usr; - 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 ); - { - 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; -} -#endif - apr_status_t init_rem_dib_table() { int pos = 0; @@ -174,19 +141,7 @@ void CloseIECReports(chnl_usr_t *chnl_usr) continue; if ( rptinfo->chnl_id != chnl_usr->chnl_id) continue; - /*get_rpt_inst_name(rptinfo,rpt_inst_name); - ret = mms_unregister_iec_rpt (chnl_usr->net_info, &g_rpt_typeids, - LD_info->LD_name,rpt_inst_name,g_pt61850app->mmsOpTimeout ); - if(ret == SD_FAILURE) - { - echo_warn3("unregister iec_rpt failed !!! domain: %s ,rpt_inst_name: %s ,chnl_id: %d \n", - LD_info->LD_name,rpt_inst_name,chnl_usr->chnl_id); - } - else - { - printf("unregister iec_rpt succeed, domain: %s ,rpt_inst_name: %s ,chnl_id: %d \n", - LD_info->LD_name,rpt_inst_name,chnl_usr->chnl_id); - } */ + rptinfo->rpt_registered = FALSE; //עȡ10 עһεƣע rptinfo->m_LastRegisterFailedTime = sGetMsTime() -10*60*1000; @@ -195,24 +150,6 @@ void CloseIECReports(chnl_usr_t *chnl_usr) } } -void prcess_ied_comm_2_json(ied_t *ied,int status) -{ - ied_usr_t *ied_usr = NULL; - LD_info_t *LD_info = NULL; - int cpuno ; - apr_time_t tm = apr_time_now()/1000; - - if (!three_secs_enabled) - return; - ied_usr = (ied_usr_t*)ied->usr_ext; - for(cpuno=0 ; cpunocpucount; cpuno++) { - LD_info = &(ied_usr->LD_info[cpuno]); - if (LD_info ) { - //prcess_monitor_comm_2_json(LD_info->line_id,status,tm); - } - } -} - void closeChannel(chnl_usr_t *chnl_usr) { char comm_str[256]; @@ -221,9 +158,6 @@ void closeChannel(chnl_usr_t *chnl_usr) add_comm_log(comm_str); FRONT_MP_NUM--; echo_warn1("Close Channel IP: %s",chnl_usr->ip_str ); - //prcess_ied_comm_2_json(chnl_usr->chnl->ied,STATUS_BREAKOFF); - //RDB_SetIedChnlStatus(chnl_usr->chnl->ied, STATUS_BREAKOFF, chnl_usr->chnl_id); - //write_status_to_db(0,chnl_usr->chnl->addr); CloseIECReports(chnl_usr); echo_warn1("-------Close Channel IP: %s success!!!!!!!!!", chnl_usr->ip_str); @@ -247,15 +181,15 @@ void closeChannel(chnl_usr_t *chnl_usr) if (ret != SD_SUCCESS){ echo_warn("---------disconnectFromServer success!\n"); - //cout<ip_str,chnl_usr->net_info); - //mms_release_connection(chnl_usr->net_info); ??????? + mvl_free_req_ctrl(chnl_usr->m_reqCtrl); chnl_usr->net_info->user_ext = NULL; chnl_usr->net_info = NULL; - //cout<<"CHANNEL Close roughly, NetInfo_Channel_Map.entries()= "<m_reqCtrl = NULL; chnl_usr->net_info = NULL; chnl_usr->m_state = CHANNEL_DISCONNECTED; @@ -270,7 +204,7 @@ void closeChannel(chnl_usr_t *chnl_usr) }else { chnl_usr->m_state = CHANNEL_DISCONNECTED; chnl_usr->m_ClosedMsTime = sGetMsTime(); - //cout<<"m_ClosedMsTime "<chnl->status = STATUS_BREAKOFF; } } @@ -280,7 +214,7 @@ ST_VOID Callback_channel_disconnect_ind(MVL_NET_INFO * NetInfo, ST_INT discType) chnl_usr_t *chnl_usr; chnl_usr = (chnl_usr_t*)NetInfo->user_ext; - //cout<<"NetInfo_Channel_Map.entries()= "<m_state == CHANNEL_CONNECTING) { //do nothing; @@ -296,22 +230,15 @@ ST_VOID Callback_channel_disconnect_ind(MVL_NET_INFO * NetInfo, ST_INT discType) printf("Do nothing,m_state == CHANNEL_DISCONNECTED ,NetInfo = %x",NetInfo); } - //cout <<"NetInfo_Channel_Map[NetInfo] " << pCh <net_info = NULL; NetInfo->user_ext = NULL; } printf(" Callback_channel_disconnect_ind ,NetInfo = %x",NetInfo); - /* cout<<"after: NetInfo_Channel_Map.entries()= "<chnl[0].ied->usr_ext); - //printf("%s", ied_usr->terminal_code); - //connectlog_pgsql(ied_usr->terminal_code); - //apr_time_t tm = apr_time_now();// - //printf("time: %llu", tm); - //apr_time_exp_t pTm; - //apr_time_exp_gmt(&pTm, tm); - //printf("time: %u %u %u", pTm.tm_year, pTm.tm_mon, pTm.tm_mday); } @@ -369,26 +296,25 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr) ied_usr = GET_IEDEXT_ADDR(ied); channel = chnl_usr->chnl; - //printf("check error %s !!!!!!!!!!!!!!cpucount:%d\n",((ied_usr_t*)chnl_usr->chnl->ied->usr_ext)->terminal_id,(int)ied->cpucount); - - //printf("1 chnl_usr->ip_str = %s \n",chnl_usr->ip_str); for(cpuno=0 ; cpunocpucount; cpuno++) - //for(cpuno = ied->cpucount - 1; cpuno >= 0; cpuno--) + { LD_info = &(ied_usr->LD_info[cpuno]); // + if (LD_info->cpuno==0) continue; - //printf("2 chnl_usr->ip_str = %s \n",chnl_usr->ip_str); + for(rpt_no=0 ; rpt_norptcount; rpt_no++) { //棨ӳļжȡıƣ rptinfo = LD_info->rptinfo[rpt_no] ; - /*if ( strstr(rptinfo->rptID,"LLN0$RP$urcbRealData") ) - continue;*/ + if (judge_rpt_next_should_do(rptinfo)==SHOULD_DO_NOTHING)//Ƿ񴥷 continue; - //printf("3 chnl_usr->ip_str = %s \n",chnl_usr->ip_str); + if(rptinfo->m_curRptSuffix==-1) - rptinfo->m_curRptSuffix = g_pt61850app->rptSuffix[g_client_id][0] ; + rptinfo->m_curRptSuffix = g_pt61850app->rptSuffix[g_client_id][0] ; + get_rpt_inst_name(rptinfo,rpt_inst_name);//ȡ + if ( ! rptinfo->rpt_registered ) { if ( (sGetMsTime() -rptinfo->m_LastRegisterFailedTime) > 20*1000 ) { //עʧܺ 20 עһ @@ -397,84 +323,39 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr) if ( strstr(rptinfo->rptID,"LLN0$BR$brcbFlickerData") ) rptinfo->IntgPd = 600; //10 + /////////////////////////WW 2023-08-30 豸뱨 rcb_info = mms_register_iec_rpt (chnl_usr->net_info, &g_rpt_typeids, LD_info->LD_name,rpt_inst_name,g_pt61850app->mmsOpTimeout, rptinfo->IntgPd,rptinfo->TrgOpt, (ST_UINT8*)rptinfo->m_EntryID ,(ST_UINT8*)rptinfo->OptFlds); - //rcb_info = mms_register_iec_rpt_by_devtype(chnl_usr->net_info, &g_rpt_typeids, - // LD_info->LD_name, rpt_inst_name, g_pt61850app->mmsOpTimeout, ied_usr->dev_type, chnl_usr->ip_str, channel->port, - // rptinfo->IntgPd, rptinfo->TrgOpt, - // (ST_UINT8*)rptinfo->m_EntryID, (ST_UINT8*)rptinfo->OptFlds); //WW end /////////////////////////// if( !rcb_info ) { if ( ++rptinfo->m_curRptSuffix > g_pt61850app->rptSuffix[g_client_id][1] ) rptinfo->m_curRptSuffix = g_pt61850app->rptSuffix[g_client_id][0] ; + rptinfo->m_LastRegisterFailedTime = sGetMsTime() ; + echo_err9("\nעᱨʧܣRregister iec_rpt failed !!! IED_ID=%d ,CPU=%d , domain: %s ,rpt_inst_name: %s ,ip: %s:%d,chnl_id: %d ,IntgPd=%d ,TrgOpt=0x%x \n", APR_EGENERAL, LD_info->ied->id,LD_info->cpuno,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl->port, chnl_usr->chnl_id, rptinfo->IntgPd,rptinfo->TrgOpt ); - //ټ¼ݽ־lnk20241104 - /*if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) - { - //ݽ¼¼¼ - SoeRptSql(LD_info->terminal_code,1, rptinfo->rptID); - }*/ - //zw޸ 2023 - 8 - 18 ʧܼ¼ - //printf("start %s \n", Rpt_errorlog_json()); - //insert into "MEAS_PQ_COMM_ERROR_TR"("TERMINAL_ID","COMM_DATE","FILE_NAME") values('8afaa9a15707483a0157262f8e78077d',date'2023-08-18','FILENAME111') - //char ERROR_DES[256] = "", ERROR_PARAM[256] = ""; - //char** varnames; - //int varnum,j; - ////double beforeCallDomainMsTime = sGetMsTime() ; - //ST_RET ret = mms_mvla_getnam(chnl_usr->net_info, VMD_SPEC, NULL, MMS_CLASS_DOM, g_pt61850app->mmsOpTimeout, - // &varnames, &varnum, g_pt61850app->tmp_pool); - //for (j = 0; j < varnum; ++j) { - // //printf("LD %d name: %s \n", j, varnames[j]); - // strcat(ERROR_PARAM, varnames[j]); - // strcat(ERROR_PARAM, " "); - //} - - //ret = mms_mvla_getnam(chnl_usr->net_info, DOM_SPEC, varnames[1], MMS_CLASS_VARLIST, 3, - // &varnames, &varnum, g_pt61850app->tmp_pool); - //for (j = 0; j < varnum; ++j) { - // //printf("LD %d name: [%s] \n", j, varnames[j]); - // strcat(ERROR_PARAM, varnames[j]); - // strcat(ERROR_PARAM, " "); - //} - - //strcat(ERROR_DES, ied_usr->org_name); - //strcat(ERROR_DES, ","); - //strcat(ERROR_DES, ied_usr->station_name); - //strcat(ERROR_DES, ","); - //strcat(ERROR_DES, ied_usr->dev_type); - //strcat(ERROR_DES, ","); - //strcat(ERROR_DES, chnl_usr->ip_str); - //strcat(ERROR_DES, ","); - //strcat(ERROR_DES, rpt_inst_name); - //errorlog_json(LD_info->terminal_code, chnl_usr->ip_str, chnl_usr->chnl->port, g_node_id, "津ʧ", ERROR_DES, ERROR_PARAM); } else { - //ټ¼ݽ־lnk20241104 - /*if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) - { - //ݽ¼¼ʧܼ¼ - SoeRptSql(LD_info->terminal_code, 0, rptinfo->rptID); - }*/ double GIoffset; rptinfo->rpt_registered = TRUE; - //rptinfo->m_LastDataTime = sGetMsTime();//WW 2023-08-29 ȥ rptinfo->m_rcb_info = rcb_info; rptinfo->chnl_id = chnl_usr->chnl_id; chnl_usr->m_NegRespTimes = 0; chnl_usr->m_LastPosRespTime = sGetMsTime(); + echo_msg11("\nRegister iec_rpt succeed, IED_ID=%d ,CPU=%d ,domain: %s ,rpt_inst_name: %s ,ip: %s:%d,chnl_id: %d ,IntgPd=%d ,TrgOpt=0x%x ,OptFlds=0x%x%x \n", LD_info->ied->id,LD_info->cpuno,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl->port,chnl_usr->chnl_id, rptinfo->IntgPd,rptinfo->TrgOpt,rptinfo->OptFlds[0],rptinfo->OptFlds[1] ); + // add here to GI not the same time GIoffset = 0.5 * g_pt61850app->giTime; rptinfo->m_LastGITime = sGetMsTime() - GIoffset*1000; @@ -486,8 +367,10 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr) if ( (sGetMsTime() -rptinfo->m_LastUnRegisterFailedTime) > 20*1000 ) { //ȡעʧܺ 20 ȡעһ printf("start mms_unregister_iec_rpt................................\n"); + ret = mms_unregister_iec_rpt (chnl_usr->net_info, &g_rpt_typeids, LD_info->LD_name,rpt_inst_name,g_pt61850app->mmsOpTimeout); + if( ret == SD_FAILURE ) { rptinfo->m_LastUnRegisterFailedTime = sGetMsTime() ; echo_err6("\nȡעᱨʧܣUnRregister iec_rpt failed !!! IED_ID=%d ,CPU=%d , domain: %s ,rpt_inst_name: %s ,ip: %s,chnl_id: %d \n", @@ -500,20 +383,8 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr) } printf("end mms_unregister_iec_rpt................................\n"); } - //double nowMsTime = sGetMsTime() ; - //int ScanRateMs = 3*rptinfo->IntgPd*1000; - //if (rptinfo->chnl_id==chnl_usr->chnl_id) { - // //IECReport_tryGI(chnl_usr,rptinfo); - // if ( (ScanRateMs) && BSTR_BIT_GET( &(rptinfo->TrgOpt), TRGOPS_BITNUM_INTEGRITY ) ) // IntgPdʱ 0, Ч - // if ( (nowMsTime - rptinfo->m_LastDataTime) > ScanRateMs ) - // { - // echo_err4("IntgPdʱδյݣͨ, domain: %s ,rpt_inst_name: %s ,ip: %s,chnl_id: %d \n", - // APR_EGENERAL,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl_id); - // closeChannel(chnl_usr); - // return; - // } - //} - } //else { //rpt_registered ==TRUE + + } } } } @@ -560,7 +431,7 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr) apr_sleep(apr_time_from_sec(1) / 10); Check_Recall_Config(LD_info->mp_id);//Իȡxmlṹ - //add_comm_log(LD_info->mp_id); + if (LD_info->autorecallcount != 0 && LD_info->autorecallflag != 1) { int i; int failed_count = 0; @@ -568,51 +439,22 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr) LD_info->autorecallflag = 1; - //loginfo->need_steady = 1; loginfo->need_voltage = 1; //ǰ̬̬lnk20241030޸ģCheck_Recall_Configxmlļȡݺ󣬸ֵLD_info loginfo->need_steady = LD_info->autorecall[i]->need_steady; loginfo->need_voltage = LD_info->autorecall[i]->need_voltage; loginfo->start_time = apr_time_from_sec(LD_info->autorecall[i]->start - 5); loginfo->end_time = apr_time_from_sec(LD_info->autorecall[i]->end - 5); - //printf("bef mms_jread............. %11d %11d \n", LD_info->autorecall[i]->start, LD_info->autorecall[i]->end); if (loginfo->need_steady == 0 && loginfo->need_voltage == 0) continue; if (loginfo->end_time <= loginfo->start_time) continue; - /*if ( (sGetMsTime() -loginfo->last_checktime) < 180*1000 ) - continue;*/ - //loginfo->last_checktime = sGetMsTime(); printf("start mms_jread................................\n"); - //now = sGetMsTime(); - //last_check_recall_config_time = now; - //printf("start ==============%.2f================\n", last_check_recall_config_time); + echo_msg6("\n mms_jread IED_ID=%d ,CPU=%d ,domain: %s ,logName: %s ,ip: %s,chnl_id: %d \n", LD_info->ied->id, LD_info->cpuno, LD_info->LD_name, loginfo->logName, chnl_usr->ip_str, chnl_usr->chnl_id); - //set_log_LineID(LD_info->line_id); - //set_line_info(LOG_IDX,LD_info->line_id,LD_info->SubV_Index,LD_info->Dev_Index,LD_info->Sub_Index,LD_info->GD_Index); - //long long start = LD_info->autorecall[i]->start; - //long long end = start; - //for (;end < LD_info->autorecall[i]->end;) - //{ - // if (end < LD_info->autorecall[i]->end - 180) - // { - // start = end; - // end = end + 180; - // loginfo->start_time = apr_time_from_sec(start - 5); - // loginfo->end_time = apr_time_from_sec(end - 5); - // } - // else { - // start = end; - // end = LD_info->autorecall[i]->end; - // loginfo->start_time = apr_time_from_sec(start - 5); - // loginfo->end_time = apr_time_from_sec(end - 5); - // } - //} - - //printf(" mms_jread..... start time: %d end time: %d\n", start, end); ret = mms_jread(loginfo, chnl_usr->net_info, loginfo->LD_info->LD_name, loginfo->logName, loginfo->start_time, loginfo->end_time, g_pt61850app->mmsOpTimeout, chnl_usr->ip_str); if (ret != SD_SUCCESS) { @@ -640,8 +482,7 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr) Delete_recall_Xml(LD_info->mp_id); } } - /*apr_time_from_sec(&loginfo->start_time, 1694275200); - apr_time_from_sec(&loginfo->end_time, 1694361600);*/ + } } @@ -654,8 +495,7 @@ void process_3s_config(trigger_3s_xml_t *trigger_3s_xml) int trigger_num; ied_t *ied; LD_info_t *LD_info; -// int rpt_no; -// rptinfo_t *rptinfo; + int need_write_file; int new_in_work_found; @@ -669,7 +509,7 @@ void process_3s_config(trigger_3s_xml_t *trigger_3s_xml) for (j=0; jwork_trigger_num; j++){ trigger_work = &trigger_3s_xml->work_triggers[j]; if (trigger_work->dev_idx==trigger[i].dev_idx && trigger_work->line_id==trigger[i].line_id ) { - //*trigger_work = trigger[i]; + if (trigger[i].real_data>=0) trigger_work->real_data = trigger[i].real_data;//rtdata־ if (trigger[i].soe_data>=0) @@ -805,7 +645,6 @@ void del_process_recall_config(recall_xml_t* recall_xml) } - //remove_recall_xml(); } void check_3s_config() @@ -827,7 +666,7 @@ void check_3s_config() //ʵʱ̨lnk20250114 //pthread_mutex_lock(&mtx); printf("3s hold lock !!!!!!!!!!!"); process_3s_config(&trigger_3s_xml); //ļ - pthread_mutex_unlock(&mtx); printf("3s free lock !!!!!!!!!!!"); + //pthread_mutex_unlock(&mtx); printf("3s free lock !!!!!!!!!!!"); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1352,110 +1191,6 @@ void check_disk_quota() freeSizeMB,totalSizeMB); } -void check_recall_config() -{ - double now; - static double last_check_recall_config_time = 0.0; - static int recall_flag = 1;// 1-δ 2- 3-нر - int recall_lenth = recall_len;// - int recall_start = recall_sta;//ǰǰ - int recall_dailytime = recall_daily;//ÿղʱ - static int recall_count = 0;//д - recall_xml_t recall_xml; - - if(g_node_id != HIS_DATA_BASE_NODE_ID) - return; - now = sGetMsTime(); - - if ( fabs(now - last_check_recall_config_time) < 5*1000 ) //wait 5 secs - return; - last_check_recall_config_time = now; - //parse_recall_xml(&recall_xml); - //process_recall_config(&recall_xml); - //printf("==============%.2f================\n", last_check_recall_config_time); - - apr_time_t previousTime = apr_time_now();// - apr_time_exp_t localTime; - apr_time_exp_gmt(&localTime, previousTime); - if (localTime.tm_hour == recall_dailytime && recall_flag == 1) { - recall_flag = 2; - recall_count = 0; - //recall_pgsql(1);//ǰһ - } - if (recall_flag == 2) // - { - if (recall_start > 30) { - recall_start = 30; - } - if (recall_lenth > 10) { - recall_lenth = 10; - } - if (recall_start < recall_lenth) //ʼСڲг ֹΪ - { - recall_lenth = recall_start; - } - if (recall_count < recall_lenth) - { - recall_pgsql(recall_start - recall_count);// - //char* day = getoneday(recall_start - recall_count);//ȡǰn yyyy-mm-dd - //printf("==============%s================\n", day); - //deletechar(day); - recall_count++; - } - else - { - recall_flag = 3; - } - } - if (localTime.tm_hour != recall_dailytime && recall_flag == 3) { - recall_flag = 1; - recall_count = 0; - } -} - -void recall_pgsql(int num) -{ - char* day = getoneday(num);//ȡǰn yyyy-mm-dd - 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); - if (chnl_usr->m_state == CHANNEL_CONNECTED) - { - 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); -//滻webӿ2024-10-21 lnk - //int ReDecide = OTL_Select_DecideRecall(day, LD_info->mp_id); - //int ReDecide = OTL_Select_DecideRecall_web(day, LD_info->mp_id);//ʹlnk20241206 - - //if (ReDecide == 1) {//ʹlnk20241206 -//滻webӿ2024-10-21 lnk - //OTL_Select_recall(day, LD_info->mp_id); - //OTL_Select_recall_web(day, LD_info->mp_id);//ʹlnk20241206 - //}//ʹlnk20241206 - - g_dead_lock_counter = 0; - g_thread_blocked_times = 0; - cpuno++; - } - } - i++; - } - deletechar(day); -} - void create_recall_xml() { //ɴxmlļ @@ -1468,8 +1203,7 @@ void create_recall_xml() void Delete_recall_Xml(char* id) { if (g_node_id == HIS_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID || g_node_id == RECALL_HIS_DATA_BASE_NODE_ID || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID)) { delete_recall_xml(id); - //process_recall_config(&recall_xml); - //remove_recall_xml(); + } } @@ -1481,34 +1215,22 @@ void Check_Recall_Config(char *id) // memset((char*)&recall_xml, 0, sizeof(recall_xml_t)); parse_recall_xml(&recall_xml,id); //ļ process_recall_config(&recall_xml); //IJݸֵȫֱ - //process_recall_config(&recall_xml); - //remove_recall_xml(); } - /*recall_xml_t recall_xml; - memset((char*)&recall_xml, 0, sizeof(recall_xml_t)); - int ret = parse_recall_xml(&recall_xml); - if (0 == ret) - process_recall_config(&recall_xml);*/ } void CheckAllConnectedChannel() { chnl_usr_t *chnl_usr; static uint32_t chnl_sequence_no = 0; - //10-11-02 20:18 beijing, only one ied by visited every loop һηһն + //һηһն do { chnl_usr = g_pt61850app->chnl_usr[chnl_sequence_no]; chnl_sequence_no = (chnl_sequence_no+1) % g_pt61850app->chnl_counts; } while ( (g_onlyIP[0]!=0) && (strcmp(g_onlyIP,chnl_usr->ip_str)!=0) ); - //for (i=0; ichnl_counts; i++) { - //chnl_usr = g_pt61850app->chnl_usr[i] ; - //printf("CheckAllConnectedChannel chnl_usr->ip_str = %s \n",chnl_usr->ip_str); + if(chnl_usr->m_state == CHANNEL_CONNECTED) { - /*if(chnl_usr->chnl->ied->id==virtual_ied){ - chnl_usr->m_state = CHANNEL_CONNECTED; - return; - }*/ + ChannelCheckIECReports(chnl_usr);// if ( (g_node_id == SOE_COMTRADE_BASE_NODE_ID) || (g_node_id == HIS_DATA_BASE_NODE_ID) || (g_node_id == NEW_HIS_DATA_BASE_NODE_ID) || (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) || (g_node_id == RECALL_ALL_DATA_BASE_NODE_ID)) ChannelCheckWaveFiles(chnl_usr);//¼ļ @@ -1518,93 +1240,58 @@ void CheckAllConnectedChannel() { char** varnames ; int varnum; - //double beforeCallDomainMsTime = sGetMsTime() ; + ST_RET ret = mms_mvla_getnam(chnl_usr->net_info, VMD_SPEC, NULL,MMS_CLASS_DOM,g_pt61850app->mmsOpTimeout, &varnames,&varnum,g_pt61850app->tmp_pool); - //for ( j = 0; j < varnum; ++j) - //printf("LD %d name: %s \n",j,varnames[j]); - //ret = mms_mvla_getnam(chnl_usr->net_info, DOM_SPEC, varnames[1],MMS_CLASS_VARLIST,3, - // &varnames,&varnum,g_pt61850app->tmp_pool); - ////ret = mms_mvla_getnam(chnl_usr->net_info, DOM_SPEC, varnames[1], MMS_CLASS_VAR, 3, - //// &varnames, &varnum, g_pt61850app->tmp_pool); - //for ( j = 0; j < varnum; ++j) - // printf("LD %d name: [%s] \n",j,varnames[j]); - - //double comdiff = sGetMsTime() - beforeCallDomainMsTime; - //cout<<"cost secs to check com "<net_info, 15 ); chnl_usr->m_LastPosRespTime = sGetMsTime(); if (ret == SD_SUCCESS) { - //chnl_usr->m_LastPosRespTime = sGetMsTime(); + chnl_usr->m_NegRespTimes = 0; }else { - // cout<<" "<GetIP()<<" domain name ʧ "<m_NegRespTimes); chnl_usr->m_NegRespTimes++; } } if ( chnl_usr->m_NegRespTimes >=2 ) { - //printf("==============chnl_usr->m_NegRespTimes================\n"); + closeChannel(chnl_usr);//???ǷҪ mms_release_connection chnl_usr->m_NegRespTimes = 0; chnl_usr->m_LastPosRespTime = sGetMsTime(); } } - //} } void CheckNextNotConnectedChannel() { static uint32_t chnl_total_no = 0; chnl_usr_t *chnl_usr; -// element_t *elem_a; -// element_t *elem_b; + do { chnl_usr = g_pt61850app->chnl_usr[chnl_total_no]; chnl_total_no = (chnl_total_no+1) % g_pt61850app->chnl_counts; } while ( (g_onlyIP[0]!=0) && (strcmp(g_onlyIP,chnl_usr->ip_str)!=0) ); - //printf("check error chnl_total_no !!!!!!!!!!!!!! %d\n",chnl_total_no); - //10-11-01 22:03 beijing if( ( (chnl_total_no+1)==g_pt61850app->chnl_counts) || (g_onlyIP[0]!=0) ){ if(g_pt61850app->initNum<255) g_pt61850app->initNum++; } - if(chnl_usr->chnl->ied->chncount == 2){ - //elem_a = RDB_GetElement(SUBSTATION, chnl_usr->chnl->ied->id,64264, 5); - //elem_b = RDB_GetElement(SUBSTATION, chnl_usr->chnl->ied->id,64264, 6); - //if(elem_a&&elem_b){ - // if((((M_DP_NA_1_t*)elem_a->value.data)->diq.parts.DPI == 0x01)&&(((M_DP_NA_1_t*)elem_b->value.data)->diq.parts.DPI == 0x01)){ - // iecs_set_ied_invalid(chnl_usr->chnl->ied); - // } - //} - } - else{ - //elem_a = RDB_GetElement(SUBSTATION, chnl_usr->chnl->ied->id,64264, 5); - //if(elem_a){ - // if(((M_DP_NA_1_t*)elem_a->value.data)->diq.parts.DPI == 0x01){ - // iecs_set_ied_invalid(chnl_usr->chnl->ied); - // } - //} - } - - //printf("check error %s !!!!!!!!!!!!!!\n",((ied_usr_t*)chnl_usr->chnl->ied->usr_ext)->terminal_id); if(chnl_usr->m_state == CHANNEL_CONNECTING)// { - //printf("check error93 !!!!!!!!!!!!!!\n"); + MVL_REQ_PEND* reqCtrl= chnl_usr->m_reqCtrl ; - //printf("check error60 !!!!!!!!!!!!!!\n"); + if( reqCtrl->done == SD_TRUE) { - //printf("check error92 !!!!!!!!!!!!!!\n"); + if(reqCtrl->result == SD_SUCCESS) { - //printf("check error91 !!!!!!!!!!!!!!\n"); + ALL_RCB_INFO *all_rcb_info; - // cout<GetIP()<<" CHANNEL_CONNECTED netInfo "<net_info<ip_str,chnl_usr->chnl->port,chnl_usr->net_info,chnl_usr); mvl_free_req_ctrl(chnl_usr->m_reqCtrl); @@ -1615,7 +1302,7 @@ void CheckNextNotConnectedChannel() all_rcb_info = (ALL_RCB_INFO *)chk_calloc(1, sizeof (ALL_RCB_INFO)); all_rcb_info->rpt_typeids = &g_rpt_typeids; - //assert(chnl_usr->net_info->user_info == NULL); + if (chnl_usr->net_info->user_info != NULL) { echo_warn("chnl_usr->net_info->user_info is not NULL\n"); } @@ -1623,8 +1310,7 @@ void CheckNextNotConnectedChannel() chnl_usr->net_info->user_info = all_rcb_info; chnl_usr->chnl->ied->status = STATUS_NORMAL; chnl_usr->chnl->status = STATUS_NORMAL; - //prcess_ied_comm_2_json(chnl_usr->chnl->ied,STATUS_NORMAL); - //RDB_SetIedChnlStatus(chnl_usr->chnl->ied, STATUS_NORMAL, chnl_usr->chnl_id); + { char comm_str[256]; memset(comm_str,0,256); @@ -1642,17 +1328,11 @@ void CheckNextNotConnectedChannel() } else {// solaris 9 224 - //printf("check error90 !!!!!!!!!!!!!!\n"); + int secsSince = (int)(sGetMsTime() - chnl_usr->m_StartConnectingTime)/1000 ; - //cout<<"reqCtrl->result == FAIL, Since StartConnecting "<GetIP()<<" !!! "<chnl->ied->usr_ext; - if (g_node_id == STAT_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID) { - //lnk202411-4 - //connectlog_pgsql(ied_usr->terminal_code);//ʧ - //printf("check error89 !!!!!!!!!!!!!!\n"); - //connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(sGetMsTime()),0);//0ʧ - //printf("check error88 !!!!!!!!!!!!!!\n"); - } + printf( "reqCtrl->result == FAIL, Since StartConnecting %i sec ,channel IP %s:%d \n",secsSince,chnl_usr->ip_str,chnl_usr->chnl->port); mvl_free_req_ctrl(chnl_usr->m_reqCtrl); chnl_usr->m_reqCtrl = NULL; @@ -1662,17 +1342,12 @@ void CheckNextNotConnectedChannel() } } else - {// - //printf("check error61 !!!!!!!!!!!!!!\n"); - if ( (sGetMsTime() - chnl_usr->m_StartConnectingTime) > 300*1000 ) //300*1000 ) //wait 300 secs ????? + { + + if ( (sGetMsTime() - chnl_usr->m_StartConnectingTime) > 300*1000 ) //300*1000 ) //wait 300 secs { ied_usr_t* ied_usr = (ied_usr_t*)chnl_usr->chnl->ied->usr_ext; - if (g_node_id == STAT_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID) { - //connectlog_pgsql(ied_usr->terminal_code);//reqCtrl->doneδɣʱ5 - //lnk202411-4 - //connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(sGetMsTime()),0);//0ʧ - } - //cout<GetIP()<<" reqCtrl->done == SD_false but time over 300 secs, close channel !!!"<doneδ,but time over 300 secs, close channel IP %s,NetInfo= %x ",chnl_usr->ip_str,chnl_usr->net_info); if (chnl_usr->net_info->req_pend_list) { echo_warn("reqCtrl->doneδ,but time over 300 secs!!!!!!!!\n"); @@ -1680,94 +1355,60 @@ void CheckNextNotConnectedChannel() chnl_usr->m_reqCtrl = NULL; } mms_release_connection(chnl_usr->net_info); - //mvl_free_req_ctrl(chnl_usr->m_reqCtrl); //??? + chnl_usr->net_info->rem_vmd = NULL; chnl_usr->m_state = CHANNEL_DISCONNECTED; chnl_usr->m_ClosedMsTime = sGetMsTime(); - //if(chnl_usr->chnl->ied->id==virtual_ied){ - // chnl_usr->m_state = CHANNEL_CONNECTED; - // chnl_usr->chnl->ied->status = STATUS_NORMAL; - // chnl_usr->chnl->status = STATUS_NORMAL; - // //Special_CPU_Set(chnl_usr->chnl->ied, STATUS_NORMAL); - // //RDB_SetIedChnlStatus(chnl_usr->chnl->ied, STATUS_NORMAL,0); - //} + } } - } //if(pChannel->m_state == CHANNEL_CONNECTING) + } else if(chnl_usr->m_state == CHANNEL_DISCONNECTED) { - // - //printf("check error99 !!!!!!!!!!!!!!\n"); if ( (sGetMsTime() - chnl_usr->m_ClosedMsTime) > NEXT_CONNECT_TIME ) //wait 10 secs { - // - //printf("check error98 !!!!!!!!!!!!!!\n"); - ST_RET ret; ST_CHAR serverARName[32]; ied_usr_t *ied_usr = (ied_usr_t*)chnl_usr->chnl->ied->usr_ext; apr_snprintf(serverARName,sizeof(serverARName),"%s:%d",chnl_usr->ip_str,chnl_usr->chnl->port); if (chnl_usr->chnl->ied->cpucount != NULL && chnl_usr->chnl->ied->cpucount > 0 && ied_usr->dev_flag == ENABLE) {//2023-09-26 czy line count<0 Ҫ//lnk20250121նЧ ret = mms_connectToServer(ied_usr->dev_key, ied_usr->dev_series, serverARName, &(chnl_usr->net_info), &(chnl_usr->m_reqCtrl)); - //printf("check error73 !!!!!!!!!!!!!!\n"); + if (ret == SD_SUCCESS) { - //printf("check error74 !!!!!!!!!!!!!!\n"); - //if(chnl_usr->chnl->ied->id==virtual_ied){ - // chnl_usr->m_state = CHANNEL_CONNECTED; - // chnl_usr->chnl->ied->status = STATUS_NORMAL; - // chnl_usr->chnl->status = STATUS_NORMAL; - // //Special_CPU_Set(chnl_usr->chnl->ied, STATUS_NORMAL); - // //RDB_SetIedChnlStatus(chnl_usr->chnl->ied, STATUS_NORMAL,0); - // return; - //} - //echo_warn3("!!!!!!!!!!!!!!!!!!!!!!!!! %s:%d %x \n", chnl_usr->ip_str, chnl_usr->chnl->port, chnl_usr->net_info); + echo_msg3("mms_connectToServer IP %s:%d ,NetInfo= %x \n", chnl_usr->ip_str, chnl_usr->chnl->port, chnl_usr->net_info); chnl_usr->m_state = CHANNEL_CONNECTING; chnl_usr->m_StartConnectingTime = sGetMsTime(); - //RDB_SetIedChnlStatus(chnl_usr->chnl->ied, STATUS_NOINIT, chnl_usr->chnl_id); - //write_status_to_db(0,chnl_usr->chnl->addr); - //lnk202411-1ӣûӳɹ - //connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(sGetMsTime()),1); } else { - // - //printf("check error97 !!!!!!!!!!!!!!\n"); + chnl_usr->m_ClosedMsTime = sGetMsTime(); - if (g_node_id == STAT_DATA_BASE_NODE_ID || g_node_id == NEW_HIS_DATA_BASE_NODE_ID) { - //lnk202411-4 - //connectlog_pgsql(ied_usr->terminal_code);//ʧ - // - //printf("check error96 !!!!!!!!!!!!!!\n"); - //connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(sGetMsTime()),0);//ʧ״̬ûиı䲻Ҫ20250312 - //printf("check error95 !!!!!!!!!!!!!!\n"); - } + echo_warn3("FAILED: mms_connectToServer IP %s:%d ,NetInfo= %x \n", chnl_usr->ip_str, chnl_usr->chnl->port, chnl_usr->net_info); } } } - }//if(pChannel->m_state == CHANNEL_DISCONNECTED) - else if(chnl_usr->m_state == CHANNEL_DISCONNECTING) //need check timeout?᲻Զͣ??? + } + else if(chnl_usr->m_state == CHANNEL_DISCONNECTING) //need check timeout?᲻Զͣ { - //printf("check error92 !!!!!!!!!!!!!!\n"); + MVL_REQ_PEND* reqCtrl= chnl_usr->m_reqCtrl ; if( reqCtrl->done == SD_TRUE) { - //printf("check error72 !!!!!!!!!!!!!!\n"); - //cout<GetIP()<<" CHANNEL_DISCONNECTING done"<ip_str,chnl_usr->chnl->port,chnl_usr->net_info); mvl_free_req_ctrl(chnl_usr->m_reqCtrl); if(chnl_usr->net_info) chnl_usr->net_info->user_ext = NULL; - //NetInfo_Channel_Map.remove(chnl_usr->net_info); - //cout<<"CHANNEL_DISCONNECTING done NetInfo_Channel_Map.entries()= "<m_reqCtrl = NULL; chnl_usr->net_info = NULL; chnl_usr->m_state = CHANNEL_DISCONNECTED; @@ -1779,18 +1420,17 @@ void CheckNextNotConnectedChannel() } else - {// - //printf("check error70 !!!!!!!!!!!!!!\n"); - // cout<GetIP()<<" CHANNEL_DISCONNECTING waiting ..."<ip_str,chnl_usr->net_info); if ( (sGetMsTime() - chnl_usr->m_StartDisconnectingTime) > 30*1000 ) // //wait 30 secs ????? { - //cout<GetIP()<<"CHANNEL_DISCONNECTING reqCtrl->done == SD_false but time over 180 secs, close channel !!!"<doneδ,but time over 180 secs, close channel IP %s,NetInfo= %x ",chnl_usr->ip_str,chnl_usr->net_info); mvl_free_req_ctrl(chnl_usr->m_reqCtrl); chnl_usr->net_info->user_ext = NULL; - //NetInfo_Channel_Map.remove(chnl_usr->net_info); + mms_release_connection(chnl_usr->net_info); chnl_usr->net_info->rem_vmd = NULL; chnl_usr->m_reqCtrl = NULL; @@ -1803,16 +1443,10 @@ void CheckNextNotConnectedChannel() connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0); } } - }//if(pChannel->m_state == CHANNEL_DISCONNECTING) - ////////////////// - //printf("check error77 !!!!!!!!!!!!!!\n"); + } } -//////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////*********ؿƲ**********//////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// - - static ST_RET Read_Named_Var(LD_info_t *LD_info,chnl_usr_t *chnl_usr,char* VarName,ST_INT type_id, ST_VOID *dataDest, ST_INT timeOut) { ST_RET ret= SD_FAILURE; @@ -1866,12 +1500,10 @@ static ST_RET Write_Named_Var(LD_info_t *LD_info,chnl_usr_t *chnl_usr,char* VarN int pt61850_write_cn_file(chnl_usr_t *chnl_usr, ied_t *ied, char *rem_filename, char *only_filename_ret) { int ret ; -// ticks_t ticks; + char loc_filename[128], loc_file_fullname[256], rem_file_fullname[256],only_filename_str[256]; -// int result ;//= FILE_NAME_UNIQUE; -// uint8_t cpuNo =0; + char *only_filename,*the_full_file; -// ied_usr_t *ied_usr = GET_IEDEXT_ADDR(ied); memset(loc_filename,0,sizeof(loc_filename)); memset(only_filename_str,0,sizeof(only_filename_str) ); @@ -1965,7 +1597,6 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info ) //WW 2023-11-01¼κַƥ޸Ϊintfltnumƥ ret2 = parse_file_names_by_fltnum(LD_info->FltNum[i], ldstr, filenames, filenum, &cfg_idx, &dat_idx, file_base_name, file_yyyymm); - //ret2 = parse_file_names(file_match_str,filenames,filenum,&cfg_idx,&dat_idx,file_base_name,file_yyyymm); //WW 2023-11-01 end if (ret2 !=APR_SUCCESS) return ret2; @@ -1979,9 +1610,7 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info ) if (ret2==SD_SUCCESS && ret3==SD_SUCCESS ) { //ļд QVVR_t *qvvr; //̬¼ long long start_tm,trig_tm,end_tm; - //char ftp_filename[256]; - //doCommService(); - //memset(ftp_filename,0,256); + ret2 = extract_timestamp_from_cfg_file(filenames[cfg_idx],&start_tm,&trig_tm);//ȡļĿʼʱʹʱ printf(">>>>>>>> extract_timestamp_from_cfg_file end \n"); if (ret2 ==APR_SUCCESS) { @@ -2001,8 +1630,6 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info ) char linux_cmd[256] = {0}; printf(">>>>>>>> qvvr ok end \n"); apr_snprintf(linux_cmd,sizeof(linux_cmd),"./sftp_upload %s %s/%04d",cfg_only_filename_ret,file_yyyymm,LD_info->line_id);//ûʹ - //printf("\n>>>>>> %s ...... \n",linux_cmd); - //system(linux_cmd); char loc_file_fullname_cfg[256];//ļ memset(loc_file_fullname_cfg, 0, sizeof(loc_file_fullname_cfg)); @@ -2041,8 +1668,6 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info ) } apr_snprintf(linux_cmd,sizeof(linux_cmd),"./sftp_upload %s %s/%04d",dat_only_filename_ret,file_yyyymm,LD_info->line_id);//ͨsftpϴŷjsonȥ - //printf("\n>>>>>> %s ...... \n",linux_cmd); - //system(linux_cmd); char loc_file_fullname_dat[256]; memset(loc_file_fullname_dat, 0, sizeof(loc_file_fullname_dat)); diff --git a/mms/mmscli_log.c b/mms/mmscli_log.c index b162fcb..6acf5cd 100644 --- a/mms/mmscli_log.c +++ b/mms/mmscli_log.c @@ -73,28 +73,22 @@ static ST_VOID log_var_jou_data (ST_INT var_type_id,VAR_ACC_DATA *var ,MMS_DECOD ST_INT data_size; /* size of data element */ type_ctrl = mvl_type_ctrl_find (var_type_id); - //char doname[32]; - //strcpy(doname, dom_name); - //type_ctrl = (MVL_TYPE_CTRL*)(sel_mvl_type_ctrl(doname)); - //printf ("\naddress: %p \n", type_ctrl); + if (type_ctrl) { num_rt = type_ctrl->num_rt; rt = type_ctrl->rt; data_size = type_ctrl->data_size; - //printf ("\nTYPE: %d %d %d\n", num_rt, data_size, rt->el_size); - /* If the TDL produced is longer than max_tdl_len, this function */ - /* "gracefully" fails (i.e. returns 0). */ + if (ms_runtime_to_tdl (rt, num_rt, tdl_buf, sizeof(tdl_buf))>0) - ;//SLOGCALWAYS1 (" TYPE: %s", tdl_buf); + ; else echo_warn (" TYPE: unknown"); - //printf("\nrt %p and rt_num: %d \n", &type_ctrl->rt,type_ctrl->num_rt); - //printf ("\nTYPE: %s \n", tdl_buf); + va_data_size = data_size; temp_data_buf = (ST_CHAR*)malloc( va_data_size); rc = ms_asn1_to_local (rt, num_rt, var->data, var->len, temp_data_buf); - //printf("type_ctrl->num_rt %d %x %x \n", type_ctrl->num_rt , &data, &(var->data)); + my_local_to_data (temp_data_buf,rt,num_rt, data); if (data->item_num==0) { echo_warn("!!!!!!!!!!!!!!!!!!!data num is 0 !!!!!!!!!!!!!!!!\n"); @@ -151,8 +145,7 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, do_name = strstr(jou_entry->ef.data.list_of_var[j].var_tag, "/"); do_name++; } - //printf("do_name =====%s=====\n", do_name); - //start = sGetMsTime(); + printf("\nbrf if"); if (sel_mvl_type_ctrl_flag(do_name) == -1) { @@ -162,20 +155,13 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, char doname[32]; strcpy(doname, do_name); add_mvl_type_ctrl(doname, var_type_id); - //printf("create var_type_id =====%d=====%p======\n", var_type_id, &doname); + } printf("\nbrf var_type_id"); var_type_id = sel_mvl_type_ctrl_flag(do_name); printf("\nafter var_type_id"); - //end = sGetMsTime(); - //last_check_recall_config_time = last_check_recall_config_time + end - start; - //printf("jou_entry->ef.data.num_of_var =====%d===== =====%d=====\n", jou_entry->ef.data.num_of_var, var_type_id); - /*var_type_id = mms_var_type_id_create(clientNetInfo, DOM_SPEC, - dom_name, do_name, iTimeout);*/ - //printf("var_type_id =====%d=====\n", var_type_id); if (var_type_id < 0) { - //return SD_FAILURE; continue; } log_var_jou_data(var_type_id,&(jou_entry->ef.data.list_of_var[j].value_spec),&mms_dec_data, do_name); @@ -336,10 +322,10 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, v = (double)mms_dec_data.data_item[ii].u.data_uint64; else if (mms_dec_data.data_item[ii].type==DATA_DOUBLE_TYPE) v = mms_dec_data.data_item[ii].u.data_double; - //printf("%s %s = %f \n",jou_entry->ef.data.list_of_var[j].var_tag, mms_dec_data.data_item[ii].comp_name,v); + apr_snprintf(mms_ref,sizeof(mms_ref),"%s$%s",do_name,mms_dec_data.data_item[ii].comp_name); if ( (strstr(mms_ref,"]")==NULL) || (strstr(mms_ref,"0]")) ) - //printf("\nlog read: %s=%f\n",mms_ref,v); + if (j==0 && ii==0) { printf("\n ----------------------------------------------------------------log read: %s=%f--------------------------------------------------------------\n",mms_ref,v); if ( strstr(mms_ref,"QVVR") ) { @@ -356,31 +342,22 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, } if ( ( (loginfo->need_steady==0) &&(log_data_type == STEADY_DATA)) || ( (loginfo->need_voltage==0) &&(log_data_type != STEADY_DATA)) ){ - //mvl_type_id_destroy(var_type_id); return SD_SUCCESS; } if ( log_data_type == QVVR_DATA ) { processQVVR_start(loginfo->LD_info); - //processQVVR_time(loginfo->LD_info,t/1000); } else if ( log_data_type == RDRE_DATA ) { processRDRE_start(loginfo->LD_info); } else { - /*ied_t* ied; - ied = find_ied_from_dev_code(loginfo->LD_info->terminal_code); - ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext; - json_block_create_start( loginfo->LD_info->voltage_level, loginfo->LD_info->mp_id,0, ied_usr->dev_type);*/ - //json_block_create_time(loginfo->LD_info->line_id,t/1000); } } //set_db_value(LOG_IDX,mms_ref,v,FALSE); length_FCDA = strlen( mms_ref ); if ( ('$'==mms_ref[length_FCDA-2]) && ('q'==mms_ref[length_FCDA-1]) ) { - //lnk20250307 - //printf("going q"); if(not_set_log_q_this && ( log_data_type == STEADY_DATA )) { int quality = 0; @@ -400,7 +377,6 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, printf("quality = 1 continue"); continue; } - //set_log_QualityFlag(quality); if (log_data_steady_type == 0) { json_block_create_flag(loginfo->LD_info->mp_id, quality, 0); } @@ -415,9 +391,6 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, } else if ( ('$'==mms_ref[length_FCDA-2]) && ('t'==mms_ref[length_FCDA-1]) ) { - //lnk20250307 - //printf("going t"); - if (not_set_log_t_this) { apr_time_t t = convert_btime6_to_apr_time(&(mms_dec_data.data_item[ii].u.data_bTime6)); if ( log_data_type == QVVR_DATA ) { @@ -445,8 +418,6 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, } } else { - //lnk20250307 - //printf("going v"); if ( log_data_type == QVVR_DATA ){ processQVVR_data(loginfo->LD_info,mms_ref,v); @@ -471,7 +442,6 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, } - //mvl_type_id_destroy(var_type_id); } printf("\naft for"); if ( log_data_type == QVVR_DATA ) { @@ -481,10 +451,9 @@ static ST_RET process_jou_entry(loginfo_t *loginfo,apr_time_t t, processRDRE_end(loginfo->LD_info); } else { - //json_block_create_end(loginfo->LD_info->mp_id,0); + } printf("\nend process_jou_entry"); - //printf("process_jou_entry ==============%.2f================\n", last_check_recall_config_time); return ret; } @@ -550,7 +519,7 @@ ST_RET mms_jread (loginfo_t *loginfo,MVL_NET_INFO *clientNetInfo, ST_CHAR *dom_n int cpuno = 0; chnl_usr = g_pt61850app->chnl_usr[i]; - //printf("\n chnl_usr->m_state ===== %d\n", chnl_usr->m_state); + if (strstr(chnl_usr->ip_str, ip) != NULL) { printf("\nSame Ip %s : %s", chnl_usr->ip_str, ip); @@ -614,25 +583,21 @@ ST_RET mms_jread (loginfo_t *loginfo,MVL_NET_INFO *clientNetInfo, ST_CHAR *dom_n if( (last_occur_time.day!=jou_entry->occur_time.day)||(last_occur_time.ms!=jou_entry->occur_time.ms) ) { last_occur_time=jou_entry->occur_time; - //append_db_records(LOG_IDX); + } printf("\nbrf convert_btod_to_apr_time"); t = convert_btod_to_apr_time(&jou_entry->occur_time); - //set_log_TimeID(convert_btod_to_apr_time(&jou_entry->occur_time)); + if (jou_entry->entry_form_tag == 2) { printf("\nbrf jou_entry->ef.data.list_of_var_pres"); if (jou_entry->ef.data.list_of_var_pres) { - //for (j = 0; j < jou_entry->ef.data.num_of_var; j++) - //{ - // printf ("\n Var # %d: var_tag = %s", j, jou_entry->ef.data.list_of_var[j].var_tag); - // printf ("\n Var # %d: value_spec.len = %d", j,jou_entry->ef.data.list_of_var[j].value_spec.len); - //} + start = sGetMsTime(); printf("\nbrf process_jou_entry"); process_jou_entry(loginfo,t,jou_entry, clientNetInfo, dom_name, iTimeout) ; - //start = sGetMsTime(); + if ( jread_resp->more_follows == 0 && ((i + 1) == jread_resp->num_of_jou_entry)) { printf("\njread_resp->more_follows == 0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); //lnk2024-8-16ӽ߲ @@ -650,14 +615,11 @@ ST_RET mms_jread (loginfo_t *loginfo,MVL_NET_INFO *clientNetInfo, ST_CHAR *dom_n end = sGetMsTime(); } last_check_recall_config_time = last_check_recall_config_time + end - start; - //printf("jread_resp->more_follows = 0 ==============%.2f================\n", last_check_recall_config_time); } else { printf ("\n annotation = %s", jou_entry->ef.annotation); } - //apr_time_exp_t newTime; - //apr_time_exp_gmt(&newTime, t); printf("\nstart timecheck"); apr_time_exp_t newTime; apr_time_exp_gmt(&newTime, process_jou_entry_t); @@ -677,10 +639,6 @@ ST_RET mms_jread (loginfo_t *loginfo,MVL_NET_INFO *clientNetInfo, ST_CHAR *dom_n } mvl_free_req_ctrl (reqCtrl); /* CRITICAL: */ } while (more_follows); - //mvl_type_id_destroy(1); - //del_mvl_type_ctrl(); - //printf("do while ==============%.2f================\n", last_check_recall_config_time); - //append_db_records(LOG_IDX); return (ret); } diff --git a/mms/rdb_client.c b/mms/rdb_client.c index 2bb97c7..802765a 100644 --- a/mms/rdb_client.c +++ b/mms/rdb_client.c @@ -25,17 +25,17 @@ extern int g_front_seg_num; #include "../include/rocketmq/SimpleProducer.h" #include "../cfg_parse/custom_printf.h"//lnk20250225 + //////////////////////////////////////////// #ifdef DEBUG_SISCO SD_CONST static ST_CHAR* SD_CONST thisFileName = __FILE__; #endif extern RPT_TYPEIDS g_rpt_typeids; -//ied_info_t *my_info; extern apr_pool_t* g_root_pool; uint8_t set_mx_q; -//rdb_t *g_rdb = NULL; + node_t* g_node = NULL; extern char g_my_conf_fname[256]; apr_pool_t* g_init_pool; @@ -51,19 +51,10 @@ uint8_t set_mx_q; pt61850app_t* g_pt61850app; -//application_t g_sysfile_app; //ϵͳļӦϢṹ -//int g_sysfile_appid = -1; -//char *g_sysfile_filedir; -//byte_t g_Master; -//byte_t g_protect_file; //0:ٻ¼ļ 1:ٻ¼ļ -//apr_time_t g_file_valid_time; //ֻٻָʱеļӣ -//byte_t g_file_name_len; //ļ洢󳤶ȣĬΪ40Ϊ0ʱʾⳤ -//byte_t g_file_time_from; //ļЧʱȡֵδ0ļ1ȡϵͳʱ static void* APR_THREAD_FUNC rtdb_worker(apr_thread_t* thd, void* data); static apr_status_t pt61850app_init(); -//static apr_status_t app_process_command(command_t *cmd); /////////////////////////////////////////////////////////////////////////////// extern int three_secs_enabled; @@ -145,7 +136,7 @@ static apr_status_t read_DEV_idx_from_db() for (iedno = 0; iedno < g_node->n_clients; iedno++) { ied = g_node->clients[iedno]; ied_usr = GET_IEDEXT_ADDR(ied); - //read_DEV_Index_from_db(ied->channel[0].addr, &ied_usr->dev_idx); + for (cpuno = 0; cpuno < ied->cpucount; cpuno++) { LD_info = &(ied_usr->LD_info[cpuno]); if (LD_info->LD_name == NULL) @@ -153,12 +144,12 @@ static apr_status_t read_DEV_idx_from_db() len = strlen(LD_info->LD_name); tmp = LD_info->LD_name[len - 1] - '0'; LD_info->line_id = ied_usr->dev_idx * 10 + tmp; - //ret = read_line_infos_from_db(LD_info->line_id, &LD_info->SubV_Index,&LD_info->Dev_Index,&LD_info->Sub_Index,&LD_info->GD_Index); + if (ret != TRUE) LD_info->line_id = -1; if (LD_info->loginfo) { loginfo = LD_info->loginfo[0]; - //read_updatetime_from_db(ied->channel[0].addr, &loginfo->start_time); + } } } @@ -168,7 +159,7 @@ static apr_status_t read_DEV_idx_from_db() apr_status_t init_rdb() { apr_status_t rv; - // driver_t* driver; + rv = apr_pool_create(&g_init_pool, g_root_pool); if (rv != APR_SUCCESS) { return rv; @@ -186,50 +177,28 @@ apr_status_t init_rdb() if (rv != APR_SUCCESS) { return rv; } - //my_info = apr_pcalloc(g_run_pool,sizeof(ied_info_t)); + rv = pt61850app_init(); if (rv != APR_SUCCESS) { return rv; } - /*rv = parse_json_cfg(); - if ( rv != APR_SUCCESS) { - echo_errg("Failed to parse json define xml file! \n"); - return rv; - }*/ - init_config(); GetServerIndexFromDB(); -/*lnk10-10*/ - //Ӳwebӿ - //rv = parse_device_web_test_ext(); - //rv = parse_device_web_test_dev(); - //rv = parse_device_web_test_front_read(); - //rv = parse_device_web_test_front_write(); + rv = parse_device_cfg_web(); - //rv = parse_device_cfg(); - //rv = parse_device_cfg_json(); - //rv = parse_device_cfg_pg(); if (rv != APR_SUCCESS) { echo_errg("Parsed device config xml file with error,try to run! \n"); return rv; } -/*lnk10-10*/ - //rv = parse_line_cfg_web(); ϲն̨ - //rv = parse_line_cfg(); - //rv = parse_line_cfg_pg(); - - /*lnk10-10*/ rv = parse_model_cfg_web(); if (rv != APR_SUCCESS) { echo_errg("Parsed model with error,try to run! \n"); return rv; } - - //OTL_Select_xmlModel(); //xmlģݿȡ Set_xml_nodeinfo();//xmlģ rv = parse_rpt_log_ini();//ʼ @@ -253,7 +222,7 @@ apr_status_t run_protocol() { apr_status_t rv; apr_thread_t* rtdb_thread; - // apr_thread_t* mms_thread; + static apr_threadattr_t* worker_attr = NULL; //lnk20250214//ģʽ̺ͨ0ȡ̨ˣȻٸԼĽ̺ @@ -366,16 +335,6 @@ apr_status_t run_protocol() } -//lnkɾݿ߳ -#if 0 - if (1 == g_iOTLFlag) { - printf("try_start_sql_thread \n"); - try_start_sql_thread(); - } - else - printf("sql_thread ignore \n"); -#endif - printf("try_start_ontimer_thread \n"); try_start_ontimer_thread(); @@ -387,44 +346,23 @@ extern uint32_t g_thread_blocked_times; /*--------------------------- ʵʱ߳ -----------------------------------*/ static void* APR_THREAD_FUNC rtdb_worker(apr_thread_t* thd, void* data) { - // apr_event_t event; - // command_t cmd[1]; - // int i =0; - /* Maintenance the clients request */ while (1) { - //pthread_mutex_lock(&mtx); printf("work hold lock !!!!!!!!!!!"); - - // - //printf("check error4 !!!!!!!!!!!!!!\n"); - doCommService();//61850Ϣ check_3s_config();//3ݽ̶ȡ3봥 - //pthread_mutex_lock(&mtx); printf("check connect hold lock !!!!!!!!!!!"); CheckNextNotConnectedChannel();//гӽж״̬ - //pthread_mutex_unlock(&mtx); printf("check connect free lock !!!!!!!!!!!"); - //pthread_mutex_lock(&mtx); printf("check prt hold lock !!!!!!!!!!!"); CheckAllConnectedChannel();//桢־١ - //pthread_mutex_unlock(&mtx); printf("check prt free lock !!!!!!!!!!!"); - //check_recall_config();//ٽ̶ȡϢ create_recall_xml();//ɴxmlļ - pthread_mutex_lock(&mtx); //printf("work hold lock !!!!!!!!!!!"); - + pthread_mutex_lock(&mtx); check_ledger_update();//lnk20250113ȡ̨˸£̨˸ + pthread_mutex_unlock(&mtx); - pthread_mutex_unlock(&mtx); //printf("work free lock !!!!!!!!!!!"); - - //Check_Recall_Config(); - /*if ((g_protect_file) && (g_pt61850app->initNum>=MIN_INIT_NUM) ) { - tryCallWaveList_in_AllIeds(); - }*/ - //clear_old_comtrade_files(); check_disk_quota();//жϴ̿ռ apr_pool_clear(g_pt61850app->tmp_pool);//ʱ @@ -436,7 +374,6 @@ static void* APR_THREAD_FUNC rtdb_worker(apr_thread_t* thd, void* data) echo_msg("rtdb worker thread terminated..."); } -//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// void Set_val_from_61850rpt(element_t* elem, double v) @@ -453,7 +390,6 @@ int Set_q_from_61850rpt(char* q) else quality = 1; return quality; - //set_rpt_QualityFlag(quality); } #define TIME_T_2036 (66*365* SECONDS_PER_DAY) @@ -481,9 +417,6 @@ apr_time_t convert_btime6_to_apr_time(MMS_BTIME6* bTime6) return ticks; } - - - /* 61850 λ ֵ @@ -594,8 +527,3 @@ byte_t get_pulse_q_from_61850(char* q_61850) else return 0; } - - -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////// diff --git a/mms/rdb_client.h b/mms/rdb_client.h index 6c81d56..78cc670 100644 --- a/mms/rdb_client.h +++ b/mms/rdb_client.h @@ -445,7 +445,6 @@ int SendMessageToWeb(int socketClient, int iErrorCode); // void CheckAllConnectedChannel() ; void check_3s_config(); -void check_recall_config(); void create_recall_xml(); void check_disk_quota(); diff --git a/mms/rdb_ext_utils.c b/mms/rdb_ext_utils.c index 5c5d6fe..b36e720 100644 --- a/mms/rdb_ext_utils.c +++ b/mms/rdb_ext_utils.c @@ -549,15 +549,6 @@ void processQVVR_end(LD_info_t* LD_info) if ( (LD_info->qvvr[i].QVVR_type==0)||(LD_info->qvvr[i].QVVR_type==LD_info->qvvr[LD_info->qvvr_idx].QVVR_type) ) { long long end_tm = (long long)(LD_info->qvvr[LD_info->qvvr_idx].QVVR_PerTime*1000) + LD_info->qvvr[i].QVVR_time;//ʱdzʱĴʱ䣬 - // - //printf("~~~~~~~this qvvr node type before record is %d~~~~~~~~~~ \n",LD_info->qvvr[i].QVVR_type); - //printf("~~~~~~~this qvvr node QVVR_PerTime before record is %f~~~~~~~~~~ \n",LD_info->qvvr[i].QVVR_PerTime); - //printf("~~~~~~~this qvvr node QVVR_Amg before record is %f~~~~~~~~~~ \n",LD_info->qvvr[i].QVVR_Amg); - //printf("~~~~~~~this qvvr node QVVR_time before record is %lld~~~~~~~~~~ \n",LD_info->qvvr[i].QVVR_time); - //printf("~~~~~~~this qvvr node used_status before record is %d~~~~~~~~~~ \n",LD_info->qvvr[i].used_status); - //printf("~~~~~~~this qvvr node QVVR_start before record is %d~~~~~~~~~~ \n",LD_info->qvvr[i].QVVR_start); - //printf("~~~~~~~this qvvr node timestamp before record is %d~~~~~~~~~~ \n",LD_info->qvvr[i].timestamp); - printf("\n~~~~~~~now qvvr node type before record is %d~~~~~~~~~~ \n",LD_info->qvvr[LD_info->qvvr_idx].QVVR_type); printf("~~~~~~~now qvvr node QVVR_PerTime before record is %f~~~~~~~~~~ \n",LD_info->qvvr[LD_info->qvvr_idx].QVVR_PerTime); @@ -583,12 +574,6 @@ void processQVVR_end(LD_info_t* LD_info) printf("~~~~~~~this qvvr node timestamp before record is %d~~~~~~~~~~ \n",LD_info->qvvr[i].timestamp); printf("~~~~~~~this qvvr node QVVR_start before record is %d~~~~~~~~~~ \n",LD_info->qvvr[i].QVVR_start); - // - //printf("\n~~~~~~~qvvr node %d status is pair~~~~~~~~~~ \n",i); - //printf("Before calling: &QVVR_Amg = %p, &QVVR_PerTime = %p\n", - //&LD_info->qvvr[LD_info->qvvr_idx].QVVR_Amg, - //&LD_info->qvvr[LD_info->qvvr_idx].QVVR_PerTime); - //ƥٷqvvrʼʱҪ̬ʱ䣬ǵһ¼ʱֻʱûֵǸʱ ret = transfer_json_qvvr_data(g_node_id, //ûʹ LD_info->line_id, // diff --git a/set_debug.sh b/set_debug.sh new file mode 100644 index 0000000..98e808a --- /dev/null +++ b/set_debug.sh @@ -0,0 +1,166 @@ +#!/bin/bash + +# @file: set_debug.sh +# @brief: 启动或删除进程的脚本 +# @version: 1.0 +# @date: 2025/2/8 10:22:43 +# @author: lunankun + +# 设置日志文件路径 +LOGFILE="$FEP_ENV/dat/log/start_fe.log" + +# 输出当前时间并打印进程操作信息 +echo "" ; echo "" +echo "****** `date "+%F %R:%S"` start set_debug Processes ******" +echo "" >>"$LOGFILE" +echo "" >>"$LOGFILE" +echo "****** `date "+%F %R:%S"` start set_debug Processes ******" >>"$LOGFILE" + +# 函数检查并处理日志文件大小 +check_log_file() { + if [ -n "$1" ]; then + FILE_SIZE=0 + FILE_SIZE=$(du "$1" | awk '{print $1}') + + if [ $FILE_SIZE -ge 5120 ]; then + if [ -f "$1".3 ]; then + rm -f "$1".3 + fi + if [ -f "$1".2 ]; then + mv "$1".2 "$1".3 + fi + if [ -f "$1".1 ]; then + mv "$1".1 "$1".2 + fi + mv "$1" "$1".1 + fi + fi +} + +# 调用检查日志文件大小的函数 +check_log_file $LOGFILE + +# 定义查找并杀死进程的函数 +kill_process_by_pid() { + PID=$1 + if [ -n "$PID" ]; then + echo "Found process with PID: $PID" + echo "Killing process..." + kill -9 $PID + if [ $? -eq 0 ]; then + echo "Process with PID: $PID killed successfully." + else + echo "Failed to kill the process with PID: $PID." + fi + else + echo "Process not found." + fi +} + +# 启动进程的函数 +start_process() { + IP=$1 + TYPE=$2 + INDEX=$3 + + # 根据类型决定启动的进程 + if [ "$TYPE" == "stat" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_stat_data -a $IP -s 0_$INDEX" + elif [ "$TYPE" == "recall" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_recallhis_data -a $IP -s 0_$INDEX" + elif [ "$TYPE" == "comtrade" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_soe_comtrade -a $IP -s 0_$INDEX" + elif [ "$TYPE" == "3s" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_3s_data -a $IP -s 0_$INDEX" + else + echo "Invalid type: $TYPE. Supported types are stat, recall, comtrade, or 3s." + exit 1 + fi + + # 检查是否已经有相同的进程在运行 + PID=$(ps -ef | grep "$PROCESS_NAME" | grep -v "grep" | awk '{print $2}') + + if [ -n "$PID" ]; then + echo "Process '$PROCESS_NAME' already running with PID: $PID. Skipping start." + echo "Process '$PROCESS_NAME' already running with PID: $PID. Skipping start." >>"$LOGFILE" + else + # 启动进程并记录PID + echo "Starting process: $PROCESS_NAME" + $PROCESS_NAME & + sleep 1 + PID=$(ps -ef | grep "$PROCESS_NAME" | grep -v "grep" | awk '{print $2}') + echo "Started process with PID: $PID" + + # 记录日志 + echo "****** `date "+%F %R:%S"` Started process $PROCESS_NAME with PID: $PID" >>"$LOGFILE" + fi +} + +# 删除进程的函数 +delete_process() { + IP=$1 + TYPE=$2 + INDEX=$3 + + if [ "$TYPE" == "stat" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_stat_data -a $IP -s 0_$INDEX" + elif [ "$TYPE" == "recall" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_recallhis_data -a $IP -s 0_$INDEX" + elif [ "$TYPE" == "comtrade" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_soe_comtrade -a $IP -s 0_$INDEX" + elif [ "$TYPE" == "3s" ]; then + PROCESS_NAME="pt61850netd_pqfe -d cfg_3s_data -a $IP -s 0_$INDEX" + else + echo "Invalid type: $TYPE. Supported types are stat, recall, comtrade, or 3s." + exit 1 + fi + + # 查找进程并获取PID + PID=$(ps -ef | grep "$PROCESS_NAME" | grep -v "grep" | awk '{print $2}') + + # 如果找到进程,杀死它 + if [ -n "$PID" ]; then + kill_process_by_pid $PID + echo "****** `date "+%F %R:%S"` Deleted process $PROCESS_NAME with PID: $PID" >>"$LOGFILE" + else + echo "delete Process $PROCESS_NAME not found." + echo "delete Process $PROCESS_NAME not found." >>"$LOGFILE" + fi +} + +# 获取当前脚本的进程ID +CURRENT_PID=$$ + +# 检查是否有其他的脚本正在运行,排除当前脚本 +if pgrep -f "set_debug.sh" | grep -v "^$CURRENT_PID$" > /dev/null; then + echo "set_debug.sh is already running. Exiting..." + echo "set_debug.sh is already running. Exiting..." >>"$LOGFILE" + exit 1 +fi + +# 脚本应该等待3秒钟 +sleep 3 + +# 根据入参判断是 start 还是 delete +if [ "$1" == "start" ]; then + if [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then + echo "Usage: $0 start " + exit 1 + fi + start_process $2 $3 $4 +elif [ "$1" == "delete" ]; then + if [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then + echo "Usage: $0 delete " + exit 1 + fi + delete_process $2 $3 $4 +else + echo "Invalid option. Usage: $0 {start|delete} {IP} {stat|recall|comtrade|3s}" + exit 1 +fi + +# 获取当前时间并记录进程操作成功的日志 +DT=$(date "+%F %R:%S.%N") +echo "****** ${DT:0:23} set_debug Process operation completed successfully ******" +echo "" >>"$LOGFILE" +echo "****** ${DT:0:23} set_debug Process operation completed successfully ******" >>"$LOGFILE"