From 760dffe884d762b00e2298b86a1e71c85af374f4 Mon Sep 17 00:00:00 2001 From: lnk Date: Fri, 17 Jan 2025 17:10:18 +0800 Subject: [PATCH] modify for ledgerupdate --- cfg_parse/cfg_parser.cpp | 174 ++++++++++++++++++++++++++++- json/create_json.cpp | 24 +++- mms/db_interface.h | 1 + mms/mms_process.c | 231 ++++++++++++++++++++++++++++++++------- mms/rdb_client.h | 4 + 5 files changed, 386 insertions(+), 48 deletions(-) diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index efea5b4..404ab6e 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -187,7 +187,7 @@ QString THREE_SECS_CONFIG_FN = QString("Trigger3S.xml");//实时 QString RECALL_CONFIG_FN = QString("Recall.xml");//不用 //lnk20241220创建一个用来台账更新的文件,保证数据完整的情况下更新台账 -std::string LEDGER_UPDATE_FN = "LedgerUpdate.xml"; +std::string LEDGER_UPDATE_FN = "LedgerUpdate.log"; const int MAX_CPUNO = 10; @@ -12809,7 +12809,70 @@ int parse_model_cfg_web() return e.code; } } +////////////////////////////////////////////////////////////icd模型重构函数lnk20250116 +char* parse_model_cfg_web_one(ied_t* ied) +{ + std::vector codes;//入参集合 + QMap icd_model_map; + ied_usr_t* ied_usr; + ied_usr = (ied_usr_t*)ied->usr_ext; + + // 手动构建 JSON 字符串 + std::string input_jstr = "["; + input_jstr += "\"" + std::string(ied_usr->dev_type) + "\""; + input_jstr += "]"; // 结束 JSON 数组 + std::cout << "input_jstr: " << input_jstr << std::endl; // 输出结果 + + codes.push_back(input_jstr); //填入终端型号列表-获取指定的icd配置文件 + + parse_model_web(&icd_model_map,codes); + + codes.clear(); + + try { + char model_id[64]; + char tmnl_type[64]; + //char tmnl_factory[64]; + char file_name[128]; + char file_path[128]; + //char timestamp[64]; + otl_datetime timestamp;//不使用 + + // 遍历终端台账容器 + QMap::iterator it; + for (it = icd_model_map.begin(); it != icd_model_map.end(); ++it) { + icd_model* value = it.value(); + + // 确保 value 不为空 + if (value != nullptr) { + // 找到容器中对应名称并取值 + strncpy(model_id, value->model_id, sizeof(model_id) - 1); + strncpy(tmnl_type, value->tmnl_type, sizeof(tmnl_type) - 1); + strncpy(file_path, value->file_path, sizeof(file_path) - 1); + strncpy(file_name, value->file_name, sizeof(file_name) - 1); + //strncpy(timestamp, value->timestamp, sizeof(timestamp) - 1); + + std::cout << "model_id" << model_id << std::endl; + std::cout << "tmnl_type" << tmnl_type << std::endl; + std::cout << "filepath" << file_path << std::endl; + std::cout << "filename" << file_name << std::endl; + + //lnk20241125测试用 + //strncpy(tmnl_type, "PS_NET", sizeof(tmnl_type) - 1); + + Set_xml_databaseinfo(model_id, tmnl_type, file_path, file_name, timestamp.year, timestamp.month, timestamp.day, timestamp.hour, timestamp.minute, timestamp.second); + } + } + return model_id; + } + catch (otl_exception& e) + { + printf("\nicd model\"%s\"select error,ERROR code= %d,msg= %s \n", g_strOTLConnect.c_str(), e.code, e.msg); + return NULL; + } +} +//////////////////////////////////////////////////////////// //自动补招接口,暂不修改,可能不使用 #if 0 bool CheckPG_To_Recall_web(long long start, long long end, char* Monitorid) @@ -14265,15 +14328,116 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i return 0; } //3-写入台账内容/////////////////////////////////// - //4-配置映射文件////////////////////////////// - - //4-配置映射文件/////////////////////////////////// + //5-报告块初始化////////////////////////////// //5-报告块初始化/////////////////////////////////// //6-init_rem_dib_table////////////////////////////// //6-init_rem_dib_table/////////////////////////////////// - +////////////////////////////////////////////////////////////////////////台账更新记录日志 +// 获取当前时间并格式化为 "YYYY-MM-DD HH:MM:SS" +std::string get_current_time() { + std::time_t t = std::time(NULL); + struct std::tm tm = *std::localtime(&t); + char buffer[80]; + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm); + return std::string(buffer); +} + +// 写入日志条目 +void write_log_entry(std::ofstream &log_file, const std::string &action, const std::string &terminal_id, const std::string ¤t_time) { + log_file << terminal_id << "\t" << action << "time:" << current_time << "\n"; +} + +// 创建台账日志 +void create_ledger_log(trigger_update_xml_t* ledger_update_xml) { + std::string log_filename = "../etc/" + std::string(LEDGER_UPDATE_FN); + std::ofstream log_file(log_filename.c_str(), std::ios::app); // 以追加模式打开文件 + + if (!log_file.is_open()) { + std::cerr << "Failed to open log file: " << log_filename << std::endl; + return; + } + + std::vector > new_entries; // 用于存储new的terminal_id和时间 + std::vector > modify_entries; // 用于存储modify的terminal_id和时间 + std::vector > delete_entries; // 用于存储delete的terminal_id和时间 + + std::string current_time = get_current_time(); // 获取当前时间 + + // 处理 new_updates + for (int i = 0; i < ledger_update_xml->new_update_num; ++i) { + std::string terminal_id = ledger_update_xml->new_updates[i].terminal_id; + new_entries.push_back(std::make_pair(terminal_id, current_time)); + } + + // 处理 modify_updates + for (int i = 0; i < ledger_update_xml->modify_update_num; ++i) { + std::string terminal_id = ledger_update_xml->modify_updates[i].terminal_id; + modify_entries.push_back(std::make_pair(terminal_id, current_time)); + } + + // 处理 delete_updates + for (int i = 0; i < ledger_update_xml->delete_update_num; ++i) { + std::string terminal_id = ledger_update_xml->delete_updates[i].terminal_id; + delete_entries.push_back(std::make_pair(terminal_id, current_time)); + } + + // 写入日志文件 + if (!new_entries.empty()) { + log_file << "\n"; + for (size_t i = 0; i < new_entries.size(); ++i) { + write_log_entry(log_file, "add", new_entries[i].first, new_entries[i].second); + } + log_file << "\n"; + } + + if (!modify_entries.empty()) { + log_file << "\n"; + for (size_t i = 0; i < modify_entries.size(); ++i) { + write_log_entry(log_file, "modify", modify_entries[i].first, modify_entries[i].second); + } + log_file << "\n"; + } + + if (!delete_entries.empty()) { + log_file << "\n"; + for (size_t i = 0; i < delete_entries.size(); ++i) { + write_log_entry(log_file, "delete", delete_entries[i].first, delete_entries[i].second); + } + log_file << "\n"; + } + + log_file.close(); + std::cout << "Ledger log has been updated." << std::endl; +} +/////////////////////////////////////////////////////////////////////////// +// 清空 ied_usr_t 结构体内容的函数 +void clear_ied_usr(ied_t* ied) { + if (ied && ied->usr_ext) { // 检查 usr_ext 是否为 NULL + ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext; + + // 清空字符串成员 + memset(ied_usr->dev_type, 0, sizeof(ied_usr->dev_type)); + memset(ied_usr->dev_key, 0, sizeof(ied_usr->dev_key)); + memset(ied_usr->dev_series, 0, sizeof(ied_usr->dev_series)); + memset(ied_usr->terminal_id, 0, sizeof(ied_usr->terminal_id)); + memset(ied_usr->org_name, 0, sizeof(ied_usr->org_name)); + memset(ied_usr->maint_name, 0, sizeof(ied_usr->maint_name)); + memset(ied_usr->station_name, 0, sizeof(ied_usr->station_name)); + memset(ied_usr->tmnl_factory, 0, sizeof(ied_usr->tmnl_factory)); + memset(ied_usr->tmnl_status, 0, sizeof(ied_usr->tmnl_status)); + memset(ied_usr->terminal_code, 0, sizeof(ied_usr->terminal_code)); + + // 清空数值类型的成员 + ied_usr->dev_idx = 0; + ied_usr->dev_flag = 0; + ied_usr->cookie = NULL; + ied_usr->last_call_wavelist_time = 0; + ied_usr->time = 0; + ied_usr->update_flag = 0; + } +} /*封装C可调用的台账更新函数 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/json/create_json.cpp b/json/create_json.cpp index 2df16e1..bdb1c8f 100644 --- a/json/create_json.cpp +++ b/json/create_json.cpp @@ -19,6 +19,7 @@ #include "mms_json_inter.h" //json头文件 #include "../mms/db_interface.h" //json头文件 +#include "../mms/rdb_client.h" //台账更新引用接口 //lnk20241031用于上传和下载文件 #include "../json/cjson.h" @@ -2895,9 +2896,9 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char //调试用lnk20241125 cout << "setxmldatabase:" << TMNL_TYPE << endl; - if (!xmlinfo_list.contains(type)) + if (!xmlinfo_list.contains(type))//在终端类型列表中查找 { - Xmldata* config = new Xmldata(); + Xmldata* config = new Xmldata(); //没找到就插个新的终端类型到列表中 xmlinfo_list.insert(type, config); //调试用lnk20241125 @@ -2909,7 +2910,7 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char cout << "xmlinfo_list type contain:" << type.toStdString() << endl; QDateTime time(QDate(year, month, day), QTime(hour, minute, second)); - if (xmlinfo_list[type]->xmlbase.datetime == time) { + if (xmlinfo_list[type]->xmlbase.datetime == time) { //终端型号更新标志,如果新增的型号错误,导致实际用的映射文件不一样,或者覆盖了原来的映射文件这里可能出问题。数据库在录入型号和映射文件时要注意 xmlinfo_list[type]->updataflag = false; } else { @@ -3571,3 +3572,20 @@ void comflag_test() } ///////////////////////////////////////////////////lnk2024-10-21//////////////////////////////////////////////////////// + //4-配置映射文件////////////////////////////// +void Set_xml_nodeinfo_one(char* dev_type) +{ + bool ret = false; + if(xmlinfo_list[QString::fromUtf8(dev_type)] != NULL){ + ret = ParseXMLConfig2(&(xmlinfo_list[QString::fromUtf8(dev_type)]->xmlcfg), &(xmlinfo_list[QString::fromUtf8(dev_type)]->topicList), xmlinfo_list[QString::fromUtf8(dev_type)]->xmlbase.MODEL_ID); + if(!ret) + { + std::cout << "!!!! this ledger xml config fail!!!!" << std::endl; + } + } + else{ + std::cout << "xmlinfo_list not contain this devtype" << std::endl; + } + +} + //4-配置映射文件/////////////////////////////////// diff --git a/mms/db_interface.h b/mms/db_interface.h index 10be391..72bd8b5 100644 --- a/mms/db_interface.h +++ b/mms/db_interface.h @@ -206,6 +206,7 @@ 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); diff --git a/mms/mms_process.c b/mms/mms_process.c index 7b183d8..3ee14b5 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -793,15 +793,14 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml) int update_num; ied_t *ied; LD_info_t *LD_info; - int need_write_file; int new_in_work_found; ied_usr_t* ied_usr; - chnl_usr_t* chnl_usr; + int chnl_no; + chnl_usr_t *chnl_usr = NULL; printf("!!!start update ledger!!!\n"); - need_write_file = FALSE; //写入台账更新记录文件 update = ledger_update_xml->new_updates; //处理新增台账部分 update_num = ledger_update_xml->new_update_num; printf("add ledger num:%d\n",update_num); @@ -877,11 +876,33 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml) //3-写入台账内容////////////////////////////// int ret = update_one_terminal_ledger(update,i,ied,g_node->n_clients); - + if(ret){ + printf("ledger can not be update!!!!!quit process!!!!!\n"); + return 0; + } //3-写入台账内容/////////////////////////////////// //4-配置映射文件////////////////////////////// - + char model[64] = {0}; + // 获取模型ID,检查是否返回 NULL + char* model_id = parse_model_cfg_web_one(ied);//存储在/FeProject/dat/ + + if (model_id != NULL) { + // 安全拷贝字符串到 model 数组 + strncpy(model, model_id, sizeof(model) - 1); + model[sizeof(model) - 1] = '\0'; // 确保以 null 结尾 + printf("ledger Model ID: %s\n", model); + } else { + printf("ledger No model ID found.\n"); + } + char full_path[128]; + snprintf(full_path, sizeof(full_path), "/FeProject/dat/%s.xml", model); // 拼接路径 + + // 打印模型路径 + printf("ledger icd config file full path: %s\n", full_path); + + //映射文件解析 + Set_xml_nodeinfo_one(ied_usr->dev_type); //4-配置映射文件/////////////////////////////////// //5-报告块初始化////////////////////////////// @@ -893,42 +914,169 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml) //6-init_rem_dib_table/////////////////////////////////// } - need_write_file = TRUE;//需要将新增的台账写到台账更新记录文件中 } -////////////////////////////////////////////////////////////////////////////// - /*trigger = trigger_3s_xml->delete_triggers; //如果没有delete这里就是0 - trigger_num = trigger_3s_xml->delete_trigger_num; - for (i=0; iwork_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 ) { - clear_rpt_counter_by_trigger(trigger_work); - trigger_work->dev_idx = INVALID_DEV_IDX; - } - } - need_write_file = TRUE; - } -////////////////////////////////////////////////////////////////////////////// - trigger = trigger_3s_xml->modify_triggers; //如果没有modify这里就是0 - trigger_num = trigger_3s_xml->modify_trigger_num; - for (i=0; iwork_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]; - clear_rpt_counter_by_trigger(trigger_work); - } - } - need_write_file = TRUE; - } -/////////////////////////////////////////////////////////////////////////////// - trigger = trigger_3s_xml->work_triggers; //文件的work块 - trigger_num = trigger_3s_xml->work_trigger_num; - if (need_write_file) - create_3s_xml(trigger_3s_xml); //写入文件的work块*/ +//////////////////////////////////////////////////////////////////////////////modify + update = ledger_update_xml->modify_updates; //处理新增台账部分 + update_num = ledger_update_xml->modify_updates_num; + printf("modify ledger num:%d\n",update_num); + for (i=0; ichncount; chnl_no++) { + chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect; + if (chnl_usr->m_state!=CHANNEL_CONNECTED){ + continue; + } + closeChannel(chnl_usr);//关闭更新台账后,任务会自动连接 + } + + //更新数据///////////////////////////////////////////////////////////////////////////////// + //3-写入台账内容////////////////////////////// + ied_usr = ied->usr_ext; + int ret = update_one_terminal_ledger(update,i,ied,ied_usr->dev_idx); + if(ret){ + printf("ledger can not be update!!!!!quit process!!!!!\n"); + return 0; + } + //3-写入台账内容//////////////////////////////////////////// + + //4-配置映射文件/////////////////////////////////////////// + char model[64] = {0}; + // 获取模型ID,检查是否返回 NULL + char* model_id = parse_model_cfg_web_one(ied);//存储在/FeProject/dat/ + + if (model_id != NULL) { + // 安全拷贝字符串到 model 数组 + strncpy(model, model_id, sizeof(model) - 1); + model[sizeof(model) - 1] = '\0'; // 确保以 null 结尾 + printf("ledger Model ID: %s\n", model); + } else { + printf("ledger No model ID found.\n"); + } + char full_path[128]; + snprintf(full_path, sizeof(full_path), "/FeProject/dat/%s.xml", model); // 拼接路径 + + // 打印模型路径 + printf("ledger icd config file full path: %s\n", full_path); + + //映射文件解析 + Set_xml_nodeinfo_one(ied_usr->dev_type); + //4-配置映射文件/////////////////////////////////// + + //5-报告块初始化////////////////////////////// + + //5-报告块初始化/////////////////////////////////// + + //6-init_rem_dib_table////////////////////////////// + + //6-init_rem_dib_table/////////////////////////////////// + //更新数据////////////////////////////////////////////////////////////////////// + } + } + + if (!new_in_work_found){ + printf("modify_updates can not find ied!!!!!!\n"); + } + } +///////////////////////////////////////////////////////////////////////////////delete + update = ledger_update_xml->delete_updates; //处理新增台账部分 + update_num = ledger_update_xml->delete_updates_num; + printf("delete ledger num:%d\n",update_num); + for (i=0; ichncount; chnl_no++) { + chnl_usr = (chnl_usr_t*)ied->channel[chnl_no].connect; + if (chnl_usr->m_state!=CHANNEL_CONNECTED){ //跳过没连接的 + continue; + } + closeChannel(chnl_usr);//关闭更新台账后,任务会自动连接 + } + + //更新数据////////////////////////////////////////////////////////////////////// + //3-删除台账内容////////////////////////////// + + // 假设要删除 g_node->clients 中的某个 ied,index 为删除的索引 + int index_to_remove = 0; + ied_t* ied_find = NULL; + int iedno; + ied_usr_t* ied_usr_find = NULL; + ied_usr = (ied_usr_t*)ied->usr_ext; + for (iedno = 0; iedno < g_node->n_clients; iedno++) { + ied_find = g_node->clients[iedno]; + ied_usr_find = (ied_usr_t*)ied_find->usr_ext; + if (ied_usr_find && strcmp(ied_usr_find->terminal_id, ied_usr->terminal_id) == 0) { + index_to_remove = iedno; + break; //找到退出 + } + } + + clear_ied_usr(ied); //台账数据部分清空 + + // 先清理要删除的 ied 的内存 + ied_t* ied_to_remove = g_node->clients[index_to_remove]; + memset(ied_to_remove, 0, sizeof(ied_t)); + + // 释放 ied_usr 结构体的内存(如果有) + if (ied_to_remove->usr_ext) { + apr_pool_clear(g_init_pool); // 如果你使用的是同一个内存池,清理它 + } + + // 移动指针数组中的元素 + for (int i = index_to_remove; i < g_node->n_clients - 1; i++) { + g_node->clients[i] = g_node->clients[i + 1]; + } + + // 重新分配内存以调整指针数组的大小 + ied_t** new_clients = (ied_t**)apr_pcalloc(g_cfg_pool, (g_node->n_clients - 1) * sizeof(ied_t*)); + memcpy(new_clients, g_node->clients, (g_node->n_clients - 1) * sizeof(ied_t*)); + + // 更新指针数组和台账数量 + g_node->clients = new_clients; + g_node->n_clients--; + + //3-删除台账内容/////////////////////////////////// + + //4-配置映射文件////////////////////////////// + //映射文件保留 + //4-配置映射文件/////////////////////////////////// + + //5-报告块////////////////////////////// + + //5-报告块/////////////////////////////////// + + //6-init_rem_dib_table////////////////////////////// + + //6-init_rem_dib_table/////////////////////////////////// + //更新数据////////////////////////////////////////////////////////////////////// + } + } + + if (!new_in_work_found) { + printf("modify_updates can not find ied!!!!!!\n"); + } + } +////////////////////////////////////////////////////////////////////////////// + if (ledger_update_xml->modify_update_num || ledger_update_xml->new_update_num || ledger_update_xml->delete_update_num){ + create_ledger_log(ledger_update_xml); //写入文件 + } + } - //台账更新调试打印函数 // 检查字符串是否为空 // 检查字符串是否为空 @@ -1021,12 +1169,15 @@ void check_ledger_update()//lnk20250113 last_check_3s_config_time = now; //记录本次运行时间 //判断是否满足执行条件,一个文件就是一个终端,读取文件后删除文件 - while (APR_SUCCESS==parse_ledger_update_xml(&trigger_ledger_update_xml)){ //处理台账更新文件,如果有可以更新或者添加台账的 + if (APR_SUCCESS==parse_ledger_update_xml(&trigger_ledger_update_xml)){ //处理台账更新文件,如果有可以更新或者添加台账的 + //调试用 print_trigger_update_xml(&trigger_ledger_update_xml); + //处理台账更新加台账锁lnk20250114 pthread_mutex_lock(&mtx); - process_ledger_update(&trigger_ledger_update_xml); //台账更新 + process_ledger_update(&trigger_ledger_update_xml); //台账更新 pthread_mutex_unlock(&mtx); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/mms/rdb_client.h b/mms/rdb_client.h index 600eb62..78ef36a 100644 --- a/mms/rdb_client.h +++ b/mms/rdb_client.h @@ -468,6 +468,10 @@ extern bool isCharPtrEmpty(const char* str); extern int parse_ledger_update_xml(trigger_update_xml_t* trigger_update_xml); extern int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index); extern void print_trigger_update_xml(const trigger_update_xml_t* trigger_update); +extern char* parse_model_cfg_web_one(ied_t* ied); +extern void Set_xml_nodeinfo_one(char* dev_type); +extern void create_ledger_log(trigger_update_xml_t* ledger_update_xml); +extern void clear_ied_usr(ied_t* ied); //////////////////////////////// int parse_3s_xml(trigger_3s_xml_t* trigger_3s_xml); int create_3s_xml(trigger_3s_xml_t* trigger_3s_xml);