MGWSServer.cpp 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591
  1. #include "stdafx.h"
  2. #include "AppService.h"
  3. #include "MGWSServer.h"
  4. #include "MGDataHandler.h"
  5. #include "MonitorObject.h"
  6. #include <gbk2utf8.h>
  7. #include "AlarmDefine.h"
  8. static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data) {
  9. time_t tmNow;
  10. time(&tmNow);
  11. if (ev == MG_EV_POLL)
  12. {
  13. //time_t tNow;
  14. //time(&tNow);
  15. //TRACE("%d\r\n", tNow);
  16. //if (c->next)
  17. // mg_ws_send(c->next, nullptr, 0, WEBSOCKET_OP_PING);
  18. if (c->fn_data)
  19. {
  20. auto pMsg = (mg_per_session_data*)c->fn_data;
  21. if (tmNow - pMsg->tmLastSendHeart > 30)
  22. {
  23. pMsg->tmLastSendHeart = tmNow;
  24. mg_ws_send(c, nullptr, 0, WEBSOCKET_OP_PING);
  25. }
  26. }
  27. }
  28. /*if (ev == MG_EV_OPEN) {
  29. c->is_hexdumping = 1;
  30. }*/
  31. else if (ev == MG_EV_HTTP_MSG) {
  32. struct mg_http_message* hm = (struct mg_http_message*)ev_data;
  33. mg_ws_upgrade(c, hm, NULL); // Upgrade HTTP to WS
  34. }
  35. else if (ev == MG_EV_WS_MSG) {
  36. // Got websocket frame. Received data is wm->data. Echo it back!
  37. struct mg_ws_message* wm = (struct mg_ws_message*)ev_data;
  38. //mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
  39. char* json = nullptr;
  40. auto pHandler = CAppService::Instance()->GetMgServer()->m_pDataHanlder;
  41. if (pHandler)
  42. {
  43. size_t len = pHandler->HandlerData(c, wm, &json);
  44. if (json)
  45. {
  46. char ip[50];
  47. if (g_bLog) CSimpleLog::Info(mg_straddr(&c->rem, ip, 50) + CString(json, len));
  48. auto send_len = mg_ws_send(c, json, len, WEBSOCKET_OP_TEXT);
  49. ((mg_per_session_data*)c->fn_data)->send_size += send_len;
  50. ((mg_per_session_data*)c->fn_data)->send_count++;
  51. free((void*)json);
  52. }
  53. }
  54. }
  55. else if (ev == MG_EV_WS_OPEN)
  56. {
  57. //websocket 链接时 为每个链接创建用户数据
  58. if (c->fn_data == nullptr)
  59. c->fn_data = new mg_per_session_data;
  60. }
  61. else if (ev == MG_EV_WS_CTL)
  62. {
  63. struct mg_ws_message* wm = (struct mg_ws_message*)ev_data;
  64. auto op = wm->flags & 15;
  65. if (op == WEBSOCKET_OP_CLOSE)
  66. {
  67. //关闭消息 释放内存数据
  68. if (c->fn_data)
  69. {
  70. delete (mg_per_session_data*)(c->fn_data);
  71. c->fn_data = nullptr;
  72. }
  73. }
  74. else if (op == WEBSOCKET_OP_PONG)
  75. {
  76. if (c->fn_data) ((mg_per_session_data*)c->fn_data)->tmLastRecvHeart = tmNow;
  77. }
  78. }
  79. (void)fn_data;
  80. }
  81. CMGWSServer::CMGWSServer()
  82. {
  83. }
  84. CMGWSServer::~CMGWSServer()
  85. {
  86. }
  87. BOOL CMGWSServer::Start(uint16_t port)//10086
  88. {
  89. Stop();
  90. m_bThreadWork = TRUE;
  91. m_pThread = new std::thread(CMGWSServer::ThreadProc, (DWORD_PTR)this, port);
  92. Sleep(100);
  93. if (m_bThreadWork == FALSE)
  94. return FALSE;
  95. m_pDataHanlder = new CMGDataHandler();
  96. return TRUE;
  97. }
  98. void CMGWSServer::Stop()
  99. {
  100. m_bThreadWork = FALSE;
  101. if (m_pThread)
  102. {
  103. m_pThread->join();
  104. delete m_pThread;
  105. m_pThread = nullptr;
  106. }
  107. if (m_pDataHanlder)
  108. {
  109. delete m_pDataHanlder;
  110. m_pDataHanlder = nullptr;
  111. }
  112. }
  113. void CMGWSServer::SendRealResistData(const string& mo_mp, const int num, const std::vector<int>& vctData0, const std::vector<int>& vctData1, const std::vector<int>& vctData2, const std::vector<bool>& vctResult, const CTime& atime)
  114. {
  115. if (m_mg_mgr.conns->is_listening && m_mg_mgr.conns->next == nullptr) return;
  116. if (mo_mp.length() == 0)return;
  117. bool bSub = false;
  118. for (auto it = m_mg_mgr.conns; it; it = it->next)
  119. {
  120. if (it->is_listening) continue;
  121. const auto& pConfInfo = (mg_per_session_data*)it->fn_data;
  122. if (pConfInfo) {
  123. if (pConfInfo->token.find("BBBBBBBB") != -1)
  124. {
  125. bSub = true; break;
  126. }
  127. if (pConfInfo->isLogin == false) continue;
  128. for (const auto& ik : pConfInfo->m_lstSubReal)
  129. {
  130. if (ik.compare(mo_mp) == 0)
  131. {
  132. bSub = true;
  133. break;
  134. }
  135. }
  136. }
  137. }
  138. //所有客户端都未订阅
  139. if (bSub == false) return;
  140. char* json = nullptr;
  141. auto len = GeneralResistData(mo_mp, num, 0, vctData0, vctData1, vctData2, vctResult, atime, &json);
  142. if (len == 0) return;
  143. char ip[50];
  144. for (auto it = m_mg_mgr.conns; it; it = it->next)
  145. {
  146. if (it->is_accepted == false) continue;
  147. if (it->is_websocket == false) continue;
  148. const auto& pConfInfo = (mg_per_session_data*)it->fn_data;
  149. if (pConfInfo) {
  150. if (pConfInfo->token.find("BBBBBBBB") != -1)
  151. {
  152. if (g_bLog) CSimpleLog::Info(mg_straddr(&it->rem, ip, 50) + CString(json, len));
  153. mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT);
  154. continue;
  155. }
  156. if (pConfInfo->isLogin == false) continue;
  157. for (const auto& ik : pConfInfo->m_lstSubReal)
  158. {
  159. if (ik.compare(mo_mp) == 0)
  160. {
  161. if (g_bLog) CSimpleLog::Info(mg_straddr(&it->rem, ip, 50) + CString(json, len));
  162. mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT);
  163. break;
  164. }
  165. }
  166. }
  167. }
  168. }
  169. void CMGWSServer::SendHumiTemp(string mo_mp, const COleDateTime& dt, int humi, int temp)
  170. {
  171. if (m_mg_mgr.conns->is_listening && m_mg_mgr.conns->next == nullptr) return;
  172. if (mo_mp.length() == 0)return;
  173. bool bSub = false;
  174. for (auto it = m_mg_mgr.conns; it; it = it->next)
  175. {
  176. if (it->is_listening) continue;
  177. const auto& pConfInfo = (mg_per_session_data*)it->fn_data;
  178. if (pConfInfo) {
  179. if (pConfInfo->token.find("BBBBBBBB") != -1)
  180. {
  181. bSub = true; break;
  182. }
  183. }
  184. }
  185. //所有客户端都未订阅
  186. if (!bSub) return;
  187. auto doc = yyjson_mut_doc_new(nullptr);
  188. auto root = yyjson_mut_obj(doc);
  189. yyjson_mut_doc_set_root(doc, root);
  190. yyjson_mut_obj_add_str(doc, root, "cmd", "new_data_notify");
  191. yyjson_mut_obj_add_strcpy(doc, root, "time", dt.Format("%Y-%m-%d %H:%M:%S"));
  192. yyjson_mut_obj_add_int(doc, root, "humi", humi / 100);
  193. yyjson_mut_obj_add_int(doc, root, "temp", temp);
  194. yyjson_mut_obj_add_strcpy(doc, root, "tag", (mo_mp + ".humi_temp").c_str());
  195. size_t len;
  196. auto json = yyjson_mut_write(doc, 0, &len);
  197. if (json)
  198. {
  199. for (auto it = m_mg_mgr.conns; it; it = it->next)
  200. {
  201. if (it->is_accepted == false) continue;
  202. if (it->is_websocket == false) continue;
  203. const auto& pConfInfo = (mg_per_session_data*)it->fn_data;
  204. if (pConfInfo) {
  205. if (pConfInfo->token.find("BBBBBBBB") != -1)
  206. {
  207. mg_ws_send(it, json, len, WEBSOCKET_OP_TEXT);
  208. }
  209. }
  210. }
  211. free((void*)json);
  212. }
  213. }
  214. void CMGWSServer::SendToAllClient(const char* ptr, size_t len)
  215. {
  216. if (g_bLog) CSimpleLog::Info(CString(ptr, len));
  217. const auto& mgr = m_mg_mgr;
  218. for (auto it = mgr.conns; it; it = it->next)
  219. {
  220. if (it->is_listening == FALSE && it->is_websocket)
  221. {
  222. mg_ws_send(it, ptr, len, WEBSOCKET_OP_TEXT);
  223. }
  224. }
  225. }
  226. void CMGWSServer::SendToClient(const char* ptr, const size_t len, const char* ip)
  227. {
  228. if (g_bLog) CSimpleLog::Info(CString(ptr, len));
  229. const auto& mgr = m_mg_mgr;
  230. mg_str ip_str = {ip, strlen(ip)};
  231. mg_addr ip_addr;
  232. mg_aton(ip_str, &ip_addr);
  233. for (auto it = mgr.conns; it; it = it->next)
  234. {
  235. if (it->is_listening == FALSE && it->is_websocket && it->rem.ip == ip_addr.ip)
  236. {
  237. mg_ws_send(it, ptr, len, WEBSOCKET_OP_TEXT);
  238. }
  239. }
  240. }
  241. void CMGWSServer::ThreadProc(DWORD_PTR wparam, uint16_t lparam)
  242. {
  243. CMGWSServer* pThis = (CMGWSServer*)wparam;
  244. if (!pThis->m_bThreadWork) return;
  245. mg_mgr_init(&pThis->m_mg_mgr);
  246. char url[128];
  247. sprintf_s(url, 128, "ws://0.0.0.0:%d", lparam);
  248. auto pConn = mg_http_listen(&pThis->m_mg_mgr, url, fn, nullptr);//用户自定义数据赋值为空
  249. if (pConn == nullptr || pConn->is_closing)
  250. CSimpleLog::Error(fmt::format("开启Webscoket端口 {} 失败!", lparam).c_str());
  251. if (pConn) do { mg_mgr_poll(&pThis->m_mg_mgr, 100); } while (pThis->m_bThreadWork);
  252. mg_mgr_free(&pThis->m_mg_mgr);
  253. pThis->m_bThreadWork = FALSE;
  254. }
  255. int CMGWSServer::GeneralResistData(const string mo_mp, const int num, const int index, const std::vector<int>& vctData0, const std::vector<int>& vctData1, const std::vector<int>& vctData2, const std::vector<bool>& vctResult, const CTime& atime, char** json)
  256. {
  257. size_t json_len = 0;
  258. char sz_utf_first[100];
  259. char sz_utf_second[100];
  260. char sz_utf_three[100];
  261. string name1, name2, name3;
  262. CMonitorObjectMng::Instance()->GetNameByMoMp(mo_mp, name1, name2, name3);
  263. if (name1[0x00] == 0x00)
  264. gbk2utf8(sz_utf_first, 100, "1号测力曲线");
  265. else
  266. gbk2utf8(sz_utf_first, 100, name1.c_str());
  267. if (name2[0x00] == 0x00)
  268. gbk2utf8(sz_utf_second, 100, "2号测力曲线");
  269. else
  270. gbk2utf8(sz_utf_second, 100, name2.c_str());
  271. if (name3[0x00] == 0x00)
  272. gbk2utf8(sz_utf_three, 100, "转换阻力曲线");
  273. else
  274. gbk2utf8(sz_utf_three, 100, name3.c_str());
  275. int step = 1000 / num;
  276. uint64_t utime_t = atime.GetTime() * 1000;
  277. string up, momp_name;
  278. CMonitorObjectMng::Instance()->GetStationNameByMomP(mo_mp, up, momp_name);
  279. auto doc = yyjson_mut_doc_new(nullptr);
  280. auto root = yyjson_mut_obj(doc);
  281. yyjson_mut_doc_set_root(doc, root);
  282. auto data = yyjson_mut_arr(doc);
  283. yyjson_mut_obj_add_val(doc, root, "data", data);
  284. auto curve_1 = yyjson_mut_obj(doc);
  285. auto curve_2 = yyjson_mut_obj(doc);
  286. auto curve_3 = yyjson_mut_obj(doc);
  287. yyjson_mut_arr_add_val(data, curve_1);
  288. yyjson_mut_arr_add_val(data, curve_2);
  289. yyjson_mut_arr_add_val(data, curve_3);
  290. yyjson_mut_obj_add_str(doc, root, "cmd", "new_data_notify");
  291. yyjson_mut_obj_add_strcpy(doc, root, "tag", (mo_mp + ".resist").c_str());
  292. yyjson_mut_obj_add_str(doc, root, "data_fmt", "curve");
  293. yyjson_mut_obj_add_str(doc, root, "unit", "N");
  294. yyjson_mut_obj_add_strcpy(doc, root, "up", ANSItoUTF8(up).c_str());
  295. yyjson_mut_obj_add_strcpy(doc, root, "tag_name", ANSItoUTF8(momp_name).c_str());
  296. //1号测力点
  297. yyjson_mut_obj_add_str(doc, curve_1, "name", sz_utf_first);
  298. {
  299. auto arr = yyjson_mut_arr(doc);
  300. yyjson_mut_obj_add_val(doc, curve_1, "points", arr);
  301. for (int i = 0; i < num; i++)
  302. {
  303. if (vctResult[i] == false) continue;
  304. if (vctData0[i] == INVLID_VAL) continue;
  305. auto item = yyjson_mut_arr(doc);
  306. yyjson_mut_arr_add_val(arr, item);
  307. yyjson_mut_arr_add_uint(doc, item, utime_t + step * i);
  308. yyjson_mut_arr_add_int(doc, item, vctData0[i]);
  309. }
  310. }
  311. //2号测力点
  312. yyjson_mut_obj_add_str(doc, curve_2, "name", sz_utf_second);
  313. {
  314. auto arr = yyjson_mut_arr(doc);
  315. yyjson_mut_obj_add_val(doc, curve_2, "points", arr);
  316. for (int i = 0; i < num; i++)
  317. {
  318. if (vctResult[i] == false) continue;
  319. if (vctData1[i] == INVLID_VAL) continue;
  320. auto item = yyjson_mut_arr(doc);
  321. yyjson_mut_arr_add_val(arr, item);
  322. yyjson_mut_arr_add_uint(doc, item, utime_t + step * i);
  323. yyjson_mut_arr_add_int(doc, item, vctData1[i]);
  324. }
  325. }
  326. //3号测力点
  327. yyjson_mut_obj_add_str(doc, curve_3, "name", sz_utf_three);
  328. {
  329. auto arr = yyjson_mut_arr(doc);
  330. yyjson_mut_obj_add_val(doc, curve_3, "points", arr);
  331. for (int i = 0; i < num; i++)
  332. {
  333. if (vctResult[i] == false) continue;
  334. if (vctData2[i] == INVLID_VAL) continue;
  335. auto item = yyjson_mut_arr(doc);
  336. yyjson_mut_arr_add_val(arr, item);
  337. yyjson_mut_arr_add_uint(doc, item, utime_t + step * i);
  338. yyjson_mut_arr_add_int(doc, item, vctData2[i]);
  339. }
  340. }
  341. *json = yyjson_mut_write(doc, 0, &json_len);
  342. yyjson_mut_doc_free(doc);
  343. return json_len;
  344. }
  345. int mg_per_session_data::SendHistResistForEcharts(struct mg_connection* c, string mo_mp, time_t start, time_t end, uint32_t subsection, std::map<time_t, int>& data0, std::map<time_t, int>& data1, std::map<time_t, int>& data2)
  346. {
  347. char sz_utf_first[100];
  348. char sz_utf_second[100];
  349. char sz_utf_three[100];
  350. string name1, name2, name3;
  351. CMonitorObjectMng::Instance()->GetNameByMoMp(mo_mp, name1, name2, name3);
  352. if (name1[0x00] == 0x00)
  353. gbk2utf8(sz_utf_first, 100, "1号测力曲线");
  354. else
  355. gbk2utf8(sz_utf_first, 100, name1.c_str());
  356. if (name2[0x00] == 0x00)
  357. gbk2utf8(sz_utf_second, 100, "2号测力曲线");
  358. else
  359. gbk2utf8(sz_utf_second, 100, name2.c_str());
  360. if (name3[0x00] == 0x00)
  361. gbk2utf8(sz_utf_three, 100, "转换阻力曲线");
  362. else
  363. gbk2utf8(sz_utf_three, 100, name3.c_str());
  364. int offset = 0; uint32_t limit = subsection;
  365. auto it_data0 = data0.begin();
  366. auto it_data1 = data1.begin();
  367. auto it_data2 = data2.begin();
  368. bBlock = false;
  369. do
  370. {
  371. static int n = 600;
  372. for (int i = 0; i < n; i++)
  373. {
  374. if (bWork == false) break;
  375. if (bBlock) this_thread::sleep_for(chrono::milliseconds(100));
  376. else break;
  377. }
  378. #ifndef _DEBUG
  379. if (bBlock) ////5秒未返回确认包,结束
  380. break;;
  381. #endif // _DEBUG
  382. auto cost_start = chrono::steady_clock::now();
  383. //10000 一次
  384. auto doc = yyjson_mut_doc_new(nullptr);
  385. auto root = yyjson_mut_obj(doc);
  386. yyjson_mut_doc_set_root(doc, root);
  387. auto data = yyjson_mut_arr(doc);
  388. yyjson_mut_obj_add_val(doc, root, "data", data);
  389. auto curve_1 = yyjson_mut_obj(doc);
  390. auto curve_2 = yyjson_mut_obj(doc);
  391. auto curve_3 = yyjson_mut_obj(doc);
  392. yyjson_mut_arr_add_val(data, curve_1);
  393. yyjson_mut_arr_add_val(data, curve_2);
  394. yyjson_mut_arr_add_val(data, curve_3);
  395. yyjson_mut_obj_add_str(doc, root, "cmd", "query_hist");
  396. yyjson_mut_obj_add_strcpy(doc, root, "tag", (mo_mp + ".resist").c_str());
  397. yyjson_mut_obj_add_str(doc, root, "data_fmt", "curve");
  398. yyjson_mut_obj_add_str(doc, root, "unit", "N");
  399. yyjson_mut_obj_add_str(doc, root, "time", "");
  400. //1号测力点
  401. yyjson_mut_obj_add_str(doc, curve_1, "name", sz_utf_first);
  402. {
  403. auto arr = yyjson_mut_arr(doc);
  404. yyjson_mut_obj_add_val(doc, curve_1, "points", arr);
  405. auto mark_points = yyjson_mut_arr(doc);
  406. yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points);
  407. for (int i = 0; i < limit && it_data0 != data0.end(); ++it_data0)
  408. {
  409. if (it_data0->first < start)
  410. continue;
  411. if (it_data0->first >= end)
  412. break;
  413. if (it_data0->second == INVLID_VAL)
  414. continue;
  415. auto item = yyjson_mut_arr(doc);
  416. yyjson_mut_arr_add_val(arr, item);
  417. yyjson_mut_arr_add_uint(doc, item, it_data0->first);
  418. yyjson_mut_arr_add_int(doc, item, it_data0->second);
  419. ++i;
  420. }
  421. }
  422. //2号测力点
  423. yyjson_mut_obj_add_str(doc, curve_2, "name", sz_utf_second);
  424. {
  425. auto arr = yyjson_mut_arr(doc);
  426. yyjson_mut_obj_add_val(doc, curve_2, "points", arr);
  427. auto mark_points = yyjson_mut_arr(doc);
  428. yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points);
  429. for (int i = 0; i < limit && it_data1 != data1.end(); ++it_data1)
  430. {
  431. if (it_data1->first < start)
  432. continue;
  433. if (it_data1->first >= end)
  434. break;
  435. if (it_data1->second == INVLID_VAL)
  436. continue;
  437. auto item = yyjson_mut_arr(doc);
  438. yyjson_mut_arr_add_val(arr, item);
  439. yyjson_mut_arr_add_uint(doc, item, it_data1->first);
  440. yyjson_mut_arr_add_int(doc, item, it_data1->second);
  441. ++i;
  442. }
  443. }
  444. //3号测力点
  445. yyjson_mut_obj_add_str(doc, curve_3, "name", sz_utf_three);
  446. {
  447. auto arr = yyjson_mut_arr(doc);
  448. yyjson_mut_obj_add_val(doc, curve_3, "points", arr);
  449. auto mark_points = yyjson_mut_arr(doc);
  450. yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points);
  451. for (int i = 0; i < limit && it_data2 != data2.end(); ++it_data2)
  452. {
  453. if (it_data2->first < start)
  454. continue;
  455. if (it_data2->first >= end)
  456. break;
  457. if (it_data2->second == INVLID_VAL)
  458. continue;
  459. auto item = yyjson_mut_arr(doc);
  460. yyjson_mut_arr_add_val(arr, item);
  461. yyjson_mut_arr_add_uint(doc, item, it_data2->first);
  462. yyjson_mut_arr_add_int(doc, item, it_data2->second);
  463. ++i;
  464. }
  465. }
  466. auto cost_end = chrono::steady_clock::now();
  467. auto cost_dif = chrono::duration_cast<chrono::milliseconds>(cost_end - cost_start).count();
  468. yyjson_mut_obj_add_strcpy(doc, root, "cost", (to_string(cost_dif) + "ms").c_str());
  469. if (bWork == false) break;
  470. size_t ll;
  471. auto json = yyjson_mut_write(doc, 0, &ll);
  472. if (json && c->is_closing == false)
  473. {
  474. mg_ws_send(c, json, ll, WEBSOCKET_OP_TEXT);
  475. free((void*)json);
  476. }
  477. yyjson_mut_doc_free(doc);
  478. bBlock = true;
  479. if (bWork == false) break;
  480. } 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)));
  481. return 0;
  482. }
  483. //现在使用的
  484. int mg_per_session_data::SendHistResistDBForEcharts(LPMGHISTORY_QUERY history_query)
  485. {
  486. char sz_utf_first[100];
  487. char sz_utf_second[100];
  488. char sz_utf_three[100];
  489. string name1, name2, name3, out_name, in_name;
  490. CMonitorObjectMng::Instance()->GetNameByMoMp(history_query->mo_mp, name1, name2, name3, out_name, in_name);
  491. if (name1[0x00] == 0x00)
  492. gbk2utf8(sz_utf_first, 100, "1号测力曲线");
  493. else
  494. gbk2utf8(sz_utf_first, 100, name1.c_str());
  495. if (name2[0x00] == 0x00)
  496. gbk2utf8(sz_utf_second, 100, "2号测力曲线");
  497. else
  498. gbk2utf8(sz_utf_second, 100, name2.c_str());
  499. if (name3[0x00] == 0x00)
  500. gbk2utf8(sz_utf_three, 100, "转换阻力曲线");
  501. else
  502. gbk2utf8(sz_utf_three, 100, name3.c_str());
  503. int offset = 0; uint32_t limit = history_query->subsection; //每次取出10000
  504. CTime ctStart(history_query->tmStart / 1000);
  505. CTime ctEnd(history_query->tmEnd / 1000);
  506. char tablename[50];
  507. char tablenameTom[50];
  508. SYSTEMTIME stStart;
  509. ctStart.GetAsSystemTime(stStart);
  510. sprintf_s(tablename, 50, "rm_resistance_%04d%02d%02d", stStart.wYear, stStart.wMonth, stStart.wDay);
  511. SYSTEMTIME stEnd;
  512. ctEnd.GetAsSystemTime(stEnd);
  513. sprintf_s(tablenameTom, 50, "rm_resistance_%04d%02d%02d", stEnd.wYear, stEnd.wMonth, stEnd.wDay);
  514. string strStartTime = ctStart.Format("%Y-%m-%d %H:%M:%S");
  515. string strEndTime = ctEnd.Format("%Y-%m-%d %H:%M:%S");
  516. bBlock = false;
  517. CString sql;
  518. do
  519. {
  520. static int n = 600;
  521. for (int i = 0; i < n; i++)
  522. {
  523. if (bWork == false) break;
  524. if (bBlock) this_thread::sleep_for(chrono::milliseconds(100));
  525. else break;
  526. }
  527. #ifndef _DEBUG
  528. if (bBlock) ////5秒未返回确认包,结束
  529. break;;
  530. #endif // _DEBUG
  531. auto cost_start = chrono::steady_clock::now();
  532. if (stStart.wDay == stEnd.wDay)
  533. {
  534. sql.Format("SELECT [acquisitiontime],[data0],[data1],[data2] "\
  535. "FROM %s WHERE IMEI = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' AND idx = %d "\
  536. "ORDER BY acquisitiontime ASC OFFSET %d ROWS FETCH NEXT %d ROWS ONLY",
  537. tablename, history_query->imei.c_str(), strStartTime.c_str(), strEndTime.c_str(), history_query->idx, offset, limit);
  538. }
  539. else
  540. {
  541. sql.Format("SELECT [acquisitiontime],[data0],[data1],[data2] "\
  542. "FROM %s WHERE IMEI = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' AND idx = %d "\
  543. "UNION ALL "\
  544. "SELECT [acquisitiontime],[data0],[data1],[data2] "\
  545. "FROM %s WHERE IMEI = '%s' AND acquisitiontime >= '%s' and acquisitiontime < '%s' AND idx = %d "\
  546. "ORDER BY acquisitiontime ASC OFFSET %d ROWS FETCH NEXT %d ROWS ONLY",
  547. tablename, history_query->imei.c_str(), strStartTime.c_str(), strEndTime.c_str(), history_query->idx,
  548. tablenameTom, history_query->imei.c_str(), strStartTime.c_str(), strEndTime.c_str(), history_query->idx,
  549. offset, limit);
  550. }
  551. TRACE("%s\r\n", sql);
  552. int no = 0;
  553. TIMESTAMP_STRUCT ts;
  554. int sdata0, sdata1, sdata2;
  555. COdbcStatement stmt;
  556. if (CDBConnectPool::Instance()->DBQuery(stmt, sql) == FALSE)
  557. {
  558. CSimpleLog::Error("查询语句出错:" + sql);
  559. break;
  560. }
  561. int nCol = 1;
  562. stmt.BindTimeStampCol(nCol++, &ts);
  563. stmt.BindIntCol(nCol++, &sdata0);
  564. stmt.BindIntCol(nCol++, &sdata1);
  565. stmt.BindIntCol(nCol++, &sdata2);
  566. std::map<time_t, int> data0, data1, data2;
  567. do
  568. {
  569. if (stmt.FetchNext() != 0)
  570. break;
  571. no++;
  572. CTime ctTime;
  573. try
  574. {
  575. ctTime = CTime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
  576. }
  577. catch (...)
  578. {
  579. continue;
  580. }
  581. time_t tm = ctTime.GetTime() * 1000 + ts.fraction / 1000000;
  582. data0[tm] = sdata0;
  583. data1[tm] = sdata1;
  584. data2[tm] = sdata2;
  585. } while (true);
  586. //扳动阈值判断 放到HTTP里
  587. //std::map<time_t, int64_t> maxlock0, maxlock1, maxForce;
  588. //list<CONVERT_RESIST> maxResist;
  589. //GetMaxResist(data2, maxResist);
  590. //GetMaxLockNew(data0, maxResist, maxlock0);
  591. //GetMaxLockNew(data1, maxResist, maxlock1);
  592. ////CalcFixOrInvert(maxResist, maxlock0, maxlock1, name1, name2);
  593. //GetMaxForce(data2, maxForce);
  594. //10000 一次
  595. auto doc = yyjson_mut_doc_new(nullptr);
  596. auto root = yyjson_mut_obj(doc);
  597. yyjson_mut_doc_set_root(doc, root);
  598. auto data = yyjson_mut_arr(doc);
  599. yyjson_mut_obj_add_val(doc, root, "data", data);
  600. auto curve_1 = yyjson_mut_obj(doc);
  601. auto curve_2 = yyjson_mut_obj(doc);
  602. auto curve_3 = yyjson_mut_obj(doc);
  603. yyjson_mut_arr_add_val(data, curve_1);
  604. yyjson_mut_arr_add_val(data, curve_2);
  605. yyjson_mut_arr_add_val(data, curve_3);
  606. yyjson_mut_obj_add_str(doc, root, "cmd", "query_hist");
  607. yyjson_mut_obj_add_strcpy(doc, root, "tag", (history_query->mo_mp + ".resist").c_str());
  608. yyjson_mut_obj_add_str(doc, root, "data_fmt", "curve");
  609. yyjson_mut_obj_add_str(doc, root, "unit", "N");
  610. yyjson_mut_obj_add_str(doc, root, "time", "");
  611. //1号测力点
  612. yyjson_mut_obj_add_str(doc, curve_1, "name", sz_utf_first);
  613. {
  614. auto arr = yyjson_mut_arr(doc);
  615. yyjson_mut_obj_add_val(doc, curve_1, "points", arr);
  616. #ifdef SHOW_DATA
  617. for (const auto& it : data0)
  618. {
  619. if (INVLID_VAL == it.second)
  620. continue;
  621. auto item = yyjson_mut_arr(doc);
  622. yyjson_mut_arr_add_val(arr, item);
  623. yyjson_mut_arr_add_uint(doc, item, it.first);
  624. yyjson_mut_arr_add_int(doc, item, it.second);
  625. }
  626. #endif // SHOW_DATA
  627. // auto mark_points = yyjson_mut_arr(doc);
  628. // yyjson_mut_obj_add_val(doc, curve_1, "mark_points", mark_points);
  629. // for (const auto& it : maxlock0)
  630. // {
  631. // auto obj = yyjson_mut_obj(doc);
  632. // yyjson_mut_arr_add_val(mark_points, obj);
  633. // auto val = (it.second >> 32);
  634. // if (val > 500)
  635. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("锁闭力:{}", val)).c_str());
  636. // else
  637. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8("锁闭力过低").c_str());
  638. // yyjson_mut_obj_add_int(doc, obj, "val", val);
  639. // auto arr = yyjson_mut_arr(doc);
  640. // yyjson_mut_obj_add_val(doc, obj, "coord", arr);
  641. //#ifdef SHOW_DATA
  642. // yyjson_mut_arr_add_uint(doc, arr, it.first);
  643. //#else
  644. // yyjson_mut_arr_add_strcpy(doc, arr, CTime(it.first / 1000).Format("%Y-%m-%d %H:%M:%S"));
  645. //#endif // _DEBUG
  646. // yyjson_mut_arr_add_int(doc, arr, (int)it.second);
  647. // }
  648. }
  649. //2号测力点
  650. yyjson_mut_obj_add_str(doc, curve_2, "name", sz_utf_second);
  651. {
  652. auto arr = yyjson_mut_arr(doc);
  653. yyjson_mut_obj_add_val(doc, curve_2, "points", arr);
  654. #ifdef SHOW_DATA
  655. for (const auto& it : data1)
  656. {
  657. if (INVLID_VAL == it.second)
  658. continue;
  659. auto item = yyjson_mut_arr(doc);
  660. yyjson_mut_arr_add_val(arr, item);
  661. yyjson_mut_arr_add_uint(doc, item, it.first);
  662. yyjson_mut_arr_add_int(doc, item, it.second);
  663. }
  664. #endif
  665. // auto mark_points = yyjson_mut_arr(doc);
  666. // yyjson_mut_obj_add_val(doc, curve_2, "mark_points", mark_points);
  667. // for (const auto& it : maxlock1)
  668. // {
  669. // auto obj = yyjson_mut_obj(doc);
  670. // yyjson_mut_arr_add_val(mark_points, obj);
  671. // auto val = (it.second >> 32);
  672. // if (val > 500)
  673. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("锁闭力:{}", val)).c_str());
  674. // else
  675. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8("锁闭力过低").c_str());
  676. // auto arr = yyjson_mut_arr(doc);
  677. // yyjson_mut_obj_add_val(doc, obj, "coord", arr);
  678. // yyjson_mut_obj_add_int(doc, obj, "val", val);
  679. //#ifdef SHOW_DATA
  680. // yyjson_mut_arr_add_uint(doc, arr, it.first);
  681. //#else
  682. // yyjson_mut_arr_add_strcpy(doc, arr, CTime(it.first / 1000).Format("%Y-%m-%d %H:%M:%S"));
  683. //#endif // _DEBUG
  684. // yyjson_mut_arr_add_int(doc, arr, (int)it.second);
  685. // }
  686. }
  687. //3号测力点
  688. yyjson_mut_obj_add_str(doc, curve_3, "name", sz_utf_three);
  689. {
  690. auto arr = yyjson_mut_arr(doc);
  691. yyjson_mut_obj_add_val(doc, curve_3, "points", arr);
  692. #ifdef SHOW_DATA
  693. for (const auto& it : data2)
  694. {
  695. if (INVLID_VAL == it.second)
  696. continue;
  697. auto item = yyjson_mut_arr(doc);
  698. yyjson_mut_arr_add_val(arr, item);
  699. yyjson_mut_arr_add_uint(doc, item, it.first);
  700. yyjson_mut_arr_add_int(doc, item, it.second);
  701. }
  702. #endif
  703. // auto mark_points = yyjson_mut_arr(doc);
  704. // yyjson_mut_obj_add_val(doc, curve_3, "mark_points", mark_points);
  705. // for (const auto& it : maxResist)
  706. // {
  707. // auto obj = yyjson_mut_obj(doc);
  708. // yyjson_mut_arr_add_val(mark_points, obj);
  709. // if (it.bUpOrDown == 1 && in_name.length() > 0)
  710. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("{}:{}", in_name, it.fluctuation_val)).c_str());
  711. // else if (it.bUpOrDown == 2 && out_name.length() > 0)
  712. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("{}:{}", out_name, it.fluctuation_val)).c_str());
  713. // else
  714. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("最大转换阻力值:{}", it.fluctuation_val)).c_str());
  715. //
  716. // if (it.bUpOrDown == 2) yyjson_mut_obj_add_str(doc, obj, "position", "bottom"); //负数增加显示位置
  717. // auto arr = yyjson_mut_arr(doc);
  718. // yyjson_mut_obj_add_val(doc, obj, "coord", arr);
  719. //#ifdef SHOW_DATA
  720. // yyjson_mut_arr_add_uint(doc, arr, it.time);
  721. //#else
  722. // yyjson_mut_arr_add_strcpy(doc, arr, CTime(it.time / 1000).Format("%Y-%m-%d %H:%M:%S"));
  723. //#endif // _DEBUG
  724. // yyjson_mut_arr_add_int(doc, arr, it.val);
  725. // }
  726. // for (const auto& it : maxForce)
  727. // {
  728. // auto obj = yyjson_mut_obj(doc);
  729. // yyjson_mut_arr_add_val(mark_points, obj);
  730. // yyjson_mut_obj_add_strcpy(doc, obj, "label", ANSItoUTF8(fmt::format("摩擦力值:{}", (it.second >> 32))).c_str());
  731. // auto arr = yyjson_mut_arr(doc);
  732. // yyjson_mut_obj_add_val(doc, obj, "coord", arr);
  733. // yyjson_mut_arr_add_uint(doc, arr, it.first);
  734. // yyjson_mut_arr_add_int(doc, arr, (int)it.second);
  735. // }
  736. }
  737. auto cost_end = chrono::steady_clock::now();
  738. auto cost_dif = chrono::duration_cast<chrono::milliseconds>(cost_end - cost_start).count();
  739. yyjson_mut_obj_add_strcpy(doc, root, "cost", (to_string(cost_dif) + "ms").c_str());
  740. if (bWork)
  741. {
  742. size_t ll;
  743. auto json = yyjson_mut_write(doc, 0, &ll);
  744. char ip[50];
  745. if (json && history_query->c->is_closing == false) {
  746. if (g_bLog) CSimpleLog::Info(mg_straddr(&history_query->c->rem, ip, 50) + CString(json, ll));
  747. mg_ws_send(history_query->c, json, ll, WEBSOCKET_OP_TEXT);
  748. free((void*)json);
  749. }
  750. }
  751. yyjson_mut_doc_free(doc);
  752. //maxlock0.clear();
  753. //maxlock1.clear();
  754. //maxForce.clear();
  755. //maxResist.clear();
  756. //len 335214
  757. bBlock = true;
  758. if (bWork == false) break;
  759. offset += no;
  760. if (no != limit)
  761. {
  762. break;
  763. }
  764. } while (true);
  765. return 0;
  766. }
  767. //{ "cmd": "login", "token": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"}
  768. //{ "cmd": "query_hist", "tag": "TLDZ24.J3.resist", "time": "2022-10-14 03:42:00~2022-10-14 03:46:30", "subsection": 5000}
  769. void mg_per_session_data::GetMaxResist(std::map<time_t, int>& data, std::map<time_t, tagSecondStatInfo>& mapSecondStatInfo, list<CONVERT_RESIST>& out, const string& mo, const string& mp)
  770. {
  771. ConvertMiroToSecond(data, mapSecondStatInfo);
  772. if (mapSecondStatInfo.size() == 0) return;
  773. GetMaxResistNew(mapSecondStatInfo, out, mo, mp);
  774. }
  775. void mg_per_session_data::GetMaxResist(std::map<time_t, tagSecondStatInfo>& mapSecondStatInfo, list<CONVERT_RESIST>& out)
  776. {
  777. int steady_val = INT_MIN;
  778. time_t move_start_t = 0; //扳动开始时间
  779. int move_start_val = INT_MIN; //扳动起始值
  780. int move_max_val = INT_MIN; //扳动峰值
  781. time_t move_max_t = 0; //扳动峰值的时间
  782. int move_min_val = INT_MAX; //扳动谷值
  783. time_t move_min_t = 0; //扳动谷值的时间
  784. time_t last_t = mapSecondStatInfo.begin()->first;
  785. time_t last_last_t;
  786. int last_end_val = mapSecondStatInfo.begin()->second.end_val;
  787. int last_last_end_val; //上一秒的最后一个值
  788. for (auto& it : mapSecondStatInfo)
  789. {
  790. auto str = CTime(it.first).Format("%Y-%m-%d %H:%M:%S") + '.' + to_string(it.first % 1000).c_str();
  791. TRACE("%s\r\n", str);
  792. last_last_t = last_t;//更新前赋值
  793. last_t = it.first;
  794. last_last_end_val = last_end_val;
  795. last_end_val = it.second.end_val;
  796. if (it.second.dif_val <= 150) //稳定 大于500N 为波动
  797. {
  798. if (move_start_t != 0) // 波动结束
  799. {
  800. CONVERT_RESIST info;
  801. info.tmStart = move_start_t;
  802. info.tmEnd = it.first;
  803. int fluctuation_t = it.first - move_start_t;//波动时间
  804. bool bMax = false;
  805. auto iMax = abs(move_max_val - steady_val);
  806. auto iMin = abs(move_min_val - steady_val);
  807. if (iMax > iMin)
  808. {
  809. bMax = true;
  810. info.fluctuation_val = iMax;//最大值减去前面的稳定平均值
  811. }
  812. else info.fluctuation_val = iMin;
  813. if (fluctuation_t >= 4 && fluctuation_t <= 8 && info.fluctuation_val > 450)
  814. {
  815. //扳动
  816. if (bMax)
  817. {
  818. //输出记录
  819. info.time = move_max_t;
  820. info.bUpOrDown = eUpOrDownInfo::UOD_UP;
  821. info.val = move_max_val;
  822. out.emplace_back(info);
  823. //out[move_max_t] = (((int64_t)move_max_val - steady_val) << 32) + move_max_val;
  824. CSimpleLog::Info(fmt::format("[转换阻力求值]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 波动值:{}",
  825. 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,
  826. 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
  827. ).c_str());
  828. }
  829. else
  830. {
  831. info.time = move_min_t;
  832. info.bUpOrDown = eUpOrDownInfo::UOD_DOWN;
  833. info.val = move_min_val;
  834. out.emplace_back(info);
  835. //out[move_min_t] = (((int64_t)move_min_val - steady_val) << 32) + move_min_val;//输出记录
  836. CSimpleLog::Info(fmt::format("[转换阻力求值]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 波动值:{}",
  837. 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,
  838. 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
  839. ).c_str());
  840. }
  841. }
  842. else
  843. {
  844. if (bMax)
  845. CSimpleLog::Info(fmt::format("[转换阻力求值]不符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 波动值:{} 不符合特征",
  846. 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,
  847. 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
  848. ).c_str());
  849. else
  850. CSimpleLog::Info(fmt::format("[转换阻力求值]不符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 波动值:{} 不符合特征",
  851. 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,
  852. 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
  853. ).c_str());
  854. }
  855. //重置
  856. move_start_t = 0;
  857. move_max_val = INT_MIN;
  858. move_max_t = 0;
  859. move_start_val = INT_MIN;
  860. move_min_val = INT_MAX; //扳动谷值
  861. move_min_t = 0; //扳动谷值的时间
  862. }
  863. //steady_val = it.second.sum_val / it.second.cout; //稳定值为平均值
  864. steady_val = it.second.end_val; //2022.10.22换成最后一个值
  865. }
  866. else if (steady_val == INT_MIN) //起始点就是波动
  867. {
  868. continue;
  869. }
  870. else if (it.second.dif_val > 400)
  871. {
  872. if (move_start_t == 0)
  873. {
  874. //开始波动
  875. if (abs(last_last_end_val - it.second.first_val) < 100) //如果前面的最后一个值 和 当前最开始的值 小于 100 . 以当前这个为准 2022.10.22
  876. {
  877. move_start_t = last_t; //取当前 it.first
  878. steady_val = it.second.first_val;
  879. CSimpleLog::Info(fmt::format("[转换阻力求值]检测到开始波动:{} 上一个稳定时间:{} 起始值:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"),
  880. CTime(last_t).Format("%Y-%m-%d %H:%M:%S"), steady_val).c_str());
  881. }
  882. else
  883. {
  884. move_start_t = last_last_t; //开始波动取上一个
  885. steady_val = last_last_end_val;
  886. CSimpleLog::Info(fmt::format("[转换阻力求值]检测到开始波动:{} 上一个稳定时间:{} 起始值:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"),
  887. CTime(last_last_t).Format("%Y-%m-%d %H:%M:%S"), steady_val).c_str());
  888. }
  889. }
  890. //波动 取出最大值
  891. if (it.second.max_val > move_max_val)
  892. {
  893. move_max_t = it.second.max_time;
  894. move_max_val = it.second.max_val;
  895. }
  896. if (it.second.min_val < move_min_val)
  897. {
  898. move_min_t = it.second.min_time;
  899. move_min_val = it.second.min_val;
  900. }
  901. }
  902. }
  903. }
  904. void mg_per_session_data::GetMaxResistNew(std::map<time_t, tagSecondStatInfo>& mapSecondStatInfo, list<CONVERT_RESIST>& out, const string& mo, const string& mp)
  905. {
  906. if (mapSecondStatInfo.size() <= 1) return;
  907. string momp = mo + "." + mp;
  908. time_t move_start_t = 0; //扳动开始时间
  909. int move_start_val = INT_MIN; //扳动起始值
  910. int move_max_val = INT_MIN; //扳动峰值
  911. time_t move_max_t = 0; //扳动峰值的时间
  912. int move_min_val = INT_MAX; //扳动谷值
  913. time_t move_min_t = 0; //扳动谷值的时间
  914. time_t last_t = mapSecondStatInfo.begin()->first;
  915. time_t last_last_t;
  916. int last_end_val = mapSecondStatInfo.begin()->second.end_val;
  917. int last_last_end_val; //上一秒的最后一个值
  918. list<tagSecondStatInfo> lstStatInfo;
  919. auto it = mapSecondStatInfo.cbegin();
  920. lstStatInfo.emplace_back(it->second);
  921. time_t tLastIt = it->first;
  922. BOOL bForContinue = TRUE;;
  923. do
  924. {
  925. it++;
  926. if (it != mapSecondStatInfo.cend())
  927. {
  928. if (it->first - tLastIt < 2) //单位秒
  929. {
  930. lstStatInfo.emplace_back(it->second);
  931. tLastIt = it->first;
  932. continue;
  933. }
  934. else
  935. tLastIt = it->first;
  936. }
  937. else
  938. bForContinue = FALSE;//遍历结束
  939. do
  940. {
  941. if (lstStatInfo.size() < 3) //扳动不小于3秒
  942. break;
  943. //处理逻辑
  944. int steady_val = INT_MIN;
  945. list<tagSecondStatInfo>::iterator it_start = lstStatInfo.end();
  946. list<tagSecondStatInfo>::reverse_iterator it_end = lstStatInfo.rend();
  947. for (auto i = lstStatInfo.begin(); i != lstStatInfo.end(); i++)
  948. {
  949. if (i->dif_val >= 100) //大于100N算波动
  950. {
  951. if (steady_val == INT_MIN)
  952. steady_val = i->first_val;
  953. it_start = i;
  954. break;
  955. }
  956. else
  957. steady_val = i->end_val;
  958. }
  959. for (auto i = lstStatInfo.rbegin(); i != lstStatInfo.rend(); i++)
  960. {
  961. if (i->dif_val >= 100) //大于100N算波动
  962. {
  963. it_end = i;
  964. break;
  965. }
  966. }
  967. if (it_start == lstStatInfo.end() || it_end == lstStatInfo.rend())
  968. break;
  969. if (it_end == lstStatInfo.rbegin())
  970. {
  971. //结束还在波动 不进行判断
  972. SPDLOG_INFO("[转换阻力判断][{}.{}] 结束还在波动 进行判断: {}", mo, mp,
  973. CTime(it_end->max_time / 1000).Format("%Y-%m-%d %H:%M:%S")); //放开测试一下
  974. }
  975. CONVERT_RESIST info;
  976. info.tmStart = it_start->max_time / 1000;
  977. info.tmEnd = it_end->max_time / 1000 + 1;
  978. //取出转换值
  979. move_max_val = it_start->max_val;
  980. move_min_val = it_start->min_val;
  981. move_max_t = move_min_t = it_start->max_time;
  982. for (auto i = it_start;;)
  983. {
  984. if (i == lstStatInfo.end())
  985. break;
  986. if (i->max_val > move_max_val)
  987. {
  988. move_max_val = i->max_val;
  989. move_max_t = i->max_time;
  990. }
  991. if (i->min_val < move_min_val)
  992. {
  993. move_min_val = i->min_val;
  994. move_min_t = i->min_time;
  995. }
  996. if (i->max_time > it_end->max_time)
  997. {
  998. break;
  999. }
  1000. i++;
  1001. }
  1002. bool bMax = false;
  1003. auto iMax = abs(move_max_val - steady_val);
  1004. auto iMin = abs(move_min_val - steady_val);
  1005. if (iMax > iMin)
  1006. {
  1007. bMax = true;
  1008. info.fluctuation_val = iMax;//最大值减去前面的稳定平均值
  1009. }
  1010. else info.fluctuation_val = iMin;
  1011. auto fluctuation_t = it_end->max_time / 1000 - it_start->max_time / 1000 + 1; //波动时长
  1012. if (fluctuation_t >= 3 && fluctuation_t <= 9 && info.fluctuation_val > 450)
  1013. {
  1014. //扳动
  1015. if (bMax)
  1016. {
  1017. //输出记录
  1018. info.time = move_max_t;
  1019. info.bUpOrDown = eUpOrDownInfo::UOD_UP;
  1020. info.val = move_max_val;
  1021. out.emplace_back(info);
  1022. //out[move_max_t] = (((int64_t)move_max_val - steady_val) << 32) + move_max_val;
  1023. if (g_bLog || g_strMoMp.compare(momp) == 0)
  1024. SPDLOG_INFO("[转换阻力求值][{}:{}]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{}", mo, mp,
  1025. 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,
  1026. CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val);
  1027. }
  1028. else
  1029. {
  1030. info.time = move_min_t;
  1031. info.bUpOrDown = eUpOrDownInfo::UOD_DOWN;
  1032. info.val = move_min_val;
  1033. out.emplace_back(info);
  1034. //out[move_min_t] = (((int64_t)move_min_val - steady_val) << 32) + move_min_val;//输出记录
  1035. if (g_bLog || g_strMoMp.compare(momp) == 0)
  1036. SPDLOG_INFO("[转换阻力求值][{}:{}]符合特征 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{}", mo, mp,
  1037. 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,
  1038. CTime(move_min_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_min_t % 1000).c_str(), move_min_val);
  1039. }
  1040. }
  1041. else
  1042. {
  1043. if (bMax)
  1044. CSimpleLog::Info(fmt::format("[转换阻力求值][{}:{}]不符合3秒~9秒 大于450N 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最大值:{} 不符合特征", mo, mp,
  1045. 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,
  1046. CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_max_t % 1000).c_str(), move_max_val
  1047. ).c_str());
  1048. else
  1049. SPDLOG_INFO("[转换阻力求值][{}:{}]不符合3秒~9秒 大于450N 波动开始:{} 结束:{} 波动时长:{} 转换阻力值大小:{} 时间:{} 最小值:{} 不符合特征", mo, mp,
  1050. 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,
  1051. CTime(move_min_t / 1000).Format("%Y-%m-%d %H:%M:%S.") + to_string(move_min_t % 1000).c_str(), move_min_val
  1052. );
  1053. }
  1054. TRACE("%s %d \r\n", CTime(it_end->max_time / 1000).Format("%Y-%m-%d %H:%M:%S"), fluctuation_t);
  1055. } while (false);
  1056. if (lstStatInfo.size()) lstStatInfo.clear();
  1057. ////遍历结束
  1058. //if (it == mapSecondStatInfo.cend())
  1059. // break;
  1060. } while (bForContinue);
  1061. }
  1062. void mg_per_session_data::GetMaxLockNew(const std::map<time_t, int>& data, const list<CONVERT_RESIST>& refer, std::map<time_t, int64_t>& out, std::map<time_t, int64_t>& retensionforce)
  1063. {
  1064. std::map<time_t, tagSecondStatInfo> mapSecondStatInfo;
  1065. ConvertMiroToSecond(data, mapSecondStatInfo);
  1066. if (mapSecondStatInfo.size() == 0) return;
  1067. GetMaxLockNew(mapSecondStatInfo, refer, out, retensionforce);
  1068. }
  1069. /*
  1070. void mg_per_session_data::GetMaxLock(std::map<time_t, tagSecondStatInfo> mapSecondStatInfo, const list<CONVERT_RESIST>& refer, std::map<time_t, int64_t>& out)
  1071. {
  1072. int steady_val = INT_MIN;
  1073. time_t move_start_t = 0; //扳动开始时间 最后一个稳态时间
  1074. time_t move_start_move_t = 0; //扳动开始时间 即波动时间
  1075. int move_start_val = INT_MIN; //扳动起始值
  1076. int move_max_val = INT_MIN; //扳动峰值
  1077. time_t move_max_t = 0; //扳动峰值的时间
  1078. int move_min_val = INT_MAX; //扳动谷值 只参与计算
  1079. time_t move_min_t = 0; //扳动谷值的时间
  1080. time_t last_t = mapSecondStatInfo.begin()->first;
  1081. time_t last_last_t;
  1082. for (auto& it : mapSecondStatInfo)
  1083. {
  1084. auto str = CTime(it.first).Format("%Y-%m-%d %H:%M:%S") + '.' + to_string(it.first % 1000).c_str();
  1085. //TRACE("%s\r\n", str);
  1086. last_last_t = last_t;//更新前赋值
  1087. last_t = it.first;
  1088. if (it.second.dif_val <= 300) //稳定 大于300N 为波动
  1089. {
  1090. if (move_start_t != 0) // 波动结束
  1091. {
  1092. int fluctuation_t = it.first - move_start_t;//波动时间
  1093. int fluctuation_val = move_max_val - steady_val; //最大值减去前面的稳定平均值
  1094. int nSecondDif = INT_MAX;
  1095. bool bCalcDif = CalcSecondDif(refer, move_start_move_t, nSecondDif);
  1096. if (fluctuation_t >= 1 && fluctuation_t <= 7 && fluctuation_val > 30 && bCalcDif && nSecondDif >= 1) //小于0 不是密贴 2023.2.10 2秒改为1秒
  1097. {
  1098. //扳动
  1099. out[move_max_t] = (((int64_t)fluctuation_val) << 32) + move_max_val;//输出记录
  1100. //SPDLOG_INFO("[锁闭力求值]符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{}", fluctuation_t, fluctuation_val,
  1101. // CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S") + to_string(move_max_t % 1000).c_str(), move_max_val);
  1102. CSimpleLog::Info(fmt::format("[锁闭力求值]符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{} nSecondDif:{} 开始波动时间:{}", fluctuation_t, fluctuation_val,
  1103. 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());
  1104. }
  1105. else
  1106. {
  1107. if (fluctuation_val < 0)
  1108. {
  1109. fluctuation_val = move_min_val - steady_val;
  1110. CSimpleLog::Info(fmt::format("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最小值:{} bCalcDif:{} nSecondDif:{} 开始波动时间:{} 不符合特征", fluctuation_t, fluctuation_val,
  1111. 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());
  1112. }
  1113. else
  1114. {
  1115. //SPDLOG_INFO("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{}", fluctuation_t, fluctuation_val,
  1116. // CTime(move_max_t / 1000).Format("%Y-%m-%d %H:%M:%S") + to_string(move_max_t % 1000).c_str(), move_max_val);
  1117. CSimpleLog::Info(fmt::format("[锁闭力求值]不符合特征 波动时长:{} 锁闭力大小:{} 时间:{} 最大值:{} bCalcDif:{} nSecondDif:{} 开始波动时间:{} 不符合特征", fluctuation_t, fluctuation_val,
  1118. 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());
  1119. }
  1120. }
  1121. //重置
  1122. move_start_t = 0;
  1123. move_start_move_t = 0;
  1124. move_max_val = INT_MIN;
  1125. move_max_t = 0;
  1126. move_start_val = INT_MIN;
  1127. move_min_val = INT_MAX; //扳动谷值
  1128. move_min_t = 0; //扳动谷值的时间
  1129. }
  1130. steady_val = it.second.sum_val / it.second.cout; //稳定值为平均值
  1131. }
  1132. else if (steady_val == INT_MIN) //起始点就是波动
  1133. {
  1134. continue;
  1135. }
  1136. else if (it.second.dif_val > 300)
  1137. {
  1138. if (move_start_t == 0)
  1139. {
  1140. move_start_t = last_last_t; //开始波动取上一个
  1141. move_start_move_t = it.first;
  1142. //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"));
  1143. CSimpleLog::Info(fmt::format("[锁闭力求值]检测到开始波动:{} 上一个稳定时间:{}", CTime(it.first).Format("%Y-%m-%d %H:%M:%S"),
  1144. CTime(last_last_t).Format("%Y-%m-%d %H:%M:%S")).c_str());
  1145. }
  1146. //波动 取出最大值
  1147. if (it.second.max_val > move_max_val)
  1148. {
  1149. move_max_t = it.second.max_time;
  1150. move_max_val = it.second.max_val;
  1151. }
  1152. if (it.second.min_val < move_min_val)
  1153. {
  1154. move_min_t = it.second.min_time;
  1155. move_min_val = it.second.min_val;
  1156. }
  1157. }
  1158. }
  1159. }
  1160. */
  1161. void mg_per_session_data::GetMaxLockNew(const std::map<time_t, tagSecondStatInfo> &mapSecondStatInfo, const list<CONVERT_RESIST>& refer, std::map<time_t, int64_t>& out, std::map<time_t, int64_t>& retensionforce)
  1162. {
  1163. for (auto& it : refer)
  1164. {
  1165. auto it_start = mapSecondStatInfo.find(it.tmStart);
  1166. if (it_start == mapSecondStatInfo.end())
  1167. continue;
  1168. int fluctuation_val = INT_MIN;
  1169. auto it_end = mapSecondStatInfo.find(it.tmEnd);
  1170. if (it_end != mapSecondStatInfo.end())
  1171. {
  1172. fluctuation_val = it_end->second.first_val - it_start->second.end_val; //取
  1173. }
  1174. else
  1175. {
  1176. it_end = mapSecondStatInfo.find(it.tmEnd - 1);
  1177. if (it_end == mapSecondStatInfo.end())
  1178. {
  1179. ASSERT(false);
  1180. continue;
  1181. }
  1182. fluctuation_val = it_end->second.end_val - it_start->second.end_val; //取
  1183. }
  1184. if (fluctuation_val < 30)
  1185. {
  1186. //保持力
  1187. if (it_end->second.dif_val < 30)
  1188. retensionforce[it_end->first * 1000] = it_start->second.end_val;
  1189. else if (it_end->second.cout)
  1190. retensionforce[it_end->first * 1000] = it_end->second.sum_val / it_end->second.cout;
  1191. continue;
  1192. }
  1193. int move_max_val = INT_MIN; //扳动峰值
  1194. time_t move_max_t = 0; //扳动峰值的时间
  1195. for (auto i = it_start; i != mapSecondStatInfo.end() && i->first < it.tmEnd; i++)
  1196. {
  1197. if (move_max_val < i->second.max_val)
  1198. {
  1199. move_max_val = i->second.max_val;
  1200. move_max_t = i->second.max_time;
  1201. }
  1202. }
  1203. out[move_max_t] = (((int64_t)fluctuation_val) << 32) + move_max_val;//输出记录
  1204. }
  1205. }
  1206. void mg_per_session_data::GetMaxForce(std::map<time_t, int>& data2, std::map<time_t, int64_t>& out)
  1207. {
  1208. }
  1209. void mg_per_session_data::CalcFixOrInvert(list<CONVERT_RESIST>& out, std::map<time_t, int64_t>& in1, std::map<time_t, int64_t>& in2, string name1, string name2)
  1210. {
  1211. if (name1.find("定") == -1 && name2.find("定") == -1) return;
  1212. if (in1.size() == 0 && in2.size() == 0) return;
  1213. for (auto& it : out)
  1214. {
  1215. uint8_t bFirstOrSecond = 0;
  1216. int time_dif = INT_MAX;
  1217. for (const auto& ik : in1)
  1218. {
  1219. auto dif = abs(it.time - ik.first);
  1220. if (dif < 8000 && dif < time_dif)
  1221. {
  1222. time_dif = dif;
  1223. bFirstOrSecond = 1;
  1224. }
  1225. }
  1226. for (const auto& ik : in2)
  1227. {
  1228. auto dif = abs(it.time - ik.first);
  1229. if (dif < 8000 && dif < time_dif)
  1230. {
  1231. time_dif = dif;
  1232. bFirstOrSecond = 2;
  1233. }
  1234. }
  1235. if (bFirstOrSecond == 1)
  1236. {
  1237. if (name1.find("定") != -1) it.bFixOrInvert = 1;
  1238. else if (name1.find("反") != -1) it.bFixOrInvert = 2;
  1239. }
  1240. else if (bFirstOrSecond == 2)
  1241. {
  1242. if (name2.find("定") != -1) it.bFixOrInvert = 1;
  1243. else if (name2.find("反") != -1) it.bFixOrInvert = 2;
  1244. }
  1245. }
  1246. }
  1247. BOOL ConmpareValue(std::map<time_t, int>* pData, time_t tsStartTime, time_t tsEndTime, int& hight_num, int& low_num, int threshold, int& iMaxDif, time_t& tMaxTime, int& nMaxValue)
  1248. {
  1249. auto it = pData->find(tsStartTime*1000);
  1250. if (it == pData->end()) return false;
  1251. int signal = 0;
  1252. tMaxTime = 0;
  1253. int startvalue = it->second / 10;
  1254. int lastvalue = startvalue;
  1255. int lastVV = lastvalue;
  1256. time_t lastTT = it->first;
  1257. int iMax = startvalue;
  1258. std::map<time_t, int> mapMaxValue;
  1259. hight_num = 0;
  1260. low_num = 0;
  1261. for (it; it != pData->end() && it->first < tsEndTime*1000; it++)
  1262. {
  1263. auto val = it->second / 10;
  1264. if (val > lastvalue)//上升
  1265. {
  1266. if (signal == 1)
  1267. {
  1268. //原来大于,现在也是大于
  1269. //continue;
  1270. }
  1271. else
  1272. {
  1273. //原来小于或者无效,现在大于
  1274. signal = 1;
  1275. startvalue = lastvalue;
  1276. if(iMax - startvalue > threshold)
  1277. low_num++;
  1278. }
  1279. }
  1280. else if (val < lastvalue)//下降
  1281. {
  1282. if (signal == -1)
  1283. {
  1284. //原来小于,现在小于等于
  1285. //continue;
  1286. }
  1287. else
  1288. {
  1289. //原来大于或者无效,现在小于
  1290. signal = -1;
  1291. iMax = lastvalue;
  1292. if (iMax - startvalue > threshold) //相差阈值计数
  1293. {
  1294. mapMaxValue[lastTT] = lastVV;
  1295. hight_num++;
  1296. }
  1297. }
  1298. }
  1299. lastvalue = val;
  1300. lastTT = it->first;
  1301. lastVV = it->second;
  1302. }
  1303. iMax = INT_MIN;
  1304. int iMin = INT_MAX;
  1305. for (auto& it : mapMaxValue)
  1306. {
  1307. if (it.second > iMax)
  1308. {
  1309. iMax = it.second;
  1310. tMaxTime = it.first;
  1311. }
  1312. if (it.second < iMin) iMin = it.second;
  1313. }
  1314. iMaxDif = iMax - iMin;
  1315. nMaxValue = iMax;
  1316. return TRUE;
  1317. }
  1318. #include "ResistAlarm.h"
  1319. void mg_per_session_data::GetPass(std::map<time_t, tagSecondStatInfo>& pStatInfo, std::map<time_t, int>* pData, const string& mo, const string& mp, OUT list<PASS_RESIST>* lstResist)
  1320. {
  1321. if (pStatInfo.size() < 5) return; //过车至少5秒
  1322. //判断连续起始点
  1323. //判断结束起始点
  1324. time_t tsStartTime = 0, tsEndTime = 0;
  1325. auto it = pStatInfo.begin();
  1326. do
  1327. {
  1328. auto it_front = it++;
  1329. if (it == pStatInfo.end())
  1330. break;
  1331. if (it->first - it_front->first > 1) //不连续
  1332. continue;
  1333. tsStartTime = it_front->first; //确定开始时间
  1334. //需求结尾
  1335. do
  1336. {
  1337. it_front = it++;
  1338. if (it == pStatInfo.end())
  1339. {
  1340. goto l;
  1341. }
  1342. if (it->first - it_front->first == 1) //连续
  1343. continue;
  1344. l:
  1345. tsEndTime = it_front->first;
  1346. auto dif = tsEndTime - tsStartTime + 1;
  1347. auto sStart = CTime(tsStartTime).Format("%Y-%m-%d %H:%M:%S");
  1348. auto sEnd = CTime(tsEndTime).Format("%Y-%m-%d %H:%M:%S");
  1349. TRACE("pass: tsStartTime:%s tsEndTime:%s dif:%d \r\n", sStart, sEnd, dif);
  1350. SPDLOG_INFO("pass: tsStartTime:{} tsEndTime:{} dif:{}", sStart, sEnd, dif);
  1351. int iUpNum = 0; //上升次数
  1352. int iDwNum = 0; //下降次数
  1353. int iMaxDif = 0;
  1354. int nMaxValue = 0;
  1355. time_t tMaxTime;
  1356. ConmpareValue(pData, tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue);
  1357. BOOL bPass = FALSE;
  1358. if ((dif >= 5 && dif < 7 && iUpNum >= 20 && iDwNum >= 20)
  1359. || (dif == 7 && iUpNum >= 30 && iDwNum >= 30)
  1360. || (dif >= 8 && iUpNum >= 40 && iDwNum >= 40))
  1361. {
  1362. bPass = TRUE;
  1363. PASS_RESIST resist;
  1364. resist.tmStart = tsStartTime;
  1365. resist.tmEnd = tsEndTime;
  1366. resist.show_time = tMaxTime;
  1367. resist.val = nMaxValue;
  1368. lstResist->emplace_back(resist);
  1369. }
  1370. SPDLOG_INFO("[过车判断]{}.{} 开始时间 {} 结束时间 {} 经过时间 {}秒 向上波动 {} 向下波动 {} maxdif 是否过车:{}",
  1371. mo, mp, sStart, sEnd, dif, iUpNum, iDwNum, iMaxDif, bPass ? "是" : "否");
  1372. break;
  1373. } while (true);
  1374. tsStartTime = tsEndTime = 0;
  1375. if (it == pStatInfo.end())
  1376. break;
  1377. } while (true);
  1378. return;
  1379. }
  1380. void mg_per_session_data::GetPassNew(std::map<time_t, tagSecondStatInfo>& pStatInfo0, std::map<time_t, int>* pData0,
  1381. std::map<time_t, tagSecondStatInfo>& pStatInfo1, std::map<time_t, int>* pData1,
  1382. const string& mo, const string& mp, OUT list<PASS_RESIST>* lstResist)
  1383. {
  1384. if (!pData0 || !pData1) return;
  1385. if (pStatInfo0.size() == 0)
  1386. ConvertMiroToSecond(*pData0, pStatInfo0);
  1387. if (pStatInfo1.size() == 0)
  1388. ConvertMiroToSecond(*pData1, pStatInfo1);
  1389. std::map<time_t, tagSecondStatInfo> mapStatInfo0;
  1390. std::map<time_t, tagSecondStatInfo> *mapStatInfo1 = nullptr;
  1391. auto it = pStatInfo0.cbegin();
  1392. mapStatInfo0.emplace(it->first, it->second);
  1393. time_t tLastIt = it->first;
  1394. BOOL bForContinue = TRUE;;
  1395. do
  1396. {
  1397. it++;
  1398. if (it != pStatInfo0.cend())
  1399. {
  1400. if (it->first - tLastIt < 2) //单位秒
  1401. {
  1402. mapStatInfo0.emplace(it->first, it->second);
  1403. tLastIt = it->first;
  1404. continue;
  1405. }
  1406. else
  1407. tLastIt = it->first;
  1408. }
  1409. else
  1410. bForContinue = FALSE;//遍历结束
  1411. do
  1412. {
  1413. if (mapStatInfo0.size() <= 3) //过车不小于3秒
  1414. break;
  1415. mapStatInfo1 = new std::map<time_t, tagSecondStatInfo>(pStatInfo1.find(mapStatInfo0.cbegin()->first), (++pStatInfo1.find(mapStatInfo0.crbegin()->first)));
  1416. GetPassNewUnit(&mapStatInfo0, pData0, mapStatInfo1, pData1, mo, mp, lstResist);
  1417. delete mapStatInfo1;
  1418. } while (false);
  1419. if (mapStatInfo0.size()) mapStatInfo0.clear();
  1420. } while (bForContinue);
  1421. }
  1422. void mg_per_session_data::GetPassNewUnit(std::map<time_t, tagSecondStatInfo>* pStatInfo0, std::map<time_t, int>* pData0, std::map<time_t, tagSecondStatInfo>* pStatInfo1, std::map<time_t, int>* pData1, const string& mo, const string& mp, OUT list<PASS_RESIST>* lstResist)
  1423. {
  1424. ASSERT(pStatInfo0->size() == pStatInfo1->size());
  1425. int nDifCount0 = 0, nDifCount1 = 0;
  1426. for (auto it = pStatInfo0->cbegin(); it != pStatInfo0->cend(); it++)
  1427. {
  1428. if (it->second.dif_val > 100) nDifCount0++;
  1429. }
  1430. for (auto it = pStatInfo1->cbegin(); it != pStatInfo1->cend(); it++)
  1431. {
  1432. if (it->second.dif_val > 100) nDifCount1++;
  1433. }
  1434. if (std::max(nDifCount0, nDifCount1) <= 3) return; //波动小于等于3秒
  1435. int iUpNum = 0; //上升次数
  1436. int iDwNum = 0; //下降次数
  1437. int iMaxDif = 0;
  1438. int nMaxValue = 0;
  1439. time_t tMaxTime;
  1440. time_t tsStartTime = pStatInfo0->begin()->first, tsEndTime = pStatInfo0->crbegin()->first + 1; //结束时间加1秒,后面判断过车时间[tsStartTime, tsEndTime)
  1441. auto dif = tsEndTime - tsStartTime;
  1442. auto sStart = CTime(tsStartTime).Format("%Y-%m-%d %H:%M:%S");
  1443. auto sEnd = CTime(tsEndTime).Format("%Y-%m-%d %H:%M:%S");
  1444. TRACE("pass: tsStartTime:%s tsEndTime:%s dif:%d \r\n", sStart, sEnd, dif);
  1445. SPDLOG_INFO("pass: nDifCount0:{} nDifCount1:{} tsStartTime:{} tsEndTime:{} dif:{}", nDifCount0, nDifCount1, sStart, sEnd, dif);
  1446. if (nDifCount0 > nDifCount1)
  1447. ConmpareValue(pData0, tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue);
  1448. else
  1449. ConmpareValue(pData1, tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue);
  1450. BOOL bPass = FALSE;
  1451. if ((dif >= 4 && dif < 7 && iUpNum >= 22 && iDwNum >= 22)
  1452. || (dif == 7 && iUpNum >= 30 && iDwNum >= 30)
  1453. || (dif >= 8 && iUpNum >= 40 && iDwNum >= 40))
  1454. {
  1455. bPass = TRUE;
  1456. PASS_RESIST resist;
  1457. resist.tmStart = tsStartTime;
  1458. resist.tmEnd = tsEndTime;
  1459. resist.show_time = tMaxTime;
  1460. resist.val = nMaxValue;
  1461. lstResist->emplace_back(resist);
  1462. }
  1463. SPDLOG_INFO("[过车判断]{}.{} 开始时间 {} 结束时间 {} 经过时间 {}秒 向上波动 {} 向下波动 {} maxdif 是否过车:{}",
  1464. mo, mp, sStart, sEnd, dif, iUpNum, iDwNum, iMaxDif, bPass ? "是" : "否");
  1465. }