add qvvr interface
This commit is contained in:
@@ -2703,7 +2703,26 @@ bool extract_timestamp_from_cfg_file(const std::string& cfg_path, long long& sta
|
||||
return start_tm > 0 && trig_tm > 0;
|
||||
}
|
||||
|
||||
bool compare_qvvr_and_file(const std::string& cfg_path, const std::vector<qvvr_data>& data_list) {
|
||||
long long start_tm = 0;
|
||||
long long trig_tm = 0;
|
||||
|
||||
// 提取 .cfg 文件中的时间戳
|
||||
if (!extract_timestamp_from_cfg_file(cfg_path, start_tm, trig_tm)) {
|
||||
std::cerr << "Failed to extract timestamp from cfg file: " << cfg_path << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// 遍历所有暂态事件,查找与 trig_tm 匹配的
|
||||
for (const auto& data : data_list) {
|
||||
long long diff = static_cast<long long>(data.QVVR_time) - trig_tm;
|
||||
if (std::abs(diff) <= 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////数据转换函数
|
||||
// DataArrayItem to_json
|
||||
void to_json(nlohmann::json& j, const DataArrayItem& d) {
|
||||
@@ -2844,7 +2863,7 @@ bool assign_qvvr_file_list(const std::string& id, ushort nCpuNo, const std::vect
|
||||
qfile.is_download = false;
|
||||
qfile.is_pair = false;
|
||||
qfile.file_time_count = 0;
|
||||
qfile.file_start =false;
|
||||
qfile.used_status =true;
|
||||
|
||||
// 添加到唯一的 qvvrevent
|
||||
monitor.qvvrevent.qvvrfile.push_back(std::move(qfile)); //记录暂态文件组
|
||||
@@ -2861,72 +2880,158 @@ bool assign_qvvr_file_list(const std::string& id, ushort nCpuNo, const std::vect
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////下载成功通知
|
||||
//提取下载路径的文件名
|
||||
std::string extract_filename(const std::string& path) {
|
||||
size_t pos = path.find_last_of("/\\");
|
||||
return (pos != std::string::npos) ? path.substr(pos + 1) : path;
|
||||
}
|
||||
|
||||
//发送匹配的所有录波文件
|
||||
bool SendAllQvvrFiles(qvvr_file& qfile, std::string& out_wavepath) {
|
||||
std::vector<std::string> wavepaths;
|
||||
std::string first_wavepath;
|
||||
bool send_success = true;
|
||||
|
||||
for (const auto& file_localpath : qfile.file_download) {
|
||||
std::string file_cloudpath = "comtrade/" + file_localpath;
|
||||
std::string wavepath_result;
|
||||
|
||||
// 发送本地文件到远端,返回 wavepath
|
||||
SOEFileWeb(const_cast<std::string&>(file_localpath), file_cloudpath, wavepath_result);
|
||||
|
||||
// 如果失败,重发一次
|
||||
if (wavepath_result.empty()) {
|
||||
std::cerr << "[SOEFileWeb] Warning: first send failed for file: " << file_localpath << ", retrying...\n";
|
||||
SOEFileWeb(const_cast<std::string&>(file_localpath), file_cloudpath, wavepath_result);
|
||||
}
|
||||
|
||||
if (wavepath_result.empty()) {
|
||||
send_success = false;
|
||||
std::cerr << "[SOEFileWeb] Failed: wavepath empty for file: " << file_localpath << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (wavepaths.empty()) {
|
||||
first_wavepath = wavepath_result;
|
||||
} else if (wavepath_result != first_wavepath) {
|
||||
send_success = false;
|
||||
std::cerr << "[SOEFileWeb] Mismatch wavepath: " << wavepath_result
|
||||
<< " vs " << first_wavepath << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
wavepaths.push_back(wavepath_result);
|
||||
}
|
||||
|
||||
// 检查数量是否一致
|
||||
if (!send_success || wavepaths.size() != qfile.file_download.size()) {
|
||||
std::cerr << "[SOEFileWeb] Failed to send all qvvr files. "
|
||||
<< "Sent: " << wavepaths.size()
|
||||
<< ", Expected: " << qfile.file_download.size() << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
out_wavepath = first_wavepath; // 返回统一的 wavepath
|
||||
|
||||
std::cout << "[SOEFileWeb] Success: all files sent for qfile. Wavepath = "
|
||||
<< first_wavepath << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
//文件下载结束接口
|
||||
bool update_qvvr_file_download(const std::string& filename_with_mac, const std::string& terminal_id) {
|
||||
// 去除 mac 路径前缀
|
||||
size_t pos = filename_with_mac.find_last_of("/\\");
|
||||
std::string filename = (pos != std::string::npos) ? filename_with_mac.substr(pos + 1) : filename_with_mac;
|
||||
// 去除 mac 路径前缀,仅保留文件名
|
||||
std::string filename = extract_filename(filename_with_mac);
|
||||
|
||||
// 提取逻辑序号(如 PQM1 → 1)
|
||||
size_t under_pos = filename.find('_');
|
||||
if (under_pos == std::string::npos) return false;
|
||||
|
||||
std::string type_part = filename.substr(0, under_pos); //PQMonitor_PQM1
|
||||
std::string type_part = filename.substr(0, under_pos); // PQMonitor_PQM1
|
||||
size_t num_start = type_part.find_last_not_of("0123456789");
|
||||
if (num_start == std::string::npos || num_start + 1 >= type_part.size()) return false;
|
||||
|
||||
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) {
|
||||
if (dev.terminal_id != terminal_id) continue;
|
||||
|
||||
for (auto& monitor : dev.line) {
|
||||
try {
|
||||
// 将监测点台账中的 logical_device_seq 转换为数字进行匹配
|
||||
ushort monitor_seq = static_cast<ushort>(std::stoi(monitor.logical_device_seq));
|
||||
if (monitor_seq != logical_seq) continue;
|
||||
} catch (...) {
|
||||
continue;
|
||||
continue; // logical_device_seq 非法,跳过
|
||||
}
|
||||
|
||||
// 匹配监测点下 qvvrfile 中的 file_name
|
||||
for (auto& qfile : monitor.qvvrevent.qvvrfile) {
|
||||
// file_name 中是文件名,需与提取的 filename 比较
|
||||
auto it = std::find(qfile.file_name.begin(), qfile.file_name.end(), filename);
|
||||
if (it != qfile.file_name.end()) {
|
||||
// 添加到 file_download(去重)
|
||||
if (std::find(qfile.file_download.begin(), qfile.file_download.end(), filename) == qfile.file_download.end()) {
|
||||
qfile.file_download.push_back(filename);
|
||||
// 添加到 file_download(记录完整路径,避免重复)
|
||||
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_time_count = 0;
|
||||
qfile.file_start = true; //开始下载文件
|
||||
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_down(qfile.file_download.begin(), qfile.file_download.end());
|
||||
std::set<std::string> s_down;
|
||||
for (const auto& path : qfile.file_download) {
|
||||
s_down.insert(extract_filename(path)); // 提取每个路径中的文件名
|
||||
}
|
||||
|
||||
// 检查 file_download 是否与 file_name 完全一致(集合相同)
|
||||
if (s_name == s_down) {
|
||||
qfile.is_download = true; //全部下载完成
|
||||
qfile.is_download = true; // 全部下载完成
|
||||
|
||||
// 找到其中的 .cfg 文件进行匹配
|
||||
for (const auto& f : qfile.file_download) {
|
||||
if (f.size() >= 4 && f.substr(f.size() - 4) == ".cfg") {
|
||||
if (compare_qvvr_and_file(f)) {//提取文件时标和监测点事件的时标匹配
|
||||
qfile.is_pair = true;
|
||||
//发送所有文件
|
||||
for (const auto& fpath : qfile.file_download) {
|
||||
std::string fname = extract_filename(fpath);
|
||||
if (fname.size() >= 4 && fname.substr(fname.size() - 4) == ".cfg") {
|
||||
// 提取文件时标和监测点事件的时标匹配
|
||||
if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata)) {
|
||||
qfile.is_pair = true; // 文件与事件匹配成功
|
||||
|
||||
//发送暂态事件
|
||||
|
||||
// 发送所有文件(已下载完成)
|
||||
std::string wavepath;
|
||||
if (SendAllQvvrFiles(qfile, wavepath)) {
|
||||
//文件发送成功后更新事件
|
||||
transfer_json_qvvr_data(terminal_id,
|
||||
logical_seq,
|
||||
monitor.qvvrevent.qvvrdata.QVVR_Amg,
|
||||
monitor.qvvrevent.qvvrdata.QVVR_PerTime,
|
||||
monitor.qvvrevent.qvvrdata.QVVR_time,
|
||||
monitor.qvvrevent.qvvrdata.QVVR_type,
|
||||
monitor.qvvrevent.qvvrdata.phase,
|
||||
wavepath);
|
||||
|
||||
// 清除暂态数据
|
||||
monitor.qvvrevent.qvvrfile.clear();
|
||||
monitor.qvvrevent.qvvrdata.clear();
|
||||
|
||||
// 删除上传成功的文件
|
||||
for (const auto& uploaded_file : qfile.file_download) {
|
||||
if (std::remove(uploaded_file.c_str()) != 0) {
|
||||
std::cerr << "[Cleanup] Failed to delete file: " << uploaded_file << "\n";
|
||||
} else {
|
||||
std::cout << "[Cleanup] Deleted uploaded file: " << uploaded_file << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break; // 只处理第一个 cfg 文件
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true; // 当前文件处理成功
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false; // 未匹配到终端ID或逻辑序号对应的监测点
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user