add qvvr interface

This commit is contained in:
lnk
2025-08-07 18:59:11 +08:00
parent ee6d9c2689
commit 83986c35cb
4 changed files with 77 additions and 34 deletions

View File

@@ -2703,7 +2703,7 @@ bool extract_timestamp_from_cfg_file(const std::string& cfg_path, long long& sta
return start_tm > 0 && trig_tm > 0; return start_tm > 0 && trig_tm > 0;
} }
bool compare_qvvr_and_file(const std::string& cfg_path, const std::vector<qvvr_data>& data_list) { bool compare_qvvr_and_file(const std::string& cfg_path, const std::vector<qvvr_data>& data_list,qvvr_data& matched_data) {
long long start_tm = 0; long long start_tm = 0;
long long trig_tm = 0; long long trig_tm = 0;
@@ -2717,6 +2717,7 @@ bool compare_qvvr_and_file(const std::string& cfg_path, const std::vector<qvvr_d
for (const auto& data : data_list) { for (const auto& data : data_list) {
long long diff = static_cast<long long>(data.QVVR_time) - trig_tm; long long diff = static_cast<long long>(data.QVVR_time) - trig_tm;
if (std::abs(diff) <= 1) { if (std::abs(diff) <= 1) {
matched_data = data; // 返回匹配到的事件
return true; return true;
} }
} }
@@ -2940,6 +2941,10 @@ bool SendAllQvvrFiles(qvvr_file& qfile, std::string& out_wavepath) {
//文件下载结束接口 //文件下载结束接口
bool update_qvvr_file_download(const std::string& filename_with_mac, const std::string& terminal_id) { bool update_qvvr_file_download(const std::string& filename_with_mac, const std::string& terminal_id) {
//台账加锁
std::lock_guard<std::mutex> lock(ledgermtx);
// 去除 mac 路径前缀,仅保留文件名 // 去除 mac 路径前缀,仅保留文件名
std::string filename = extract_filename(filename_with_mac); std::string filename = extract_filename(filename_with_mac);
@@ -2954,9 +2959,11 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std::
std::string seq_str = type_part.substr(num_start + 1); std::string seq_str = type_part.substr(num_start + 1);
ushort logical_seq = static_cast<ushort>(std::stoi(seq_str)); // 逻辑序号 ushort logical_seq = static_cast<ushort>(std::stoi(seq_str)); // 逻辑序号
//找终端
for (auto& dev : terminal_devlist) { for (auto& dev : terminal_devlist) {
if (dev.terminal_id != terminal_id) continue; if (dev.terminal_id != terminal_id) continue;
//找监测点
for (auto& monitor : dev.line) { for (auto& monitor : dev.line) {
try { try {
// 将监测点台账中的 logical_device_seq 转换为数字进行匹配 // 将监测点台账中的 logical_device_seq 转换为数字进行匹配
@@ -2967,16 +2974,19 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std::
} }
// 匹配监测点下 qvvrfile 中的 file_name // 匹配监测点下 qvvrfile 中的 file_name
for (auto& qfile : monitor.qvvrevent.qvvrfile) { for (size_t i = 0; i < monitor.qvvrevent.qvvrfile.size(); ++i) {
auto& qfile = monitor.qvvrevent.qvvrfile[i];
// file_name 中是文件名,需与提取的 filename 比较 // file_name 中是文件名,需与提取的 filename 比较
auto it = std::find(qfile.file_name.begin(), qfile.file_name.end(), filename); auto it = std::find(qfile.file_name.begin(), qfile.file_name.end(), filename);
//找到匹配文件名
if (it != qfile.file_name.end()) { if (it != qfile.file_name.end()) {
// 添加到 file_download记录完整路径避免重复 // 添加到 file_download记录完整路径避免重复
if (std::find(qfile.file_download.begin(), qfile.file_download.end(), filename_with_mac) == qfile.file_download.end()) { if (std::find(qfile.file_download.begin(), qfile.file_download.end(), filename_with_mac) == qfile.file_download.end()) {
qfile.file_download.push_back(filename_with_mac); qfile.file_download.push_back(filename_with_mac);
} }
qfile.file_time_count = 0; // 文件下载开始后,计时归零 qfile.file_time_count = 0; // 任一录波文件下载后,计时归零
// file_download 中是完整路径,需提取文件名后与 file_name 做集合比较 // file_download 中是完整路径,需提取文件名后与 file_name 做集合比较
std::set<std::string> s_name(qfile.file_name.begin(), qfile.file_name.end()); std::set<std::string> s_name(qfile.file_name.begin(), qfile.file_name.end());
@@ -2994,7 +3004,8 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std::
std::string fname = extract_filename(fpath); std::string fname = extract_filename(fpath);
if (fname.size() >= 4 && fname.substr(fname.size() - 4) == ".cfg") { if (fname.size() >= 4 && fname.substr(fname.size() - 4) == ".cfg") {
// 提取文件时标和监测点事件的时标匹配 // 提取文件时标和监测点事件的时标匹配
if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata)) { qvvr_data matched;
if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata,matched)) {
qfile.is_pair = true; // 文件与事件匹配成功 qfile.is_pair = true; // 文件与事件匹配成功
// 发送所有文件(已下载完成) // 发送所有文件(已下载完成)
@@ -3003,17 +3014,13 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std::
//文件发送成功后更新事件 //文件发送成功后更新事件
transfer_json_qvvr_data(terminal_id, transfer_json_qvvr_data(terminal_id,
logical_seq, logical_seq,
monitor.qvvrevent.qvvrdata.QVVR_Amg, matched.QVVR_Amg,
monitor.qvvrevent.qvvrdata.QVVR_PerTime, matched.QVVR_PerTime,
monitor.qvvrevent.qvvrdata.QVVR_time, matched.QVVR_time,
monitor.qvvrevent.qvvrdata.QVVR_type, matched.QVVR_type,
monitor.qvvrevent.qvvrdata.phase, matched.phase,
wavepath); wavepath);
// 清除暂态数据
monitor.qvvrevent.qvvrfile.clear();
monitor.qvvrevent.qvvrdata.clear();
// 删除上传成功的文件 // 删除上传成功的文件
for (const auto& uploaded_file : qfile.file_download) { for (const auto& uploaded_file : qfile.file_download) {
if (std::remove(uploaded_file.c_str()) != 0) { if (std::remove(uploaded_file.c_str()) != 0) {
@@ -3022,15 +3029,37 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std::
std::cout << "[Cleanup] Deleted uploaded file: " << uploaded_file << "\n"; std::cout << "[Cleanup] Deleted uploaded file: " << uploaded_file << "\n";
} }
} }
// 清除已发送的暂态文件
monitor.qvvrevent.qvvrfile.erase(monitor.qvvrevent.qvvrfile.begin() + i);
//清除暂态事件
auto it = std::find_if(
monitor.qvvrevent.qvvrdata.begin(),
monitor.qvvrevent.qvvrdata.end(),
[&](const qvvr_data& d) {
return d.QVVR_time == matched.QVVR_time;
});
if (it != monitor.qvvrevent.qvvrdata.end()) {
monitor.qvvrevent.qvvrdata.erase(it);
}
} }
} }
break; // 只处理第一个 cfg 文件 break; // 只处理第一个 cfg 文件
} }
} }
} }
else{
std::cout << "qvvr file still imcomplete!!!" << std::endl;
}
return true; // 当前文件处理成功 return true; // 当前文件处理成功
} }
} }
std::cout << "file name doesnt match any file in this monitor!!!" << std::endl;
} }
} }
return false; // 未匹配到终端ID或逻辑序号对应的监测点 return false; // 未匹配到终端ID或逻辑序号对应的监测点

View File

@@ -1154,8 +1154,8 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
const std::string& wavepath) { const std::string& wavepath) {
// 监测点日志的 key, lnk20250526 // 监测点日志的 key, lnk20250526
std::string full_key_m_c = "monitor." + std::to_string(monitor_id) + ".COM"; std::string full_key_m_c = "monitor." + dev_id + "." + std::to_string(monitor_id) + ".COM";
std::string full_key_m_d = "monitor." + std::to_string(monitor_id) + ".DATA"; std::string full_key_m_d = "monitor." + dev_id + "." + std::to_string(monitor_id) + ".DATA";
// 监测点日志的 key, lnk20250526 // 监测点日志的 key, lnk20250526
if (dev_id.empty()) { if (dev_id.empty()) {
@@ -1199,21 +1199,21 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
// 有效响应,略过 // 有效响应,略过
} catch (...) { } catch (...) {
// 响应异常,保存 json // 响应异常,保存 json
DIY_ERRORLOG(full_key_m_d.c_str(), "【ERROR】暂态接口响应异常,无法上送监测点%s的暂态事件", mp_id.c_str()); DIY_ERRORLOG(full_key_m_d.c_str(), "【ERROR】暂态接口响应异常,无法上送监测点%s的暂态事件", monitor_id.c_str());
std::cout << "qvvr send fail ,store in local" << std::endl; std::cout << "qvvr send fail ,store in local" << std::endl;
std::string qvvrDir = FRONT_PATH + "/dat/qvvr/"; std::string qvvrDir = FRONT_PATH + "/dat/qvvr/";
std::string fileName = qvvrDir + mp_id + "-" + FormatTimeForFilename(start_time_str) + "-" + std::to_string(dis_kind) + ".txt"; std::string fileName = qvvrDir + monitor_id + "-" + FormatTimeForFilename(start_time_str) + "-" + std::to_string(dis_kind) + ".txt";
writeJsonToFile(fileName, json_string); writeJsonToFile(fileName, json_string);
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024); checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
} }
} else { } else {
// 无响应,保存 json // 无响应,保存 json
DIY_ERRORLOG(full_key_m_d.c_str(), "【ERROR】暂态接口无响应,无法上送监测点%s的暂态事件", mp_id.c_str()); DIY_ERRORLOG(full_key_m_d.c_str(), "【ERROR】暂态接口无响应,无法上送监测点%s的暂态事件", monitor_id.c_str());
std::cout << "qvvr send fail ,store in local" << std::endl; std::cout << "qvvr send fail ,store in local" << std::endl;
std::string qvvrDir = FRONT_PATH + "/dat/qvvr/"; std::string qvvrDir = FRONT_PATH + "/dat/qvvr/";
std::string fileName = qvvrDir + mp_id + "-" + FormatTimeForFilename(start_time_str) + "-" + std::to_string(dis_kind) + ".txt"; std::string fileName = qvvrDir + monitor_id + "-" + FormatTimeForFilename(start_time_str) + "-" + std::to_string(dis_kind) + ".txt";
writeJsonToFile(fileName, json_string); writeJsonToFile(fileName, json_string);
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024); checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
return 1; return 1;

View File

@@ -52,28 +52,31 @@ public:
//录波文件和暂态事件 //录波文件和暂态事件
class qvvr_data class qvvr_data
{ {
bool used_status; //是否占用 public:
int QVVR_type; //暂态类型 bool used_status; //是否占用
uint64_t QVVR_time; //暂态开始时间 unsigned longlong int QVVR_type; //暂态类型
double QVVR_PerTime; //暂态持续时间 uint64_t QVVR_time; //暂态开始时间 unsigned longlong
double QVVR_Amg; //暂态幅值 double QVVR_PerTime; //暂态持续时间
int phase; //相别(仅瞬态上送)0-A 1-B 2-C 3-AB 4-BC 5-CA 其他-ABC/异常 double QVVR_Amg; //暂态幅值
int phase; //相别(仅瞬态上送)0-A 1-B 2-C 3-AB 4-BC 5-CA 其他-ABC/异常
}; };
class qvvr_file class qvvr_file
{ {
bool used_status; public:
int file_time_count; //组内文件下载时间计数第一个文件下载后十分钟内如果其他文件没下载全或者下载全了没匹配事件则将已下载的文件都移到备份区comtrade_bak bool used_status;
bool is_download; //文件是否下载完全,最后一个文件下载成功后对比成功则更新这个标志 int file_time_count; //组内文件下载时间计数第一个文件下载后十分钟内如果其他文件没下载全或者下载全了没匹配事件则将已下载的文件都移到备份区comtrade_bak
bool is_pair; //文件是否和事件匹配从comtrade/mac/路径下取file_download中的cfg文件提取时间和持续时间来匹配匹配后接口发送这组file_download全部文件发送成功后删除这组文件然后更新事件中的文件列表 bool is_download; //文件是否下载完全,最后一个文件下载成功后对比成功则更新这个标志
std::list<std::string> file_name; //文件列表(文件列表上送后就记录) bool is_pair; //文件是否和事件匹配从comtrade/mac/路径下取file_download中的cfg文件提取时间和持续时间来匹配匹配后接口发送这组file_download全部文件发送成功后删除这组文件然后更新事件中的文件列表
std::list<std::string> file_download; //文件已下载列表(每次列表上送会有多个文件多个文件都下载完全则开始匹配每次更新都去重并对比file_name std::list<std::string> file_name; //文件列表(文件列表上送后就记录
std::list<std::string> file_download; //文件已下载列表(每次列表上送会有多个文件多个文件都下载完全则开始匹配每次更新都去重并对比file_name
}; };
class qvvr_event class qvvr_event
{ {
std::vector<qvvr_data> qvvrdata; //暂态事件列表 public:
std::vector<qvvr_file> qvvrfile; //暂态文件组列表 std::vector<qvvr_data> qvvrdata; //暂态事件列表
std::vector<qvvr_file> qvvrfile; //暂态文件组列表
}; };
//监测点台账 //监测点台账

View File

@@ -120,6 +120,11 @@ void process_received_message(string mac, string id,const char* data, size_t len
<< ", <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: " << record.fMagntitude << " pu" << ", <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: " << record.fMagntitude << " pu"
<< ", ʱ<><CAB1><EFBFBD><EFBFBD>: " << record.triggerTimeMs << "ms" << std::endl; << ", ʱ<><CAB1><EFBFBD><EFBFBD>: " << record.triggerTimeMs << "ms" << std::endl;
//lnk20250805 <20>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>¼<EFBFBD><C2BC>¼<EFBFBD><C2BC><EFBFBD>ļ<EFBFBD><C4BC>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD><D9B8><EFBFBD><EFBFBD>ļ<EFBFBD>
transfer_json_qvvr_data(id,event.head.name,
record.fMagntitude,record.fPersisstime,record.triggerTimeMs,record.nType,record.phase,
"");
} }
else { else {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡʧ<C8A1>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡʧ<C8A1>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD>
@@ -197,6 +202,9 @@ void process_received_message(string mac, string id,const char* data, size_t len
} }
std::cout << std::endl; std::cout << std::endl;
//lnk20250805¼<35><C2BC><EFBFBD>ļ<EFBFBD>Ŀ¼<C4BF>ӿ<EFBFBD>
assign_qvvr_file_list(id, line_id, fullFilenames);
// ========== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊÿ<CEAA><C3BF><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ========== // ========== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊÿ<CEAA><C3BF><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==========
for (const auto& filename : fullFilenames) { for (const auto& filename : fullFilenames) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><D6A1><EFBFBD>Ź̶<C5B9>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><D6A1><EFBFBD>Ź̶<C5B9>Ϊ1<CEAA><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
@@ -644,6 +652,9 @@ void process_received_message(string mac, string id,const char* data, size_t len
out_file.write(reinterpret_cast<const char*>(file_data.data()), out_file.write(reinterpret_cast<const char*>(file_data.data()),
file_data.size()); file_data.size());
std::cout << "File saved: " << file_path << std::endl; std::cout << "File saved: " << file_path << std::endl;
//lnk20250805<30>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ͽӿ<CDBD>
update_qvvr_file_download(file_path, id);
} }
else { else {
std::cerr << "Failed to save file: " << file_path std::cerr << "Failed to save file: " << file_path