5 Commits

Author SHA1 Message Date
lnk
9f74ada894 pqdif进程跳过xml和报告初始化 2026-07-20 16:29:23 +08:00
lnk
86dc51d066 添加单点补招pqdif文件的逻辑 2026-07-17 16:25:44 +08:00
lnk
abc5f9e735 添加pqdif处理函数 2026-07-17 15:58:19 +08:00
lnk
0e2ade351c 台账更新添加comtype 2026-07-17 13:57:45 +08:00
lnk
fe16beb188 初始化添加pqdif判断,新增pqdif进程 2026-07-17 11:15:16 +08:00
11 changed files with 791 additions and 38 deletions

View File

@@ -156,6 +156,7 @@ public:
char dev_type[64]; char dev_type[64];
char dev_key[255]; char dev_key[255];
char dev_series[255]; char dev_series[255];
char com_type[32];
char addr_str[64]; char addr_str[64];
char port[64]; char port[64];
char timestamp[64]; char timestamp[64];
@@ -860,6 +861,9 @@ void init_config() {
else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波 else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波
TEST_PORT = TEST_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index; TEST_PORT = TEST_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index;
} }
else if (g_node_id == PQDIF_DATA_BASE_NODE_ID) {
TEST_PORT = TEST_PORT + PQDIF_DATA_BASE_NODE_ID + g_front_seg_index;
}
} }
@@ -1700,6 +1704,8 @@ void add_terminal_to_trigger_update(trigger_update_xml_t* trigger_update_xml, co
} }
} }
static bool terminal_update_should_bind_to_current_process(const terminal* dev);
// 解析 XML 数据并提取 terminal 信息 // 解析 XML 数据并提取 terminal 信息
void parse_terminal_from_data(trigger_update_xml_t* trigger_update_xml, const std::string& str_tag, const std::string& data,const std::string& guid_value) { void parse_terminal_from_data(trigger_update_xml_t* trigger_update_xml, const std::string& str_tag, const std::string& data,const std::string& guid_value) {
terminal work_terminal = {}; // 创建新的 terminal 对象 terminal work_terminal = {}; // 创建新的 terminal 对象
@@ -1715,6 +1721,13 @@ void parse_terminal_from_data(trigger_update_xml_t* trigger_update_xml, const st
strcpy(work_terminal.dev_type, extract_value(data, "devType").c_str()); strcpy(work_terminal.dev_type, extract_value(data, "devType").c_str());
strcpy(work_terminal.dev_key, extract_value(data, "devKey").c_str()); strcpy(work_terminal.dev_key, extract_value(data, "devKey").c_str());
strcpy(work_terminal.dev_series, extract_value(data, "series").c_str()); strcpy(work_terminal.dev_series, extract_value(data, "series").c_str());
std::string com_type = extract_value(data, "comType");
if (com_type.empty())
com_type = extract_value(data, "com_type");
if (com_type.empty())
com_type = "MMS";
strncpy(work_terminal.com_type, com_type.c_str(), sizeof(work_terminal.com_type) - 1);
work_terminal.com_type[sizeof(work_terminal.com_type) - 1] = '\0';
strcpy(work_terminal.processNo, extract_value(data, "processNo").c_str()); strcpy(work_terminal.processNo, extract_value(data, "processNo").c_str());
strcpy(work_terminal.addr_str, extract_value(data, "ip").c_str()); strcpy(work_terminal.addr_str, extract_value(data, "ip").c_str());
strcpy(work_terminal.port, extract_value(data, "port").c_str()); strcpy(work_terminal.port, extract_value(data, "port").c_str());
@@ -1801,6 +1814,13 @@ void parse_terminal_from_data(trigger_update_xml_t* trigger_update_xml, const st
// 根据 str_tag 将 terminal 添加到相应的数组 // 根据 str_tag 将 terminal 添加到相应的数组
if (!terminal_update_should_bind_to_current_process(&work_terminal)) {
std::cout << "skip ledger update xml by comType:" << work_terminal.com_type
<< " terminal:" << work_terminal.terminal_id
<< " process:" << subdir << g_front_seg_index << std::endl;
return;
}
add_terminal_to_trigger_update(trigger_update_xml, str_tag, work_terminal); add_terminal_to_trigger_update(trigger_update_xml, str_tag, work_terminal);
} }
@@ -1821,11 +1841,25 @@ void parse_ledger_update(trigger_update_xml_t* trigger_update_xml, const std::st
if (strTag == "delete") { if (strTag == "delete") {
// 填充终端信息 // 填充终端信息
strcpy(delete_terminal.terminal_id, extract_value(data, "id").c_str()); strcpy(delete_terminal.terminal_id, extract_value(data, "id").c_str());
std::string com_type = extract_value(data, "comType");
if (com_type.empty())
com_type = extract_value(data, "com_type");
if (com_type.empty())
com_type = "MMS";
strncpy(delete_terminal.com_type, com_type.c_str(), sizeof(delete_terminal.com_type) - 1);
delete_terminal.com_type[sizeof(delete_terminal.com_type) - 1] = '\0';
//添加guid20250506 //添加guid20250506
strncpy(delete_terminal.guid, guid_value.c_str(), sizeof(delete_terminal.guid) - 1); strncpy(delete_terminal.guid, guid_value.c_str(), sizeof(delete_terminal.guid) - 1);
delete_terminal.guid[sizeof(delete_terminal.guid) - 1] = '\0'; delete_terminal.guid[sizeof(delete_terminal.guid) - 1] = '\0';
if (!terminal_update_should_bind_to_current_process(&delete_terminal)) {
std::cout << "skip delete ledger update xml by comType:" << delete_terminal.com_type
<< " terminal:" << delete_terminal.terminal_id
<< " process:" << subdir << g_front_seg_index << std::endl;
return;
}
// 将删除信息写入 delete_updates // 将删除信息写入 delete_updates
std::cout << "delete ledger!!!!!"<<std::endl; std::cout << "delete ledger!!!!!"<<std::endl;
if (trigger_update_xml->delete_update_num < MAX_UPDATEA_NUM) { if (trigger_update_xml->delete_update_num < MAX_UPDATEA_NUM) {
@@ -3388,6 +3422,45 @@ void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::str
} }
// 打印 terminal_dev_map 中所有内容的函数 // 打印 terminal_dev_map 中所有内容的函数
static bool is_cfg_pqdif_process()
{
return std::strstr(subdir, "cfg_pqdif_data") != NULL;
}
static bool is_pqdif_com_type(const char* com_type)
{
QString type = com_type ? QString::fromLocal8Bit(com_type).trimmed() : QString();
return type.compare("PQDIF", Qt::CaseInsensitive) == 0;
}
static bool terminal_should_bind_to_current_process(const terminal_dev* dev)
{
if (dev == NULL)
return false;
if (is_pqdif_com_type(dev->com_type))
return is_cfg_pqdif_process();
if (is_cfg_pqdif_process())
return false;
return (atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0);
}
static bool terminal_update_should_bind_to_current_process(const terminal* dev)
{
if (dev == NULL)
return false;
if (is_pqdif_com_type(dev->com_type))
return is_cfg_pqdif_process();
if (is_cfg_pqdif_process())
return false;
return true;
}
void printTerminalDevMap(const QMap<QString, terminal_dev*>& terminal_dev_map) { void printTerminalDevMap(const QMap<QString, terminal_dev*>& terminal_dev_map) {
QMap<QString, terminal_dev*>::const_iterator it; QMap<QString, terminal_dev*>::const_iterator it;
for (it = terminal_dev_map.constBegin(); it != terminal_dev_map.constEnd(); ++it) { for (it = terminal_dev_map.constBegin(); it != terminal_dev_map.constEnd(); ++it) {
@@ -3406,6 +3479,7 @@ void printTerminalDevMap(const QMap<QString, terminal_dev*>& terminal_dev_map) {
<< ", Device Type:" << QString(dev->dev_type) << ", Device Type:" << QString(dev->dev_type)
<< ", Device Key:" << QString(dev->dev_key) << ", Device Key:" << QString(dev->dev_key)
<< ", Device Series:" << QString(dev->dev_series) << ", Device Series:" << QString(dev->dev_series)
<< ", Device comType:" << QString(dev->com_type)
<< ", Device processNo:" << QString(dev->processNo) << ", Device processNo:" << QString(dev->processNo)
<< ", Device maxProcessNum:" << QString(dev->maxProcessNum) << ", Device maxProcessNum:" << QString(dev->maxProcessNum)
<< ", Address:" << QString(dev->addr_str) << ", Address:" << QString(dev->addr_str)
@@ -3440,6 +3514,7 @@ void printLedger(const ied_usr_t& ied_usr) {
std::cout << "|-- dev_type: " << ied_usr.dev_type << std::endl; std::cout << "|-- dev_type: " << ied_usr.dev_type << std::endl;
std::cout << "|-- dev_key: " << ied_usr.dev_key << std::endl; std::cout << "|-- dev_key: " << ied_usr.dev_key << std::endl;
std::cout << "|-- dev_series: " << ied_usr.dev_series << std::endl; std::cout << "|-- dev_series: " << ied_usr.dev_series << std::endl;
std::cout << "|-- com_type: " << ied_usr.com_type << std::endl;
std::cout << "|-- dev_flag: " << ied_usr.dev_flag << std::endl; std::cout << "|-- dev_flag: " << ied_usr.dev_flag << std::endl;
std::cout << "|-- last_call_wavelist_time: " << ied_usr.last_call_wavelist_time << std::endl; std::cout << "|-- last_call_wavelist_time: " << ied_usr.last_call_wavelist_time << std::endl;
@@ -3534,6 +3609,7 @@ void printLedgerinshell(const ied_usr_t& ied_usr, QIODevice* outputDevice) {
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_type: " + QByteArray(ied_usr.dev_type) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_type: " + QByteArray(ied_usr.dev_type) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_key: " + QByteArray(ied_usr.dev_key) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_key: " + QByteArray(ied_usr.dev_key) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_series: " + QByteArray(ied_usr.dev_series) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_series: " + QByteArray(ied_usr.dev_series) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- com_type: " + QByteArray(ied_usr.com_type) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_processNo: " + QByteArray(ied_usr.processNo) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_processNo: " + QByteArray(ied_usr.processNo) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_flag: " + QByteArray::number(ied_usr.dev_flag) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write("|-- dev_flag: " + QByteArray::number(ied_usr.dev_flag) + "\n");
outputDevice->write("\r\x1B[K");outputDevice->write("|-- last_call_wavelist_time: " + QByteArray::number(ied_usr.last_call_wavelist_time) + "\n"); outputDevice->write("\r\x1B[K");outputDevice->write("|-- last_call_wavelist_time: " + QByteArray::number(ied_usr.last_call_wavelist_time) + "\n");
@@ -4085,6 +4161,13 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
else strncpy(dev->dev_series, "N/A", sizeof(dev->dev_series) - 1); else strncpy(dev->dev_series, "N/A", sizeof(dev->dev_series) - 1);
dev->dev_series[sizeof(dev->dev_series) - 1] = '\0'; dev->dev_series[sizeof(dev->dev_series) - 1] = '\0';
cJSON* comType = cJSON_GetObjectItem(item, "comType");
if (comType == NULL)
comType = cJSON_GetObjectItem(item, "com_type");
if (comType && comType->type == cJSON_String) strncpy(dev->com_type, comType->valuestring, sizeof(dev->com_type) - 1);
else strncpy(dev->com_type, "MMS", sizeof(dev->com_type) - 1);
dev->com_type[sizeof(dev->com_type) - 1] = '\0';
//lnk20250210台账进程号 //lnk20250210台账进程号
cJSON* processNo = cJSON_GetObjectItem(item, "processNo"); // processNo转为字符串 cJSON* processNo = cJSON_GetObjectItem(item, "processNo"); // processNo转为字符串
if (processNo && processNo->type == cJSON_Number) snprintf(dev->processNo, sizeof(dev->processNo), "%d", processNo->valueint); if (processNo && processNo->type == cJSON_Number) snprintf(dev->processNo, sizeof(dev->processNo), "%d", processNo->valueint);
@@ -4190,19 +4273,20 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
//lnk20260312防止内存泄漏 //lnk20260312防止内存泄漏
bool inserted = false; bool inserted = false;
bool should_bind = terminal_should_bind_to_current_process(dev);
// 检查是否存在重复键 // 检查是否存在重复键
if (terminal_dev_map->contains(key)) { if (terminal_dev_map->contains(key)) {
std::cerr << "Duplicate terminal_code found: " << key.toStdString() << std::endl; std::cerr << "Duplicate terminal_code found: " << key.toStdString() << std::endl;
// 删除旧的 terminal_dev 对象以避免内存泄漏 // 删除旧的 terminal_dev 对象以避免内存泄漏
delete terminal_dev_map->value(key); if (should_bind) delete terminal_dev_map->value(key);
// 移除旧的键值对 // 移除旧的键值对
terminal_dev_map->remove(key); if (should_bind) terminal_dev_map->remove(key);
// 插入新的 terminal_dev 对象 // 插入新的 terminal_dev 对象
if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号 if(should_bind){//lnk20250210匹配进程号
//调试用 //调试用
std::cout<< "process num match" << std::endl; std::cout<< "process num match" << std::endl;
terminal_dev_map->insert(key, dev); terminal_dev_map->insert(key, dev);
@@ -4210,7 +4294,7 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
}//后续修改为只有进程号匹配上index才录入当前进程 }//后续修改为只有进程号匹配上index才录入当前进程
} else { } else {
// 插入新的 terminal_dev 对象 // 插入新的 terminal_dev 对象
if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号 if(should_bind){//lnk20250210匹配进程号
//调试用 //调试用
std::cout<< "process num match" << std::endl; std::cout<< "process num match" << std::endl;
terminal_dev_map->insert(key, dev); terminal_dev_map->insert(key, dev);
@@ -4371,6 +4455,7 @@ int parse_device_cfg_web()
char dev_type[64]; char dev_type[64];
char dev_key[255]; char dev_key[255];
char dev_series[255]; char dev_series[255];
char com_type[32];
char addr_str[64]; char addr_str[64];
char port_char[64]; char port_char[64];
@@ -4400,6 +4485,8 @@ int parse_device_cfg_web()
strncpy(dev_type, value->dev_type, sizeof(dev_type) - 1); strncpy(dev_type, value->dev_type, sizeof(dev_type) - 1);
strncpy(dev_key, value->dev_key, sizeof(dev_key) - 1); strncpy(dev_key, value->dev_key, sizeof(dev_key) - 1);
strncpy(dev_series, value->dev_series, sizeof(dev_series) - 1); strncpy(dev_series, value->dev_series, sizeof(dev_series) - 1);
strncpy(com_type, value->com_type, sizeof(com_type) - 1);
com_type[sizeof(com_type) - 1] = '\0';
strncpy(addr_str, value->addr_str, sizeof(addr_str) - 1); strncpy(addr_str, value->addr_str, sizeof(addr_str) - 1);
strncpy(port_char, value->port, sizeof(port_char) - 1); strncpy(port_char, value->port, sizeof(port_char) - 1);
strncpy(processNo, value->processNo, sizeof(processNo) - 1);//进程号 strncpy(processNo, value->processNo, sizeof(processNo) - 1);//进程号
@@ -4465,6 +4552,14 @@ int parse_device_cfg_web()
cout << "ied_usr->dev_type:" << ied_usr->dev_type << endl; cout << "ied_usr->dev_type:" << ied_usr->dev_type << endl;
} }
//lnk20250210台账进程号 //lnk20250210台账进程号
if (com_type != NULL && com_type[0] != '\0') {
apr_snprintf(ied_usr->com_type, sizeof(ied_usr->com_type), "%s", com_type);//comType
cout << "ied_usr->com_type:" << ied_usr->com_type << endl;
}
else {
apr_snprintf(ied_usr->com_type, sizeof(ied_usr->com_type), "%s", "MMS");
cout << "ied_usr->com_type(default):" << ied_usr->com_type << endl;
}
if (processNo != NULL) { if (processNo != NULL) {
apr_snprintf(ied_usr->processNo, sizeof(ied_usr->processNo), "%s", processNo);//processNo apr_snprintf(ied_usr->processNo, sizeof(ied_usr->processNo), "%s", processNo);//processNo
cout << "ied_usr->processNo:" << ied_usr->processNo << endl; cout << "ied_usr->processNo:" << ied_usr->processNo << endl;
@@ -5734,6 +5829,13 @@ int update_one_terminal_ledger(terminal* update, int i,ied_t* ied,int terminal_i
apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", update[i].dev_type); apr_snprintf(ied_usr->dev_type, sizeof(ied_usr->dev_type), "%s", update[i].dev_type);
printf("ied_usr->dev_type: %s\n", ied_usr->dev_type); printf("ied_usr->dev_type: %s\n", ied_usr->dev_type);
} }
if (update[i].com_type != NULL && update[i].com_type[0] != '\0') {
apr_snprintf(ied_usr->com_type, sizeof(ied_usr->com_type), "%s", update[i].com_type);
printf("ied_usr->com_type: %s\n", ied_usr->com_type);
} else {
apr_snprintf(ied_usr->com_type, sizeof(ied_usr->com_type), "%s", "MMS");
printf("ied_usr->com_type (default): %s\n", ied_usr->com_type);
}
if (update[i].processNo != NULL) { if (update[i].processNo != NULL) {
apr_snprintf(ied_usr->processNo, sizeof(ied_usr->processNo), "%s", update[i].processNo); apr_snprintf(ied_usr->processNo, sizeof(ied_usr->processNo), "%s", update[i].processNo);
printf("ied_usr->processNo: %s\n", ied_usr->processNo); printf("ied_usr->processNo: %s\n", ied_usr->processNo);
@@ -6564,6 +6666,7 @@ void clearIedUsr(ied_usr_t *ied_usr) {
memset(ied_usr->dev_type, 0, sizeof(ied_usr->dev_type)); 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_key, 0, sizeof(ied_usr->dev_key));
memset(ied_usr->dev_series, 0, sizeof(ied_usr->dev_series)); memset(ied_usr->dev_series, 0, sizeof(ied_usr->dev_series));
memset(ied_usr->com_type, 0, sizeof(ied_usr->com_type));
memset(ied_usr->terminal_id, 0, sizeof(ied_usr->terminal_id)); 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->org_name, 0, sizeof(ied_usr->org_name));
memset(ied_usr->maint_name, 0, sizeof(ied_usr->maint_name)); memset(ied_usr->maint_name, 0, sizeof(ied_usr->maint_name));
@@ -7290,6 +7393,8 @@ const char* get_front_msg_from_subdir() {
return "实时数据进程"; return "实时数据进程";
else if (std::strstr(subdir, "cfg_soe_comtrade") != NULL) else if (std::strstr(subdir, "cfg_soe_comtrade") != NULL)
return "暂态和告警进程"; return "暂态和告警进程";
else if (std::strstr(subdir, "cfg_pqdif_data") != NULL)
return "pqdif处理进程";
else if (std::strstr(subdir, "cfg_recallhis_data") != NULL) else if (std::strstr(subdir, "cfg_recallhis_data") != NULL)
return "稳态补招进程"; return "稳态补招进程";
else if (std::strstr(subdir, "cfg_stat_data") != NULL) else if (std::strstr(subdir, "cfg_stat_data") != NULL)

View File

@@ -229,6 +229,8 @@ std::string get_front_type_from_subdir() {
return "realTime"; return "realTime";
else if (std::strstr(subdir, "cfg_soe_comtrade") != NULL) else if (std::strstr(subdir, "cfg_soe_comtrade") != NULL)
return "comtrade"; return "comtrade";
else if (std::strstr(subdir, "cfg_pqdif_data") != NULL)
return "PQDIF";
else if (std::strstr(subdir, "cfg_recallhis_data") != NULL) else if (std::strstr(subdir, "cfg_recallhis_data") != NULL)
return "recall"; return "recall";
else if (std::strstr(subdir, "cfg_stat_data") != NULL) else if (std::strstr(subdir, "cfg_stat_data") != NULL)

View File

@@ -26,6 +26,7 @@
#define THREE_SECS_DATA_BASE_NODE_ID 200 // 三秒数据、实时数据 #define THREE_SECS_DATA_BASE_NODE_ID 200 // 三秒数据、实时数据
#define SOE_COMTRADE_BASE_NODE_ID 300 // soe 录波 #define SOE_COMTRADE_BASE_NODE_ID 300 // soe 录波
#define HIS_DATA_BASE_NODE_ID 400 //历史、补招 #define HIS_DATA_BASE_NODE_ID 400 //历史、补招
#define PQDIF_DATA_BASE_NODE_ID 800 // pqdif数据
class json_block_data //json拼接参数类 class json_block_data //json拼接参数类
{ {

View File

@@ -271,6 +271,8 @@ void add_comm_log(char* log_str)
com_log_fn += "comm_300_comtrade.txt"; com_log_fn += "comm_300_comtrade.txt";
else if (g_node_id == HIS_DATA_BASE_NODE_ID) else if (g_node_id == HIS_DATA_BASE_NODE_ID)
com_log_fn += "comm_400_his.txt"; com_log_fn += "comm_400_his.txt";
else if (g_node_id == PQDIF_DATA_BASE_NODE_ID)
com_log_fn += "comm_800_pqdif.txt";
else if (g_node_id == NEW_HIS_DATA_BASE_NODE_ID) { else if (g_node_id == NEW_HIS_DATA_BASE_NODE_ID) {
com_log_fn.append(QString("comm_400_his_%1.txt").arg(g_front_seg_index)); com_log_fn.append(QString("comm_400_his_%1.txt").arg(g_front_seg_index));
} }
@@ -1194,6 +1196,48 @@ void add_indent(std::stringstream& stream, int level) {
} }
} }
static bool is_cfg_pqdif_process()
{
return std::strstr(subdir, "cfg_pqdif_data") != NULL;
}
static bool is_pqdif_com_type(const char* com_type)
{
QString type = com_type ? QString::fromLocal8Bit(com_type).trimmed() : QString();
return type.compare("PQDIF", Qt::CaseInsensitive) == 0;
}
static void fill_terminal_com_type(terminal* tmnl, cJSON* item)
{
if (tmnl == NULL)
return;
cJSON* comType = cJSON_GetObjectItem(item, "comType");
if (comType == NULL)
comType = cJSON_GetObjectItem(item, "com_type");
if (comType && comType->type == cJSON_String)
std::strncpy(tmnl->com_type, comType->valuestring, sizeof(tmnl->com_type) - 1);
else
std::strncpy(tmnl->com_type, "MMS", sizeof(tmnl->com_type) - 1);
tmnl->com_type[sizeof(tmnl->com_type) - 1] = '\0';
}
static bool terminal_update_should_write_file(const terminal* tmnl)
{
if (tmnl == NULL)
return false;
if (is_pqdif_com_type(tmnl->com_type))
return is_cfg_pqdif_process();
if (is_cfg_pqdif_process())
return false;
return true;
}
std::string prepare_update(const std::string& code_str, const terminal& json_data,const std::string& guid) //添加guid std::string prepare_update(const std::string& code_str, const terminal& json_data,const std::string& guid) //添加guid
{ {
std::cout << "prepare update" << std::endl; std::cout << "prepare update" << std::endl;
@@ -1265,6 +1309,9 @@ std::string prepare_update(const std::string& code_str, const terminal& json_dat
add_indent(xmlStream, indentLevel); add_indent(xmlStream, indentLevel);
xmlStream << "<series>" << json_data.dev_series << "</series>" << std::endl; xmlStream << "<series>" << json_data.dev_series << "</series>" << std::endl;
add_indent(xmlStream, indentLevel);
xmlStream << "<comType>" << (json_data.com_type[0] ? json_data.com_type : "MMS") << "</comType>" << std::endl;
//lnk20250210 //lnk20250210
add_indent(xmlStream, indentLevel); add_indent(xmlStream, indentLevel);
xmlStream << "<processNo>" << json_data.processNo << "</processNo>" << std::endl; xmlStream << "<processNo>" << json_data.processNo << "</processNo>" << std::endl;
@@ -1347,6 +1394,9 @@ std::string prepare_update(const std::string& code_str, const terminal& json_dat
add_indent(xmlStream, indentLevel); add_indent(xmlStream, indentLevel);
xmlStream << "<id>" << json_data.terminal_id << "</id>" << std::endl; xmlStream << "<id>" << json_data.terminal_id << "</id>" << std::endl;
add_indent(xmlStream, indentLevel);
xmlStream << "<comType>" << (json_data.com_type[0] ? json_data.com_type : "MMS") << "</comType>" << std::endl;
indentLevel--; indentLevel--;
add_indent(xmlStream, indentLevel); add_indent(xmlStream, indentLevel);
xmlStream << "</terminalData>" << std::endl; xmlStream << "</terminalData>" << std::endl;
@@ -1625,7 +1675,7 @@ int parse_control(const std::string& json_str, const std::string& output_dir) {
std::string guid = guidstr->valuestring; std::string guid = guidstr->valuestring;
//进程号为0的进程处理所有台账更新消息 //进程号为0的进程处理所有台账更新消息
if (process_No != g_front_seg_index && g_front_seg_index !=0) { if (!is_cfg_pqdif_process() && process_No != g_front_seg_index && g_front_seg_index !=0) {
std::cout << "msg index:"<< process_No <<"doesnt match self index:" << g_front_seg_index << std::endl; std::cout << "msg index:"<< process_No <<"doesnt match self index:" << g_front_seg_index << std::endl;
cJSON_Delete(messageBody); cJSON_Delete(messageBody);
cJSON_Delete(root); cJSON_Delete(root);
@@ -1654,6 +1704,7 @@ int parse_control(const std::string& json_str, const std::string& output_dir) {
cJSON* item = cJSON_GetArrayItem(data, i); cJSON* item = cJSON_GetArrayItem(data, i);
terminal json_data; terminal json_data;
memset(&json_data, 0, sizeof(json_data));
// 填充 terminal_dev 的数据 // 填充 terminal_dev 的数据
cJSON* id = cJSON_GetObjectItem(item, "id"); // terminal_id cJSON* id = cJSON_GetObjectItem(item, "id"); // terminal_id
if (id && id->type == cJSON_String) if (id && id->type == cJSON_String)
@@ -1715,6 +1766,8 @@ int parse_control(const std::string& json_str, const std::string& output_dir) {
else else
std::strncpy(json_data.dev_series, "N/A", sizeof(json_data.dev_series) - 1); std::strncpy(json_data.dev_series, "N/A", sizeof(json_data.dev_series) - 1);
fill_terminal_com_type(&json_data, item);
//lnk20250210台账进程号 //lnk20250210台账进程号
cJSON* processNo = cJSON_GetObjectItem(item, "processNo"); // processNo转为字符串 cJSON* processNo = cJSON_GetObjectItem(item, "processNo"); // processNo转为字符串
if (processNo && processNo->type == cJSON_Number) snprintf(json_data.processNo, sizeof(json_data.processNo), "%d", processNo->valueint); if (processNo && processNo->type == cJSON_Number) snprintf(json_data.processNo, sizeof(json_data.processNo), "%d", processNo->valueint);
@@ -1765,6 +1818,7 @@ int parse_control(const std::string& json_str, const std::string& output_dir) {
for (int j = 0; j < monitorData_size && j < 10; j++) { // 最多 10 个监测点 for (int j = 0; j < monitorData_size && j < 10; j++) { // 最多 10 个监测点
cJSON* monitor_item = cJSON_GetArrayItem(monitorData, j); cJSON* monitor_item = cJSON_GetArrayItem(monitorData, j);
monitor monitor_data; monitor monitor_data;
memset(&monitor_data, 0, sizeof(monitor_data));
cJSON* monitor_id = cJSON_GetObjectItem(monitor_item, "id"); // monitor_id cJSON* monitor_id = cJSON_GetObjectItem(monitor_item, "id"); // monitor_id
if (monitor_id && monitor_id->type == cJSON_String) if (monitor_id && monitor_id->type == cJSON_String)
@@ -1835,6 +1889,13 @@ int parse_control(const std::string& json_str, const std::string& output_dir) {
print_terminal(&json_data); print_terminal(&json_data);
if (!terminal_update_should_write_file(&json_data)) {
std::cout << "skip ledger update by comType:" << json_data.com_type
<< " terminal:" << json_data.terminal_id
<< " process:" << subdir << g_front_seg_index << std::endl;
continue;
}
// 准备 XML 内容并写入文件 // 准备 XML 内容并写入文件
std::string xmlContent = prepare_update(code_str, json_data,guid);//添加guid20250506 std::string xmlContent = prepare_update(code_str, json_data,guid);//添加guid20250506
if (xmlContent != "") { if (xmlContent != "") {
@@ -1868,7 +1929,17 @@ int parse_control(const std::string& json_str, const std::string& output_dir) {
cJSON* id = cJSON_GetObjectItem(item, "id"); cJSON* id = cJSON_GetObjectItem(item, "id");
if (id != nullptr) { if (id != nullptr) {
terminal json_data; terminal json_data;
memset(&json_data, 0, sizeof(json_data));
std::strncpy(json_data.terminal_id, cJSON_GetObjectItem(item, "id")->valuestring, sizeof(json_data.terminal_id) - 1); std::strncpy(json_data.terminal_id, cJSON_GetObjectItem(item, "id")->valuestring, sizeof(json_data.terminal_id) - 1);
fill_terminal_com_type(&json_data, item);
if (!terminal_update_should_write_file(&json_data)) {
std::cout << "skip delete ledger update by comType:" << json_data.com_type
<< " terminal:" << json_data.terminal_id
<< " process:" << subdir << g_front_seg_index << std::endl;
continue;
}
// 准备 XML 内容并写入文件 // 准备 XML 内容并写入文件
std::string xmlContent = prepare_update(code_str, json_data,guid);//添加guid20250506 std::string xmlContent = prepare_update(code_str, json_data,guid);//添加guid20250506
if(xmlContent != ""){ if(xmlContent != ""){

View File

@@ -688,6 +688,7 @@ struct terminal // 终端台账
char dev_type[64]; char dev_type[64];
char dev_key[255]; char dev_key[255];
char dev_series[255]; char dev_series[255];
char com_type[32];
char processNo[64]; //lnk20250210进程号 char processNo[64]; //lnk20250210进程号
char addr_str[64]; char addr_str[64];
char port[64]; char port[64];

View File

@@ -31,6 +31,7 @@
#define NEW_HIS_DATA_BASE_NODE_ID 500 #define NEW_HIS_DATA_BASE_NODE_ID 500
#define RECALL_HIS_DATA_BASE_NODE_ID 600 #define RECALL_HIS_DATA_BASE_NODE_ID 600
#define RECALL_ALL_DATA_BASE_NODE_ID 700 #define RECALL_ALL_DATA_BASE_NODE_ID 700
#define PQDIF_DATA_BASE_NODE_ID 800
#define REPORT_TYPE_STAT 1 #define REPORT_TYPE_STAT 1
#define REPORT_TYPE_REAL 2 #define REPORT_TYPE_REAL 2

View File

@@ -81,6 +81,8 @@ void init_global_function_enable()
three_secs_enabled = 1; three_secs_enabled = 1;
}else if (strcmp(subdir,"cfg_soe_comtrade")==0) { //告警和录波和暂态 }else if (strcmp(subdir,"cfg_soe_comtrade")==0) { //告警和录波和暂态
g_node_id = SOE_COMTRADE_BASE_NODE_ID; g_node_id = SOE_COMTRADE_BASE_NODE_ID;
}else if (strcmp(subdir,"cfg_pqdif_data")==0) {
g_node_id = PQDIF_DATA_BASE_NODE_ID;
}else if (strcmp(subdir,"cfg_his_data")==0) { //不使用 }else if (strcmp(subdir,"cfg_his_data")==0) { //不使用
g_node_id = RECALL_ALL_DATA_BASE_NODE_ID; g_node_id = RECALL_ALL_DATA_BASE_NODE_ID;
g_node_id = HIS_DATA_BASE_NODE_ID; g_node_id = HIS_DATA_BASE_NODE_ID;

View File

@@ -44,7 +44,13 @@ SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#ifdef _OS_UNIX_ #ifdef _OS_UNIX_
#include <sys/vfs.h> #include <sys/vfs.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif #endif
#include <ctype.h>
#include <errno.h>
#include <time.h>
extern uint32_t g_dead_lock_counter; extern uint32_t g_dead_lock_counter;
extern uint32_t g_thread_blocked_times; extern uint32_t g_thread_blocked_times;
@@ -95,6 +101,9 @@ static void format_time_ms(long long ms, char* buf, size_t buf_len){
tm_time.tm_sec, tm_time.tm_sec,
milli); milli);
} }
static apr_status_t ChannelCheckPQDIFFiles(chnl_usr_t *chnl_usr);
static apr_status_t ChannelRecallPQDIFFiles(chnl_usr_t *chnl_usr, LD_info_t *LD_info, long long start_sec, long long end_sec);
//lnk20250122start //lnk20250122start
apr_status_t init_rem_dib_table() apr_status_t init_rem_dib_table()
{ {
@@ -572,21 +581,28 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
LD_info_t *LD_info; LD_info_t *LD_info;
loginfo_t *loginfo = NULL; loginfo_t *loginfo = NULL;
int cpuno; int cpuno;
int is_pqdif_process;
double now; double now;
static double last_check_recall_config_time = 0.0; static double last_check_recall_config_time = 0.0;
ied = chnl_usr->chnl->ied; ied = chnl_usr->chnl->ied;
ied_usr = GET_IEDEXT_ADDR(ied); ied_usr = GET_IEDEXT_ADDR(ied);
is_pqdif_process = (g_node_id == PQDIF_DATA_BASE_NODE_ID);
for(cpuno=0 ; cpuno<ied->cpucount; cpuno++) { for(cpuno=0 ; cpuno<ied->cpucount; cpuno++) {
LD_info = &(ied_usr->LD_info[cpuno]); LD_info = &(ied_usr->LD_info[cpuno]);
//添加保护,防止台账中测点号不连续导致的崩溃 //添加保护,防止台账中测点号不连续导致的崩溃
if (LD_info->cpuno == 0 || if (LD_info->cpuno == 0 ||
LD_info->LD_name == NULL || LD_info->LD_name == NULL)
LD_info->logcount <= 0 || {
LD_info->loginfo == NULL) continue;
}
if (!is_pqdif_process &&
(LD_info->logcount <= 0 ||
LD_info->loginfo == NULL))
{ {
continue; continue;
} }
@@ -612,11 +628,13 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
continue; continue;
}*/ }*/
loginfo = LD_info->loginfo[0] ; if (!is_pqdif_process) {
loginfo = LD_info->loginfo[0] ;
//添加保护,防止台账中测点号不连续导致的崩溃 //添加保护,防止台账中测点号不连续导致的崩溃
if (loginfo == NULL || loginfo->LD_info == NULL) if (loginfo == NULL || loginfo->LD_info == NULL)
continue; continue;
}
apr_sleep(apr_time_from_sec(1) / 10); apr_sleep(apr_time_from_sec(1) / 10);
@@ -628,14 +646,17 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
int failed_count = 0; int failed_count = 0;
/////////////////////////////////////////////////////根据配置文件控制下发补招时间为北京时间还是utc时间 /////////////////////////////////////////////////////根据配置文件控制下发补招时间为北京时间还是utc时间
long long utc_or_beijing = 0;
if (!is_pqdif_process) {
printf("~~~~~~~this dev type is %s~~~~~~~",ied_usr->dev_type); printf("~~~~~~~this dev type is %s~~~~~~~",ied_usr->dev_type);
XmlConfigC cfg1; XmlConfigC cfg1;
memset(&cfg1,0,sizeof(cfg1));
if (get_xml_config_by_dev_type(ied_usr->dev_type, &cfg1)) { if (get_xml_config_by_dev_type(ied_usr->dev_type, &cfg1)) {
printf("ValueOfTimeUnit = %s\n", cfg1.ValueOfTimeUnit); printf("ValueOfTimeUnit = %s\n", cfg1.ValueOfTimeUnit);
} else { } else {
printf("读取失败,未找到 dev_type\n"); printf("读取失败,未找到 dev_type\n");
} }
long long utc_or_beijing; utc_or_beijing = 0;
if(strcmp(cfg1.ValueOfTimeUnit, "utc") == 0){//装置时间是utc还是北京 if(strcmp(cfg1.ValueOfTimeUnit, "utc") == 0){//装置时间是utc还是北京
utc_or_beijing = 28800;//秒 utc_or_beijing = 28800;//秒
@@ -646,6 +667,11 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s开始补招数据,注意!下发补招时间为beijing时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type); DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s开始补招数据,注意!下发补招时间为beijing时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type);
} }
}
else {
DIY_WARNLOG_CODE(LD_info->mp_id,2,LOG_CODE_RECALL,"[PQDIF][RECALL] monitor:%s - id:%s start recall PQDIF files, dev_type:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type);
}
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
//记录本次补招的时间范围 //记录本次补招的时间范围
long long min_start_sec = LLONG_MAX; long long min_start_sec = LLONG_MAX;
@@ -666,6 +692,9 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
LD_info->autorecallflag = 1;//正在补招 LD_info->autorecallflag = 1;//正在补招
//当前不区分稳态和暂态lnk20241030如果做区分修改Check_Recall_Config从xml文件获取数据后赋值给了LD_info //当前不区分稳态和暂态lnk20241030如果做区分修改Check_Recall_Config从xml文件获取数据后赋值给了LD_info
if (is_pqdif_process)
continue;
loginfo->need_steady = LD_info->autorecall[i]->need_steady; loginfo->need_voltage = LD_info->autorecall[i]->need_voltage; 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->start_time = apr_time_from_sec(LD_info->autorecall[i]->start - 5);//保证时间开头
@@ -718,6 +747,24 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr)
//不管是否成功这个补招文件必须删除可能出现一直失败循环读取文件和循环补招导致程序崩溃202050724lnk //不管是否成功这个补招文件必须删除可能出现一直失败循环读取文件和循环补招导致程序崩溃202050724lnk
//if (failed_count==0) {//成功 //if (failed_count==0) {//成功
if (is_pqdif_process) {
if (min_start_sec == LLONG_MAX || max_end_sec <= min_start_sec) {
failed_count++;
printf("[PQDIF][RECALL] invalid recall range mp_id=%s min=%lld max=%lld\n",
LD_info->mp_id, min_start_sec, max_end_sec);
}
else {
ret = ChannelRecallPQDIFFiles(chnl_usr, LD_info, min_start_sec, max_end_sec);
if (ret != APR_SUCCESS)
failed_count++;
}
g_dead_lock_counter = 0;
g_thread_blocked_times = 0;
now = sGetMsTime();
last_check_recall_config_time = now;
}
Delete_recall_Xml(LD_info->mp_id); Delete_recall_Xml(LD_info->mp_id);
// ===== [新增] 组装上送的补招开始/结束时间字符串(本地时区,直接“秒转字符串”)===== // ===== [新增] 组装上送的补招开始/结束时间字符串(本地时区,直接“秒转字符串”)=====
@@ -1129,7 +1176,8 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml)
//3-写入台账内容/////////////////////////////////// //3-写入台账内容///////////////////////////////////
//4-配置映射文件////////////////////////////// //4-配置映射文件//////////////////////////////
char model[64] = {0}; if (g_node_id != PQDIF_DATA_BASE_NODE_ID) {
char model[64] = {0};
// 获取模型ID检查是否返回 NULL // 获取模型ID检查是否返回 NULL
parse_model_cfg_web_one(ied,&model);//存储在/FeProject/dat/ parse_model_cfg_web_one(ied,&model);//存储在/FeProject/dat/
@@ -1163,6 +1211,11 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml)
//5-报告块初始化/////////////////////////////////// //5-报告块初始化///////////////////////////////////
//调试 //调试
}
else {
printf("[PQDIF] skip model xml and report init terminal=%s\n", ied_usr->terminal_id);
}
printf("ledger id: %s\n", ((ied_usr_t*)ied->channel[0].ied->usr_ext)->terminal_id); printf("ledger id: %s\n", ((ied_usr_t*)ied->channel[0].ied->usr_ext)->terminal_id);
//6-init_rem_dib_table////////////////////////////// //6-init_rem_dib_table//////////////////////////////
@@ -1232,7 +1285,8 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml)
//3-写入台账内容//////////////////////////////////////////// //3-写入台账内容////////////////////////////////////////////
//4-配置映射文件/////////////////////////////////////////// //4-配置映射文件///////////////////////////////////////////
char model[64] = {0}; if (g_node_id != PQDIF_DATA_BASE_NODE_ID) {
char model[64] = {0};
// 获取模型ID检查是否返回 NULL // 获取模型ID检查是否返回 NULL
parse_model_cfg_web_one(ied,&model);//存储在/FeProject/dat/ parse_model_cfg_web_one(ied,&model);//存储在/FeProject/dat/
@@ -1266,6 +1320,11 @@ void process_ledger_update(trigger_update_xml_t *ledger_update_xml)
parse_rpt_log_ini_one(ied); parse_rpt_log_ini_one(ied);
//5-报告块初始化/////////////////////////////////// //5-报告块初始化///////////////////////////////////
}
else {
printf("[PQDIF] skip model xml and report init terminal=%s\n", ied_usr->terminal_id);
}
//6-init_rem_dib_table////////////////////////////// //6-init_rem_dib_table//////////////////////////////
init_rem_dib_table_one(ied); init_rem_dib_table_one(ied);
//6-init_rem_dib_table/////////////////////////////////// //6-init_rem_dib_table///////////////////////////////////
@@ -1423,6 +1482,7 @@ void print_terminal(const terminal* tmnl) {
printf("Device Type: %s\n", is_empty(tmnl->dev_type) ? "N/A" : tmnl->dev_type); printf("Device Type: %s\n", is_empty(tmnl->dev_type) ? "N/A" : tmnl->dev_type);
printf("Device Key: %s\n", is_empty(tmnl->dev_key) ? "N/A" : tmnl->dev_key); printf("Device Key: %s\n", is_empty(tmnl->dev_key) ? "N/A" : tmnl->dev_key);
printf("Device Series: %s\n", is_empty(tmnl->dev_series) ? "N/A" : tmnl->dev_series); printf("Device Series: %s\n", is_empty(tmnl->dev_series) ? "N/A" : tmnl->dev_series);
printf("Com Type: %s\n", is_empty(tmnl->com_type) ? "MMS" : tmnl->com_type);
printf("Address: %s\n", is_empty(tmnl->addr_str) ? "N/A" : tmnl->addr_str); printf("Address: %s\n", is_empty(tmnl->addr_str) ? "N/A" : tmnl->addr_str);
printf("Port: %s\n", is_empty(tmnl->port) ? "N/A" : tmnl->port); printf("Port: %s\n", is_empty(tmnl->port) ? "N/A" : tmnl->port);
printf("Timestamp: %s\n", is_empty(tmnl->timestamp) ? "N/A" : tmnl->timestamp); printf("Timestamp: %s\n", is_empty(tmnl->timestamp) ? "N/A" : tmnl->timestamp);
@@ -1634,12 +1694,19 @@ void CheckAllConnectedChannel()
if(DEBUGOPEN)printf("[FILEDIR] enter HandleFileDirReqForChannel"); if(DEBUGOPEN)printf("[FILEDIR] enter HandleFileDirReqForChannel");
HandleFileDirReqForChannel(chnl_usr);//文件目录请求 HandleFileDirReqForChannel(chnl_usr);//文件目录请求
} }
if(g_node_id == PQDIF_DATA_BASE_NODE_ID){
ChannelCheckPQDIFFiles(chnl_usr);
}
else{
ChannelCheckIECReports(chnl_usr);//报告
}
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)) 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);//录波文件 ChannelCheckWaveFiles(chnl_usr);//录波文件
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)) 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)
|| g_node_id == PQDIF_DATA_BASE_NODE_ID)
ChannelCheckIECLogs(chnl_usr);//补招文件 ChannelCheckIECLogs(chnl_usr);//补招文件
if ( (sGetMsTime() - chnl_usr->m_LastPosRespTime) > 15*1000 ) //wait 15 secs隔15秒获取一次响应两次没响应后关闭 if ( (sGetMsTime() - chnl_usr->m_LastPosRespTime) > 15*1000 ) //wait 15 secs隔15秒获取一次响应两次没响应后关闭
{ {
char** varnames ; char** varnames ;
@@ -1982,6 +2049,361 @@ static ST_RET Write_Named_Var(LD_info_t *LD_info,chnl_usr_t *chnl_usr,char* VarN
#define TICKS_PER_MIN 60LL*1000LL*1000LL #define TICKS_PER_MIN 60LL*1000LL*1000LL
/* PQDIF 文件召唤参数。
* C# 读取程序的默认周期是 2 小时,文件名形如:
* PQMonitor_PQM1_20190401_1400_02.pqd
* 其中 “1_20190401_1400_” 用于匹配测点序号和时间片。
* 当前进程没有单独的手动时间窗输入,所以这里实现自动模式:
* 1. 每个终端按固定扫描间隔读取一次 /PQDIF/ 目录;
* 2. 只下载最近一个完整周期内、且测点序号匹配的 .pqd 文件;
* 3. 下载前检查 /FeProject/data/pqdif/ 下是否已有同名文件,避免重复下载。
*/
#define PQDIF_REMOTE_DIR "/PQDIF/"
#define PQDIF_LOCAL_DIR "/FeProject/data/pqdif"
#define PQDIF_AUTO_INTERVAL_HOURS 2
#define PQDIF_SCAN_INTERVAL_MS (60 * 1000)
#define PQDIF_MAX_DEVICE_INDEX 4096
#define PQDIF_MAX_FETCH_PER_SCAN 32
static const char* pqdif_basename(const char* filename)
{
const char* base = filename;
const char* p;
if (filename == NULL)
return "";
for (p = filename; *p != '\0'; ++p) {
if (*p == '/' || *p == '\\')
base = p + 1;
}
return base;
}
static int pqdif_has_pqd_suffix(const char* filename)
{
size_t len;
if (filename == NULL)
return FALSE;
len = strlen(filename);
if (len < 4)
return FALSE;
return (filename[len - 4] == '.'
&& tolower((unsigned char)filename[len - 3]) == 'p'
&& tolower((unsigned char)filename[len - 2]) == 'q'
&& tolower((unsigned char)filename[len - 1]) == 'd');
}
static void pqdif_make_time_match(int cpu_no, time_t tm_value, char* out, size_t out_len)
{
struct tm tm_local;
memset(&tm_local, 0, sizeof(tm_local));
localtime_r(&tm_value, &tm_local);
/* C# 目录匹配逻辑使用 “测点号_yyyyMMdd_HH00_” 作为关键片段。
* 例如测点号 1、2026-07-17 10 点,对应 “1_20260717_1000_”。
*/
snprintf(out, out_len, "%d_%04d%02d%02d_%02d00_",
cpu_no % 10,
tm_local.tm_year + 1900,
tm_local.tm_mon + 1,
tm_local.tm_mday,
tm_local.tm_hour);
}
static int pqdif_use_interval_end_time(const char* dev_type)
{
return (dev_type != NULL && strcmp(dev_type, "PS_NET_PQDIF") == 0);
}
static time_t pqdif_align_interval_start(long long sec)
{
time_t hour_floor;
struct tm tm_local;
int hour_mod;
memset(&tm_local, 0, sizeof(tm_local));
hour_floor = (time_t)sec;
localtime_r(&hour_floor, &tm_local);
tm_local.tm_min = 0;
tm_local.tm_sec = 0;
hour_floor = mktime(&tm_local);
hour_mod = tm_local.tm_hour % PQDIF_AUTO_INTERVAL_HOURS;
return hour_floor - hour_mod * 3600;
}
static int pqdif_match_interval(const char* filename, int cpu_no, time_t interval_start, const char* dev_type)
{
time_t name_time;
char time_match[64];
if (!pqdif_has_pqd_suffix(filename))
return FALSE;
if (cpu_no <= 0)
return FALSE;
/* C# 原逻辑按设备类型决定文件名时间:
* - 普通设备用周期开始时间;
* - PS_NET_PQDIF 用周期结束时间。
* 这里保持同样规则,避免把普通设备下一周期的开始文件误认为本周期结束文件。
*/
name_time = interval_start;
if (pqdif_use_interval_end_time(dev_type))
name_time += PQDIF_AUTO_INTERVAL_HOURS * 3600;
pqdif_make_time_match(cpu_no, name_time, time_match, sizeof(time_match));
return strstr(filename, time_match) != NULL;
}
static int pqdif_match_recent_interval(const char* filename, int cpu_no, const char* dev_type)
{
time_t now_time;
time_t interval_start;
now_time = time(NULL);
interval_start = pqdif_align_interval_start((long long)now_time) - PQDIF_AUTO_INTERVAL_HOURS * 3600;
return pqdif_match_interval(filename, cpu_no, interval_start, dev_type);
}
static int pqdif_ensure_local_dir()
{
#ifdef _OS_UNIX_
if (mkdir("/FeProject/data", 0777) != 0 && errno != EEXIST)
return SD_FAILURE;
if (mkdir(PQDIF_LOCAL_DIR, 0777) != 0 && errno != EEXIST)
return SD_FAILURE;
#endif
return SD_SUCCESS;
}
static int pqdif_local_file_exists(const char* filename)
{
char local_file[512];
const char* base = pqdif_basename(filename);
if (base[0] == '\0')
return FALSE;
snprintf(local_file, sizeof(local_file), "%s/%s", PQDIF_LOCAL_DIR, base);
#ifdef _OS_UNIX_
return access(local_file, F_OK) == 0;
#else
return FALSE;
#endif
}
static void pqdif_build_remote_filename(const char* dir_filename, char* out, size_t out_len)
{
if (dir_filename == NULL || dir_filename[0] == '\0') {
out[0] = '\0';
return;
}
/* mms_mvla_fdir 的返回值有两种可能:
* 1. 带目录:/PQDIF/xxx.pqd
* 2. 仅文件名xxx.pqd
* PQDIF 必须固定从 /PQDIF/ 取,所以仅返回文件名时要补齐远端目录。
*/
if (strchr(dir_filename, '/') != NULL || strchr(dir_filename, '\\') != NULL)
snprintf(out, out_len, "%s", dir_filename);
else
snprintf(out, out_len, "%s%s", PQDIF_REMOTE_DIR, dir_filename);
}
static int pqdif_get_file_from_device(chnl_usr_t *chnl_usr, const char *rem_filename, char *only_filename_ret, size_t only_filename_ret_len)
{
int ret;
char loc_file_fullname[512];
char rem_file_fullname[512];
const char *only_filename;
if (chnl_usr == NULL || chnl_usr->net_info == NULL || rem_filename == NULL || rem_filename[0] == '\0')
return SD_FAILURE;
only_filename = pqdif_basename(rem_filename);
if (only_filename[0] == '\0')
return SD_FAILURE;
if (pqdif_ensure_local_dir() != SD_SUCCESS) {
echo_warn1("[PQDIF] create local dir failed: %s\n", PQDIF_LOCAL_DIR);
return SD_FAILURE;
}
memset(loc_file_fullname,0,sizeof(loc_file_fullname));
memset(rem_file_fullname,0,sizeof(rem_file_fullname));
apr_snprintf(loc_file_fullname,sizeof(loc_file_fullname),"%s/%s",PQDIF_LOCAL_DIR,only_filename);
apr_snprintf(rem_file_fullname,sizeof(rem_file_fullname),"%s",rem_filename);
if (only_filename_ret != NULL && only_filename_ret_len > 0)
apr_snprintf(only_filename_ret,only_filename_ret_len,"%s",only_filename);
printf("[PQDIF] mms_getFile local=%s remote=%s\n", loc_file_fullname, rem_file_fullname);
ret = mms_getFile(chnl_usr->net_info,loc_file_fullname,rem_file_fullname,g_pt61850app->mmsOpTimeout);
if (ret != SD_SUCCESS) {
echo_warn3("[PQDIF] mms_getFile failed IP=%s local=%s remote=%s\n",
chnl_usr->ip_str, loc_file_fullname, rem_file_fullname);
return ret;
}
#ifdef _OS_UNIX_
{
struct stat st;
if (stat(loc_file_fullname, &st) != 0 || st.st_size <= 0) {
unlink(loc_file_fullname);
echo_warn2("[PQDIF] file is empty or invalid: %s from %s\n",
loc_file_fullname, rem_file_fullname);
return SD_FAILURE;
}
}
#endif
return SD_SUCCESS;
}
static apr_status_t ChannelRecallPQDIFFiles(chnl_usr_t *chnl_usr, LD_info_t *LD_info, long long start_sec, long long end_sec)
{
ied_t *ied;
ied_usr_t *ied_usr;
char **filenames = NULL;
int filenum = 0;
int ret;
int file_idx;
int fetched = 0;
int existed = 0;
int missing = 0;
int failed = 0;
time_t interval_start;
time_t interval_step;
if (chnl_usr == NULL || chnl_usr->chnl == NULL || chnl_usr->chnl->ied == NULL ||
chnl_usr->chnl->ied->usr_ext == NULL || chnl_usr->net_info == NULL ||
LD_info == NULL) {
printf("[PQDIF][RECALL] invalid context, skip\n");
return APR_EGENERAL;
}
if (LD_info->cpuno == 0 || LD_info->LD_name == NULL || LD_info->mp_id[0] == '\0') {
printf("[PQDIF][RECALL] invalid LD_info, skip\n");
return APR_EGENERAL;
}
if (end_sec <= start_sec) {
printf("[PQDIF][RECALL] invalid time range mp_id=%s start=%lld end=%lld\n",
LD_info->mp_id, start_sec, end_sec);
return APR_EGENERAL;
}
ied = chnl_usr->chnl->ied;
ied_usr = (ied_usr_t*)ied->usr_ext;
if (pqdif_ensure_local_dir() != SD_SUCCESS) {
echo_warn1("[PQDIF][RECALL] create local dir failed: %s\n", PQDIF_LOCAL_DIR);
return APR_EGENERAL;
}
/* 单点补招与 C# 手动/补招逻辑保持一致:
* 1. 先读取装置 /PQDIF/ 目录;
* 2. 按 PQDIF_AUTO_INTERVAL_HOURS 将补招时间范围切成多个文件周期;
* 3. 普通设备用周期开始时间匹配文件名PS_NET_PQDIF 用周期结束时间匹配文件名;
* 4. 每个周期只取一份匹配文件,下载接口直接调用 mms_getFile。
*/
ret = mms_mvla_fdir(chnl_usr->net_info,(ST_CHAR*)PQDIF_REMOTE_DIR,
3*g_pt61850app->mmsOpTimeout,&filenames,&filenum,g_pt61850app->tmp_pool);
if (ret != SD_SUCCESS) {
echo_warn2("[PQDIF][RECALL] mms_mvla_fdir failed, IED=%d IP=%s\n", ied->id, chnl_usr->ip_str);
return APR_EGENERAL;
}
if (filenames == NULL || filenum <= 0) {
printf("[PQDIF][RECALL] no file in remote dir %s, mp_id=%s IP=%s\n",
PQDIF_REMOTE_DIR, LD_info->mp_id, chnl_usr->ip_str);
return APR_EGENERAL;
}
interval_step = PQDIF_AUTO_INTERVAL_HOURS * 3600;
interval_start = pqdif_align_interval_start(start_sec);
printf("[PQDIF][RECALL] begin mp_id=%s cpuno=%d range=%lld~%lld interval_start=%lld files=%d dev_type=%s\n",
LD_info->mp_id, LD_info->cpuno, start_sec, end_sec, (long long)interval_start,
filenum, ied_usr->dev_type);
while ((long long)interval_start < end_sec) {
int found_this_interval = FALSE;
for (file_idx = 0; file_idx < filenum; file_idx++) {
const char *base_name;
char remote_filename[256];
char only_filename_ret[256];
int ret_get;
if (filenames[file_idx] == NULL)
continue;
base_name = pqdif_basename(filenames[file_idx]);
if (base_name[0] == '\0')
continue;
if (!pqdif_match_interval(base_name, LD_info->cpuno, interval_start, ied_usr->dev_type))
continue;
found_this_interval = TRUE;
if (pqdif_local_file_exists(base_name)) {
existed++;
printf("[PQDIF][RECALL] local file exists, skip mp_id=%s interval=%lld file=%s\n",
LD_info->mp_id, (long long)interval_start, base_name);
break;
}
memset(remote_filename,0,sizeof(remote_filename));
memset(only_filename_ret,0,sizeof(only_filename_ret));
pqdif_build_remote_filename(filenames[file_idx], remote_filename, sizeof(remote_filename));
if (remote_filename[0] == '\0') {
failed++;
break;
}
ret_get = pqdif_get_file_from_device(chnl_usr, remote_filename, only_filename_ret, sizeof(only_filename_ret));
if (ret_get == SD_SUCCESS) {
fetched++;
chnl_usr->m_LastPosRespTime = sGetMsTime();
printf("[PQDIF][RECALL] fetch success mp_id=%s interval=%lld remote=%s local=%s/%s\n",
LD_info->mp_id, (long long)interval_start, remote_filename, PQDIF_LOCAL_DIR, only_filename_ret);
}
else {
failed++;
echo_warn3("[PQDIF][RECALL] fetch failed mp_id=%s remote=%s IP=%s\n",
LD_info->mp_id, remote_filename, chnl_usr->ip_str);
}
break;
}
if (!found_this_interval) {
missing++;
printf("[PQDIF][RECALL] no matched file mp_id=%s interval=%lld dev_type=%s\n",
LD_info->mp_id, (long long)interval_start, ied_usr->dev_type);
}
interval_start += interval_step;
}
printf("[PQDIF][RECALL] finish mp_id=%s fetched=%d existed=%d missing=%d failed=%d\n",
LD_info->mp_id, fetched, existed, missing, failed);
if (missing > 0 || failed > 0)
return APR_EGENERAL;
return APR_SUCCESS;
}
int pt61850_write_cn_file(chnl_usr_t *chnl_usr, ied_t *ied, char *rem_filename, char *only_filename_ret) int pt61850_write_cn_file(chnl_usr_t *chnl_usr, ied_t *ied, char *rem_filename, char *only_filename_ret)
{ {
@@ -2027,6 +2449,140 @@ int pt61850_write_cn_file(chnl_usr_t *chnl_usr, ied_t *ied, char *rem_filename,
return ret; return ret;
} }
static apr_status_t ChannelCheckPQDIFFiles(chnl_usr_t *chnl_usr)
{
ied_t *ied;
ied_usr_t *ied_usr;
LD_info_t *LD_info;
char **filenames = NULL;
int filenum = 0;
int ret;
int cpuno;
int file_idx;
int fetched = 0;
int matched = 0;
int scan_idx;
double now_ms;
static double s_last_scan_ms[PQDIF_MAX_DEVICE_INDEX] = {0};
if (chnl_usr == NULL || chnl_usr->chnl == NULL || chnl_usr->chnl->ied == NULL ||
chnl_usr->chnl->ied->usr_ext == NULL || chnl_usr->net_info == NULL) {
printf("[PQDIF] invalid channel context, skip scan\n");
return APR_EGENERAL;
}
ied = chnl_usr->chnl->ied;
ied_usr = (ied_usr_t*)ied->usr_ext;
/* CheckAllConnectedChannel 会轮询通道;这里按终端做节流,避免每次循环都读一次
* /PQDIF/ 目录。目录读和文件下载都走 MMS同一个终端一分钟扫描一次即可。
*/
scan_idx = ied_usr->dev_idx;
if (scan_idx < 0 || scan_idx >= PQDIF_MAX_DEVICE_INDEX)
scan_idx = (int)chnl_usr->chnl_id;
if (scan_idx < 0 || scan_idx >= PQDIF_MAX_DEVICE_INDEX)
scan_idx = 0;
now_ms = sGetMsTime();
if (s_last_scan_ms[scan_idx] > 0 &&
(now_ms - s_last_scan_ms[scan_idx]) < PQDIF_SCAN_INTERVAL_MS) {
return APR_SUCCESS;
}
s_last_scan_ms[scan_idx] = now_ms;
/* 本函数只做 PQDIF 文件获取:
* 1. 从装置固定目录 /PQDIF/ 取文件列表;
* 2. 用台账里的 LD_info->cpuno 匹配文件名里的 “测点号_yyyyMMdd_HH00_”
* 3. 只下载 .pqd 文件,且本地 /FeProject/data/pqdif/ 已存在同名文件时跳过;
* 4. 真正下载直接调用 mms_getFile不改动原录波文件下载函数。
*/
if (pqdif_ensure_local_dir() != SD_SUCCESS) {
echo_warn1("[PQDIF] create local dir failed: %s\n", PQDIF_LOCAL_DIR);
return APR_EGENERAL;
}
ret = mms_mvla_fdir(chnl_usr->net_info,(ST_CHAR*)PQDIF_REMOTE_DIR,
3*g_pt61850app->mmsOpTimeout,&filenames,&filenum,g_pt61850app->tmp_pool);
if (ret != SD_SUCCESS) {
echo_warn2("[PQDIF] mms_mvla_fdir failed, IED=%d IP=%s\n", ied->id, chnl_usr->ip_str);
return APR_EGENERAL;
}
if (filenames == NULL || filenum <= 0) {
printf("[PQDIF] no file in remote dir %s, IED=%d IP=%s\n", PQDIF_REMOTE_DIR, ied->id, chnl_usr->ip_str);
return APR_SUCCESS;
}
printf("[PQDIF] scan remote dir %s success, IED=%d IP=%s file_count=%d\n",
PQDIF_REMOTE_DIR, ied->id, chnl_usr->ip_str, filenum);
for (cpuno = 0; cpuno < ied->cpucount; cpuno++) {
LD_info = &(ied_usr->LD_info[cpuno]);
if (LD_info->cpuno == 0 ||
LD_info->LD_name == NULL ||
LD_info->mp_id[0] == '\0') {
continue;
}
for (file_idx = 0; file_idx < filenum; file_idx++) {
const char *base_name;
char remote_filename[256];
char only_filename_ret[256];
int ret_get;
if (filenames[file_idx] == NULL)
continue;
base_name = pqdif_basename(filenames[file_idx]);
if (base_name[0] == '\0')
continue;
/* C# 读取程序的兼容逻辑是读目录后按片段匹配:
* cpuNo%10_yyyyMMdd_HH00_
* 这里保持同样的匹配方式,不依赖厂家前缀,也兼容普通设备用
* 周期开始时间命名、振兴类设备用周期结束时间命名的差异。
*/
if (!pqdif_match_recent_interval(base_name, LD_info->cpuno, ied_usr->dev_type))
continue;
matched++;
if (pqdif_local_file_exists(base_name)) {
printf("[PQDIF] local file exists, skip mp_id=%s file=%s\n", LD_info->mp_id, base_name);
continue;
}
memset(remote_filename,0,sizeof(remote_filename));
memset(only_filename_ret,0,sizeof(only_filename_ret));
pqdif_build_remote_filename(filenames[file_idx], remote_filename, sizeof(remote_filename));
if (remote_filename[0] == '\0')
continue;
ret_get = pqdif_get_file_from_device(chnl_usr, remote_filename, only_filename_ret, sizeof(only_filename_ret));
if (ret_get == SD_SUCCESS) {
fetched++;
chnl_usr->m_LastPosRespTime = sGetMsTime();
printf("[PQDIF] fetch success mp_id=%s name=%s remote=%s local=%s/%s\n",
LD_info->mp_id, LD_info->name, remote_filename, PQDIF_LOCAL_DIR, only_filename_ret);
}
else {
echo_warn3("[PQDIF] fetch failed mp_id=%s remote=%s IP=%s\n",
LD_info->mp_id, remote_filename, chnl_usr->ip_str);
}
if (fetched >= PQDIF_MAX_FETCH_PER_SCAN) {
printf("[PQDIF] reach fetch limit per scan=%d, IED=%d IP=%s\n",
PQDIF_MAX_FETCH_PER_SCAN, ied->id, chnl_usr->ip_str);
return APR_SUCCESS;
}
}
}
printf("[PQDIF] scan finish IED=%d IP=%s matched=%d fetched=%d\n",
ied->id, chnl_usr->ip_str, matched, fetched);
return APR_SUCCESS;
}
apr_status_t prepare_call_cn_wavelist(LD_info_t *LD_info, int FltNum) apr_status_t prepare_call_cn_wavelist(LD_info_t *LD_info, int FltNum)
{ {
int i; int i;
@@ -2467,4 +3023,3 @@ char* convertMsToDateTimeString(int64_t usTime) {
return buffer; return buffer;
} }

View File

@@ -205,27 +205,32 @@ apr_status_t init_rdb()
//台账读取过后初始化各级的日志 //台账读取过后初始化各级的日志
init_loggers(); init_loggers();
rv = parse_model_cfg_web(); if (g_node_id != PQDIF_DATA_BASE_NODE_ID) {
if (rv != APR_SUCCESS) {//不可能 rv = parse_model_cfg_web();
echo_errg("Parsed model with error,try to run! \n"); if (rv != APR_SUCCESS) {//不可能
echo_errg("Parsed model with error,try to run! \n");
//char buf[256]; //char buf[256];
//format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index); //format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index);
//log_error("process", buf); //log_error("process", buf);
DIY_ERRORLOG_CODE("process",0,LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index); DIY_ERRORLOG_CODE("process",0,LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index);
return rv; return rv;
}
Set_xml_nodeinfo();//解析xml模型
rv = parse_rpt_log_ini();//报告块初始化
if (rv != APR_SUCCESS) {
echo_errg("Failed to parse report log define ini file! \n");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_RPTINIT,"【ERROR】前置的%s%d号进程报告初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
return rv;
}
} }
else {
Set_xml_nodeinfo();//解析xml模型 printf("[PQDIF] skip model xml and report init in init_rdb\n");
rv = parse_rpt_log_ini();//报告块初始化
if (rv != APR_SUCCESS) {
echo_errg("Failed to parse report log define ini file! \n");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_RPTINIT,"【ERROR】前置的%s%d号进程报告初始化失败", get_front_msg_from_subdir(), g_front_seg_index);
return rv;
} }
} }
@@ -311,6 +316,9 @@ apr_status_t run_protocol()
else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波 else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波
ServerPort = SOCKET_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index; ServerPort = SOCKET_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index;
} }
else if (g_node_id == PQDIF_DATA_BASE_NODE_ID) {
ServerPort = SOCKET_PORT + PQDIF_DATA_BASE_NODE_ID + g_front_seg_index;
}
struct sockaddr_in server_sockaddr; struct sockaddr_in server_sockaddr;
memset(&server_sockaddr, 0, sizeof(server_sockaddr)); memset(&server_sockaddr, 0, sizeof(server_sockaddr));
@@ -351,6 +359,9 @@ apr_status_t run_protocol()
else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波 else if (g_node_id == SOE_COMTRADE_BASE_NODE_ID) {//暂态录波
HTTP_PORT = HTTP_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index; HTTP_PORT = HTTP_PORT + SOE_COMTRADE_BASE_NODE_ID + g_front_seg_index;
} }
else if (g_node_id == PQDIF_DATA_BASE_NODE_ID) {
HTTP_PORT = HTTP_PORT + PQDIF_DATA_BASE_NODE_ID + g_front_seg_index;
}
printf("try_start_web_http_thread \n"); printf("try_start_web_http_thread \n");
try_start_web_http_thread(); try_start_web_http_thread();
printf("try_start_http_thread \n"); printf("try_start_http_thread \n");

View File

@@ -337,6 +337,7 @@ struct ied_usr_t{
char dev_type[256]; /**< 设备类型 */ char dev_type[256]; /**< 设备类型 */
char dev_key[256]; /**< 设备秘钥 */ char dev_key[256]; /**< 设备秘钥 */
char dev_series[256]; /**< 设备识别码 */ char dev_series[256]; /**< 设备识别码 */
char com_type[32]; /**< 通讯类型 mms/pqdif */
int dev_flag; /**< 设备标志 */ int dev_flag; /**< 设备标志 */
void *cookie; void *cookie;
double last_call_wavelist_time ; //上次召录波列表时间 double last_call_wavelist_time ; //上次召录波列表时间

View File

@@ -329,6 +329,7 @@ handle_reset() {
sed -i '/cfg_recallhis_data/d' /FeProject/etc/runtime.cf sed -i '/cfg_recallhis_data/d' /FeProject/etc/runtime.cf
sed -i '/cfg_3s_data/d' /FeProject/etc/runtime.cf sed -i '/cfg_3s_data/d' /FeProject/etc/runtime.cf
sed -i '/cfg_soe_comtrade/d' /FeProject/etc/runtime.cf sed -i '/cfg_soe_comtrade/d' /FeProject/etc/runtime.cf
sed -i '/cfg_pqdif_data/d' /FeProject/etc/runtime.cf
sed -i '/fe_watchdog/d' /FeProject/etc/runtime.cf sed -i '/fe_watchdog/d' /FeProject/etc/runtime.cf
# 根据进程号添加对应进程配置 # 根据进程号添加对应进程配置
@@ -340,6 +341,7 @@ handle_reset() {
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s 1_1^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_recallhis_data -s 1_1^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_pqdif_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
else else
#看门狗固定放在第一个防止stop时会把要杀死的进程重启 #看门狗固定放在第一个防止stop时会把要杀死的进程重启
@@ -353,6 +355,7 @@ handle_reset() {
#以下部分没有多进程 #以下部分没有多进程
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_3s_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_soe_comtrade^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
sed -i "2a\\$(printf '/FeProject/bin/ ^ pt61850netd_pqfe -d cfg_pqdif_data^ ^ ^ 1 ^ ^\n')" /FeProject/etc/runtime.cf
fi fi