This commit is contained in:
zw
2025-08-08 16:26:01 +08:00
8 changed files with 429 additions and 144 deletions

View File

@@ -7,6 +7,8 @@
#include <cctype>
#include <cstdlib>
#include "client2.h"
#include <iostream>
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float IntToFloat(int num) {
return static_cast<float>(num) / 65536.0f;
@@ -32,7 +34,62 @@ void ReversalBuff(uint8_t* buff, int start, int length) {
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MAC<41><43>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_t startIndex) {
//lnk20250808
static inline int hex_nibble(char c) {
if (c >= '0' && c <= '9') return c - '0';
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
return -1;
}
// <20><>ȫ<EFBFBD><EFBFBD><E6A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true/false
bool GetMAC(const std::string& strMAC,
std::vector<unsigned char>& packet,
size_t startIndex,
std::string* err = nullptr) {
// 1) <20><EFBFBD><E6B7B6><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5> '-', ':', ' '
std::string s;
s.reserve(strMAC.size());
for (char c : strMAC) {
if (c == '-' || c == ':' || c == ' ') continue;
s.push_back(c);
}
// 2) <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>
if (s.size() != 12) {
if (err) *err = "MAC<EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD>Ϊ12<EFBFBD><EFBFBD>ʮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>";
return false;
}
// 3) ʮ<><CAAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3> + <20><><EFBFBD><EFBFBD>
std::array<unsigned char, 6> mac{};
for (int i = 0; i < 6; ++i) {
int hi = hex_nibble(s[2*i]);
int lo = hex_nibble(s[2*i + 1]);
if (hi < 0 || lo < 0) {
if (err) *err = "MAC<EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ַ<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0-9<><39>A-F)";
return false;
}
mac[i] = static_cast<unsigned char>((hi << 4) | lo);
}
// 4) ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㹻д<E3B9BB><D0B4>64<36>ֽڣ<D6BD>MAC 6<>ֽ<EFBFBD> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
const size_t need = startIndex + 64;
if (packet.size() < need) packet.resize(need, 0);
// 5) д<><D0B4>MAC
for (int i = 0; i < 6; ++i) {
packet[startIndex + i] = mac[i];
}
// 6) <20><><EFBFBD><EFBFBD>λ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD><E3A3A8> resize <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤һ<D6A4>£<EFBFBD>
for (size_t i = 6; i < 64; ++i) {
packet[startIndex + i] = 0;
}
return true;
}
/*void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_t startIndex) {
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>пո<D0BF><D5B8>Ͷ̺<CDB6><CCBA><EFBFBD>
std::string cleanedMAC = strMAC;
cleanedMAC.erase(std::remove(cleanedMAC.begin(), cleanedMAC.end(), ' '), cleanedMAC.end());
@@ -70,7 +127,7 @@ void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_
catch (const std::exception& e) {
throw std::invalid_argument("<22><>Ч<EFBFBD><D0A7>MAC<41><43>ַ: " + std::string(e.what()));
}
}
}*/
// CRC<52><43><EFBFBD><EFBFBD><E3BAAF>
unsigned char GetCrcSum(const std::vector<unsigned char>& Check, int nOffset, int nLen) {
@@ -292,7 +349,13 @@ std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac
// [16-19] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2 (<28><><EFBFBD><EFBFBD>Ϊ0)
// <20><><EFBFBD><EFBFBD>MAC<41><43>ַ (<28><>λ<EFBFBD><CEBB>20<32><30>ʼ<EFBFBD><CABC>64<36>ֽ<EFBFBD>)
GetMAC(strMac, packet, 20);
//GetMAC(strMac, packet, 20);
//lnk20250808
std::string err;
if (!GetMAC(strMac, packet, 0, &err)) {
std::cerr << "[GetMAC] parse failed: " << err << "\n";
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򷵻<EFBFBD>
}
// <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD> (<28><>ƫ<EFBFBD><C6AB>8<EFBFBD><38>137)
unsigned char checksum = 0;

View File

@@ -2703,7 +2703,27 @@ 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,qvvr_data& matched_data) {
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) {
matched_data = data; // 返回匹配到的事件
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////数据转换函数
// DataArrayItem to_json
void to_json(nlohmann::json& j, const DataArrayItem& d) {
@@ -2730,6 +2750,7 @@ void to_json(nlohmann::json& j, const MsgObj& m) {
// FullObj to_json
void to_json(nlohmann::json& j, const FullObj& f) {
j = nlohmann::json{
{"Id", f.mac},
{"Mid", f.Mid},
{"Did", f.Did},
{"Pri", f.Pri},
@@ -2738,6 +2759,7 @@ void to_json(nlohmann::json& j, const FullObj& f) {
};
}
std::string generate_json(
const std::string mac,
int Mid, //需应答的报文订阅者收到后需以此ID应答无需应答填入“-1”
int Did, //设备唯一标识Ldid填入0代表Ndid。
int Pri, //报文处理的优先级
@@ -2749,6 +2771,7 @@ std::string generate_json(
const std::vector<DataArrayItem>& dataArray //数据数组。
) {
FullObj fobj;
fobj.mac = mac;
fobj.Mid = Mid;
fobj.Did = Did;
fobj.Pri = Pri;
@@ -2772,7 +2795,7 @@ void upload_data_test(){
arr.push_back({2, 1691741340, 0, 1, "yyyy"});
std::string js = generate_json(
-1, 2, 1, 4866, 1, 0, 2, 1, arr
"123",-1, 1, 1, 4866, 1, 0, 2, 1, arr
);
std::cout << js << std::endl;
@@ -2794,8 +2817,9 @@ std::vector<DeviceInfo> GenerateDeviceInfoFromLedger(const std::vector<terminal_
DeviceInfo device;
device.device_id = terminal.terminal_id;
device.name = terminal.terminal_name;
device.model = terminal.dev_series;
device.mac = terminal.mac;
device.model = terminal.dev_type;
device.mac = terminal.addr_str;
device.status = 1;
for (const auto& monitor : terminal.line) {
PointInfo point;
@@ -2806,6 +2830,9 @@ std::vector<DeviceInfo> GenerateDeviceInfoFromLedger(const std::vector<terminal_
point.PT2 = monitor.PT2;
point.CT1 = monitor.CT1;
point.CT2 = monitor.CT2;
point.strScale = monitor.voltage_level;
point.nCpuNo = std::stoi(monitor.logical_device_seq);
point.nPTType = std::stoi(monitor.terminal_connect);
device.points.push_back(point);
}
@@ -2844,7 +2871,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,11 +2888,72 @@ bool assign_qvvr_file_list(const std::string& id, ushort nCpuNo, const std::vect
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////下载成功通知
//提取下载路径的文件名
std::string extract_filename1(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;
//台账加锁
std::lock_guard<std::mutex> lock(ledgermtx);
// 去除 mac 路径前缀,仅保留文件名
std::string filename = extract_filename1(filename_with_mac);
// 提取逻辑序号(如 PQM1 → 1
size_t under_pos = filename.find('_');
@@ -2876,57 +2964,117 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std::
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) {
for (size_t i = 0; i < monitor.qvvrevent.qvvrfile.size(); ++i) {
auto& qfile = monitor.qvvrevent.qvvrfile[i];
// 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_filename1(path)); // 提取每个路径中的文件名
}
// 检查 file_download 是否与 file_name 完全一致(集合相同)
if (s_name == s_down) {
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_filename1(fpath);
if (fname.size() >= 4 && fname.substr(fname.size() - 4) == ".cfg") {
// 提取文件时标和监测点事件的时标匹配
qvvr_data matched;
if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata,matched)) {
qfile.is_pair = true; // 文件与事件匹配成功
//发送暂态事件
// 发送所有文件(已下载完成)
std::string wavepath;
if (SendAllQvvrFiles(qfile, wavepath)) {
//文件发送成功后更新事件
transfer_json_qvvr_data(terminal_id,
logical_seq,
matched.QVVR_Amg,
matched.QVVR_PerTime,
matched.QVVR_time,
matched.QVVR_type,
matched.phase,
wavepath);
// 删除上传成功的文件
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";
}
}
// 清除已发送的暂态文件
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 文件
}
}
}
else{
std::cout << "qvvr file still imcomplete!!!" << std::endl;
}
return true;
}
}
return true; // 当前文件处理成功
}
}
return false;
std::cout << "file name doesnt match any file in this monitor!!!" << std::endl;
}
}
return false; // 未匹配到终端ID或逻辑序号对应的监测点
}
////////////////////////////////////////////////////////////////////////////////////////提取mac
std::string normalize_mac(const std::string& mac) {
std::string result = mac;
result.erase(std::remove(result.begin(), result.end(), '-'), result.end());
return result;
}

View File

@@ -609,27 +609,27 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
dev.terminal_id = safe_str(item, "id");
dev.addr_str = safe_str(item, "ip");
dev.terminal_name = safe_str(item, "name");
dev.org_name = safe_str(item, "org_name");
dev.maint_name = safe_str(item, "maint_name");
dev.station_name = safe_str(item, "stationName");
dev.tmnl_factory = safe_str(item, "manufacturer");
dev.tmnl_status = safe_str(item, "status");
//dev.org_name = safe_str(item, "org_name");
//dev.maint_name = safe_str(item, "maint_name");
//dev.station_name = safe_str(item, "stationName");
//dev.tmnl_factory = safe_str(item, "manufacturer");
//dev.tmnl_status = safe_str(item, "status");
dev.dev_type = safe_str(item, "devType");
dev.dev_key = safe_str(item, "devKey");
dev.dev_series = safe_str(item, "series");
dev.port = safe_str(item, "port");
dev.timestamp = safe_str(item, "updateTime");
dev.processNo = safe_str(item, "processNo");
dev.maxProcessNum = safe_str(item, "maxProcessNum");
//dev.dev_key = safe_str(item, "devKey");
//dev.dev_series = safe_str(item, "series");
//dev.port = safe_str(item, "port");
//dev.timestamp = safe_str(item, "updateTime");
dev.processNo = safe_str(item, "node");
//dev.maxProcessNum = safe_str(item, "maxProcessNum");
dev.mac = safe_str(item, "mac");//添加mac
//dev.mac = safe_str(item, "mac");//添加mac
if (item.contains("monitorData") && item["monitorData"].is_array()) {
for (auto& mon : item["monitorData"]) {
if (dev.line.size() >= 10) break;
ledger_monitor m;
m.monitor_id = safe_str(mon, "id");
m.terminal_id = safe_str(mon, "terminal_id");
m.terminal_id = safe_str(mon, "deviceId");
m.monitor_name = safe_str(mon, "name");
m.logical_device_seq = safe_str(mon, "lineNo");
m.voltage_level = safe_str(mon, "voltageLevel");
@@ -637,10 +637,10 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
m.timestamp = safe_str(mon, "updateTime");
m.status = safe_str(mon, "status");
m.CT1 = mon.value("CT1", 0.0);
m.CT2 = mon.value("CT2", 0.0);
m.PT1 = mon.value("PT1", 0.0);
m.PT2 = mon.value("PT2", 0.0);
m.CT1 = mon.value("ct1", 0.0);
m.CT2 = mon.value("ct2", 0.0);
m.PT1 = mon.value("pt1", 0.0);
m.PT2 = mon.value("pt2", 0.0);
dev.line.push_back(m);
}
@@ -736,9 +736,9 @@ int parse_device_cfg_web()
if (IED_COUNT < count_cfg) {
std::cout << "!!!!!!!!!!single process can not add any ledger unless reboot!!!!!!!" << std::endl;
DIY_WARNLOG("process","【WARN】前置的%d号进程获取到的台账的数量大于配置文件中给单个进程配置的台账数量:%d,这个进程将按照获取到的台账的数量来创建台账空间,这个进程不能直接通过台账添加来新增台账,只能通过重启进程或者先删除已有台账再添加台账的方式来添加新台账", g_front_seg_index, IED_COUNT);
//DIY_WARNLOG("process","【WARN】前置的%d号进程获取到的台账的数量大于配置文件中给单个进程配置的台账数量:%d,这个进程将按照获取到的台账的数量来创建台账空间,这个进程不能直接通过台账添加来新增台账,只能通过重启进程或者先删除已有台账再添加台账的方式来添加新台账", g_front_seg_index, IED_COUNT);
} else {
DIY_INFOLOG("process","【NORMAL】前置的%d号进程根据配置文件中给单个进程配置的台账数量:%d来创建台账空间", g_front_seg_index, IED_COUNT);
//DIY_INFOLOG("process","【NORMAL】前置的%d号进程根据配置文件中给单个进程配置的台账数量:%d来创建台账空间", g_front_seg_index, IED_COUNT);
}
///////////////////////////////////////////////////////////////////////////////用例这里将局部的map拷贝到全局map后续根据协议台账修改
@@ -1149,32 +1149,24 @@ static void scanAndResendOfflineFiles(const std::string& dirPath)
}
}
int transfer_json_qvvr_data(unsigned int func_type, int monitor_id,
double mag, double dur, long long start_tm, long long end_tm, int dis_kind,
const std::string& uuid_cfg, const std::string& uuid_dat,
const std::string& mp_id, const std::string& Qvvr_rptname, const std::string& devtype) {
int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
double mag, double dur, long long start_tm, int dis_kind,int phase,
const std::string& wavepath) {
// 监测点日志的 key, lnk20250526
std::string full_key_m_c = "monitor." + mp_id + ".COM";
std::string full_key_m_d = "monitor." + mp_id + ".DATA";
std::string full_key_m_c = "monitor." + dev_id + "." + std::to_string(monitor_id) + ".COM";
std::string full_key_m_d = "monitor." + dev_id + "." + std::to_string(monitor_id) + ".DATA";
// 监测点日志的 key, lnk20250526
// 获取装置类型的映射配置
XmlConfig c_xmlcfg;
if (xmlinfo_list.count(devtype)) {
c_xmlcfg = xmlinfo_list[devtype]->xmlcfg;
} else {
c_xmlcfg = xmlcfg;
}
if (mp_id.empty()) {
std::cout << "mp_id is null" << std::endl;
if (dev_id.empty()) {
std::cout << "dev_id is null" << std::endl;
return 0;
}
// 构造 JSON 对象
json root;
root["monitorId"] = mp_id;
root["devId"] = dev_id;
root["CpuNo"] = monitor_id;
root["amplitude"] = mag;
root["duration"] = dur;
root["eventType"] = dis_kind;
@@ -1189,21 +1181,9 @@ int transfer_json_qvvr_data(unsigned int func_type, int monitor_id,
std::string start_time_str = start_time_stream.str();
root["startTime"] = start_time_str;
root["wavePath"] = uuid_dat; //接口提供了两个文件名入参,实际上名字一样只用一个,可优化
root["wavePath"] = wavepath;
root["phase"] = phase;
if (c_xmlcfg.WavePhasicFlag == "1") { //映射配置分相
if (Qvvr_rptname.find(c_xmlcfg.WavePhasicA) != std::string::npos) {
root["phase"] = "A";
} else if (Qvvr_rptname.find(c_xmlcfg.WavePhasicB) != std::string::npos) {
root["phase"] = "B";
} else if (Qvvr_rptname.find(c_xmlcfg.WavePhasicC) != std::string::npos) {
root["phase"] = "C";
} else {
root["phase"] = "unknow";
}
} else {
root["phase"] = "unknow"; //不分相
}
std::string json_string = root.dump(4);
std::cout << json_string << std::endl;
@@ -1212,28 +1192,28 @@ int transfer_json_qvvr_data(unsigned int func_type, int monitor_id,
std::string response;
SendJsonAPI_web(WEB_EVENT, "", json_string, response);
// ================ 插入新功能 =========================
// ================ 暂态重发功能 =========================
if (!response.empty()) {
try {
json j_r = json::parse(response);
// 有效响应,略过
} catch (...) {
// 响应异常,保存 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监测点%s的暂态事件",dev_id, monitor_id);
std::cout << "qvvr send fail ,store in local" << std::endl;
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 + dev_id + "-" + std::to_string(monitor_id) + "-" + FormatTimeForFilename(start_time_str) + "-" + std::to_string(dis_kind) + ".txt";
writeJsonToFile(fileName, json_string);
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
}
} else {
// 无响应,保存 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监测点%s的暂态事件",dev_id, monitor_id);
std::cout << "qvvr send fail ,store in local" << std::endl;
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 + dev_id + "-" + std::to_string(monitor_id) + "-" + FormatTimeForFilename(start_time_str) + "-" + std::to_string(dis_kind) + ".txt";
writeJsonToFile(fileName, json_string);
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
return 1;
@@ -1254,13 +1234,9 @@ int transfer_json_qvvr_data(unsigned int func_type, int monitor_id,
void qvvr_test()
{
char uuid_cfg[] = {"/comtrade/"};
char uuid_dat[] = {"/comtrade/"};
char mp_id[] = {"qvvrtest123"};
char Qvvr_rptname[] = {"unknow"};
char devtype[] = {"01"};
transfer_json_qvvr_data(1, 123456789, 220, 180, 1730894400.123, 1730894580, 1210001,uuid_cfg,uuid_dat,mp_id,Qvvr_rptname,devtype);
transfer_json_qvvr_data("qvvrtest123", 6,
10.98, 1234, 1754566628692, 1,1,
"testwavepath");
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////通用接口响应

View File

@@ -52,7 +52,8 @@ public:
//录波文件和暂态事件
class qvvr_data
{
int used_status; //是否占用
public:
bool used_status; //是否占用
int QVVR_type; //暂态类型
uint64_t QVVR_time; //暂态开始时间 unsigned longlong
double QVVR_PerTime; //暂态持续时间
@@ -62,7 +63,8 @@ class qvvr_data
class qvvr_file
{
bool file_start;
public:
bool used_status;
int file_time_count; //组内文件下载时间计数第一个文件下载后十分钟内如果其他文件没下载全或者下载全了没匹配事件则将已下载的文件都移到备份区comtrade_bak
bool is_download; //文件是否下载完全,最后一个文件下载成功后对比成功则更新这个标志
bool is_pair; //文件是否和事件匹配从comtrade/mac/路径下取file_download中的cfg文件提取时间和持续时间来匹配匹配后接口发送这组file_download全部文件发送成功后删除这组文件然后更新事件中的文件列表
@@ -72,6 +74,7 @@ class qvvr_file
class qvvr_event
{
public:
std::vector<qvvr_data> qvvrdata; //暂态事件列表
std::vector<qvvr_file> qvvrfile; //暂态文件组列表
};
@@ -426,6 +429,7 @@ struct MsgObj {
// 整体
struct FullObj {
std::string mac;
int Mid;
int Did;
int Pri;
@@ -443,6 +447,7 @@ void to_json(nlohmann::json& j, const FullObj& f);
std::vector<DeviceInfo> GenerateDeviceInfoFromLedger(const std::vector<terminal_dev>& terminal_devlist);//接口读取台账后,再调用这个将台账拷贝过来
std::string generate_json( //构造装置主动上送数据的报文
const std::string mac,
int Mid, //需应答的报文订阅者收到后需以此ID应答无需应答填入“-1”
int Did, //设备唯一标识Ldid填入0代表Ndid。
int Pri, //报文处理的优先级
@@ -454,14 +459,21 @@ std::string generate_json( //构造装置主动上送数据的报文
const std::vector<DataArrayItem>& dataArray //数据数组。
);
int transfer_json_qvvr_data(unsigned int func_type, int monitor_id, //暂态事件接口
double mag, double dur, long long start_tm, long long end_tm, int dis_kind,
const std::string& uuid_cfg, const std::string& uuid_dat,
const std::string& mp_id, const std::string& Qvvr_rptname, const std::string& devtype);
//暂态事件接口
int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
double mag, double dur, long long start_tm, int dis_kind,int phase,
const std::string& wavepath);
//录波文件上传接口
void SOEFileWeb(std::string& localpath,std::string& cloudpath, std::string& wavepath);
//录波文件目录接口
bool assign_qvvr_file_list(const std::string& id, ushort nCpuNo, const std::vector<std::string>& file_list_raw);
//录波文件下载完成通知接口
bool update_qvvr_file_download(const std::string& filename_with_mac, const std::string& terminal_id);
//提取mac
std::string normalize_mac(const std::string& mac);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -334,8 +334,8 @@ void init_loggers_bydevid(const std::string& dev_id)
const ledger_monitor& monitor = term.line[j];
if (!monitor.monitor_id.empty()) {
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
mon_key_c << "monitor." << monitor.monitor_id << ".COM";
mon_key_d << "monitor." << monitor.monitor_id << ".DATA";
mon_key_c << "monitor." << term.terminal_id << "." << monitor.logical_device_seq << ".COM";
mon_key_d << "monitor." << term.terminal_id << "." << monitor.logical_device_seq << ".DATA";
mon_path << device_dir << "/monitor" << j;
mon_name << monitor.monitor_id;
@@ -355,7 +355,7 @@ void init_loggers_bydevid(const std::string& dev_id)
logger_map[mon_key_c.str()] = TypedLogger(mon_logger_c, LOGTYPE_COM);
logger_map[mon_key_d.str()] = TypedLogger(mon_logger_d, LOGTYPE_DATA);
DIY_WARNLOG(mon_key_d.str().c_str(), "【WARN】监测点:%s - id:%s监测点级日志初始化完毕", monitor.monitor_name.c_str(), monitor.monitor_id.c_str());
DIY_WARNLOG(mon_key_d.str().c_str(), "【WARN】监测点:%s - id:%s监测点级日志初始化完毕", monitor.monitor_name.c_str(), monitor.logical_device_seq.c_str());
}
}
}
@@ -406,8 +406,8 @@ void init_loggers()
if (!monitor.monitor_id.empty()) {
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
mon_key_c << "monitor." << monitor.monitor_id << ".COM";
mon_key_d << "monitor." << monitor.monitor_id << ".DATA";
mon_key_c << "monitor." << term.terminal_id << "." << monitor.logical_device_seq << ".COM";
mon_key_d << "monitor." << term.terminal_id << "." << monitor.logical_device_seq << ".DATA";
mon_path << device_dir << "/monitor" << i; // 用monitor+序号作为目录
mon_name << monitor.monitor_id;
@@ -425,7 +425,7 @@ void init_loggers()
logger_map[mon_key_d.str()] = TypedLogger(mon_logger_d, LOGTYPE_DATA);
DIY_WARNLOG(mon_key_d.str().c_str(), "【WARN】监测点:%s - id:%s监测点级日志初始化完毕",
monitor.monitor_name.c_str(), monitor.monitor_id.c_str());
monitor.monitor_name.c_str(), monitor.logical_device_seq.c_str());
}
}
}

View File

@@ -215,7 +215,7 @@ std::string get_parent_directory() {
init_loggers();
//读取模型,下载模板文件
parse_model_cfg_web();
//parse_model_cfg_web();
//解析模板文件
//Set_xml_nodeinfo();
@@ -518,16 +518,35 @@ void Front::mqproducerThread()
extern thread_info_t thread_info[THREAD_CONNECTIONS];
void cleanup_args(ThreadArgs* args) {
for (int i = 0; i < args->argc; ++i) {
free(args->argv[i]); // strdup 分配的
}
delete[] args->argv;
delete args;
}
void* cloudfrontthread(void* arg) {
///////////////////////////////////////
ThreadArgs* args = static_cast<ThreadArgs*>(arg);
int argc = args->argc;
char **argv = args->argv;
printf("argc = %d, argv[0] = %s\n", argc, argv[0]);
printf("[cloudfrontthread] argc = %d\n", argc);
for (int i = 0; i < argc; ++i) {
printf(" argv[%d] = %s\n", i, argv[i]);
}
//添加线程处理
int index = *(int*)argv[0];
// 动态解析线程 index
int index = 0;
if (argc > 0 && argv[0]) {
try {
index = std::stoi(argv[0]);
} catch (...) {
std::cerr << "[cloudfrontthread] Failed to parse index from argv[0]: " << argv[0] << "\n";
return nullptr;
}
}
// 更新线程状态为运行中
pthread_mutex_lock(&thread_info[index].lock);
@@ -539,11 +558,12 @@ void* cloudfrontthread(void* arg) {
// 解析命令行参数
if(!parse_param(argc,argv)){
std::cerr << "process param error,exit" << std::endl;
cleanup_args(args);
return nullptr;
}
// 线程使用完后清理参数
delete args;
cleanup_args(args);
//路径获取
FRONT_PATH = get_parent_directory();

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"
<< ", ʱ<><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 {
// <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;
//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> ==========
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>)
@@ -346,22 +354,23 @@ void process_received_message(string mac, string id,const char* data, size_t len
std::vector<DataArrayItem> arr;
arr.push_back({1, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1-<2D>ޣ<EFBFBD> 0-<2D><>Rt<52><74>,1-<2D><>Max<61><78>,2-<2D><>Min<69><6E>,3-<2D><>Avg<76><67>,4-<2D><>Cp95<39><35>
data_time, //<2F><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EAA3AC><EFBFBD><EFBFBD>1970<37><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA3AC>Ч<EFBFBD><D0A7><EFBFBD>롰-1<><31>
-1, //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>꣬΢<EAA3AC><CEA2><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>롰-1<><31>
0, //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>꣬΢<EAA3AC><CEA2><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>롰-1<><31>
0, //<2F><><EFBFBD>ݱ<EFBFBD>ʶ<EFBFBD><CAB6>1-<2D><>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD>
max_base64Str});
arr.push_back({2, data_time, -1, 0, min_base64Str});
arr.push_back({3, data_time, -1, 0, avg_base64Str});
arr.push_back({4, data_time, -1, 0, cp95_base64Str});
arr.push_back({2, data_time, 0, 0, min_base64Str});
arr.push_back({3, data_time, 0, 0, avg_base64Str});
arr.push_back({4, data_time, 0, 0, cp95_base64Str});
std::string js = generate_json(
normalize_mac(mac),
-1, //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD>ı<EFBFBD><C4B1>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>IDӦ<44><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>롰-1<><31>
123456, //<2F>豸Ψһ<CEA8><D2BB>ʶLdid<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>Ndid,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>id<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
3, //<2F><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>1 I<><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 2 II<49><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 3 <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>/<2F><>Ӧ 4 <20><EFBFBD><E3B2A5><EFBFBD><EFBFBD>
1, //<2F>豸Ψһ<CEA8><D2BB>ʶLdid<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>Ndid,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>id<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1, //<2F><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>1 I<><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 2 II<49><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 3 <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>/<2F><>Ӧ 4 <20><EFBFBD><E3B2A5><EFBFBD><EFBFBD>
0x1302, //<2F><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
avg_data.name, //<2F>߼<EFBFBD><DFBC><EFBFBD><EFBFBD>豸ID<49><44>0-<2D>߼<EFBFBD><DFBC><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
0x04, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹̶<CDB9>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3>ޡ<EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>ʵʱ<CAB5><CAB1>1<EFBFBD><31><EFBFBD><EFBFBD>ͳ<EFBFBD>ơ<EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD>
-1, //<2F><><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
1, //<2F><><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
arr //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
);
@@ -535,18 +544,19 @@ void process_received_message(string mac, string id,const char* data, size_t len
std::vector<DataArrayItem> arr;
arr.push_back({1, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -1-<2D>ޣ<EFBFBD> 0-<2D><>Rt<52><74>,1-<2D><>Max<61><78>,2-<2D><>Min<69><6E>,3-<2D><>Avg<76><67>,4-<2D><>Cp95<39><35>
data_time, //<2F><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EAA3AC><EFBFBD><EFBFBD>1970<37><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA3AC>Ч<EFBFBD><D0A7><EFBFBD>롰-1<><31>
-1, //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>꣬΢<EAA3AC><CEA2><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>롰-1<><31>
0, //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>꣬΢<EAA3AC><CEA2><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>롰-1<><31>
0, //<2F><><EFBFBD>ݱ<EFBFBD>ʶ<EFBFBD><CAB6>1-<2D><>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD>
base64});
std::string js = generate_json(
normalize_mac(mac),
-1, //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD>ı<EFBFBD><C4B1>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>IDӦ<44><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>롰-1<><31>
123456, //<2F>豸Ψһ<CEA8><D2BB>ʶLdid<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>Ndid,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>id<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
3, //<2F><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>1 I<><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 2 II<49><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 3 <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>/<2F><>Ӧ 4 <20><EFBFBD><E3B2A5><EFBFBD><EFBFBD>
1, //<2F>豸Ψһ<CEA8><D2BB>ʶLdid<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>Ndid,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>id<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1, //<2F><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD>1 I<><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 2 II<49><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>Ӧ 3 <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>/<2F><>Ӧ 4 <20><EFBFBD><E3B2A5><EFBFBD><EFBFBD>
0x1302, //<2F><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cid, //<2F>߼<EFBFBD><DFBC><EFBFBD><EFBFBD>豸ID<49><44>0-<2D>߼<EFBFBD><DFBC><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
0x04, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹̶<CDB9>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3>ޡ<EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD>ʵʱ<CAB5><CAB1>1<EFBFBD><31><EFBFBD><EFBFBD>ͳ<EFBFBD>ơ<EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD>
-1, //<2F><><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
1, //<2F><><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
arr //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
);
//std::cout << js << std::en
@@ -644,6 +654,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()),
file_data.size());
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 {
std::cerr << "Failed to save file: " << file_path

View File

@@ -8,6 +8,8 @@
#include "cloudfront/code/interface.h"
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
#if 0
@@ -32,6 +34,9 @@ typedef struct {
} thread_info_t;
#endif
extern int INITFLAG;//̨<>˵ȳ<CBB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־
extern void cleanup_args(ThreadArgs* args);
void init_daemon(void)
{
int pid;
@@ -108,6 +113,32 @@ std::vector<DeviceInfo> generate_test_devices(int count) {
return devices;
}
void PrintDevices(const std::vector<DeviceInfo>& devices) {
std::cout << "==== Devices List (" << devices.size() << ") ====\n";
for (const auto& dev : devices) {
std::cout << "Device ID : " << dev.device_id << "\n";
std::cout << "Name : " << dev.name << "\n";
std::cout << "Model : " << dev.model << "\n";
std::cout << "MAC : " << dev.mac << "\n";
std::cout << "Status : " << dev.status << "\n";
std::cout << "Points (" << dev.points.size() << "):\n";
for (const auto& pt : dev.points) {
std::cout << " Point ID : " << pt.point_id << "\n";
std::cout << " Name : " << pt.name << "\n";
std::cout << " Device ID : " << pt.device_id << "\n";
std::cout << " Cpu No : " << pt.nCpuNo << "\n";
std::cout << " PT1 : " << pt.PT1 << "\n";
std::cout << " PT2 : " << pt.PT2 << "\n";
std::cout << " CT1 : " << pt.CT1 << "\n";
std::cout << " CT2 : " << pt.CT2 << "\n";
std::cout << " Scale : " << pt.strScale << "\n";
std::cout << " PTType : " << pt.nPTType << "\n";
std::cout << "----------------------\n";
}
std::cout << "==========================\n";
}
}
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<><30><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
/* <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD>̺߳<DFB3><CCBA><EFBFBD>*/
void* client_manager_thread(void* arg) {
@@ -207,7 +238,7 @@ void restart_thread(int index) {
int* new_index = (int*)malloc(sizeof(int));
*new_index = index;
if (index == 0) {
if (index == 1) {
// <20>ͻ<EFBFBD><CDBB>˹<EFBFBD><CBB9><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[index].tid, NULL, client_manager_thread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
@@ -217,7 +248,7 @@ void restart_thread(int index) {
free(new_index);
}
}
else if (index == 1) {
else if (index == 2) {
// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[index].tid, NULL, message_processor_thread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
@@ -227,7 +258,7 @@ void restart_thread(int index) {
free(new_index);
}
}
else if (index == 2) {
else if (index == 0) {
// <20>ӿڣ<D3BF>mq
char* argv[] = { (char*)new_index };//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺Ų<CCBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ThreadArgs* args = new ThreadArgs{1, argv};
@@ -251,6 +282,16 @@ int is_thread_alive(pthread_t tid) {
return pthread_tryjoin_np(tid, NULL) == EBUSY; // EBUSY<53><59>ʾ<EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
//lnk<6E><6B><EFBFBD><EFBFBD>
ThreadArgs* make_thread_args_from_strs(const std::vector<std::string>& args_vec) {
char** argv = new char*[args_vec.size() + 1]; // <20><>һ<EFBFBD><D2BB> nullptr <20><>β
for (size_t i = 0; i < args_vec.size(); ++i) {
argv[i] = strdup(args_vec[i].c_str()); // strdup <20><> malloc <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
argv[args_vec.size()] = nullptr;
return new ThreadArgs{static_cast<int>(args_vec.size()), argv};
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
int main(int argc ,char** argv) {//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>
if(!parse_param(argc,argv)){
@@ -267,34 +308,46 @@ int main(int argc ,char** argv) {//
pthread_mutex_init(&thread_info[i].lock, NULL); // <20><>ʼ<EFBFBD><CABC>ÿ<EFBFBD><C3BF><EFBFBD>̵߳<DFB3><CCB5><EFBFBD>
}
//<2F>ӿں<D3BF>mq
ThreadArgs* args = make_thread_args_from_strs({ "0" });
if (pthread_create(&thread_info[0].tid, NULL, cloudfrontthread, args) != 0) {
printf("Failed to create message processor thread 0\n");
cleanup_args(args);
}
while(!INITFLAG){
std::this_thread::sleep_for(std::chrono::seconds(3));
std::cout << "waiting cloudfront initialize ..." << std::endl;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>߳<EFBFBD><DFB3><EFBFBD>
for (int i = 0; i < THREAD_CONNECTIONS; i++) {
for (int i = 1; i < THREAD_CONNECTIONS; i++) {
int* index = (int*)malloc(sizeof(int));
*index = i;
if (i == 0) {
if (i == 1) {
// <20>ͻ<EFBFBD><CDBB>˹<EFBFBD><CBB9><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[i].tid, NULL, client_manager_thread, index) != 0) {
printf("Failed to create client manager thread %d\n", i);
free(index);
}
}
else if (i == 1) {
else if (i == 2) {
// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[i].tid, NULL, message_processor_thread, index) != 0) {
printf("Failed to create message processor thread %d\n", i);
free(index);
}
}
else if (i == 2){
//<2F>ӿں<D3BF>mq
else if (i == 3){
/*//<2F>ӿں<D3BF>mq
char* argv[] = { (char*)index };//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺Ų<CCBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ThreadArgs* args = new ThreadArgs{1, argv};
if (pthread_create(&thread_info[i].tid, NULL, cloudfrontthread, args) != 0) {
printf("Failed to create message processor thread %d\n", i);
delete args; // <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6>ͷ<EFBFBD>
free(index);
}
}*/
}
else {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>