diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index 07e25a0..f947daf 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -3433,6 +3433,153 @@ static bool is_pqdif_com_type(const char* com_type) return type.compare("PQDIF", Qt::CaseInsensitive) == 0; } +static const char* PQDIF_CONFIG_DIR = "/FeProject/etc"; +static const char* PQDIF_CONFIG_FILE = "/FeProject/etc/pqdif-config.xml"; +static const char* PQDIF_CONFIG_TMP_FILE = "/FeProject/etc/pqdif-config.xml.tmp"; + +static bool pqdif_config_value_valid(const char* value) +{ + if (value == NULL) + return false; + + QString text = QString::fromLocal8Bit(value).trimmed(); + return !text.isEmpty() && text.compare("N/A", Qt::CaseInsensitive) != 0; +} + +static int pqdif_config_write_begin(QFile& file, QXmlStreamWriter& writer) +{ + if (!QDir().mkpath(PQDIF_CONFIG_DIR)) { + printf("[PQDIF][CONFIG] mkdir failed: %s\n", PQDIF_CONFIG_DIR); + return APR_EGENERAL; + } + + QFile::remove(PQDIF_CONFIG_TMP_FILE); + file.setFileName(PQDIF_CONFIG_TMP_FILE); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { + printf("[PQDIF][CONFIG] open tmp failed: %s, err=%s\n", + PQDIF_CONFIG_TMP_FILE, + file.errorString().toLocal8Bit().constData()); + return APR_EGENERAL; + } + + // Always write a complete temporary XML first. Java only reads the + // final file after the tmp file has been closed and atomically renamed. + writer.setDevice(&file); + writer.setAutoFormatting(true); + writer.setCodec("UTF-8"); + writer.writeStartDocument("1.0"); + writer.writeStartElement("PqdifConfig"); + return APR_SUCCESS; +} + +static int pqdif_config_write_commit(QFile& file, QXmlStreamWriter& writer) +{ + writer.writeEndElement(); + writer.writeEndDocument(); + file.flush(); + file.close(); + + if (::rename(PQDIF_CONFIG_TMP_FILE, PQDIF_CONFIG_FILE) != 0) { + printf("[PQDIF][CONFIG] rename %s to %s failed\n", + PQDIF_CONFIG_TMP_FILE, + PQDIF_CONFIG_FILE); + QFile::remove(PQDIF_CONFIG_TMP_FILE); + return APR_EGENERAL; + } + + return APR_SUCCESS; +} + +static void pqdif_config_write_abort(QFile& file) +{ + if (file.isOpen()) + file.close(); + QFile::remove(PQDIF_CONFIG_TMP_FILE); +} + +static void pqdif_config_write_point(QXmlStreamWriter& writer, const LD_info_t* LD_info) +{ + writer.writeEmptyElement("Point"); + writer.writeAttribute("pointNo", QString::number((int)LD_info->cpuno)); + writer.writeAttribute("monitorId", QString::fromLocal8Bit(LD_info->mp_id).trimmed()); +} + +static int pqdif_config_write_device(QXmlStreamWriter& writer, + ied_t* ied, + ied_usr_t* ied_usr) +{ + writer.writeStartElement("Device"); + writer.writeAttribute("ip", QString::fromLocal8Bit(ied->channel[0].addr_str).trimmed()); + writer.writeAttribute("pqdifType", QString::fromLocal8Bit(ied_usr->dev_type).trimmed()); + + int point_count = 0; + if (ied_usr->LD_info != NULL) { + for (int cpuno = 0; cpuno < ied->cpucount; ++cpuno) { + LD_info_t* LD_info = &(ied_usr->LD_info[cpuno]); + if (LD_info->read_flag != ENABLE) + continue; + if (LD_info->cpuno == 0 || !pqdif_config_value_valid(LD_info->mp_id)) + continue; + + pqdif_config_write_point(writer, LD_info); + ++point_count; + } + } + + writer.writeEndElement(); + return point_count; +} + +int pqdif_rebuild_config_from_current_ledger() +{ + if (!is_cfg_pqdif_process()) + return APR_SUCCESS; + + QFile file; + QXmlStreamWriter writer; + int write_count = 0; + int point_count = 0; + + if (pqdif_config_write_begin(file, writer) != APR_SUCCESS) + return APR_EGENERAL; + + if (g_node != NULL && g_node->clients != NULL) { + for (int i = 0; i < g_node->n_clients; ++i) { + ied_t* ied = g_node->clients[i]; + if (ied == NULL || ied->usr_ext == NULL || ied->chncount <= 0 || ied->channel == NULL) + continue; + + ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext; + if (ied_usr->dev_flag != ENABLE) + continue; + if (!is_pqdif_com_type(ied_usr->com_type)) + continue; + if (!pqdif_config_value_valid(ied->channel[0].addr_str) || + !pqdif_config_value_valid(ied_usr->dev_type)) { + printf("[PQDIF][CONFIG] skip invalid ledger, terminal=%s ip=%s type=%s\n", + ied_usr->terminal_id, + ied->channel[0].addr_str, + ied_usr->dev_type); + continue; + } + + point_count += pqdif_config_write_device(writer, ied, ied_usr); + ++write_count; + } + } + + if (pqdif_config_write_commit(file, writer) != APR_SUCCESS) { + pqdif_config_write_abort(file); + return APR_EGENERAL; + } + + printf("[PQDIF][CONFIG] rebuild success, file=%s, devices=%d, points=%d\n", + PQDIF_CONFIG_FILE, + write_count, + point_count); + return APR_SUCCESS; +} + static bool terminal_should_bind_to_current_process(const terminal_dev* dev) { if (dev == NULL) @@ -4782,6 +4929,9 @@ int parse_device_cfg_web() cout << "dev init create count:" << count_real; + if (pqdif_rebuild_config_from_current_ledger() != APR_SUCCESS) + return APR_EGENERAL; + return APR_SUCCESS; } catch (...) diff --git a/mms/mms_process.c b/mms/mms_process.c index ee7d0b6..f74a7f5 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -1446,6 +1446,11 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml) ////////////////////////////////////////////////////////////////////////////// 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); //写入文件 + if (g_node_id == PQDIF_DATA_BASE_NODE_ID) { + if (pqdif_rebuild_config_from_current_ledger() != APR_SUCCESS) { + printf("[PQDIF][CONFIG] rebuild pqdif-config.xml failed after ledger update\n"); + } + } } } diff --git a/mms/rdb_client.h b/mms/rdb_client.h index c0c0ce3..41500a5 100644 --- a/mms/rdb_client.h +++ b/mms/rdb_client.h @@ -503,6 +503,7 @@ int stringToInt(const char* str, int* result); bool isCharPtrEmpty(const char* str); int parse_ledger_update_xml(trigger_update_xml_t* trigger_update_xml); int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_index,int ied_take); +int pqdif_rebuild_config_from_current_ledger(); void print_trigger_update_xml(const trigger_update_xml_t* trigger_update); char* parse_model_cfg_web_one(ied_t* ied,char* out_model); void Set_xml_nodeinfo_one(char* dev_type);