#include "stdafx.h" #include "AppService.h" #include "MGWSServer.h" #include "MGDataHandler.h" #include "MonitorObject.h" #include #include "AlarmDefine.h" static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data) { time_t tmNow; time(&tmNow); if (ev == MG_EV_POLL) { //time_t tNow; //time(&tNow); //TRACE("%d\r\n", tNow); //if (c->next) // mg_ws_send(c->next, nullptr, 0, WEBSOCKET_OP_PING); if (c->fn_data) { auto pMsg = (mg_per_session_data*)c->fn_data; if (tmNow - pMsg->tmLastSendHeart > 30) { pMsg->tmLastSendHeart = tmNow; mg_ws_send(c, nullptr, 0, WEBSOCKET_OP_PING); } } } /*if (ev == MG_EV_OPEN) { c->is_hexdumping = 1; }*/ else if (ev == MG_EV_HTTP_MSG) { struct mg_http_message* hm = (struct mg_http_message*)ev_data; mg_ws_upgrade(c, hm, NULL); // Upgrade HTTP to WS } else if (ev == MG_EV_WS_MSG) { // Got websocket frame. Received data is wm->data. Echo it back! struct mg_ws_message* wm = (struct mg_ws_message*)ev_data; //mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT); char* json = nullptr; auto pHandler = CAppService::Instance()->GetMgServer()->m_pDataHanlder; if (pHandler) { size_t len = pHandler->HandlerData(c, wm, &json); if (json) { char ip[50] = { 0 }; SPDLOG_DEBUG("[WS]{}send data:{}", mg_straddr(&c->rem, ip, 50), json); auto send_len = mg_ws_send(c, json, len, WEBSOCKET_OP_TEXT); ((mg_per_session_data*)c->fn_data)->send_size += send_len; ((mg_per_session_data*)c->fn_data)->send_count++; free((void*)json); } } } else if (ev == MG_EV_WS_OPEN) { //websocket 链接时 为每个链接创建用户数据 if (c->fn_data == nullptr) c->fn_data = new mg_per_session_data; } else if (ev == MG_EV_WS_CTL) { struct mg_ws_message* wm = (struct mg_ws_message*)ev_data; auto op = wm->flags & 15; if (op == WEBSOCKET_OP_CLOSE) { //关闭消息 释放内存数据 if (c->fn_data) { delete (mg_per_session_data*)(c->fn_data); c->fn_data = nullptr; } } else if (op == WEBSOCKET_OP_PONG) { if (c->fn_data) ((mg_per_session_data*)c->fn_data)->tmLastRecvHeart = tmNow; } } (void)fn_data; } CMGWSServer::CMGWSServer() { } CMGWSServer::~CMGWSServer() { } BOOL CMGWSServer::Start(uint16_t port)//10086 { Stop(); m_bThreadWork = TRUE; m_pThread = new std::thread(CMGWSServer::ThreadProc, (DWORD_PTR)this, port); Sleep(100); if (m_bThreadWork == FALSE) return FALSE; m_pDataHanlder = new CMGDataHandler(); return TRUE; } void CMGWSServer::Stop() { m_bThreadWork = FALSE; if (m_pThread) { m_pThread->join(); delete m_pThread; m_pThread = nullptr; } if (m_pDataHanlder) { delete m_pDataHanlder; m_pDataHanlder = nullptr; } } void CMGWSServer::SendRealResistData(const string& mo_mp, const int num, const std::vector& vctData0, const std::vector& vctData1, const std::vector& vctData2, const std::vector& vctResult, const CTime& atime) { if (m_mg_mgr.conns->is_listening && m_mg_mgr.conns->next == nullptr) return; if (mo_mp.length() == 0)return; bool bSub = false; for (auto it = m_mg_mgr.conns; it; it = it->next) { if (it->is_listening) continue; const auto& pConfInfo = (mg_per_session_data*)it->fn_data; if (pConfInfo) { //if (pConfInfo->token.find("BBBBBBBB") != -1) //{ // bSub = true; break; //} if (pConfInfo->isLogin == false) continue; for (const auto& ik : pConfInfo->m_lstSubReal) { if (ik.compare(mo_mp) == 0) { bSub = true; break; } } } } if (bSub == false) return; //所有客户端都未订阅 char* json = nullptr; auto len = GeneralResistData(mo_mp, num, 0, vctData0, vctData1, vctData2, vctResult, atime, &json); if (len == 0) return; char ip[50]; for (auto it = m_mg_mgr.conns; it; it = it->next) { if (it->is_accepted == false) continue; const auto& pConfInfo = (mg_per_session_data*)it->fn_data; if (pConfInfo) { //if (pConfInfo->token.find("BBBBBBBB") != -1) //{ // SPDLOG_DEBUG("[WS]{}:{}", mg_straddr(&it->rem, ip, 50), json); // mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT); // continue; //} if (pConfInfo->isLogin == false) continue; for (const auto& ik : pConfInfo->m_lstSubReal) { if (ik.compare(mo_mp) == 0) { SPDLOG_DEBUG("[WS]{}:{}", mg_straddr(&it->rem, ip, 50), json); mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT); break; } } } } } void CMGWSServer::SendHumiTemp(string mo_mp, const COleDateTime& dt, int humi, int temp) { return;//数据中心屏蔽 if (m_mg_mgr.conns->is_listening && m_mg_mgr.conns->next == nullptr) return; if (mo_mp.length() == 0)return; bool bSub = false; for (auto it = m_mg_mgr.conns; it; it = it->next) { if (it->is_listening) continue; const auto& pConfInfo = (mg_per_session_data*)it->fn_data; if (pConfInfo) { if (pConfInfo->token.find("BBBBBBBB") != -1) { bSub = true; break; } } } //所有客户端都未订阅 if (!bSub) return; auto doc = yyjson_mut_doc_new(nullptr); auto root = yyjson_mut_obj(doc); yyjson_mut_doc_set_root(doc, root); yyjson_mut_obj_add_str(doc, root, "cmd", "new_data_notify"); yyjson_mut_obj_add_strcpy(doc, root, "time", dt.Format("%Y-%m-%d %H:%M:%S")); yyjson_mut_obj_add_int(doc, root, "humi", humi / 100); yyjson_mut_obj_add_int(doc, root, "temp", temp); yyjson_mut_obj_add_strcpy(doc, root, "tag", (mo_mp + ".humi_temp").c_str()); size_t len; auto json = yyjson_mut_write(doc, 0, &len); if (json) { for (auto it = m_mg_mgr.conns; it; it = it->next) { if (it->is_accepted == false) continue; const auto& pConfInfo = (mg_per_session_data*)it->fn_data; if (pConfInfo) { if (pConfInfo->token.find("BBBBBBBB") != -1) { mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT); } } } free((void*)json); } } void CMGWSServer::SendToAllClient(const char* ptr, size_t len) { SPDLOG_DEBUG("SendToAllClient:{}", ptr); const auto& mgr = m_mg_mgr; for (auto it = mgr.conns; it; it = it->next) { if (it->is_listening == FALSE && it->is_websocket) { mg_ws_send(it, ptr, len, WEBSOCKET_OP_TEXT); } } } void CMGWSServer::SendToClient(const char* ptr, const size_t len, const char* ip) { SPDLOG_DEBUG("Send Client {}:{}", ip, ptr); const auto& mgr = m_mg_mgr; mg_str ip_str = {ip, strlen(ip)}; mg_addr ip_addr; mg_aton(ip_str, &ip_addr); for (auto it = mgr.conns; it; it = it->next) { if (it->is_listening == FALSE && it->is_websocket && it->rem.ip == ip_addr.ip) { mg_ws_send(it, ptr, len, WEBSOCKET_OP_TEXT); } } } void CMGWSServer::ThreadProc(DWORD_PTR wparam, uint16_t lparam) { CMGWSServer* pThis = (CMGWSServer*)wparam; if (!pThis->m_bThreadWork) return; mg_mgr_init(&pThis->m_mg_mgr); char url[128]; sprintf_s(url, 128, "ws://0.0.0.0:%d", lparam); auto pConn = mg_http_listen(&pThis->m_mg_mgr, url, fn, nullptr);//用户自定义数据赋值为空 if (pConn == nullptr || pConn->is_closing) SPDLOG_ERROR("开启Webscoket端口 {} 失败!", lparam); if (pConn) do { mg_mgr_poll(&pThis->m_mg_mgr, 100); } while (pThis->m_bThreadWork); mg_mgr_free(&pThis->m_mg_mgr); pThis->m_bThreadWork = FALSE; } int CMGWSServer::GeneralResistData(const string mo_mp, const int num, const int index, const std::vector& vctData0, const std::vector& vctData1, const std::vector& vctData2, const std::vector& vctResult, const CTime& atime, char** json) { size_t json_len = 0; char sz_utf_first[100]; char sz_utf_second[100]; char sz_utf_three[100]; string name1, name2, name3; CMonitorObjectMng::Instance()->GetNameByMoMp(mo_mp, name1, name2, name3); if (name1[0x00] == 0x00) gbk2utf8(sz_utf_first, 100, "1号测力曲线"); else gbk2utf8(sz_utf_first, 100, name1.c_str()); if (name2[0x00] == 0x00) gbk2utf8(sz_utf_second, 100, "2号测力曲线"); else gbk2utf8(sz_utf_second, 100, name2.c_str()); if (name3[0x00] == 0x00) gbk2utf8(sz_utf_three, 100, "转换阻力曲线"); else gbk2utf8(sz_utf_three, 100, name3.c_str()); int step = 1000 / num; uint64_t utime_t = atime.GetTime() * 1000; string up, momp_name; CMonitorObjectMng::Instance()->GetStationNameByMomP(mo_mp, up, momp_name); auto doc = yyjson_mut_doc_new(nullptr); auto root = yyjson_mut_obj(doc); yyjson_mut_doc_set_root(doc, root); auto data = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, root, "data", data); auto curve_1 = yyjson_mut_obj(doc); auto curve_2 = yyjson_mut_obj(doc); auto curve_3 = yyjson_mut_obj(doc); yyjson_mut_arr_add_val(data, curve_1); yyjson_mut_arr_add_val(data, curve_2); yyjson_mut_arr_add_val(data, curve_3); yyjson_mut_obj_add_str(doc, root, "cmd", "new_data_notify"); yyjson_mut_obj_add_strcpy(doc, root, "tag", (mo_mp + ".resist").c_str()); yyjson_mut_obj_add_str(doc, root, "data_fmt", "curve"); yyjson_mut_obj_add_str(doc, root, "unit", "N"); yyjson_mut_obj_add_strcpy(doc, root, "up", ANSItoUTF8(up).c_str()); yyjson_mut_obj_add_strcpy(doc, root, "tag_name", ANSItoUTF8(momp_name).c_str()); //1号测力点 yyjson_mut_obj_add_str(doc, curve_1, "name", sz_utf_first); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_1, "points", arr); for (int i = 0; i < num; i++) { if (vctResult[i] == false) continue; if (vctData0[i] == INVALID_RESIST) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, utime_t + step * i); yyjson_mut_arr_add_int(doc, item, vctData0[i]); } } //2号测力点 yyjson_mut_obj_add_str(doc, curve_2, "name", sz_utf_second); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_2, "points", arr); for (int i = 0; i < num; i++) { if (vctResult[i] == false) continue; if (vctData1[i] == INVALID_RESIST) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, utime_t + step * i); yyjson_mut_arr_add_int(doc, item, vctData1[i]); } } //3号测力点 yyjson_mut_obj_add_str(doc, curve_3, "name", sz_utf_three); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_3, "points", arr); for (int i = 0; i < num; i++) { if (vctResult[i] == false) continue; if (vctData2[i] == false) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, utime_t + step * i); yyjson_mut_arr_add_int(doc, item, vctData2[i]); ++i; } } *json = yyjson_mut_write(doc, 0, &json_len); yyjson_mut_doc_free(doc); return json_len; } BOOL CMGWSServer::IsClientSubReal(const string& momp) { if (m_mg_mgr.conns == nullptr) return false; if (m_mg_mgr.conns->is_listening && m_mg_mgr.conns->next == nullptr) return false; bool bSub = false; for (auto it = m_mg_mgr.conns; it; it = it->next) { if (it->is_listening) continue; const auto& pConfInfo = (mg_per_session_data*)it->fn_data; if (pConfInfo) { if (pConfInfo->isLogin == false) continue; for (const auto& ik : pConfInfo->m_lstSubReal) { if (ik.compare(momp) == 0) { bSub = true; break; } } } } return bSub; } BOOL CMGWSServer::SendClientSubReal(const string& momp, const char* json, const size_t len) { char ip[50]; for (auto it = m_mg_mgr.conns; it; it = it->next) { if (it->is_accepted == false) continue; const auto& pConfInfo = (mg_per_session_data*)it->fn_data; if (pConfInfo) { if (pConfInfo->isLogin == false) continue; for (const auto& ik : pConfInfo->m_lstSubReal) { if (ik.compare(momp) == 0) { if (g_bLog) SPDLOG_DEBUG(mg_straddr(&it->rem, ip, 50) + CString(json, len)); mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT); break; } } } } return true; } int mg_per_session_data::SendHistResistForEcharts(struct mg_connection* c, string mo_mp, time_t start, time_t end, uint32_t subsection, std::map& data0, std::map& data1, std::map& data2) { char sz_utf_first[100]; char sz_utf_second[100]; char sz_utf_three[100]; string name1, name2, name3; CMonitorObjectMng::Instance()->GetNameByMoMp(mo_mp, name1, name2, name3); if (name1[0x00] == 0x00) gbk2utf8(sz_utf_first, 100, "1号测力曲线"); else gbk2utf8(sz_utf_first, 100, name1.c_str()); if (name2[0x00] == 0x00) gbk2utf8(sz_utf_second, 100, "2号测力曲线"); else gbk2utf8(sz_utf_second, 100, name2.c_str()); if (name3[0x00] == 0x00) gbk2utf8(sz_utf_three, 100, "转换阻力曲线"); else gbk2utf8(sz_utf_three, 100, name3.c_str()); int offset = 0; uint32_t limit = subsection; auto it_data0 = data0.begin(); auto it_data1 = data1.begin(); auto it_data2 = data2.begin(); bBlock = false; do { static int n = 600; for (int i = 0; i < n; i++) { if (bWork == false) break; if (bBlock) this_thread::sleep_for(chrono::milliseconds(100)); else break; } #ifndef _DEBUG if (bBlock) ////5秒未返回确认包,结束 break;; #endif // _DEBUG auto cost_start = chrono::steady_clock::now(); //10000 一次 auto doc = yyjson_mut_doc_new(nullptr); auto root = yyjson_mut_obj(doc); yyjson_mut_doc_set_root(doc, root); auto data = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, root, "data", data); auto curve_1 = yyjson_mut_obj(doc); auto curve_2 = yyjson_mut_obj(doc); auto curve_3 = yyjson_mut_obj(doc); yyjson_mut_arr_add_val(data, curve_1); yyjson_mut_arr_add_val(data, curve_2); yyjson_mut_arr_add_val(data, curve_3); yyjson_mut_obj_add_str(doc, root, "cmd", "query_hist"); yyjson_mut_obj_add_strcpy(doc, root, "tag", (mo_mp + ".resist").c_str()); yyjson_mut_obj_add_str(doc, root, "data_fmt", "curve"); yyjson_mut_obj_add_str(doc, root, "unit", "N"); yyjson_mut_obj_add_str(doc, root, "time", ""); //1号测力点 yyjson_mut_obj_add_str(doc, curve_1, "name", sz_utf_first); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_1, "points", arr); auto mark_points = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points); for (int i = 0; i < limit && it_data0 != data0.end(); ++it_data0) { if (it_data0->first < start) continue; if (it_data0->first >= end) break; if (it_data0->second == INVALID_RESIST) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, it_data0->first); yyjson_mut_arr_add_int(doc, item, it_data0->second); ++i; } } //2号测力点 yyjson_mut_obj_add_str(doc, curve_2, "name", sz_utf_second); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_2, "points", arr); auto mark_points = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points); for (int i = 0; i < limit && it_data1 != data1.end(); ++it_data1) { if (it_data1->first < start) continue; if (it_data1->first >= end) break; if (it_data1->second == INVALID_RESIST) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, it_data1->first); yyjson_mut_arr_add_int(doc, item, it_data1->second); ++i; } } //3号测力点 yyjson_mut_obj_add_str(doc, curve_3, "name", sz_utf_three); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_3, "points", arr); auto mark_points = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points); for (int i = 0; i < limit && it_data2 != data2.end(); ++it_data2) { if (it_data2->first < start) continue; if (it_data2->first >= end) break; if (it_data2->second == INVALID_RESIST) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, it_data2->first); yyjson_mut_arr_add_int(doc, item, it_data2->second); ++i; } } auto cost_end = chrono::steady_clock::now(); auto cost_dif = chrono::duration_cast(cost_end - cost_start).count(); yyjson_mut_obj_add_strcpy(doc, root, "cost", (to_string(cost_dif) + "ms").c_str()); if (bWork == false) break; size_t ll; auto json = yyjson_mut_write(doc, 0, &ll); if (json && c->is_closing == false) { mg_ws_send(c, json, ll, WEBSOCKET_OP_TEXT); free((void*)json); } yyjson_mut_doc_free(doc); bBlock = true; if (bWork == false) break; } while (!((it_data0 == data0.end() || it_data0->first >= end) && (it_data1 == data1.end() || it_data1->first >= end) && (it_data2 == data2.end() || it_data2->first >= end))); return 0; } //#ifndef _DEBUG #define SHOW_DATA //#endif // _DEBUG int mg_per_session_data::SendHistResistDBForEcharts(LPMGHISTORY_QUERY history_query) { static string str_utf_fix = ANSItoUTF8("定位测力曲线"); static string str_utf_invert = ANSItoUTF8("反位测力曲线"); static string str_utf_convert = ANSItoUTF8("转换阻力曲线"); int offset = 0; uint32_t limit = history_query->subsection; //每次取出10000 CTime ctStart(history_query->tmStart / 1000); CTime ctEnd(history_query->tmEnd / 1000); char tablename[50]; char tablenameTom[50]; SYSTEMTIME stStart; ctStart.GetAsSystemTime(stStart); sprintf_s(tablename, 50, "rm_resistance_%04d%02d%02d", stStart.wYear, stStart.wMonth, stStart.wDay); SYSTEMTIME stEnd; ctEnd.GetAsSystemTime(stEnd); sprintf_s(tablenameTom, 50, "rm_resistance_%04d%02d%02d", stEnd.wYear, stEnd.wMonth, stEnd.wDay); string strStartTime = ctStart.Format("%Y-%m-%d %H:%M:%S"); string strEndTime = ctEnd.Format("%Y-%m-%d %H:%M:%S"); bBlock = false; CString sql; do { static int n = 600; for (int i = 0; i < n; i++) { if (bWork == false) break; if (bBlock) this_thread::sleep_for(chrono::milliseconds(100)); else break; } #ifndef _DEBUG if (bBlock) ////5秒未返回确认包,结束 break;; #endif // _DEBUG auto cost_start = chrono::steady_clock::now(); if (stStart.wDay == stEnd.wDay) { sql.Format("SELECT [acquisitiontime],[data0],[data1],[data2] "\ "FROM %s WHERE momp = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' "\ "ORDER BY acquisitiontime ASC OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", tablename, history_query->mo_mp.c_str(), strStartTime.c_str(), strEndTime.c_str(), offset, limit); } else { sql.Format("SELECT [acquisitiontime],[data0],[data1],[data2] "\ "FROM %s WHERE momp = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' "\ "UNION ALL "\ "SELECT [acquisitiontime],[data0],[data1],[data2] "\ "FROM %s WHERE momp = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' "\ "ORDER BY acquisitiontime ASC OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", tablename, history_query->mo_mp.c_str(), strStartTime.c_str(), strEndTime.c_str(), tablenameTom, history_query->mo_mp.c_str(), strStartTime.c_str(), strEndTime.c_str(), offset, limit); } TRACE("%s\r\n", sql); int no = 0; TIMESTAMP_STRUCT ts; int sdata0, sdata1, sdata2; COdbcStatement stmt; if (CDBConnectPool::Instance()->DBQuery(stmt, sql) == FALSE) { SPDLOG_ERROR("查询语句出错:{}", sql); break; } int nCol = 1; stmt.BindTimeStampCol(nCol++, &ts); stmt.BindIntCol(nCol++, &sdata0); stmt.BindIntCol(nCol++, &sdata1); stmt.BindIntCol(nCol++, &sdata2); std::map data0, data1, data2; do { if (stmt.FetchNext() != 0) break; no++; CTime ctTime; try { ctTime = CTime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second); } catch (...) { continue; } time_t tm = ctTime.GetTime() * 1000 + ts.fraction / 1000000; data0[tm] = sdata0; data1[tm] = sdata1; data2[tm] = sdata2; } while (true); //扳动阈值判断 放到HTTP里 //std::map maxlock0, maxlock1, maxForce; //list maxResist; //GetMaxResist(data2, maxResist); //GetMaxLockNew(data0, maxResist, maxlock0); //GetMaxLockNew(data1, maxResist, maxlock1); ////CalcFixOrInvert(maxResist, maxlock0, maxlock1, name1, name2); //GetMaxForce(data2, maxForce); //10000 一次 auto doc = yyjson_mut_doc_new(nullptr); auto root = yyjson_mut_obj(doc); yyjson_mut_doc_set_root(doc, root); auto data = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, root, "data", data); auto curve_1 = yyjson_mut_obj(doc); auto curve_2 = yyjson_mut_obj(doc); auto curve_3 = yyjson_mut_obj(doc); yyjson_mut_arr_add_val(data, curve_1); yyjson_mut_arr_add_val(data, curve_2); yyjson_mut_arr_add_val(data, curve_3); yyjson_mut_obj_add_str(doc, root, "cmd", "query_hist"); yyjson_mut_obj_add_strcpy(doc, root, "tag", (history_query->mo_mp + ".resist").c_str()); yyjson_mut_obj_add_str(doc, root, "data_fmt", "curve"); yyjson_mut_obj_add_str(doc, root, "unit", "N"); yyjson_mut_obj_add_str(doc, root, "time", ""); //1号测力点 yyjson_mut_obj_add_str(doc, curve_1, "name", str_utf_fix.c_str()); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_1, "points", arr); #ifdef SHOW_DATA for (const auto& it : data0) { if (INVALID_RESIST == it.second) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, it.first); yyjson_mut_arr_add_int(doc, item, it.second); } #endif // SHOW_DATA // auto mark_points = yyjson_mut_arr(doc); // yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points); // for (const auto& it : maxlock0) // { // auto obj = yyjson_mut_obj(doc); // yyjson_mut_arr_add_val(mark_points, obj); // auto val = (it.second >> 32); // if (val > 500) // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("锁闭力:{}", val)).c_str()); // else // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8("锁闭力过低").c_str()); // yyjson_mut_obj_add_int(doc, obj, "val", val); // auto arr = yyjson_mut_arr(doc); // yyjson_mut_obj_add_val(doc, obj, "coord", arr); //#ifdef SHOW_DATA // yyjson_mut_arr_add_uint(doc, arr, it.first); //#else // yyjson_mut_arr_add_strcpy(doc, arr, CTime(it.first / 1000).Format("%Y-%m-%d %H:%M:%S")); //#endif // _DEBUG // yyjson_mut_arr_add_int(doc, arr, (int)it.second); // } } //2号测力点 yyjson_mut_obj_add_str(doc, curve_2, "name", str_utf_invert.c_str()); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_2, "points", arr); #ifdef SHOW_DATA for (const auto& it : data1) { if (INVALID_RESIST == it.second) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, it.first); yyjson_mut_arr_add_int(doc, item, it.second); } #endif // auto mark_points = yyjson_mut_arr(doc); // yyjson_mut_obj_add_val(doc, curve_2, "mark_points", mark_points); // for (const auto& it : maxlock1) // { // auto obj = yyjson_mut_obj(doc); // yyjson_mut_arr_add_val(mark_points, obj); // auto val = (it.second >> 32); // if (val > 500) // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("锁闭力:{}", val)).c_str()); // else // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8("锁闭力过低").c_str()); // auto arr = yyjson_mut_arr(doc); // yyjson_mut_obj_add_val(doc, obj, "coord", arr); // yyjson_mut_obj_add_int(doc, obj, "val", val); //#ifdef SHOW_DATA // yyjson_mut_arr_add_uint(doc, arr, it.first); //#else // yyjson_mut_arr_add_strcpy(doc, arr, CTime(it.first / 1000).Format("%Y-%m-%d %H:%M:%S")); //#endif // _DEBUG // yyjson_mut_arr_add_int(doc, arr, (int)it.second); // } } //3号测力点 yyjson_mut_obj_add_str(doc, curve_3, "name", str_utf_convert.c_str()); { auto arr = yyjson_mut_arr(doc); yyjson_mut_obj_add_val(doc, curve_3, "points", arr); #ifdef SHOW_DATA for (const auto& it : data2) { if (INVALID_RESIST == it.second) continue; auto item = yyjson_mut_arr(doc); yyjson_mut_arr_add_val(arr, item); yyjson_mut_arr_add_uint(doc, item, it.first); yyjson_mut_arr_add_int(doc, item, it.second); } #endif // auto mark_points = yyjson_mut_arr(doc); // yyjson_mut_obj_add_val(doc, curve_3, "mark_points", mark_points); // for (const auto& it : maxResist) // { // auto obj = yyjson_mut_obj(doc); // yyjson_mut_arr_add_val(mark_points, obj); // if (it.bUpOrDown == 1 && in_name.length() > 0) // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("{}:{}", in_name, it.fluctuation_val)).c_str()); // else if (it.bUpOrDown == 2 && out_name.length() > 0) // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("{}:{}", out_name, it.fluctuation_val)).c_str()); // else // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("最大转换阻力值:{}", it.fluctuation_val)).c_str()); // // if (it.bUpOrDown == 2) yyjson_mut_obj_add_str(doc, obj, "position", "bottom"); //负数增加显示位置 // auto arr = yyjson_mut_arr(doc); // yyjson_mut_obj_add_val(doc, obj, "coord", arr); //#ifdef SHOW_DATA // yyjson_mut_arr_add_uint(doc, arr, it.time); //#else // yyjson_mut_arr_add_strcpy(doc, arr, CTime(it.time / 1000).Format("%Y-%m-%d %H:%M:%S")); //#endif // _DEBUG // yyjson_mut_arr_add_int(doc, arr, it.val); // } // for (const auto& it : maxForce) // { // auto obj = yyjson_mut_obj(doc); // yyjson_mut_arr_add_val(mark_points, obj); // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("摩擦力值:{}", (it.second >> 32))).c_str()); // auto arr = yyjson_mut_arr(doc); // yyjson_mut_obj_add_val(doc, obj, "coord", arr); // yyjson_mut_arr_add_uint(doc, arr, it.first); // yyjson_mut_arr_add_int(doc, arr, (int)it.second); // } } auto cost_end = chrono::steady_clock::now(); auto cost_dif = chrono::duration_cast(cost_end - cost_start).count(); yyjson_mut_obj_add_strcpy(doc, root, "cost", (to_string(cost_dif) + "ms").c_str()); if (bWork) { size_t ll; auto json = yyjson_mut_write(doc, 0, &ll); char ip[50]; if (json && history_query->c->is_closing == false) { SPDLOG_DEBUG("[WS]send data {}:{}", mg_straddr(&history_query->c->rem, ip, 50), json); mg_ws_send(history_query->c, json, ll, WEBSOCKET_OP_TEXT); free((void*)json); } } yyjson_mut_doc_free(doc); //maxlock0.clear(); //maxlock1.clear(); //maxForce.clear(); //maxResist.clear(); //len 335214 bBlock = true; if (bWork == false) break; offset += no; if (no != limit) { break; } } while (true); return 0; } //{ "cmd": "login", "token": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"} //{ "cmd": "query_hist", "tag": "TLDZ24.J3.resist", "time": "2022-10-14 03:42:00~2022-10-14 03:46:30", "subsection": 5000} void mg_per_session_data::GetMaxResist(std::map& data, list& out, const string& mo, const string& mp) { std::map mapSecondStatInfo; ConvertMiroToSecond(data, mapSecondStatInfo); if (mapSecondStatInfo.size() == 0) return; GetMaxResistNew(mapSecondStatInfo, out, mo, mp); } void mg_per_session_data::GetMaxResist(std::map& mapSecondStatInfo, list& out) { int steady_val = INT_MIN; time_t move_start_t = 0; //扳动开始时间 int move_start_val = INT_MIN; //扳动起始值 int move_max_val = INT_MIN; //扳动峰值 time_t move_max_t = 0; //扳动峰值的时间 int move_min_val = INT_MAX; //扳动谷值 time_t move_min_t = 0; //扳动谷值的时间 time_t last_t = mapSecondStatInfo.begin()->first; time_t last_last_t; int last_end_val = mapSecondStatInfo.begin()->second.end_val; int last_last_end_val; //上一秒的最后一个值 for (auto& it : mapSecondStatInfo) { auto str = CTime(it.first).Format("%Y-%m-%d %H:%M:%S") + '.' + to_string(it.first % 1000).c_str(); TRACE("%s\r\n", str); last_last_t = last_t;//更新前赋值 last_t = it.first; last_last_end_val = last_end_val; last_end_val = it.second.end_val; if (it.second.dif_val <= 150) //稳定 大于500N 为波动 { if (move_start_t != 0) // 波动结束 { CONVERT_RESIST info; info.tmStart = move_start_t; info.tmEnd = it.first; int fluctuation_t = it.first - move_start_t;//波动时间 bool bMax = false; auto iMax = abs(move_max_val - steady_val); auto iMin = abs(move_min_val - steady_val); if (iMax > iMin) { bMax = true; info.fluctuation_val = iMax;//最大值减去前面的稳定平均值 } else info.fluctuation_val = iMin; if (fluctuation_t >= 4 && fluctuation_t <= 8 && info.fluctuation_val > 450) { //扳动 if (bMax) { //输出记录 info.time = move_max_t; info.bUpOrDown = 1; info.val = move_max_val; out.emplace_back(info); //out[move_max_t] = (((int64_t)move_max_val - steady_val) << 32) + move_max_val; SPDLOG_INFO("[转换阻力求值]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 波动值:{}", CTime(move_start_t).Format("%Y-%m-%d %H:%M:%S"), CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val, it.second.dif_val ); } else { info.time = move_min_t; info.bUpOrDown = 2; info.val = move_min_val; out.emplace_back(info); //out[move_min_t] = (((int64_t)move_min_val - steady_val) << 32) + move_min_val;//输出记录 SPDLOG_INFO("[转换阻力求值]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 波动值:{}", CTime(move_start_t).Format("%Y-%m-%d %H:%M:%S"), CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_min_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_min_t % 1000).c_str(), move_min_val, it.second.dif_val ); } } else { if (bMax) SPDLOG_INFO("[转换阻力求值]不符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 波动值:{} 不符合特征", CTime(move_start_t).Format("%Y-%m-%d %H:%M:%S"), CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val, it.second.dif_val ); else SPDLOG_INFO("[转换阻力求值]不符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 波动值:{} 不符合特征", CTime(move_start_t).Format("%Y-%m-%d %H:%M:%S"), CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_min_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_min_t % 1000).c_str(), move_min_val, it.second.dif_val ); } //重置 move_start_t = 0; move_max_val = INT_MIN; move_max_t = 0; move_start_val = INT_MIN; move_min_val = INT_MAX; //扳动谷值 move_min_t = 0; //扳动谷值的时间 } //steady_val = it.second.sum_val / it.second.cout; //稳定值为平均值 steady_val = it.second.end_val; //2022.10.22换成最后一个值 } else if (steady_val == INT_MIN) //起始点就是波动 { continue; } else if (it.second.dif_val > 400) { if (move_start_t == 0) { //开始波动 if (abs(last_last_end_val - it.second.first_val) < 100) //如果前面的最后一个值 和 当前最开始的值 小于 100 . 以当前这个为准 2022.10.22 { move_start_t = last_t; //取当前 it.first steady_val = it.second.first_val; SPDLOG_INFO("[转换阻力求值]检测到开始波动:{} 上一个稳定时间:{} 起始值:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), CTime(last_t).Format("%Y-%m-%d %H:%M:%S"), steady_val); } else { move_start_t = last_last_t; //开始波动取上一个 steady_val = last_last_end_val; SPDLOG_INFO("[转换阻力求值]检测到开始波动:{} 上一个稳定时间:{} 起始值:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), CTime(last_last_t).Format("%Y-%m-%d %H:%M:%S"), steady_val); } } //波动 取出最大值 if (it.second.max_val > move_max_val) { move_max_t = it.second.max_time; move_max_val = it.second.max_val; } if (it.second.min_val < move_min_val) { move_min_t = it.second.min_time; move_min_val = it.second.min_val; } } } } void mg_per_session_data::GetMaxResistNew(std::map& mapSecondStatInfo, list& out, const string& mo, const string& mp) { if (mapSecondStatInfo.size() == 0) return; time_t move_start_t = 0; //扳动开始时间 int move_start_val = INT_MIN; //扳动起始值 int move_max_val = INT_MIN; //扳动峰值 time_t move_max_t = 0; //扳动峰值的时间 int move_min_val = INT_MAX; //扳动谷值 time_t move_min_t = 0; //扳动谷值的时间 time_t last_t = mapSecondStatInfo.begin()->first; time_t last_last_t; int last_end_val = mapSecondStatInfo.begin()->second.end_val; int last_last_end_val; //上一秒的最后一个值 list lstStatInfo; auto it = mapSecondStatInfo.cbegin(); lstStatInfo.emplace_back(it->second); time_t tLastIt = it->first; BOOL bForContinue = TRUE;; do { it++; if (it != mapSecondStatInfo.cend()) { if (it->first - tLastIt < 2) //单位秒 { lstStatInfo.emplace_back(it->second); tLastIt = it->first; continue; } else tLastIt = it->first; } else bForContinue = FALSE;//遍历结束 do { if (lstStatInfo.size() < 7) //扳动不小于7秒 break; //处理逻辑 int steady_val = INT_MIN; list::iterator it_start = lstStatInfo.end(); list::reverse_iterator it_end = lstStatInfo.rend(); for (auto i = lstStatInfo.begin(); i != lstStatInfo.end(); i++) { if (i->dif_val >= 100) //大于100N算波动 { if (steady_val == INT_MIN) steady_val = i->first_val; it_start = i; break; } else steady_val = i->end_val; } for (auto i = lstStatInfo.rbegin(); i != lstStatInfo.rend(); i++) { if (i->dif_val >= 100) //大于100N算波动 { it_end = i; break; } } if (it_start == lstStatInfo.end() || it_end == lstStatInfo.rend()) break; if (it_end == lstStatInfo.rbegin()) { //结束还在波动 不进行判断 SPDLOG_INFO("[转换阻力判断][{}:{}] 结束还在波动 不进行判断: {}", mo, mp, CTime(it_end->max_time / 1000).Format("%Y-%m-%d %H:%M:%S")); break; } CONVERT_RESIST info; info.tmStart = it_start->max_time / 1000; info.tmEnd = it_end->max_time / 1000 + 1; //取出转换值 move_max_val = it_start->max_val; move_min_val = it_start->min_val; move_max_t = move_min_t = it_start->max_time; for (auto i = it_start;;) { if (i->max_val > move_max_val) { move_max_val = i->max_val; move_max_t = i->max_time; } if (i->min_val < move_min_val) { move_min_val = i->min_val; move_min_t = i->min_time; } if (i->max_time > it_end->max_time) { break; } i++; } bool bMax = false; auto iMax = abs(move_max_val - steady_val); auto iMin = abs(move_min_val - steady_val); if (iMax > iMin) { bMax = true; info.fluctuation_val = iMax;//最大值减去前面的稳定平均值 } else info.fluctuation_val = iMin; auto fluctuation_t = it_end->max_time / 1000 - it_start->max_time / 1000 + 1; //波动时长 if (fluctuation_t >= 3 && fluctuation_t <= 9 && info.fluctuation_val > 450) { //扳动 if (bMax) { //输出记录 info.time = move_max_t; info.bUpOrDown = 1; info.val = move_max_val; out.emplace_back(info); //out[move_max_t] = (((int64_t)move_max_val - steady_val) << 32) + move_max_val; if (g_bLog) SPDLOG_INFO("[转换阻力求值][{}:{}]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{}", mo, mp, CTime(info.tmStart).Format("%Y-%m-%d %H:%M:%S"), CTime(info.tmEnd).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val ); } else { info.time = move_min_t; info.bUpOrDown = 2; info.val = move_min_val; out.emplace_back(info); //out[move_min_t] = (((int64_t)move_min_val - steady_val) << 32) + move_min_val;//输出记录 if (g_bLog) SPDLOG_INFO("[转换阻力求值][{}:{}]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{}", mo, mp, CTime(info.tmStart).Format("%Y-%m-%d %H:%M:%S"), CTime(info.tmEnd).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_min_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_min_t % 1000).c_str(), move_min_val ); } } else { if (bMax) SPDLOG_INFO("[转换阻力求值][{}:{}]不符合3秒~9秒 大于450N 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 不符合特征", mo, mp, CTime(info.tmStart).Format("%Y-%m-%d %H:%M:%S"), CTime(info.tmEnd).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val ); else SPDLOG_INFO("[转换阻力求值][{}:{}]不符合3秒~9秒 大于450N 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 不符合特征", mo, mp, CTime(info.tmStart).Format("%Y-%m-%d %H:%M:%S"), CTime(info.tmEnd).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t, info.fluctuation_val, CTime(move_min_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_min_t % 1000).c_str(), move_min_val ); } TRACE("%s %d \r\n", CTime(it_end->max_time / 1000).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t); } while (false); if (lstStatInfo.size()) lstStatInfo.clear(); ////遍历结束 //if (it == mapSecondStatInfo.cend()) // break; } while (bForContinue); } void mg_per_session_data::GetMaxLockNew(const std::map& data, const list& refer, std::map& out) { std::map mapSecondStatInfo; ConvertMiroToSecond(data, mapSecondStatInfo); if (mapSecondStatInfo.size() == 0) return; GetMaxLockNew(mapSecondStatInfo, refer, out); } /* void mg_per_session_data::GetMaxLock(std::map mapSecondStatInfo, const list& refer, std::map& out) { int steady_val = INT_MIN; time_t move_start_t = 0; //扳动开始时间 最后一个稳态时间 time_t move_start_move_t = 0; //扳动开始时间 即波动时间 int move_start_val = INT_MIN; //扳动起始值 int move_max_val = INT_MIN; //扳动峰值 time_t move_max_t = 0; //扳动峰值的时间 int move_min_val = INT_MAX; //扳动谷值 只参与计算 time_t move_min_t = 0; //扳动谷值的时间 time_t last_t = mapSecondStatInfo.begin()->first; time_t last_last_t; for (auto& it : mapSecondStatInfo) { auto str = CTime(it.first).Format("%Y-%m-%d %H:%M:%S") + '.' + to_string(it.first % 1000).c_str(); //TRACE("%s\r\n", str); last_last_t = last_t;//更新前赋值 last_t = it.first; if (it.second.dif_val <= 300) //稳定 大于300N 为波动 { if (move_start_t != 0) // 波动结束 { int fluctuation_t = it.first - move_start_t;//波动时间 int fluctuation_val = move_max_val - steady_val; //最大值减去前面的稳定平均值 int nSecondDif = INT_MAX; bool bCalcDif = CalcSecondDif(refer, move_start_move_t, nSecondDif); if (fluctuation_t >= 1 && fluctuation_t <= 7 && fluctuation_val > 30 && bCalcDif && nSecondDif >= 1) //小于0 不是密贴 2023.2.10 2秒改为1秒 { //扳动 out[move_max_t] = (((int64_t)fluctuation_val) << 32) + move_max_val;//输出记录 //SPDLOG_INFO("[锁闭力求值]符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{}", fluctuation_t, fluctuation_val, // CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S") + to_string(move_max_t % 1000).c_str(), move_max_val); SPDLOG_INFO("[锁闭力求值]符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{} nSecondDif:{} 开始波动时间:{}", fluctuation_t, fluctuation_val, CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val, nSecondDif, CTime(move_start_move_t).Format("%Y-%m-%d %H:%M:%S")).c_str()); } else { if (fluctuation_val < 0) { fluctuation_val = move_min_val - steady_val; SPDLOG_INFO("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最小值:{} bCalcDif:{} nSecondDif:{} 开始波动时间:{} 不符合特征", fluctuation_t, fluctuation_val, CTime(move_min_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_min_t % 1000).c_str(), move_min_val, bCalcDif, nSecondDif, CTime(move_start_move_t).Format("%Y-%m-%d %H:%M:%S")).c_str()); } else { //SPDLOG_INFO("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{}", fluctuation_t, fluctuation_val, // CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S") + to_string(move_max_t % 1000).c_str(), move_max_val); SPDLOG_INFO("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{} bCalcDif:{} nSecondDif:{} 开始波动时间:{} 不符合特征", fluctuation_t, fluctuation_val, CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val, bCalcDif, nSecondDif, CTime(move_start_move_t).Format("%Y-%m-%d %H:%M:%S")).c_str()); } } //重置 move_start_t = 0; move_start_move_t = 0; move_max_val = INT_MIN; move_max_t = 0; move_start_val = INT_MIN; move_min_val = INT_MAX; //扳动谷值 move_min_t = 0; //扳动谷值的时间 } steady_val = it.second.sum_val / it.second.cout; //稳定值为平均值 } else if (steady_val == INT_MIN) //起始点就是波动 { continue; } else if (it.second.dif_val > 300) { if (move_start_t == 0) { move_start_t = last_last_t; //开始波动取上一个 move_start_move_t = it.first; //SPDLOG_INFO("检测到开始波动:{} 上一个稳定时间:{}", CTime(it.first / 1000).Format("%Y-%m-%d %H:%M:%S"), CTime(last_last_t / 1000).Format("%Y-%m-%d %H:%M:%S")); SPDLOG_INFO("[锁闭力求值]检测到开始波动:{} 上一个稳定时间:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), CTime(last_last_t).Format("%Y-%m-%d %H:%M:%S")).c_str()); } //波动 取出最大值 if (it.second.max_val > move_max_val) { move_max_t = it.second.max_time; move_max_val = it.second.max_val; } if (it.second.min_val < move_min_val) { move_min_t = it.second.min_time; move_min_val = it.second.min_val; } } } } */ void mg_per_session_data::GetMaxLockNew(std::map mapSecondStatInfo, const list& refer, std::map& out) { for (auto& it : refer) { auto it_start = mapSecondStatInfo.find(it.tmStart); auto it_end = mapSecondStatInfo.find(it.tmEnd); if (it_start == mapSecondStatInfo.end() || it_end == mapSecondStatInfo.end()) continue; auto fluctuation_val = it_end->second.first_val - it_start->second.end_val; if (fluctuation_val < 30) continue; int move_max_val = INT_MIN; //扳动峰值 time_t move_max_t = 0; //扳动峰值的时间 for (auto i = it_start; i->first < it_end->first; i++) { if (move_max_val < i->second.max_val) { move_max_val = i->second.max_val; move_max_t = i->second.max_time; } } out[move_max_t] = (((int64_t)fluctuation_val) << 32) + move_max_val;//输出记录 } } void mg_per_session_data::GetMaxForce(std::map& data2, std::map& out) { } void mg_per_session_data::CalcFixOrInvert(list& out, std::map& in1, std::map& in2, string name1, string name2) { if (name1.find("定") == -1 && name2.find("定") == -1) return; if (in1.size() == 0 && in2.size() == 0) return; for (auto& it : out) { uint8_t bFirstOrSecond = 0; int time_dif = INT_MAX; for (const auto& ik : in1) { auto dif = abs(it.time - ik.first); if (dif < 8000 && dif < time_dif) { time_dif = dif; bFirstOrSecond = 1; } } for (const auto& ik : in2) { auto dif = abs(it.time - ik.first); if (dif < 8000 && dif < time_dif) { time_dif = dif; bFirstOrSecond = 2; } } if (bFirstOrSecond == 1) { if (name1.find("定") != -1) it.bFixOrInvert = 1; else if (name1.find("反") != -1) it.bFixOrInvert = 2; } else if (bFirstOrSecond == 2) { if (name2.find("定") != -1) it.bFixOrInvert = 1; else if (name2.find("反") != -1) it.bFixOrInvert = 2; } } }