数据追踪原始报告块
This commit is contained in:
@@ -32,10 +32,12 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QMapIterator>
|
||||
#include <QStringList>
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
|
||||
// ★MOD: 全局追踪表:mp_id -> remaining times
|
||||
//全局追踪表:mp_id -> rpt_no -> remaining times
|
||||
static QMutex g_trace_mutex;
|
||||
static QHash<QString, int> g_trace_map;
|
||||
static QHash<QString, QHash<int, int> > g_trace_map;
|
||||
|
||||
///////////////////////////////////////////////////lnk2024-10-21////////////////////////////////////////////////////////
|
||||
extern void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr);
|
||||
@@ -258,36 +260,77 @@ static QString escape_json_string(const QString& s)
|
||||
return out;
|
||||
}
|
||||
|
||||
// 打开追踪:次数 times(比如 5)
|
||||
// 打开追踪:每个报告各追踪一次
|
||||
void process_trace_command(const std::string& id, int times)
|
||||
{
|
||||
if (times <= 0) return;
|
||||
(void)times;
|
||||
QString qid = QString::fromStdString(id).trimmed();
|
||||
if (qid.isEmpty()) return;
|
||||
|
||||
QList<int> rpt_nos;
|
||||
|
||||
QByteArray qid_bytes = qid.toLocal8Bit();
|
||||
|
||||
pthread_mutex_lock(&mtx);
|
||||
LD_info_t *ld_info = find_LD_info_only_from_mp_id(qid_bytes.data());
|
||||
if (ld_info != NULL && ld_info->rptinfo != NULL && ld_info->rptcount > 0) {
|
||||
for (int i = 0; i < ld_info->rptcount; ++i) {
|
||||
if (ld_info->rptinfo[i] == NULL)
|
||||
continue;
|
||||
|
||||
int rpt_no = ld_info->rptinfo[i]->rptNo;
|
||||
if (!rpt_nos.contains(rpt_no))
|
||||
rpt_nos.append(rpt_no);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mtx);
|
||||
|
||||
if (rpt_nos.isEmpty()) {
|
||||
cout << "[TRACE] mp_id=" << id << " has no report info" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
QMutexLocker lk(&g_trace_mutex);
|
||||
g_trace_map[qid] = times; // 重新打开就覆盖/重置次数
|
||||
QHash<int, int>& rpt_map = g_trace_map[qid];
|
||||
for (int i = 0; i < rpt_nos.size(); ++i) {
|
||||
int rpt_no = rpt_nos.at(i);
|
||||
rpt_map[rpt_no] = rpt_map.value(rpt_no, 0) + 1;
|
||||
cout << "[TRACE] mp_id=" << id << " add rpt_no=" << rpt_no
|
||||
<< " left=" << rpt_map.value(rpt_no) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 查询是否要追踪
|
||||
static bool trace_is_enabled(const QString& mp_id)
|
||||
static bool trace_is_enabled(const QString& mp_id, int rpt_no)
|
||||
{
|
||||
QMutexLocker lk(&g_trace_mutex);
|
||||
auto it = g_trace_map.constFind(mp_id);
|
||||
return (it != g_trace_map.constEnd() && it.value() > 0);
|
||||
QHash<QString, QHash<int, int> >::const_iterator mp_it = g_trace_map.constFind(mp_id);
|
||||
if (mp_it == g_trace_map.constEnd())
|
||||
return false;
|
||||
|
||||
QHash<int, int>::const_iterator rpt_it = mp_it.value().constFind(rpt_no);
|
||||
return (rpt_it != mp_it.value().constEnd() && rpt_it.value() > 0);
|
||||
}
|
||||
|
||||
// 命中一次并扣减;扣到 0 自动删
|
||||
static void trace_hit_and_decrement(const QString& mp_id)
|
||||
static void trace_hit_and_decrement(const QString& mp_id, int rpt_no)
|
||||
{
|
||||
QMutexLocker lk(&g_trace_mutex);
|
||||
auto it = g_trace_map.find(mp_id);
|
||||
if (it == g_trace_map.end()) return;
|
||||
QHash<QString, QHash<int, int> >::iterator mp_it = g_trace_map.find(mp_id);
|
||||
if (mp_it == g_trace_map.end()) return;
|
||||
|
||||
int left = it.value();
|
||||
QHash<int, int>::iterator rpt_it = mp_it.value().find(rpt_no);
|
||||
if (rpt_it == mp_it.value().end()) return;
|
||||
|
||||
int left = rpt_it.value();
|
||||
left -= 1;
|
||||
if (left <= 0) g_trace_map.erase(it);
|
||||
else it.value() = left;
|
||||
if (left <= 0)
|
||||
mp_it.value().erase(rpt_it);
|
||||
else
|
||||
rpt_it.value() = left;
|
||||
|
||||
if (mp_it.value().isEmpty())
|
||||
g_trace_map.erase(mp_it);
|
||||
}
|
||||
|
||||
//追踪61850原始数据
|
||||
@@ -316,19 +359,20 @@ static QString build_mms_json_object(const json_block_data* data)
|
||||
return json;
|
||||
}
|
||||
|
||||
static QString build_trace_json(const json_block_data* data, const char *v_wiring_type, const char *source_name)
|
||||
static QString build_trace_json(const json_block_data* data, const char *v_wiring_type, const char *rpt_id, int rpt_no)
|
||||
{
|
||||
if (!data) return "{}";
|
||||
|
||||
QString mms_json = build_mms_json_object(data);
|
||||
QString wiring_type = v_wiring_type ? QString::fromLocal8Bit(v_wiring_type) : "";
|
||||
QString source = source_name ? QString::fromLocal8Bit(source_name) : "";
|
||||
QString rpt = rpt_id ? QString::fromLocal8Bit(rpt_id) : "";
|
||||
|
||||
QString json;
|
||||
json += "{";
|
||||
json += QString("\"mp_id\":\"%1\",").arg(escape_json_string(data->mp_id));
|
||||
json += QString("\"v_wiring_type\":\"%1\",").arg(escape_json_string(wiring_type));
|
||||
json += QString("\"source_name\":\"%1\",").arg(escape_json_string(source));
|
||||
json += QString("\"rpt_id\":\"%1\",").arg(escape_json_string(rpt));
|
||||
json += QString("\"rpt_no\":%1,").arg(rpt_no);
|
||||
json += QString("\"func_type\":%1,").arg(data->func_type);
|
||||
json += QString("\"data_time\":%1,").arg(QString::number((qlonglong)data->time));
|
||||
json += QString("\"voltage_level\":\"%1\",").arg(QString::number(data->voltage_level, 'f', 6));
|
||||
@@ -339,13 +383,13 @@ static QString build_trace_json(const json_block_data* data, const char *v_wirin
|
||||
return json;
|
||||
}
|
||||
|
||||
static void send_trace_if_needed(json_block_data* pdata, const char *v_wiring_type, const char *source_name)
|
||||
static void send_trace_if_needed(json_block_data* pdata, const char *v_wiring_type, const char *rpt_id, int rpt_no)
|
||||
{
|
||||
const QString mp_id_q = pdata->mp_id;
|
||||
if (trace_is_enabled(mp_id_q)) {
|
||||
if (trace_is_enabled(mp_id_q, rpt_no)) {
|
||||
|
||||
// 1) 组 json
|
||||
QString jsonText = build_trace_json(pdata, v_wiring_type, source_name);
|
||||
QString jsonText = build_trace_json(pdata, v_wiring_type, rpt_id, rpt_no);
|
||||
|
||||
// 2) 组 KafkaData
|
||||
Ckafka_data_t KafkaData;
|
||||
@@ -359,9 +403,25 @@ static void send_trace_if_needed(json_block_data* pdata, const char *v_wiring_ty
|
||||
kafka_data_list_mutex.unlock();
|
||||
|
||||
// 3) 次数 -1
|
||||
trace_hit_and_decrement(mp_id_q);
|
||||
trace_hit_and_decrement(mp_id_q, rpt_no);
|
||||
}
|
||||
}
|
||||
|
||||
int trace_json_block_data(char v_wiring_type[], json_block_data *data, const char *rpt_id, int rpt_no)
|
||||
{
|
||||
send_trace_if_needed(data, v_wiring_type, rpt_id, rpt_no);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int trace_json_is_enabled(const char *mp_id, int rpt_no)
|
||||
{
|
||||
QString mp_id_q = mp_id ? QString::fromLocal8Bit(mp_id).trimmed() : "";
|
||||
if (mp_id_q.isEmpty())
|
||||
return 0;
|
||||
|
||||
return trace_is_enabled(mp_id_q, rpt_no) ? 1 : 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////lnk20250710添加频率值存储
|
||||
struct mp_freq_save {
|
||||
double G_FREQ;
|
||||
@@ -1166,9 +1226,12 @@ void printCTopicList(const std::list<CTopic*>& ctopic_list) {
|
||||
val->fValue);
|
||||
}
|
||||
}
|
||||
break; // 只打印第一个 Item 的 SequenceList 和 DataValueList,避免输出过多
|
||||
}
|
||||
break; // 只打印第一个 Monitor 的 ItemList,避免输出过多
|
||||
}
|
||||
|
||||
|
||||
// 如果需要打印 SOEList,可加以下:
|
||||
/*
|
||||
int soeIndex = 0;
|
||||
@@ -1214,16 +1277,13 @@ static void print_mms_str_map(const json_block_data* data)
|
||||
}
|
||||
|
||||
//20250214添加角型接线处理
|
||||
int transfer_json_block_data(char v_wiring_type[], json_block_data *data, const char *source_name) //json生成函数 zw修改 2023-8-11 调整传送json结构 目前仅限历史稳态数据
|
||||
int transfer_json_block_data(char v_wiring_type[], json_block_data *data) //json生成函数 zw修改 2023-8-11 调整传送json结构 目前仅限历史稳态数据
|
||||
{
|
||||
// 刚进函数就打印 mms_str_map
|
||||
if (DEBUGOPEN) {
|
||||
print_mms_str_map(data);
|
||||
}
|
||||
|
||||
//数据追踪上送
|
||||
send_trace_if_needed(data, v_wiring_type, source_name);
|
||||
|
||||
list<CTopic*> ctopic_list;
|
||||
|
||||
////lnk2024-8-15 区分星型,角型接线
|
||||
|
||||
Reference in New Issue
Block a user