#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]; if (g_bLog) CSimpleLog::Info(mg_straddr(&c->rem, ip, 50) + CString(json, len)); 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; if (it->is_websocket == false) continue; const auto& pConfInfo = (mg_per_session_data*)it->fn_data; if (pConfInfo) { if (pConfInfo->token.find("BBBBBBBB") != -1) { if (g_bLog) CSimpleLog::Info(mg_straddr(&it->rem, ip, 50) + CString(json, len)); 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) { if (g_bLog) CSimpleLog::Info(mg_straddr(&it->rem, ip, 50) + CString(json, len)); mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT); break; } } } } } void CMGWSServer::SendHumiTemp(string mo_mp, const COleDateTime& dt, int humi, int temp) { 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; if (it->is_websocket == 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) { if (g_bLog) CSimpleLog::Info(CString(ptr, len)); 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) { if (g_bLog) CSimpleLog::Info(CString(ptr, len)); 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) CSimpleLog::Error(fmt::format("开启Webscoket端口 {} 失败!", lparam).c_str()); 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] == INVLID_VAL) 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] == INVLID_VAL) 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] == INVLID_VAL) 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]); } } *json = yyjson_mut_write(doc, 0, &json_len); yyjson_mut_doc_free(doc); return json_len; } 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 == INVLID_VAL) 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 == INVLID_VAL) 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 == INVLID_VAL) 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; } //现在使用的 int mg_per_session_data::SendHistResistDBForEcharts(LPMGHISTORY_QUERY history_query) { char sz_utf_first[100]; char sz_utf_second[100]; char sz_utf_three[100]; string name1, name2, name3, out_name, in_name; CMonitorObjectMng::Instance()->GetNameByMoMp(history_query->mo_mp, name1, name2, name3, out_name, in_name); 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 = 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 IMEI = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' AND idx = %d "\ "ORDER BY acquisitiontime ASC OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", tablename, history_query->imei.c_str(), strStartTime.c_str(), strEndTime.c_str(), history_query->idx, offset, limit); } else { sql.Format("SELECT [acquisitiontime],[data0],[data1],[data2] "\ "FROM %s WHERE IMEI = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' AND idx = %d "\ "UNION ALL "\ "SELECT [acquisitiontime],[data0],[data1],[data2] "\ "FROM %s WHERE IMEI = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' AND idx = %d "\ "ORDER BY acquisitiontime ASC OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", tablename, history_query->imei.c_str(), strStartTime.c_str(), strEndTime.c_str(), history_query->idx, tablenameTom, history_query->imei.c_str(), strStartTime.c_str(), strEndTime.c_str(), history_query->idx, 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) { CSimpleLog::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", sz_utf_first); { 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 (INVLID_VAL == 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", sz_utf_second); { 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 (INVLID_VAL == 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", sz_utf_three); { 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 (INVLID_VAL == 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) { if (g_bLog) CSimpleLog::Info(mg_straddr(&history_query->c->rem, ip, 50) + CString(json, ll)); 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, std::map& mapSecondStatInfo, list& out, const string& mo, const string& mp) { 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 = eUpOrDownInfo::UOD_UP; info.val = move_max_val; out.emplace_back(info); //out[move_max_t] = (((int64_t)move_max_val - steady_val) << 32) + move_max_val; CSimpleLog::Info(fmt::format("[转换阻力求值]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 波动值:{}", 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 ).c_str()); } else { info.time = move_min_t; info.bUpOrDown = eUpOrDownInfo::UOD_DOWN; info.val = move_min_val; out.emplace_back(info); //out[move_min_t] = (((int64_t)move_min_val - steady_val) << 32) + move_min_val;//输出记录 CSimpleLog::Info(fmt::format("[转换阻力求值]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 波动值:{}", 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 ).c_str()); } } else { if (bMax) CSimpleLog::Info(fmt::format("[转换阻力求值]不符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 波动值:{} 不符合特征", 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 ).c_str()); else CSimpleLog::Info(fmt::format("[转换阻力求值]不符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 波动值:{} 不符合特征", 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 ).c_str()); } //重置 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; CSimpleLog::Info(fmt::format("[转换阻力求值]检测到开始波动:{} 上一个稳定时间:{} 起始值:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), CTime(last_t).Format("%Y-%m-%d %H:%M:%S"), steady_val).c_str()); } else { move_start_t = last_last_t; //开始波动取上一个 steady_val = last_last_end_val; CSimpleLog::Info(fmt::format("[转换阻力求值]检测到开始波动:{} 上一个稳定时间:{} 起始值:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"), CTime(last_last_t).Format("%Y-%m-%d %H:%M:%S"), steady_val).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::GetMaxResistNew(std::map& mapSecondStatInfo, list& out, const string& mo, const string& mp) { if (mapSecondStatInfo.size() <= 1) return; string momp = mo + "." + mp; 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() < 3) //扳动不小于3秒 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")); //放开测试一下 } 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 == lstStatInfo.end()) break; 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 = eUpOrDownInfo::UOD_UP; 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 || g_strMoMp.compare(momp) == 0) 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 = eUpOrDownInfo::UOD_DOWN; 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 || g_strMoMp.compare(momp) == 0) 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) CSimpleLog::Info(fmt::format("[转换阻力求值][{}:{}]不符合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 ).c_str()); 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& retensionforce) { std::map mapSecondStatInfo; ConvertMiroToSecond(data, mapSecondStatInfo); if (mapSecondStatInfo.size() == 0) return; GetMaxLockNew(mapSecondStatInfo, refer, out, retensionforce); } /* 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); CSimpleLog::Info(fmt::format("[锁闭力求值]符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{} 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; CSimpleLog::Info(fmt::format("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最小值:{} 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); CSimpleLog::Info(fmt::format("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{} 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")); CSimpleLog::Info(fmt::format("[锁闭力求值]检测到开始波动:{} 上一个稳定时间:{}", 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(const std::map &mapSecondStatInfo, const list& refer, std::map& out, std::map& retensionforce) { for (auto& it : refer) { auto it_start = mapSecondStatInfo.find(it.tmStart); if (it_start == mapSecondStatInfo.end()) continue; int fluctuation_val = INT_MIN; auto it_end = mapSecondStatInfo.find(it.tmEnd); if (it_end != mapSecondStatInfo.end()) { fluctuation_val = it_end->second.first_val - it_start->second.end_val; //取 } else { it_end = mapSecondStatInfo.find(it.tmEnd - 1); if (it_end == mapSecondStatInfo.end()) { ASSERT(false); continue; } fluctuation_val = it_end->second.end_val - it_start->second.end_val; //取 } if (fluctuation_val < 30) { //保持力 if (it_end->second.dif_val < 30) retensionforce[it_end->first * 1000] = it_start->second.end_val; else if (it_end->second.cout) retensionforce[it_end->first * 1000] = it_end->second.sum_val / it_end->second.cout; continue; } int move_max_val = INT_MIN; //扳动峰值 time_t move_max_t = 0; //扳动峰值的时间 for (auto i = it_start; i != mapSecondStatInfo.end() && i->first < it.tmEnd; 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; } } } BOOL ConmpareValue(std::map* pData, time_t tsStartTime, time_t tsEndTime, int& hight_num, int& low_num, int threshold, int& iMaxDif, time_t& tMaxTime, int& nMaxValue) { auto it = pData->find(tsStartTime*1000); if (it == pData->end()) return false; int signal = 0; tMaxTime = 0; int startvalue = it->second / 10; int lastvalue = startvalue; int lastVV = lastvalue; time_t lastTT = it->first; int iMax = startvalue; std::map mapMaxValue; hight_num = 0; low_num = 0; for (it; it != pData->end() && it->first < tsEndTime*1000; it++) { auto val = it->second / 10; if (val > lastvalue)//上升 { if (signal == 1) { //原来大于,现在也是大于 //continue; } else { //原来小于或者无效,现在大于 signal = 1; startvalue = lastvalue; if(iMax - startvalue > threshold) low_num++; } } else if (val < lastvalue)//下降 { if (signal == -1) { //原来小于,现在小于等于 //continue; } else { //原来大于或者无效,现在小于 signal = -1; iMax = lastvalue; if (iMax - startvalue > threshold) //相差阈值计数 { mapMaxValue[lastTT] = lastVV; hight_num++; } } } lastvalue = val; lastTT = it->first; lastVV = it->second; } iMax = INT_MIN; int iMin = INT_MAX; for (auto& it : mapMaxValue) { if (it.second > iMax) { iMax = it.second; tMaxTime = it.first; } if (it.second < iMin) iMin = it.second; } iMaxDif = iMax - iMin; nMaxValue = iMax; return TRUE; } #include "ResistAlarm.h" void mg_per_session_data::GetPass(std::map& pStatInfo, std::map* pData, const string& mo, const string& mp, OUT list* lstResist) { if (pStatInfo.size() < 5) return; //过车至少5秒 //判断连续起始点 //判断结束起始点 time_t tsStartTime = 0, tsEndTime = 0; auto it = pStatInfo.begin(); do { auto it_front = it++; if (it == pStatInfo.end()) break; if (it->first - it_front->first > 1) //不连续 continue; tsStartTime = it_front->first; //确定开始时间 //需求结尾 do { it_front = it++; if (it == pStatInfo.end()) { goto l; } if (it->first - it_front->first == 1) //连续 continue; l: tsEndTime = it_front->first; auto dif = tsEndTime - tsStartTime + 1; auto sStart = CTime(tsStartTime).Format("%Y-%m-%d %H:%M:%S"); auto sEnd = CTime(tsEndTime).Format("%Y-%m-%d %H:%M:%S"); TRACE("pass: tsStartTime:%s tsEndTime:%s dif:%d \r\n", sStart, sEnd, dif); SPDLOG_INFO("pass: tsStartTime:{} tsEndTime:{} dif:{}", sStart, sEnd, dif); int iUpNum = 0; //上升次数 int iDwNum = 0; //下降次数 int iMaxDif = 0; int nMaxValue = 0; time_t tMaxTime; ConmpareValue(pData, tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue); BOOL bPass = FALSE; if ((dif >= 5 && dif < 7 && iUpNum >= 20 && iDwNum >= 20) || (dif == 7 && iUpNum >= 30 && iDwNum >= 30) || (dif >= 8 && iUpNum >= 40 && iDwNum >= 40)) { bPass = TRUE; PASS_RESIST resist; resist.tmStart = tsStartTime; resist.tmEnd = tsEndTime; resist.show_time = tMaxTime; resist.val = nMaxValue; lstResist->emplace_back(resist); } SPDLOG_INFO("[过车判断]{}.{} 开始时间 {} 结束时间 {} 经过时间 {}秒 向上波动 {} 向下波动 {} maxdif 是否过车:{}", mo, mp, sStart, sEnd, dif, iUpNum, iDwNum, iMaxDif, bPass ? "是" : "否"); break; } while (true); tsStartTime = tsEndTime = 0; if (it == pStatInfo.end()) break; } while (true); return; } void mg_per_session_data::GetPassNew(std::map& pStatInfo0, std::map* pData0, std::map& pStatInfo1, std::map* pData1, const string& mo, const string& mp, OUT list* lstResist) { if (!pData0 || !pData1) return; if (pStatInfo0.size() == 0) ConvertMiroToSecond(*pData0, pStatInfo0); if (pStatInfo1.size() == 0) ConvertMiroToSecond(*pData1, pStatInfo1); std::map mapStatInfo0; std::map *mapStatInfo1 = nullptr; auto it = pStatInfo0.cbegin(); mapStatInfo0.emplace(it->first, it->second); time_t tLastIt = it->first; BOOL bForContinue = TRUE;; do { it++; if (it != pStatInfo0.cend()) { if (it->first - tLastIt < 2) //单位秒 { mapStatInfo0.emplace(it->first, it->second); tLastIt = it->first; continue; } else tLastIt = it->first; } else bForContinue = FALSE;//遍历结束 do { if (mapStatInfo0.size() <= 3) //过车不小于3秒 break; mapStatInfo1 = new std::map(pStatInfo1.find(mapStatInfo0.cbegin()->first), (++pStatInfo1.find(mapStatInfo0.crbegin()->first))); GetPassNewUnit(&mapStatInfo0, pData0, mapStatInfo1, pData1, mo, mp, lstResist); delete mapStatInfo1; } while (false); if (mapStatInfo0.size()) mapStatInfo0.clear(); } while (bForContinue); } void mg_per_session_data::GetPassNewUnit(std::map* pStatInfo0, std::map* pData0, std::map* pStatInfo1, std::map* pData1, const string& mo, const string& mp, OUT list* lstResist) { ASSERT(pStatInfo0->size() == pStatInfo1->size()); int nDifCount0 = 0, nDifCount1 = 0; for (auto it = pStatInfo0->cbegin(); it != pStatInfo0->cend(); it++) { if (it->second.dif_val > 100) nDifCount0++; } for (auto it = pStatInfo1->cbegin(); it != pStatInfo1->cend(); it++) { if (it->second.dif_val > 100) nDifCount1++; } if (std::max(nDifCount0, nDifCount1) <= 3) return; //波动小于等于3秒 int iUpNum = 0; //上升次数 int iDwNum = 0; //下降次数 int iMaxDif = 0; int nMaxValue = 0; time_t tMaxTime; time_t tsStartTime = pStatInfo0->begin()->first, tsEndTime = pStatInfo0->crbegin()->first + 1; //结束时间加1秒,后面判断过车时间[tsStartTime, tsEndTime) auto dif = tsEndTime - tsStartTime; auto sStart = CTime(tsStartTime).Format("%Y-%m-%d %H:%M:%S"); auto sEnd = CTime(tsEndTime).Format("%Y-%m-%d %H:%M:%S"); TRACE("pass: tsStartTime:%s tsEndTime:%s dif:%d \r\n", sStart, sEnd, dif); SPDLOG_INFO("pass: nDifCount0:{} nDifCount1:{} tsStartTime:{} tsEndTime:{} dif:{}", nDifCount0, nDifCount1, sStart, sEnd, dif); if (nDifCount0 > nDifCount1) ConmpareValue(pData0, tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue); else ConmpareValue(pData1, tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue); BOOL bPass = FALSE; if ((dif >= 4 && dif < 7 && iUpNum >= 22 && iDwNum >= 22) || (dif == 7 && iUpNum >= 30 && iDwNum >= 30) || (dif >= 8 && iUpNum >= 40 && iDwNum >= 40)) { bPass = TRUE; PASS_RESIST resist; resist.tmStart = tsStartTime; resist.tmEnd = tsEndTime; resist.show_time = tMaxTime; resist.val = nMaxValue; lstResist->emplace_back(resist); } SPDLOG_INFO("[过车判断]{}.{} 开始时间 {} 结束时间 {} 经过时间 {}秒 向上波动 {} 向下波动 {} maxdif 是否过车:{}", mo, mp, sStart, sEnd, dif, iUpNum, iDwNum, iMaxDif, bPass ? "是" : "否"); }