ResistAlarm.cpp 163 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596
  1. #include "stdafx.h"
  2. #include "ResistAlarm.h"
  3. #include "MonitorObject.h"
  4. #include "Device.h"
  5. #include <ODBC/DBConnectPool.h>
  6. #include <rapidjson/document.h>
  7. #include <rapidjson/writer.h>
  8. #include <rapidjson/stringbuffer.h>
  9. #include <Simplelog.h>
  10. #include <sstream>
  11. #include <gbk2utf8.h>
  12. #include "AppService.h"
  13. #include <yyjson.h>
  14. #include <315ClientManager.h>
  15. #include "SkylightMng.h"
  16. CResistAlarm::CResistAlarm()
  17. {
  18. }
  19. CResistAlarm::~CResistAlarm()
  20. {
  21. }
  22. CResistAlarmMng::CResistAlarmMng()
  23. {
  24. }
  25. CResistAlarmMng::~CResistAlarmMng()
  26. {
  27. }
  28. BOOL CResistAlarmMng::Start(CString strIniPath)
  29. {
  30. LoadAlarmSet();
  31. if (FALSE == LoadAlarmID()) return FALSE;
  32. LoadUnAck();
  33. m_bWork = true;
  34. m_pThreadAlarmSet = new thread(CResistAlarmMng::ThreadProcAlarmSet, (DWORD_PTR)this, strIniPath);
  35. if (m_pThreadAlarmSet == nullptr) return FALSE;
  36. //离线报警
  37. /*m_pThreadDevice = new thread(CResistAlarmMng::ThreadProcDevice, (DWORD_PTR)this);
  38. if (m_pThreadDevice == nullptr) return FALSE;*/
  39. if (g_bExternalData)
  40. {
  41. m_pThreadMove = new thread(CResistAlarmMng::ThreadProcMoveFromDB, (DWORD_PTR)this);
  42. if (m_pThreadMove == nullptr) return FALSE;
  43. }
  44. else
  45. {
  46. m_pThreadMove = new thread(CResistAlarmMng::ThreadProcMove, (DWORD_PTR)this);
  47. if (m_pThreadMove == nullptr) return FALSE;
  48. }
  49. return TRUE;
  50. }
  51. void CResistAlarmMng::Stop()
  52. {
  53. m_bWork = false;
  54. if (m_pThreadAlarmSet)
  55. {
  56. m_pThreadAlarmSet->join();
  57. delete m_pThreadAlarmSet;
  58. m_pThreadAlarmSet = nullptr;
  59. }
  60. if (m_pThreadDevice)
  61. {
  62. m_pThreadDevice->join();
  63. delete m_pThreadDevice;
  64. m_pThreadDevice = nullptr;
  65. }
  66. if (m_pThreadMove)
  67. {
  68. m_pThreadMove->join();
  69. delete m_pThreadMove;
  70. m_pThreadMove = nullptr;
  71. }
  72. for (auto& it : m_alarm_set)
  73. {
  74. if (it.second)
  75. {
  76. if (it.second->type == eZL_ALARMTYPE::MAX_OVER_LIMIT)
  77. {
  78. delete (MAX_OVER_LIMIT_INFO*)it.second;
  79. it.second = nullptr;
  80. }
  81. else if (it.second->type == eZL_ALARMTYPE::FRICTION_OVER_LIMIT)
  82. {
  83. delete (FRICTION_OVER_LIMIT_INFO*)it.second;
  84. it.second = nullptr;
  85. }
  86. else if (it.second->type == eZL_ALARMTYPE::CONVERT_LIMIT)
  87. {
  88. delete (CONVERT_RESIST_OVER_LIMIT*)it.second;
  89. it.second = nullptr;
  90. }
  91. else if (it.second->type == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT)
  92. {
  93. delete (SUOBI_OVER_LIMIT_INFO*)it.second;
  94. it.second = nullptr;
  95. }
  96. else
  97. {
  98. assert(0);
  99. }
  100. }
  101. }
  102. m_alarm_set.clear();
  103. for (auto& it : m_lstUnConfirmAlarm) delete it;
  104. m_lstUnConfirmAlarm.clear();
  105. }
  106. //BASE_INFO* CResistAlarmMng::Find(string momp, uint8_t no, uint8_t type)
  107. //{
  108. // stringstream ss;
  109. // ss << momp << '.' << to_string(no) << '.' << to_string(type);
  110. // auto it = m_alarm_set.find(ss.str());
  111. // if (it != m_alarm_set.end())
  112. // {
  113. // return it->second;
  114. // }
  115. // return nullptr;
  116. //}
  117. BASE_INFO* CResistAlarmMng::Find(string mo, string mp, uint8_t no, eZL_ALARMTYPE type)
  118. {
  119. stringstream ss;
  120. ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string((uint8_t)type);
  121. auto it = m_alarm_set.find(ss.str());
  122. if (it != m_alarm_set.end())
  123. {
  124. return it->second;
  125. }
  126. return nullptr;
  127. }
  128. //bool CResistAlarmMng::Insert(const string& momp, uint8_t no, uint8_t type, BASE_INFO* info)
  129. //{
  130. // auto it = m_alarm_set.insert(make_pair(momp + '.' + to_string(no) + '.' + to_string(type), info));
  131. // return it.second;
  132. //}
  133. bool CResistAlarmMng::Insert(string mo, string mp, uint8_t no, uint8_t type, BASE_INFO* info)
  134. {
  135. auto it = m_alarm_set.insert(make_pair(mo + '.' + mp + '.' + to_string(no) + '.' + to_string(type), info));
  136. return it.second;
  137. }
  138. //bool CResistAlarmMng::ConfirmAlarm(string mo, string mp, uint8_t no, uint8_t type, const SYSTEMTIME& st)
  139. //{
  140. // lock_guard<mutex> lock(m_mtxAlarm);
  141. // auto it = m_lstUnConfirmAlarm.begin();
  142. // for (it; it != m_lstUnConfirmAlarm.end(); ++it)
  143. // {
  144. // const auto& pInfo = *it;
  145. // if (pInfo->mo.compare(mo) == 0 && pInfo->mp.compare(mp) == 0 && pInfo->no == no && pInfo->type == type && pInfo->time.wYear == st.wYear &&
  146. // pInfo->time.wMonth == st.wMonth && pInfo->time.wDay == st.wDay && pInfo->time.wHour == st.wHour && pInfo->time.wMinute == st.wMinute)
  147. // {
  148. // m_lstUnConfirmAlarm.erase(it);
  149. // return true;
  150. // }
  151. // }
  152. // return false;
  153. //}
  154. bool CResistAlarmMng::AckAlarm(int alarm_id, string& name, CTime& time)
  155. {
  156. lock_guard<mutex> lock(m_mtxAlarm);
  157. auto it = m_lstUnConfirmAlarm.begin();
  158. auto pInfo = *it;
  159. bool result = false;
  160. for (it; it != m_lstUnConfirmAlarm.end(); ++it)
  161. {
  162. pInfo = *it;
  163. if (alarm_id == pInfo->id)
  164. {
  165. result = true;
  166. break;
  167. //g_p315ClientManager->GetTcpClient()->SendAlarmData(pInfo->no, 2, CTime(pInfo->time).GetTime(), time.GetTime(), (WORD)pInfo->type, pInfo->val, 0, 0);
  168. }
  169. }
  170. if (!result) return false;
  171. auto itNew = m_lstUnConfirmAlarm.begin();
  172. for (itNew;itNew != m_lstUnConfirmAlarm.end();++itNew) {
  173. auto& pInfoNew = *itNew;
  174. if (pInfo->mo == pInfoNew->mo
  175. && pInfo->mp == pInfoNew->mp
  176. && pInfo->no == pInfoNew->no
  177. && pInfo->type == pInfoNew->type) {
  178. pInfoNew->ack_result = 1;
  179. pInfoNew->ack_name = name;
  180. pInfoNew->ack_time = time;
  181. }
  182. }
  183. return true;
  184. }
  185. bool CResistAlarmMng::HandleAlarm(int alarm_id)
  186. {
  187. lock_guard<mutex> lock(m_mtxAlarm);
  188. auto it = m_lstUnConfirmAlarm.begin();
  189. for (it; it != m_lstUnConfirmAlarm.end(); ++it)
  190. {
  191. const auto& pInfo = *it;
  192. if (pInfo->id == alarm_id && pInfo->ack_result == 1 && pInfo->recoveryTime.wYear > 2000)
  193. {
  194. m_lstUnConfirmAlarm.erase(it);
  195. return true;
  196. }
  197. }
  198. return true;
  199. }
  200. void CResistAlarmMng::GeneralAlarm(string mo, string mp, uint8_t no, eZL_ALARMTYPE type, uint8_t level, SYSTEMTIME& tAlarm)
  201. {
  202. ALARM_INFO* pAlarmInfo = nullptr;
  203. bool bNew = false;
  204. {
  205. std::lock_guard<mutex> lock(m_mtxAlarm);
  206. for (const auto& alarm : m_lstUnConfirmAlarm)
  207. {
  208. if (alarm->type == type && alarm->mo.compare(mo) == 0 && alarm->recoveryTime.wYear < 2000
  209. && alarm->mp.compare(mp) == 0 && no == alarm->no) //跟上次报警时间超过1小时,则算新报警
  210. {
  211. pAlarmInfo = alarm;
  212. break;
  213. }
  214. }
  215. }
  216. if (pAlarmInfo == nullptr)
  217. {
  218. bNew = true;
  219. pAlarmInfo = new ALARM_INFO;
  220. pAlarmInfo->event_id = hjfunc_GetGUID();
  221. pAlarmInfo->id = ++m_nAlarmID;
  222. pAlarmInfo->level = 1;
  223. pAlarmInfo->mo = mo;
  224. pAlarmInfo->mp = mp;
  225. pAlarmInfo->no = no;
  226. pAlarmInfo->time = tAlarm;
  227. pAlarmInfo->type = type;
  228. pAlarmInfo->val = 0;
  229. char szInfo[200];
  230. sprintf_s(szInfo, sizeof(szInfo), "传感器异常时间:%04d-%02d-%02d %02d:%02d:%02d",
  231. tAlarm.wYear, tAlarm.wMonth, tAlarm.wDay, tAlarm.wHour, tAlarm.wMinute, tAlarm.wSecond);
  232. pAlarmInfo->desc = szInfo;
  233. lock_guard<mutex> lock(m_mtxAlarm);
  234. m_lstUnConfirmAlarm.push_back(pAlarmInfo);
  235. }
  236. //send
  237. if (bNew) //不再推送
  238. {
  239. rapidjson::StringBuffer buffer;
  240. auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);
  241. const char* output = buffer.GetString();
  242. //CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());
  243. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  244. }
  245. //save
  246. if (bNew)
  247. {
  248. CTime ctAlarmTime(tAlarm);
  249. CString sql;
  250. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  251. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  252. pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, (int)pAlarmInfo->type,
  253. (LPCSTR)(ctAlarmTime.Format("%Y-%m-%d %H:%M:%S")), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,
  254. pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val, pAlarmInfo->sunroof);
  255. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  256. CSimpleLog::Error("执行语句失败" + sql);
  257. else
  258. {
  259. uint8_t* pack = nullptr; int len = 0;
  260. auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);
  261. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  262. //g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pAlarmInfo->type, pAlarmInfo->val, 0, 0);
  263. delete[] pack;
  264. pack = nullptr;
  265. }
  266. }
  267. }
  268. //报警恢复, 报警恢复逻辑与受理确认逻辑分开
  269. void CResistAlarmMng::RecoverAlarm(const string mo, const string mp, const uint8_t no, const eZL_ALARMTYPE type, const uint8_t level, const SYSTEMTIME& tAlarm)
  270. {
  271. vector<uint32_t> vctAlarmID;
  272. vector<string> vctEventID;
  273. //ALARM_INFO tmpalarm;
  274. {
  275. std::lock_guard<mutex> lock(m_mtxAlarm);
  276. for (auto it = m_lstUnConfirmAlarm.begin(); it != m_lstUnConfirmAlarm.end();)
  277. {
  278. auto pAlarm = *it;
  279. if (pAlarm->type == type && pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0 && no == pAlarm->no && level == pAlarm->level
  280. && pAlarm->recoveryTime.wYear < 2000)
  281. {
  282. vctAlarmID.emplace_back(pAlarm->id);
  283. vctEventID.emplace_back(pAlarm->event_id);
  284. //CopyMemory(&tmpalarm, *it, sizeof(tmpalarm)); 有string 不能拷贝
  285. //tmpalarm = *pAlarm;
  286. if (pAlarm->ack_result == 1)//如果已确认则可以删除
  287. {
  288. it = m_lstUnConfirmAlarm.erase(it);
  289. continue;
  290. }
  291. else
  292. memcpy(&pAlarm->recoveryTime, &tAlarm, sizeof(SYSTEMTIME));
  293. }
  294. it++;
  295. }
  296. }
  297. if (vctAlarmID.size() == 0)
  298. return;
  299. CTime ctAlarm(tAlarm);
  300. string recovery_time = ctAlarm.Format("%Y-%m-%d %H:%M:%S");
  301. //g_p315ClientManager->GetTcpClient()->SendAlarmData(tmpalarm.no, 2, CTime(tmpalarm.time).GetTime(), ctAlarm.GetTime(), (WORD)tmpalarm.type, tmpalarm.val, 0, 0);
  302. //更新数据库
  303. {
  304. CString sql;
  305. for (auto& it : vctAlarmID)
  306. {
  307. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), it);
  308. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  309. }
  310. //for (auto& it : vctEventID)
  311. //{
  312. // sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE [event_id] = '%s';", recovery_time.c_str(), it);
  313. // CDBConnectPool::Instance()->DBExecuteSQL(sql);
  314. //}
  315. }
  316. //恢复暂时不通知
  317. //auto doc = yyjson_mut_doc_new(nullptr);
  318. //auto root = yyjson_mut_obj(doc);
  319. //yyjson_mut_doc_set_root(doc, root);
  320. //yyjson_mut_obj_add_str(doc, root, "cmd", "alm_ack");
  321. //yyjson_mut_obj_add_uint(doc, root, "alarm_id", alarm_id);
  322. //yyjson_mut_obj_add_strcpy(doc, root, "ack_time", recovery_time.c_str());
  323. //yyjson_mut_obj_add_strcpy(doc, root, "ack_name", ANSItoUTF8("系统").c_str());
  324. //size_t len;
  325. //auto json = yyjson_mut_write(doc, 0, &len);
  326. //if (json)
  327. //{
  328. // CAppService::Instance()->GetMgServer()->SendToAllClient(json, len);
  329. // free(json);
  330. //}
  331. //yyjson_mut_doc_free(doc);
  332. }
  333. eZL_MP_STAT CResistAlarmMng::GetAlarmStat(string& mo, string& mp, SYSTEMTIME& stAlarm)
  334. {
  335. eZL_MP_STAT stat = eZL_MP_STAT::MP_STAT_UNKNOW;
  336. lock_guard<mutex> lock(m_mtxAlarm);
  337. auto it = m_lstUnConfirmAlarm.rbegin();
  338. for (it; it != m_lstUnConfirmAlarm.rend(); ++it)
  339. {
  340. const auto& pInfo = *it;
  341. if (pInfo->ack_result) continue;//受理了暂时放过
  342. if (pInfo->mo.compare(mo) == 0 && pInfo->mp.compare(mp) == 0 && pInfo->recoveryTime.wYear < 2000)
  343. {
  344. if (pInfo->type == eZL_ALARMTYPE::EQUIP_OFFLINE || pInfo->type == eZL_ALARMTYPE::SENSOR_ABNORMAL)
  345. {
  346. stat = eZL_MP_STAT::MP_STAT_OFFLINE_GRAY;
  347. break;
  348. }
  349. else if (pInfo->level == 1)
  350. {
  351. stAlarm = pInfo->time;
  352. stat = eZL_MP_STAT::MP_STAT_ALARM_RED;
  353. break;
  354. }
  355. else if (pInfo->level == 0)
  356. {
  357. stAlarm = pInfo->time;
  358. stat = eZL_MP_STAT::MP_STAT_WARN_ORANGE;
  359. break;
  360. }
  361. }
  362. }
  363. return stat;
  364. }
  365. uint32_t CResistAlarmMng::GeneralAlarmSet(uint8_t** pack, int* len)
  366. {
  367. auto doc = yyjson_mut_doc_new(nullptr);
  368. auto root = yyjson_mut_arr(doc);
  369. yyjson_mut_doc_set_root(doc, root);
  370. for (const auto& it : m_alarm_set)
  371. {
  372. auto obj = yyjson_mut_obj(doc);
  373. yyjson_mut_arr_add_val(root, obj);
  374. auto ss = it.second;
  375. auto kk = it.first;
  376. int nPos = kk.find('.');
  377. int nPos2 = kk.find('.', nPos + 1);
  378. string mo = kk.substr(0, nPos);
  379. string mp = kk.substr(nPos + 1, nPos2 - nPos - 1);
  380. string momp = kk.substr(0, nPos2);
  381. string mmomp_name, station;
  382. CMonitorObjectMng::Instance()->GetStationNameByMomP(momp, station, mmomp_name);
  383. yyjson_mut_obj_add_strcpy(doc, obj, "mo", mo.c_str());
  384. yyjson_mut_obj_add_strcpy(doc, obj, "mp", mp.c_str());
  385. yyjson_mut_obj_add_strcpy(doc, obj, "station", station.c_str());
  386. yyjson_mut_obj_add_int(doc, obj, "no", ss->no);
  387. yyjson_mut_obj_add_int(doc, obj, "type", uint8_t(ss->type));
  388. switch (ss->type)
  389. {
  390. case eZL_ALARMTYPE::MAX_OVER_LIMIT:
  391. {
  392. auto conf = yyjson_mut_arr(doc);
  393. yyjson_mut_obj_add_val(doc, obj, "conf", conf);
  394. {
  395. auto object = yyjson_mut_obj(doc);
  396. yyjson_mut_arr_add_val(conf, object);
  397. yyjson_mut_obj_add_str(doc, object, "name", "enable");
  398. yyjson_mut_obj_add_str(doc, object, "val", ss->enable ? "true" : "false");
  399. }
  400. auto pInfo = (MAX_OVER_LIMIT_INFO*)ss;
  401. {
  402. auto object = yyjson_mut_obj(doc);
  403. yyjson_mut_arr_add_val(conf, object);
  404. if (ss->no == 2)
  405. yyjson_mut_obj_add_str(doc, object, "name", "d_alarm_high_limit");
  406. else
  407. yyjson_mut_obj_add_str(doc, object, "name", "lock_alarm_high_limit");
  408. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->alarm_high_limit).c_str());
  409. }
  410. {
  411. auto object = yyjson_mut_obj(doc);
  412. yyjson_mut_arr_add_val(conf, object);
  413. if (ss->no == 2)
  414. yyjson_mut_obj_add_str(doc, object, "name", "d_warn_high_limit");
  415. else
  416. yyjson_mut_obj_add_str(doc, object, "name", "lock_warn_high_limit");
  417. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->warn_high_limit).c_str());
  418. }
  419. {
  420. auto object = yyjson_mut_obj(doc);
  421. yyjson_mut_arr_add_val(conf, object);
  422. if (ss->no == 2)
  423. yyjson_mut_obj_add_str(doc, object, "name", "f_alarm_high_limit");
  424. else
  425. yyjson_mut_obj_add_str(doc, object, "name", "keep_alarm_high_limit");
  426. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->f_alarm_high_limit).c_str());
  427. }
  428. {
  429. auto object = yyjson_mut_obj(doc);
  430. yyjson_mut_arr_add_val(conf, object);
  431. if (ss->no == 2)
  432. yyjson_mut_obj_add_str(doc, object, "name", "keep_warn_high_limit");
  433. else
  434. yyjson_mut_obj_add_str(doc, object, "name", "f_warn_high_limit");
  435. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->f_warn_high_limit).c_str());
  436. }
  437. }
  438. break;
  439. case eZL_ALARMTYPE::FRICTION_OVER_LIMIT:
  440. {
  441. auto conf = yyjson_mut_arr(doc);
  442. yyjson_mut_obj_add_val(doc, obj, "conf", conf);
  443. {
  444. auto object = yyjson_mut_obj(doc);
  445. yyjson_mut_arr_add_val(conf, object);
  446. yyjson_mut_obj_add_str(doc, object, "name", "enable");
  447. yyjson_mut_obj_add_str(doc, object, "val", ss->enable ? "true" : "false");
  448. }
  449. auto pInfo = (FRICTION_OVER_LIMIT_INFO*)ss;
  450. {
  451. auto object = yyjson_mut_obj(doc);
  452. yyjson_mut_arr_add_val(conf, object);
  453. yyjson_mut_obj_add_str(doc, object, "name", "up_alarm_low_limit");
  454. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->up_alarm_low_limit).c_str());
  455. }
  456. {
  457. auto object = yyjson_mut_obj(doc);
  458. yyjson_mut_arr_add_val(conf, object);
  459. yyjson_mut_obj_add_str(doc, object, "name", "up_warn_low_limit");
  460. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->up_warn_low_limit).c_str());
  461. }
  462. {
  463. auto object = yyjson_mut_obj(doc);
  464. yyjson_mut_arr_add_val(conf, object);
  465. yyjson_mut_obj_add_str(doc, object, "name", "dw_alarm_high_limit");
  466. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->dw_alarm_high_limit).c_str());
  467. }
  468. {
  469. auto object = yyjson_mut_obj(doc);
  470. yyjson_mut_arr_add_val(conf, object);
  471. yyjson_mut_obj_add_str(doc, object, "name", "dw_warn_high_limit");
  472. yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->dw_warn_high_limit).c_str());
  473. }
  474. }
  475. break;
  476. case eZL_ALARMTYPE::SUOBI_LOCK_LIMIT:
  477. {
  478. auto conf = yyjson_mut_obj(doc);
  479. yyjson_mut_obj_add_val(doc, obj, "conf", conf);
  480. auto pInfo = (SUOBI_OVER_LIMIT_INFO*)ss;
  481. yyjson_mut_obj_add_bool(doc, conf, "enable", pInfo->enable);
  482. yyjson_mut_obj_add_int(doc, conf, "alarm_low_limit", pInfo->alarm_low_limit);
  483. yyjson_mut_obj_add_int(doc, conf, "warn_low_limit", pInfo->warn_low_limit);
  484. yyjson_mut_obj_add_int(doc, conf, "alarm_high_limit", pInfo->alarm_high_limit);
  485. yyjson_mut_obj_add_int(doc, conf, "warn_high_limit", pInfo->warn_high_limit);
  486. }
  487. break;
  488. case eZL_ALARMTYPE::CONVERT_LIMIT:
  489. {
  490. auto conf = yyjson_mut_obj(doc);
  491. yyjson_mut_obj_add_val(doc, obj, "conf", conf);
  492. auto pInfo = (CONVERT_RESIST_OVER_LIMIT*)ss;
  493. yyjson_mut_obj_add_bool(doc, conf, "enable", pInfo->enable);
  494. yyjson_mut_obj_add_int(doc, conf, "dw_alarm_low_limit", pInfo->dw_alarm_low_limit);
  495. yyjson_mut_obj_add_int(doc, conf, "dw_warn_low_limit", pInfo->dw_warn_low_limit);
  496. yyjson_mut_obj_add_int(doc, conf, "up_alarm_high_limit", pInfo->up_alarm_high_limit);
  497. yyjson_mut_obj_add_int(doc, conf, "up_warn_high_limit", pInfo->up_warn_high_limit);
  498. }
  499. break;
  500. case eZL_ALARMTYPE::RETENSION_FORCE:
  501. {
  502. auto conf = yyjson_mut_arr(doc);
  503. yyjson_mut_obj_add_val(doc, obj, "conf", conf);
  504. auto pInfo = (tagRetension_Force_Drop*)ss;
  505. yyjson_mut_obj_add_bool(doc, conf, "enable", pInfo->enable);
  506. yyjson_mut_obj_add_int(doc, conf, "dw_alarm_low_drop", pInfo->dw_alarm_low_drop);
  507. yyjson_mut_obj_add_int(doc, conf, "alarm_low_percent", pInfo->alarm_low_percent);
  508. yyjson_mut_obj_add_int(doc, conf, "alarm_high_percent", pInfo->alarm_high_percent);
  509. }
  510. break;
  511. default:
  512. ASSERT(0);
  513. break;
  514. }
  515. }
  516. size_t json_len;
  517. auto json = yyjson_mut_write(doc, 0, &json_len);
  518. yyjson_mut_doc_free(doc);
  519. *len = json_len + sizeof(HJDATAHEAD2) + 2;
  520. *pack = new uint8_t[*len];
  521. auto no = CAppService::Instance()->GetPackNo();
  522. CHjDataConver::conver_sendpack(*pack, (LPBYTE)json, json_len, 0, no, E_ZL_PROTOCAL::ZL_ALARM_SET,
  523. OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_SYNC));
  524. free(json);
  525. return no;
  526. }
  527. uint32_t CResistAlarmMng::GeneralUnAck(uint8_t** pack, int* len)
  528. {
  529. auto doc = yyjson_mut_doc_new(nullptr);
  530. auto root = yyjson_mut_arr(doc);
  531. yyjson_mut_doc_set_root(doc, root);
  532. {
  533. //查询数据库近一天的数据
  534. lock_guard<mutex> lock(m_mtxAlarm);
  535. auto it = m_lstUnConfirmAlarm.begin();
  536. for (it; it != m_lstUnConfirmAlarm.end(); ++it)
  537. {
  538. auto& pInfo = *it;
  539. auto obj = yyjson_mut_obj(doc);
  540. yyjson_mut_arr_add_val(root, obj);
  541. yyjson_mut_obj_add_uint(doc, obj, "id", pInfo->id);
  542. yyjson_mut_obj_add_strcpy(doc, obj, "mo", pInfo->mo.c_str());
  543. yyjson_mut_obj_add_strcpy(doc, obj, "mp", pInfo->mp.c_str());
  544. yyjson_mut_obj_add_int(doc, obj, "no", pInfo->no);
  545. yyjson_mut_obj_add_int(doc, obj, "type", int(pInfo->type));
  546. yyjson_mut_obj_add_int(doc, obj, "level", pInfo->level);
  547. yyjson_mut_obj_add_strcpy(doc, obj, "time", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}",
  548. pInfo->time.wYear, pInfo->time.wMonth, pInfo->time.wDay, pInfo->time.wHour, pInfo->time.wMinute, pInfo->time.wSecond).c_str());
  549. yyjson_mut_obj_add_strcpy(doc, obj, "desc", pInfo->desc.c_str());
  550. yyjson_mut_obj_add_strcpy(doc, obj, "desc", pInfo->suggest.c_str());
  551. yyjson_mut_obj_add_int(doc, obj, "val", pInfo->val);
  552. yyjson_mut_obj_add_int(doc, obj, "ack_result", pInfo->ack_result);
  553. yyjson_mut_obj_add_strcpy(doc, obj, "ack_name", pInfo->ack_name.c_str());
  554. yyjson_mut_obj_add_int(doc, obj, "ack_time", pInfo->ack_time.GetTime());
  555. yyjson_mut_obj_add_strcpy(doc, obj, "event_id", pInfo->event_id.c_str());
  556. yyjson_mut_obj_add_strcpy(doc, obj, "rel_id", pInfo->rel_id.c_str());
  557. yyjson_mut_obj_add_strcpy(doc, obj, "recoverytime", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}",
  558. pInfo->recoveryTime.wYear, pInfo->recoveryTime.wMonth, pInfo->recoveryTime.wDay, pInfo->recoveryTime.wHour, pInfo->recoveryTime.wMinute, pInfo->recoveryTime.wSecond).c_str());
  559. }
  560. }
  561. size_t json_len;
  562. auto json = yyjson_mut_write(doc, 0, &json_len);
  563. yyjson_mut_doc_free(doc);
  564. *len = json_len + sizeof(HJDATAHEAD2) + 2;
  565. *pack = new uint8_t[*len];
  566. auto no = CAppService::Instance()->GetPackNo();
  567. CHjDataConver::conver_sendpack(*pack, (LPBYTE)json, json_len, 0, no, E_ZL_PROTOCAL::ZL_ALARM_UNACK,
  568. OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_SYNC));
  569. free(json);
  570. return no;
  571. }
  572. uint32_t CResistAlarmMng::GeneralNewAlarmData(ALARM_INFO* pInfo, uint8_t** pack, int* len)
  573. {
  574. auto doc = yyjson_mut_doc_new(nullptr);
  575. auto root = yyjson_mut_arr(doc);
  576. yyjson_mut_doc_set_root(doc, root);
  577. auto obj = yyjson_mut_obj(doc);
  578. yyjson_mut_arr_add_val(root, obj);
  579. yyjson_mut_obj_add_uint(doc, obj, "id", pInfo->id);
  580. yyjson_mut_obj_add_strcpy(doc, obj, "mo", pInfo->mo.c_str());
  581. yyjson_mut_obj_add_strcpy(doc, obj, "mp", pInfo->mp.c_str());
  582. yyjson_mut_obj_add_int(doc, obj, "no", pInfo->no);
  583. yyjson_mut_obj_add_int(doc, obj, "type", int(pInfo->type));
  584. yyjson_mut_obj_add_int(doc, obj, "level", pInfo->level);
  585. yyjson_mut_obj_add_strcpy(doc, obj, "time", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}",
  586. pInfo->time.wYear, pInfo->time.wMonth, pInfo->time.wDay, pInfo->time.wHour, pInfo->time.wMinute, pInfo->time.wSecond).c_str());
  587. yyjson_mut_obj_add_strcpy(doc, obj, "desc", pInfo->desc.c_str());
  588. yyjson_mut_obj_add_strcpy(doc, obj, "suggest", pInfo->suggest.c_str());
  589. yyjson_mut_obj_add_int(doc, obj, "val", pInfo->val);
  590. yyjson_mut_obj_add_int(doc, obj, "ack_result", pInfo->ack_result);
  591. yyjson_mut_obj_add_strcpy(doc, obj, "ack_name", pInfo->ack_name.c_str());
  592. yyjson_mut_obj_add_int(doc, obj, "ack_time", pInfo->ack_time.GetTime());
  593. yyjson_mut_obj_add_strcpy(doc, obj, "event_id", pInfo->event_id.c_str());
  594. yyjson_mut_obj_add_strcpy(doc, obj, "rel_id", pInfo->rel_id.c_str());
  595. yyjson_mut_obj_add_strcpy(doc, obj, "recoverytime", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}",
  596. pInfo->recoveryTime.wYear, pInfo->recoveryTime.wMonth, pInfo->recoveryTime.wDay, pInfo->recoveryTime.wHour, pInfo->recoveryTime.wMinute, pInfo->recoveryTime.wSecond).c_str());
  597. size_t json_len;
  598. auto json = yyjson_mut_write(doc, 0, &json_len);
  599. yyjson_mut_doc_free(doc);
  600. *len = json_len + sizeof(HJDATAHEAD2) + 2;
  601. *pack = new uint8_t[*len];
  602. auto no = CAppService::Instance()->GetPackNo();
  603. CHjDataConver::conver_sendpack(*pack, (LPBYTE)json, json_len, 0, no, E_ZL_PROTOCAL::ZL_ALARM_DATA,
  604. OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_ADD));
  605. free(json);
  606. return no;
  607. }
  608. bool CResistAlarmMng::AlarmInfo2Pack(const ALARM_INFO* pAlarmInfo, rapidjson::StringBuffer& buffer, bool bGb2312 /*= false*/)
  609. {
  610. char szInfo[200];
  611. char szUtf[200];
  612. using namespace rapidjson;
  613. Writer<StringBuffer> writer(buffer);
  614. writer.StartObject();
  615. writer.Key("cmd");
  616. writer.String("new_alarm");
  617. writer.Key("type");
  618. //if (pAlarmInfo->type == MAX_OVER_LIMIT) writer.String("monitor.alarm.max_over_limit");
  619. //else if (pAlarmInfo->type == EQUIP_OFFLINE) writer.String("monitor.alarm.equip_offline");
  620. //else if (pAlarmInfo->type == SENSOR_ABNORMAL) writer.String("monitor.alarm.sensor_abnormal");
  621. //else writer.String("");
  622. writer.Int((int)pAlarmInfo->type);
  623. writer.Key("tag");
  624. writer.String((pAlarmInfo->mo + '.' + pAlarmInfo->mp + '.' + to_string(pAlarmInfo->no + 1) + "#").c_str());
  625. string up, momp_name, up_name;
  626. string momp = pAlarmInfo->mo + "." + pAlarmInfo->mp;
  627. CMonitorObjectMng::Instance()->GetStationNameByMomP(momp, up, momp_name);
  628. auto pObject = CMonitorObjectMng::Instance()->GetTreeByID(up);
  629. if (pObject) up_name = pObject->name;
  630. string name1, name2, name3;
  631. CMonitorObjectMng::Instance()->GetNameByMoMp(momp, name1, name2, name3);
  632. if (pAlarmInfo->no == 0 && name1.length() == 0) name1 = "1号测力点";
  633. else if (pAlarmInfo->no == 1 && name2.length() == 0) name2 = "2号测力点";
  634. else if (pAlarmInfo->no == 2 && name3.length() == 0) name3 = "3号测力点";
  635. sprintf_s(szInfo, 200, "%s.%s.%s.%s%s", up_name.c_str(), momp_name.c_str(),
  636. pAlarmInfo->no == 0 ? name1.c_str() : pAlarmInfo->no == 1 ? name2.c_str() : pAlarmInfo->no == 2 ? name3.c_str() : "",
  637. GetAlarmName(pAlarmInfo->type).c_str(),
  638. pAlarmInfo->level == 1 ? "报警" : "预警"
  639. );
  640. gbk2utf8(szUtf, sizeof(szUtf), szInfo);
  641. writer.Key("title");
  642. writer.String(szUtf);
  643. gbk2utf8(szUtf, sizeof(szUtf), up.c_str());
  644. writer.Key("up");
  645. writer.String(szUtf);
  646. gbk2utf8(szUtf, sizeof(szUtf), up_name.c_str());
  647. writer.Key("up_name");
  648. writer.String(szUtf);
  649. writer.Key("alarm_id");
  650. writer.Uint(pAlarmInfo->id);
  651. writer.Key("event_id");
  652. writer.String(pAlarmInfo->event_id.c_str());
  653. writer.Key("rel_id");
  654. writer.String(pAlarmInfo->rel_id.c_str());
  655. writer.Key("sunroof");
  656. writer.Int(pAlarmInfo->sunroof);
  657. writer.Key("level");
  658. if (pAlarmInfo->level)
  659. writer.String("alarm");
  660. else
  661. writer.String("warn");
  662. writer.Key("occur_time");
  663. sprintf_s(szInfo, sizeof(szInfo), "%04d-%02d-%02d %02d:%02d:%02d.%03d",
  664. pAlarmInfo->time.wYear, pAlarmInfo->time.wMonth, pAlarmInfo->time.wDay,
  665. pAlarmInfo->time.wHour, pAlarmInfo->time.wMinute, pAlarmInfo->time.wSecond, pAlarmInfo->time.wMilliseconds);
  666. writer.String(szInfo);
  667. writer.Key("val");
  668. if (pAlarmInfo->type == eZL_ALARMTYPE::EQUIP_OFFLINE || pAlarmInfo->type == eZL_ALARMTYPE::SENSOR_ABNORMAL)
  669. writer.String("-");
  670. else
  671. writer.String(to_string(pAlarmInfo->val).c_str());
  672. writer.String("desc");
  673. gbk2utf8(szInfo, sizeof(szInfo), pAlarmInfo->desc.c_str());
  674. writer.String(szInfo);
  675. writer.Key("suggest");
  676. writer.String("");
  677. if (pAlarmInfo->ack_result)
  678. {
  679. //已受理的报警
  680. writer.String("ack_result");
  681. writer.Int(pAlarmInfo->ack_result);
  682. writer.Key("ack_name");
  683. writer.String(ANSItoUTF8(pAlarmInfo->ack_name).c_str());
  684. writer.Key("ack_time");
  685. writer.String(pAlarmInfo->ack_time.Format("%Y-%m-%d %H:%M:%S"));
  686. }
  687. if (pAlarmInfo->recoveryTime.wYear != 1900)
  688. {
  689. writer.Key("recoverytime");
  690. sprintf_s(szInfo, sizeof(szInfo), "%04d-%02d-%02d %02d:%02d:%02d.%03d",
  691. pAlarmInfo->recoveryTime.wYear, pAlarmInfo->recoveryTime.wMonth, pAlarmInfo->recoveryTime.wDay,
  692. pAlarmInfo->recoveryTime.wHour, pAlarmInfo->recoveryTime.wMinute, pAlarmInfo->recoveryTime.wSecond, pAlarmInfo->recoveryTime.wMilliseconds);
  693. writer.String(szInfo);
  694. }
  695. writer.EndObject();
  696. return true;
  697. }
  698. CResistAlarmMng CResistAlarmMng::obj;
  699. void CResistAlarmMng::InsertToDBByMove(string mo, string mp, time_t show_time, time_t start_time, time_t end_time,
  700. int curr_val, int show_val, uint8_t idx, uint8_t posi, uint8_t type,
  701. string mark)
  702. {
  703. if (show_time == 0) return;
  704. CTime ctShowTime(show_time / 1000);
  705. uint8_t sunroof = CSkylightMng::GetInstance()->IsSkylight(&ctShowTime); //2024年6月9日 添加天窗
  706. string table_name = fmt::format("rm_move_{:0>4}{:0>2}", ctShowTime.GetYear(), ctShowTime.GetMonth());
  707. auto strShowTime = (LPCSTR)ctShowTime.Format("%Y-%m-%d %H:%M:%S.") + to_string(show_time % 1000);
  708. auto strStartTime = start_time ? CTime(start_time).Format("%Y-%m-%d %H:%M:%S") : "";
  709. auto strEndTime = end_time ? CTime(end_time).Format("%Y-%m-%d %H:%M:%S") : "";
  710. CString sql = fmt::format("INSERT INTO {} (mo,mp,show_time,start_time,end_time,curr_val,show_val,idx,posi,type,sunroof,mark) values ('{}', '{}', '{}', '{}','{}', {}, {}, {}, {}, {}, {}, '{}');",
  711. table_name, mo, mp, strShowTime, strStartTime, strEndTime, curr_val, show_val, idx, posi, type, sunroof, mark).c_str();
  712. if (CDBConnectPool::Instance()->DBExecuteSQL(sql) == FALSE)
  713. CSimpleLog::Error(sql);
  714. //上送
  715. //组装数据
  716. auto doc = yyjson_mut_doc_new(nullptr);
  717. auto root = yyjson_mut_arr(doc);
  718. yyjson_mut_doc_set_root(doc, root);
  719. //添加数据
  720. auto obj = yyjson_mut_obj(doc);
  721. yyjson_mut_arr_add_val(root, obj);
  722. yyjson_mut_obj_add_strcpy(doc, obj, "mo", mo.c_str());
  723. yyjson_mut_obj_add_strcpy(doc, obj, "mp", mp.c_str());
  724. yyjson_mut_obj_add_strcpy(doc, obj, "show_time", strShowTime.c_str());
  725. yyjson_mut_obj_add_strcpy(doc, obj, "start_time", strStartTime);
  726. yyjson_mut_obj_add_strcpy(doc, obj, "end_time", strEndTime);
  727. yyjson_mut_obj_add_strcpy(doc, obj, "mark", mark.c_str());
  728. yyjson_mut_obj_add_int(doc, obj, "curr_val", curr_val);
  729. yyjson_mut_obj_add_int(doc, obj, "show_val", show_val);
  730. yyjson_mut_obj_add_int(doc, obj, "idx", idx);
  731. yyjson_mut_obj_add_int(doc, obj, "posi", posi);
  732. yyjson_mut_obj_add_int(doc, obj, "sunroof", sunroof);
  733. size_t json_len;
  734. auto json = yyjson_mut_write(doc, 0, &json_len);
  735. auto send_len = json_len + sizeof(HJDATAHEAD2) + 2;
  736. auto pack = new uint8_t[send_len];
  737. auto packno = CAppService::Instance()->GetPackNo();
  738. CHjDataConver::conver_sendpack(pack, (LPBYTE)json, json_len, 0, packno, E_ZL_PROTOCAL::ZL_MOVE,
  739. OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_ADD));
  740. CSuperManager::Instance()->SendPack(pack, send_len, packno, E_ZL_PROTOCAL::ZL_MOVE, true);
  741. delete[] pack;
  742. pack = nullptr;
  743. free(json);
  744. yyjson_mut_doc_free(doc);
  745. }
  746. //判断锁闭力是否超限
  747. void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, SUOBI_OVER_LIMIT_INFO* pSuobiOverInfo,
  748. time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, uint32_t zzjno)
  749. {
  750. if (pSuobiOverInfo == nullptr || pSuobiOverInfo->enable == false) return;
  751. bool bNew = false;
  752. ALARM_INFO* pAlarmInfo = nullptr;
  753. bool bAlarm = false, bWarn = false; int alarm_value = 0, alarm_refer; time_t alarm_time = show_time;
  754. CTime ctAlarmTime = CTime(alarm_time / 1000);
  755. eLowHigh loworhigh = eLowHigh::LH_UNKNOWN; //0:最小值 1:最大值
  756. {
  757. if (show_val < pSuobiOverInfo->alarm_low_limit)
  758. {
  759. bAlarm = true;
  760. alarm_refer = pSuobiOverInfo->alarm_low_limit;
  761. alarm_value = show_val;
  762. loworhigh = eLowHigh::LH_LOW;
  763. }
  764. else if (show_val < pSuobiOverInfo->warn_low_limit)
  765. {
  766. bWarn = true;
  767. alarm_refer = pSuobiOverInfo->warn_low_limit;
  768. alarm_value = show_val;
  769. loworhigh = eLowHigh::LH_LOW;
  770. }
  771. if (show_val > pSuobiOverInfo->alarm_high_limit)
  772. {
  773. bAlarm = true;
  774. alarm_refer = pSuobiOverInfo->alarm_high_limit;
  775. alarm_value = show_val;
  776. loworhigh = eLowHigh::LH_HIGH;
  777. }
  778. else if (show_val > pSuobiOverInfo->warn_high_limit)
  779. {
  780. bWarn = true;
  781. alarm_refer = pSuobiOverInfo->warn_high_limit;
  782. alarm_value = show_val;
  783. loworhigh = eLowHigh::LH_HIGH;
  784. }
  785. if (bAlarm == false && bWarn == false)
  786. {
  787. {
  788. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  789. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
  790. {
  791. auto pAlarm = *it;
  792. if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT && pAlarm->recoveryTime.wYear < 2000 //预警和报警单独计算
  793. && pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0)
  794. {
  795. pAlarmInfo = pAlarm;
  796. if (pAlarmInfo)
  797. {
  798. //恢复
  799. //1. 更新数据库
  800. //2. 更新内存数据
  801. //3. 上送恢复消息
  802. if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();
  803. string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
  804. CString sql;
  805. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
  806. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  807. if (pAlarmInfo->ack_result == 1)
  808. {
  809. it = pService->m_lstUnConfirmAlarm.erase(it);
  810. continue;
  811. }
  812. else
  813. {
  814. ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);
  815. }
  816. g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,
  817. pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,
  818. TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);
  819. }
  820. }
  821. it++;
  822. }
  823. }
  824. return;
  825. }
  826. //查找是否原有的报警已存在
  827. uint8_t level = 0;
  828. if (bAlarm) level = 1;
  829. {
  830. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  831. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  832. {
  833. if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算
  834. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)
  835. {
  836. pAlarmInfo = alarm;
  837. break;
  838. }
  839. }
  840. }
  841. ALARM_INFO *pNewAlarmInfo = nullptr;
  842. {
  843. bNew = true;
  844. pNewAlarmInfo = new ALARM_INFO;
  845. pNewAlarmInfo->event_id = hjfunc_GetGUID();
  846. pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";
  847. pNewAlarmInfo->id = ++pService->m_nAlarmID;
  848. pNewAlarmInfo->level = (bAlarm == 1);
  849. pNewAlarmInfo->mo = mo;
  850. pNewAlarmInfo->mp = mp;
  851. pNewAlarmInfo->no = (uint8_t)posi;
  852. ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);
  853. pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;
  854. pNewAlarmInfo->type = eZL_ALARMTYPE::SUOBI_LOCK_LIMIT;
  855. pNewAlarmInfo->val = alarm_value;
  856. pNewAlarmInfo->refer_val = alarm_refer;
  857. pNewAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);
  858. pNewAlarmInfo->loworhigh = loworhigh;
  859. pNewAlarmInfo->zzjno = zzjno;
  860. pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);
  861. char szInfo[200] = { 0 };
  862. sprintf_s(szInfo, sizeof(szInfo), "锁闭力超限,位置:%s, 报警值为%dN, 参考值为%dN",
  863. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", alarm_value, alarm_refer);
  864. pNewAlarmInfo->desc = szInfo;
  865. lock_guard<mutex> lock(pService->m_mtxAlarm);
  866. pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);
  867. }
  868. //send
  869. //if (bNew) //不再推送
  870. {
  871. rapidjson::StringBuffer buffer;
  872. auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);
  873. const char* output = buffer.GetString();
  874. //CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());
  875. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  876. }
  877. //主动推送315
  878. //if (bNew)
  879. {
  880. g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,
  881. pNewAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pNewAlarmInfo->level, loworhigh,
  882. TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_MOVEING), 0);
  883. }
  884. //save
  885. //if (bNew)
  886. {
  887. CString sql;
  888. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  889. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  890. pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,
  891. ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,
  892. pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val,
  893. pNewAlarmInfo->sunroof);
  894. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  895. CSimpleLog::Error("执行语句失败" + sql);
  896. else
  897. {
  898. uint8_t* pack = nullptr; int len = 0;
  899. auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);
  900. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  901. //g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pNewAlarmInfo->type, pNewAlarmInfo->val, 0, 0);
  902. delete[] pack;
  903. pack = nullptr;
  904. }
  905. }
  906. }
  907. }
  908. //判断转换阻力是否超限
  909. void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, CONVERT_RESIST_OVER_LIMIT* pConvertOverLimit,
  910. time_t show_time, int show_val, eDaoChaPosi posi, string mo, string mp, uint32_t zzjno)
  911. {
  912. if (pConvertOverLimit == nullptr || pConvertOverLimit->enable == false) return;
  913. bool bNew = false;
  914. ALARM_INFO* pAlarmInfo = nullptr;
  915. bool bAlarm = false, bWarn = false; int alarm_value = show_val, alarm_refer; time_t alarm_time = show_time;
  916. CTime ctAlarmTime = CTime(alarm_time / 1000);
  917. {
  918. if (posi == eDaoChaPosi::DCP_INVERT2FIX)
  919. {
  920. if (show_val > pConvertOverLimit->up_alarm_high_limit)
  921. {
  922. bAlarm = true;
  923. alarm_refer = pConvertOverLimit->up_alarm_high_limit;
  924. }
  925. else if (show_val > pConvertOverLimit->up_warn_high_limit)
  926. {
  927. bWarn = true;
  928. alarm_refer = pConvertOverLimit->up_warn_high_limit;
  929. }
  930. }
  931. else if (posi == eDaoChaPosi::DCP_FIX2INVERT)
  932. {
  933. if (show_val > pConvertOverLimit->dw_alarm_low_limit)
  934. {
  935. bAlarm = true;
  936. alarm_refer = pConvertOverLimit->dw_alarm_low_limit;
  937. }
  938. else if (show_val > pConvertOverLimit->dw_warn_low_limit)
  939. {
  940. bWarn = true;
  941. alarm_refer = pConvertOverLimit->dw_warn_low_limit;
  942. }
  943. }
  944. if (bAlarm == false && bWarn == false)
  945. {
  946. {
  947. string strPosi= "方向:";
  948. strPosi += (posi == eDaoChaPosi::DCP_FIX2INVERT ? "定扳反" : "反扳定");
  949. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  950. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
  951. {
  952. auto alarm = *it;
  953. if (alarm->no == 2 && alarm->type == eZL_ALARMTYPE::CONVERT_LIMIT //预警和报警单独计算 //
  954. && alarm->posi == posi && alarm->recoveryTime.wYear < 2000
  955. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0) //跟上次报警时间超过1小时,则算新报警
  956. {
  957. pAlarmInfo = alarm;
  958. if (pAlarmInfo)
  959. {
  960. //恢复
  961. //1. 更新数据库
  962. //2. 更新内存数据
  963. //3. 上送恢复消息
  964. if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();
  965. string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
  966. CString sql;
  967. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
  968. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  969. if (pAlarmInfo->ack_result == 1)
  970. {
  971. it = pService->m_lstUnConfirmAlarm.erase(it);
  972. continue;
  973. }
  974. else
  975. {
  976. ctAlarmTime.GetAsSystemTime(alarm->recoveryTime);
  977. }
  978. g_p315ClientManager->GetTcpClient()->SendAlarmData(alarm->zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,
  979. pAlarmInfo->type, posi, pAlarmInfo->level, eLowHigh::LH_HIGH,
  980. TIEDA_ACQ_VALUE(alarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);
  981. }
  982. }
  983. ++it;
  984. }
  985. }
  986. return;
  987. }
  988. //查找是否原有的报警已存在
  989. uint8_t level = 0;
  990. if (bAlarm) level = 1;
  991. {
  992. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  993. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  994. {
  995. if (alarm->no == 2 && alarm->type == eZL_ALARMTYPE::CONVERT_LIMIT && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算
  996. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)
  997. {
  998. pAlarmInfo = alarm;
  999. break;
  1000. }
  1001. }
  1002. }
  1003. ALARM_INFO* pNewAlarmInfo = nullptr;
  1004. {
  1005. bNew = true;
  1006. pNewAlarmInfo = new ALARM_INFO;
  1007. pNewAlarmInfo->event_id = hjfunc_GetGUID();
  1008. pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";
  1009. pNewAlarmInfo->id = ++pService->m_nAlarmID;
  1010. pNewAlarmInfo->level = (bAlarm == 1);
  1011. pNewAlarmInfo->mo = mo;
  1012. pNewAlarmInfo->mp = mp;
  1013. pNewAlarmInfo->no = 2;
  1014. ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);
  1015. pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;
  1016. pNewAlarmInfo->type = eZL_ALARMTYPE::CONVERT_LIMIT;
  1017. pNewAlarmInfo->val = alarm_value;
  1018. pNewAlarmInfo->refer_val = alarm_refer;
  1019. pNewAlarmInfo->posi = posi;
  1020. pNewAlarmInfo->zzjno = zzjno;
  1021. pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);
  1022. char szInfo[200] = { 0 };
  1023. sprintf_s(szInfo, sizeof(szInfo), "转换阻力超限,方向:%s, 报警值为%dN, 参考值为%dN",
  1024. posi == eDaoChaPosi::DCP_FIX2INVERT ? "定扳反" : "反扳定", alarm_value, alarm_refer);
  1025. pNewAlarmInfo->desc = szInfo;
  1026. lock_guard<mutex> lock(pService->m_mtxAlarm);
  1027. pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);
  1028. }
  1029. //send
  1030. //if (bNew) //不再推送
  1031. {
  1032. rapidjson::StringBuffer buffer;
  1033. auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);
  1034. const char* output = buffer.GetString();
  1035. //CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());
  1036. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  1037. }
  1038. //主动推送315
  1039. //if (bNew)
  1040. {
  1041. g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,
  1042. pNewAlarmInfo->type, posi, pNewAlarmInfo->level, eLowHigh::LH_HIGH,
  1043. TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_MOVEING), 0);
  1044. }
  1045. //save
  1046. {
  1047. CString sql;
  1048. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  1049. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  1050. pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,
  1051. ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,
  1052. pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val,
  1053. pNewAlarmInfo->sunroof);
  1054. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  1055. CSimpleLog::Error("执行语句失败" + sql);
  1056. else
  1057. {
  1058. uint8_t* pack = nullptr; int len = 0;
  1059. auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);
  1060. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  1061. //g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pNewAlarmInfo->type, pNewAlarmInfo->val, 0, 0);
  1062. delete[] pack;
  1063. pack = nullptr;
  1064. }
  1065. }
  1066. }
  1067. }
  1068. void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, FRICTION_OVER_LIMIT_INFO* pAlarmSet, time_t show_time, int showval, eDaoChaPosi posi, eUpOrDownInfo eUpOrDown, void* pMoMpInfo)
  1069. {
  1070. if (pAlarmSet == nullptr || pAlarmSet->enable == false) return;
  1071. auto pInfo = (ST_MOMP_INFO*)pMoMpInfo;
  1072. bool bNew = false;
  1073. ALARM_INFO* pAlarmInfo = nullptr;
  1074. int show_val = showval < 0 ? -showval : showval;
  1075. bool bAlarm = false, bWarn = false; int alarm_value = show_val, alarm_refer; time_t alarm_time = show_time;
  1076. CTime ctAlarmTime = CTime(alarm_time / 1000);
  1077. eLowHigh loworhigh = eLowHigh::LH_UNKNOWN; //0:最小值 1:最大值
  1078. {
  1079. if (show_val >= pAlarmSet->up_alarm_low_limit)
  1080. {
  1081. bAlarm = true;
  1082. alarm_refer = pAlarmSet->up_alarm_low_limit;
  1083. alarm_value = show_val;
  1084. loworhigh = eLowHigh::LH_HIGH;
  1085. }
  1086. else if (show_val <= pAlarmSet->dw_alarm_high_limit)
  1087. {
  1088. bAlarm = true;
  1089. alarm_refer = pAlarmSet->dw_alarm_high_limit;
  1090. alarm_value = show_val;
  1091. loworhigh = eLowHigh::LH_LOW;
  1092. }
  1093. else if (show_val >= pAlarmSet->up_warn_low_limit)
  1094. {
  1095. bWarn = true;
  1096. alarm_refer = pAlarmSet->up_warn_low_limit;
  1097. alarm_value = show_val;
  1098. loworhigh = eLowHigh::LH_HIGH;
  1099. }
  1100. else if (show_val <= pAlarmSet->dw_warn_high_limit)
  1101. {
  1102. bWarn = true;
  1103. alarm_refer = pAlarmSet->dw_warn_high_limit;
  1104. alarm_value = show_val;
  1105. loworhigh = eLowHigh::LH_LOW;
  1106. }
  1107. if (bAlarm == false && bWarn == false)
  1108. {
  1109. {
  1110. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1111. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
  1112. {
  1113. auto alarm = *it;
  1114. if (alarm->no == 2 && alarm->type == pAlarmSet->type //预警和报警单独计算 //
  1115. && alarm->posi == posi && alarm->recoveryTime.wYear < 2000
  1116. && alarm->mo.compare(pInfo->mo) == 0 && alarm->mp.compare(pInfo->mp) == 0) //跟上次报警时间超过1小时,则算新报警
  1117. {
  1118. pAlarmInfo = alarm;
  1119. if (pAlarmInfo)
  1120. {
  1121. //恢复
  1122. //1. 更新数据库
  1123. //2. 更新内存数据
  1124. //3. 上送恢复消息
  1125. if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();
  1126. string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
  1127. CString sql;
  1128. sql.Format("UPDATE rm_alarm SET recovery_time='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
  1129. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  1130. if (pAlarmInfo->ack_result == 1)
  1131. {
  1132. it = pService->m_lstUnConfirmAlarm.erase(it);
  1133. continue;
  1134. }
  1135. else
  1136. {
  1137. ctAlarmTime.GetAsSystemTime(alarm->recoveryTime);
  1138. }
  1139. g_p315ClientManager->GetTcpClient()->SendAlarmData(alarm->zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,
  1140. pAlarmInfo->type, posi, pAlarmInfo->level, loworhigh,
  1141. TIEDA_ACQ_VALUE(alarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);
  1142. }
  1143. }
  1144. ++it;
  1145. }
  1146. }
  1147. return;
  1148. }
  1149. //查找是否原有的报警已存在
  1150. uint8_t level = 0;
  1151. if (bAlarm) level = 1;
  1152. {
  1153. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1154. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  1155. {
  1156. if (alarm->no == 2 && alarm->type == pAlarmSet->type && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算
  1157. && alarm->mo.compare(pInfo->mo) == 0 && alarm->mp.compare(pInfo->mp) == 0)
  1158. {
  1159. pAlarmInfo = alarm;
  1160. break;
  1161. }
  1162. }
  1163. }
  1164. ALARM_INFO* pNewAlarmInfo = nullptr;
  1165. {
  1166. bNew = true;
  1167. pNewAlarmInfo = new ALARM_INFO;
  1168. pNewAlarmInfo->event_id = hjfunc_GetGUID();
  1169. pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";
  1170. pNewAlarmInfo->id = ++pService->m_nAlarmID;
  1171. pNewAlarmInfo->level = (bAlarm == 1);
  1172. pNewAlarmInfo->mo = pInfo->mo;
  1173. pNewAlarmInfo->mp = pInfo->mp;
  1174. pNewAlarmInfo->no = 2;
  1175. ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);
  1176. pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;
  1177. pNewAlarmInfo->type = pAlarmSet->type;
  1178. pNewAlarmInfo->val = alarm_value;
  1179. pNewAlarmInfo->refer_val = alarm_refer;
  1180. pNewAlarmInfo->posi = posi;
  1181. pNewAlarmInfo->zzjno = pInfo->zzjno;
  1182. pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);
  1183. char szInfo[200] = { 0 };
  1184. sprintf_s(szInfo, sizeof(szInfo), "摩擦力稳态值%s超限,报警值为%dN, 参考值为%dN",
  1185. loworhigh == eLowHigh::LH_LOW ? "下" : "上", alarm_value, alarm_refer);
  1186. pNewAlarmInfo->desc = szInfo;
  1187. lock_guard<mutex> lock(pService->m_mtxAlarm);
  1188. pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);
  1189. }
  1190. //send
  1191. if (bNew) //不再推送
  1192. {
  1193. rapidjson::StringBuffer buffer;
  1194. auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);
  1195. const char* output = buffer.GetString();
  1196. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  1197. }
  1198. //主动推送315
  1199. if (bNew)
  1200. {
  1201. g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,
  1202. pNewAlarmInfo->type, posi, pNewAlarmInfo->level, loworhigh,
  1203. TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_MOVEING), 0);
  1204. }
  1205. //save
  1206. {
  1207. CString sql;
  1208. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  1209. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  1210. pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,
  1211. ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,
  1212. pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val,
  1213. pNewAlarmInfo->sunroof);
  1214. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  1215. CSimpleLog::Error("执行语句失败" + sql);
  1216. else
  1217. {
  1218. uint8_t* pack = nullptr; int len = 0;
  1219. auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);
  1220. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  1221. delete[] pack;
  1222. pack = nullptr;
  1223. }
  1224. }
  1225. }
  1226. }
  1227. void CResistAlarmMng::JudgeAlarm2(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pRetensionForceDropInfo, time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, uint32_t zzjno)
  1228. {
  1229. if (pRetensionForceDropInfo == nullptr || pRetensionForceDropInfo->enable == false) return;
  1230. bool bNew = false;
  1231. ALARM_INFO* pAlarmInfo = nullptr;
  1232. bool bAlarm = false, bWarn = false; int alarm_value = 0, alarm_refer; time_t alarm_time = show_time;
  1233. CTime ctAlarmTime = CTime(alarm_time / 1000);
  1234. eLowHigh loworhigh = eLowHigh::LH_HIGH; //0:最小值 1:最大值
  1235. {
  1236. if (show_val < pRetensionForceDropInfo->dw_alarm_low_drop)
  1237. {
  1238. bWarn = true;
  1239. alarm_refer = pRetensionForceDropInfo->dw_alarm_low_drop;
  1240. alarm_value = show_val;
  1241. //loworhigh = eLowHigh::LH_LOW;
  1242. }
  1243. if (bAlarm == false && bWarn == false)
  1244. {
  1245. if (g_strMoMp.compare(mo + "." + mp) == 0)
  1246. SPDLOG_INFO("[保持力下降]{}.{} 未检测到下降. {} ", mo, mp, show_val);
  1247. {
  1248. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1249. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
  1250. {
  1251. auto pAlarm = *it;
  1252. if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::RETENSION_FORCE && pAlarm->recoveryTime.wYear < 2000 //预警和报警统一恢复
  1253. && pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0)
  1254. {
  1255. pAlarmInfo = pAlarm;
  1256. if (pAlarmInfo)
  1257. {
  1258. //恢复
  1259. //1. 更新数据库
  1260. //2. 更新内存数据
  1261. //3. 上送恢复消息
  1262. if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();
  1263. string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
  1264. CString sql;
  1265. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
  1266. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  1267. if (pAlarmInfo->ack_result == 1)
  1268. {
  1269. it = pService->m_lstUnConfirmAlarm.erase(it);
  1270. continue;
  1271. }
  1272. else
  1273. {
  1274. ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);
  1275. }
  1276. g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), ctAlarmTime.GetTime(),
  1277. pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,
  1278. TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
  1279. }
  1280. }
  1281. it++;
  1282. }
  1283. }
  1284. return;
  1285. }
  1286. SPDLOG_INFO("[保持力下降]{}.{} 检测到下降. {} ", mo, mp, show_val);
  1287. //查找是否原有的报警已存在
  1288. uint8_t level = 0;
  1289. if (bAlarm) level = 1;
  1290. {
  1291. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1292. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  1293. {
  1294. if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::RETENSION_FORCE && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算
  1295. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)
  1296. {
  1297. pAlarmInfo = alarm;
  1298. break;
  1299. }
  1300. }
  1301. }
  1302. if (pAlarmInfo == nullptr)
  1303. {
  1304. bNew = true;
  1305. pAlarmInfo = new ALARM_INFO;
  1306. pAlarmInfo->event_id = hjfunc_GetGUID();
  1307. pAlarmInfo->id = ++pService->m_nAlarmID;
  1308. pAlarmInfo->level = (bAlarm == 1);
  1309. pAlarmInfo->mo = mo;
  1310. pAlarmInfo->mp = mp;
  1311. pAlarmInfo->no = (uint8_t)posi;
  1312. ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);
  1313. pAlarmInfo->time.wMilliseconds = alarm_time % 1000;
  1314. pAlarmInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;
  1315. pAlarmInfo->val = alarm_value;
  1316. pAlarmInfo->refer_val = alarm_refer;
  1317. pAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);
  1318. pAlarmInfo->loworhigh = loworhigh;
  1319. pAlarmInfo->zzjno = zzjno;
  1320. pAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pAlarmInfo->time);
  1321. char szInfo[200] = { 0 };
  1322. sprintf_s(szInfo, sizeof(szInfo), "保持力下降,位置:%s, 报警值为%dN, 参考值为%dN",
  1323. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", alarm_value, alarm_refer);
  1324. pAlarmInfo->desc = szInfo;
  1325. lock_guard<mutex> lock(pService->m_mtxAlarm);
  1326. pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);
  1327. }
  1328. //send
  1329. if (bNew) //不再推送
  1330. {
  1331. rapidjson::StringBuffer buffer;
  1332. auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);
  1333. const char* output = buffer.GetString();
  1334. //CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());
  1335. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  1336. }
  1337. //主动推送315
  1338. if (bNew)
  1339. {
  1340. g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 1, CTime(pAlarmInfo->time).GetTime(), 0xFFFFFFFF,
  1341. pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, loworhigh,
  1342. TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
  1343. }
  1344. //save
  1345. if (bNew)
  1346. {
  1347. CString sql;
  1348. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  1349. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  1350. pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,
  1351. ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,
  1352. pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val,
  1353. pAlarmInfo->sunroof);
  1354. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  1355. CSimpleLog::Error("执行语句失败" + sql);
  1356. else
  1357. {
  1358. uint8_t* pack = nullptr; int len = 0;
  1359. auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);
  1360. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  1361. delete[] pack;
  1362. pack = nullptr;
  1363. }
  1364. }
  1365. }
  1366. }
  1367. void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pAlarmSet,
  1368. time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, void* pInfo, int detectToday, eDaoChaPosi posiLast, BOOL isRedAlarm, BOOL alarmStatus)
  1369. {
  1370. if (pAlarmSet == nullptr) {
  1371. return;
  1372. }
  1373. if (show_val < 0) {
  1374. return;
  1375. }
  1376. ST_MOMP_INFO* pMoMpInfo = (ST_MOMP_INFO*)pInfo;
  1377. CTime ctShowTime(show_time / 1000);
  1378. bool bSkylight = CSkylightMng::GetInstance()->IsSkylight(&ctShowTime);
  1379. if (pAlarmSet->enable == false) {
  1380. return;
  1381. }
  1382. eLowHigh loworhigh = eLowHigh::LH_UNKNOWN;
  1383. int alarm_refer = 0, alarm_value = 0;
  1384. bool bAlarm = false;
  1385. int level = 0;
  1386. if (show_val < pAlarmSet->dw_alarm_low_drop
  1387. && (alarmStatus ==0 || alarmStatus ==1)
  1388. && std::abs(pAlarmSet->dw_alarm_low_drop) <= 100000)
  1389. {
  1390. BOOL judgePass = false;
  1391. if (isRedAlarm) {
  1392. judgePass = JudgePass(mo, mp);
  1393. }
  1394. if (!isRedAlarm ||(isRedAlarm &&!judgePass)) {
  1395. bAlarm = true;
  1396. level = 1;
  1397. alarm_refer = pAlarmSet->dw_alarm_low_drop;
  1398. alarm_value = show_val;
  1399. loworhigh = eLowHigh::LH_LOW;
  1400. SPDLOG_INFO("[最低值红线保持力报警]:{}.{},发生时间:{},报警值:{},参考值:{},是否红线密贴:{},是否红线密贴过车:{}",
  1401. mo, mp, (LPCSTR)(CTime(show_time / 1000).Format("%Y-%m-%d %H:%M:%S")), alarm_value, alarm_refer, isRedAlarm==true?"是":"否", judgePass == true ? "是" : "否");
  1402. }
  1403. }
  1404. if (loworhigh == eLowHigh::LH_UNKNOWN && isRedAlarm!=1 && pAlarmSet->is_page_dyna && (alarmStatus == 0 || alarmStatus == 2))
  1405. {
  1406. int nRatio = show_val * 100 / detectToday;
  1407. //下降20%或上升40% 进行预警
  1408. if (std::abs(nRatio) <= (100 - pAlarmSet->alarm_low_percent)&&
  1409. detectToday<40000 && detectToday > 3000 && pAlarmSet->alarm_low_percent>=5 && pAlarmSet->alarm_low_percent<=95)
  1410. {
  1411. level = 0;
  1412. loworhigh = eLowHigh::LH_LOW;
  1413. alarm_value = show_val;
  1414. alarm_refer = detectToday* (100 - pAlarmSet->alarm_low_percent)/100;
  1415. SPDLOG_INFO("[动态下降保持力报警]:{}.{},发生时间:{},报警值:{},参考值:{},下降百分比:{}%,当日标定值:{}",
  1416. mo, mp, (LPCSTR)(CTime(show_time / 1000).Format("%Y-%m-%d %H:%M:%S")), alarm_value, alarm_refer, pAlarmSet->alarm_low_percent, detectToday);
  1417. }
  1418. else if (std::abs(nRatio) >= (100 + pAlarmSet->alarm_high_percent)
  1419. && detectToday < 40000 && detectToday > 3000 && pAlarmSet->alarm_high_percent >= 5 && pAlarmSet->alarm_high_percent <= 95)
  1420. {
  1421. level = 0;
  1422. loworhigh = eLowHigh::LH_HIGH;
  1423. alarm_value = show_val;
  1424. alarm_refer = detectToday * (100 + pAlarmSet->alarm_high_percent)/100;
  1425. SPDLOG_INFO("[动态上升保持力报警]:{}.{},发生时间:{},报警值:{},参考值:{},上升百分比:{}%,当日标定值:{}",
  1426. mo, mp, (LPCSTR)(CTime(show_time / 1000).Format("%Y-%m-%d %H:%M:%S")), alarm_value, alarm_refer, pAlarmSet->alarm_high_percent, detectToday);
  1427. }
  1428. }
  1429. ALARM_INFO* pAlarmInfo = nullptr;
  1430. bool bNew = false;
  1431. //产生预警
  1432. if (loworhigh != eLowHigh::LH_UNKNOWN)
  1433. {
  1434. //查找是否原有的报警已存在
  1435. {
  1436. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1437. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  1438. {
  1439. if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::RETENSION_FORCE
  1440. && alarm->recoveryTime.wYear < 2000
  1441. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0 && alarm->ack_result==0)
  1442. {
  1443. pAlarmInfo = alarm;
  1444. break;
  1445. }
  1446. }
  1447. }
  1448. if (pAlarmInfo == nullptr)
  1449. {
  1450. pAlarmInfo = new ALARM_INFO;
  1451. pAlarmInfo->id = ++pService->m_nAlarmID;
  1452. pAlarmInfo->event_id = hjfunc_GetGUID();
  1453. pAlarmInfo->level = level;
  1454. pAlarmInfo->mo = mo;
  1455. pAlarmInfo->mp = mp;
  1456. pAlarmInfo->no = (uint8_t)posi;
  1457. ctShowTime.GetAsSystemTime(pAlarmInfo->time);
  1458. pAlarmInfo->time.wMilliseconds = show_time % 1000;
  1459. pAlarmInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;
  1460. pAlarmInfo->val = alarm_value;
  1461. pAlarmInfo->refer_val = alarm_refer;
  1462. pAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);
  1463. pAlarmInfo->loworhigh = loworhigh;
  1464. pAlarmInfo->zzjno = pMoMpInfo->zzjno;
  1465. pAlarmInfo->sunroof = bSkylight;
  1466. char szInfo[200] = { 0 };
  1467. if (level == 1) {
  1468. sprintf_s(szInfo, sizeof(szInfo), "保持力超最低值报警,位置:%s, 报警值为%dN, 参考值为%dN",
  1469. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, alarm_refer);
  1470. }
  1471. else if (level == 0 && loworhigh == eLowHigh::LH_LOW) {
  1472. sprintf_s(szInfo, sizeof(szInfo), "保持力下降超%d%%预警,位置:%s, 报警值为%dN, 参考值为%dN", pAlarmSet->alarm_low_percent,
  1473. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, alarm_refer);
  1474. }
  1475. else if (level == 0 && loworhigh == eLowHigh::LH_HIGH) {
  1476. sprintf_s(szInfo, sizeof(szInfo), "保持力上升超%d%%预警,位置:%s, 报警值为%dN, 参考值为%dN", pAlarmSet->alarm_high_percent,
  1477. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, alarm_refer);
  1478. }
  1479. pAlarmInfo->desc = szInfo;
  1480. if (!bSkylight) {
  1481. bNew = true;
  1482. lock_guard<mutex> lock(pService->m_mtxAlarm);
  1483. pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);
  1484. }
  1485. SPDLOG_INFO("[保持力产生新报警]:{}.{},描述:{},目前队列报警数:{},是否天窗:{}",mo, mp,pAlarmInfo->desc, pService->m_lstUnConfirmAlarm.size(),bSkylight==true?"是":"否");
  1486. }else{
  1487. pAlarmInfo->id = ++pService->m_nAlarmID;
  1488. ctShowTime.GetAsSystemTime(pAlarmInfo->time);
  1489. pAlarmInfo->time.wMilliseconds = show_time % 1000;
  1490. pAlarmInfo->val = alarm_value;
  1491. pAlarmInfo->level = level;
  1492. pAlarmInfo->refer_val = alarm_refer;
  1493. pAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);
  1494. pAlarmInfo->loworhigh = loworhigh;
  1495. pAlarmInfo->zzjno = pMoMpInfo->zzjno;
  1496. pAlarmInfo->sunroof = bSkylight;
  1497. pAlarmInfo->event_id = hjfunc_GetGUID();
  1498. char szInfo[200] = { 0 };
  1499. if (level == 1) {
  1500. sprintf_s(szInfo, sizeof(szInfo), "保持力超最低值报警,位置:%s, 报警值为%dN, 参考值为%dN",
  1501. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, alarm_refer);
  1502. }
  1503. else if (level == 0 && loworhigh == eLowHigh::LH_LOW) {
  1504. sprintf_s(szInfo, sizeof(szInfo), "保持力下降超%d%%预警,位置:%s, 报警值为%dN, 参考值为%dN", pAlarmSet->alarm_low_percent,
  1505. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, alarm_refer);
  1506. }
  1507. else if (level == 0 && loworhigh == eLowHigh::LH_HIGH) {
  1508. sprintf_s(szInfo, sizeof(szInfo), "保持力上升超%d%%预警,位置:%s, 报警值为%dN, 参考值为%dN", pAlarmSet->alarm_high_percent,
  1509. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, alarm_refer);
  1510. }
  1511. pAlarmInfo->desc = szInfo;
  1512. SPDLOG_INFO("[保持力存在相同报警]:{}.{},描述:{},目前队列报警数:{},是否天窗:{}", mo, mp, pAlarmInfo->desc, pService->m_lstUnConfirmAlarm.size(), bSkylight == true ? "是" : "否");
  1513. }
  1514. //send
  1515. if (bNew)
  1516. {
  1517. rapidjson::StringBuffer buffer;
  1518. auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);
  1519. const char* output = buffer.GetString();
  1520. //CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());
  1521. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  1522. SPDLOG_INFO("[保持力报警发送页面]:{}.{},是否红线:{},发送内容:{}", mo, mp,level==1?"红线报警":"动态保持力报警", output);
  1523. }
  1524. //主动推送315
  1525. if (bNew && level==1){
  1526. g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 1, CTime(pAlarmInfo->time).GetTime(), 0xFFFFFFFF,
  1527. pAlarmInfo->type, posiLast, pAlarmInfo->level, loworhigh,
  1528. TIEDA_ACQ_VALUE(pAlarmInfo->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarmInfo->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
  1529. SPDLOG_INFO("[保持力报警发送315]:{}.{}", mo, mp);
  1530. }
  1531. CString sql;
  1532. if (bNew) {
  1533. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  1534. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  1535. pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,
  1536. ctShowTime.Format("%Y-%m-%d %H:%M:%S"), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,
  1537. pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val,
  1538. pAlarmInfo->sunroof);
  1539. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  1540. SPDLOG_INFO("[保持力报警执行语句失败,sql]:{}", sql);
  1541. else {
  1542. uint8_t* pack = nullptr; int len = 0;
  1543. auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);
  1544. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  1545. delete[] pack;
  1546. pack = nullptr;
  1547. }
  1548. }
  1549. }
  1550. else{//恢复
  1551. {
  1552. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1553. if (alarmStatus == 31) {
  1554. level = 1;
  1555. }
  1556. if (alarmStatus == 30) {
  1557. level = 0;
  1558. }
  1559. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();){
  1560. auto pAlarm = *it;
  1561. if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::RETENSION_FORCE && pAlarm->recoveryTime.wYear < 2000
  1562. && pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0 && pAlarm->level ==level){
  1563. pAlarmInfo = pAlarm;
  1564. if (pAlarmInfo){
  1565. //恢复
  1566. //1. 更新数据库
  1567. //2. 更新内存数据
  1568. //3. 上送恢复消息
  1569. if (ctShowTime.GetTime() == 0) ctShowTime = CTime::GetCurrentTime();
  1570. string recovery_time = ctShowTime.Format("%Y-%m-%d %H:%M:%S");
  1571. CString sql;
  1572. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE mo = '%s' and mp = '%s' and no = %d and type = %d and level = %d and recovery_time< '2000';",
  1573. recovery_time.c_str(), pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,pAlarmInfo->level);
  1574. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  1575. if (pAlarmInfo->ack_result == 1){
  1576. it = pService->m_lstUnConfirmAlarm.erase(it);
  1577. continue;
  1578. }
  1579. else{
  1580. ctShowTime.GetAsSystemTime(pAlarm->recoveryTime);
  1581. }
  1582. if (pAlarmInfo->level == 1) {
  1583. g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 2, CTime(pAlarmInfo->time).GetTime(), ctShowTime.GetTime(),
  1584. pAlarmInfo->type, pAlarmInfo->posi, pAlarmInfo->level, pAlarm->loworhigh,
  1585. TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
  1586. }
  1587. SPDLOG_INFO("[保持力恢复]:{}.{},恢复sql:{},确认结果:{},等级:{}",mo, mp, sql, pAlarmInfo->ack_result == 1?"确认":"未确认",level==0?"预警":"报警");
  1588. }
  1589. }
  1590. it++;
  1591. }
  1592. }
  1593. return;
  1594. }
  1595. }
  1596. void CResistAlarmMng::JudgeAlarm3(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pRetensionForceDropInfo, time_t show_time, int show_val,
  1597. eSuoBiPosi posi, string mo, string mp, uint32_t zzjno)
  1598. {
  1599. if (pRetensionForceDropInfo == nullptr || pRetensionForceDropInfo->enable == false) return;
  1600. bool bNew = false;
  1601. ALARM_INFO* pAlarmInfo = nullptr;
  1602. bool bAlarm = false, bWarn = false; int alarm_value = 0, alarm_refer; time_t alarm_time = show_time;
  1603. CTime ctAlarmTime = CTime(alarm_time / 1000);
  1604. eLowHigh loworhigh = eLowHigh::LH_HIGH; //0:最小值 1:最大值
  1605. {
  1606. if (show_val < pRetensionForceDropInfo->dw_alarm_low_drop)
  1607. {
  1608. bAlarm = true;
  1609. alarm_refer = pRetensionForceDropInfo->dw_alarm_low_drop;
  1610. alarm_value = show_val;
  1611. //loworhigh = eLowHigh::LH_LOW;
  1612. }
  1613. if (bAlarm == false && bWarn == false)
  1614. {
  1615. {
  1616. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1617. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
  1618. {
  1619. auto pAlarm = *it;
  1620. if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::RETENSION_FORCE && pAlarm->recoveryTime.wYear < 2000 //预警和报警统一恢复
  1621. && pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0)
  1622. {
  1623. pAlarmInfo = pAlarm;
  1624. if (pAlarmInfo)
  1625. {
  1626. //恢复
  1627. //1. 更新数据库
  1628. //2. 更新内存数据
  1629. //3. 上送恢复消息
  1630. if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();
  1631. string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
  1632. CString sql;
  1633. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
  1634. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  1635. if (pAlarmInfo->ack_result == 1)
  1636. {
  1637. it = pService->m_lstUnConfirmAlarm.erase(it);
  1638. continue;
  1639. }
  1640. else
  1641. {
  1642. ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);
  1643. }
  1644. g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,
  1645. pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,
  1646. TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
  1647. }
  1648. }
  1649. it++;
  1650. }
  1651. }
  1652. return;
  1653. }
  1654. //查找是否原有的报警已存在
  1655. uint8_t level = 0;
  1656. if (bAlarm) level = 1;
  1657. {
  1658. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  1659. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  1660. {
  1661. if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::RETENSION_FORCE && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算
  1662. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)
  1663. {
  1664. pAlarmInfo = alarm;
  1665. break;
  1666. }
  1667. }
  1668. }
  1669. ALARM_INFO* pNewAlarmInfo = nullptr;
  1670. {
  1671. bNew = true;
  1672. pNewAlarmInfo = new ALARM_INFO;
  1673. pNewAlarmInfo->event_id = hjfunc_GetGUID();
  1674. pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";
  1675. pNewAlarmInfo->id = ++pService->m_nAlarmID;
  1676. pNewAlarmInfo->level = (bAlarm == 1);
  1677. pNewAlarmInfo->mo = mo;
  1678. pNewAlarmInfo->mp = mp;
  1679. pNewAlarmInfo->no = (uint8_t)posi;
  1680. ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);
  1681. pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;
  1682. pNewAlarmInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;
  1683. pNewAlarmInfo->val = alarm_value;
  1684. pNewAlarmInfo->refer_val = alarm_refer;
  1685. pNewAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);
  1686. pNewAlarmInfo->loworhigh = loworhigh;
  1687. pNewAlarmInfo->zzjno = zzjno;
  1688. pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);
  1689. char szInfo[200] = { 0 };
  1690. sprintf_s(szInfo, sizeof(szInfo), "保持力下降,位置:%s, 报警值为%dN, 参考值为%dN",
  1691. posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", alarm_value, alarm_refer);
  1692. pNewAlarmInfo->desc = szInfo;
  1693. lock_guard<mutex> lock(pService->m_mtxAlarm);
  1694. pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);
  1695. }
  1696. //send
  1697. //if (bNew) //不再推送
  1698. {
  1699. rapidjson::StringBuffer buffer;
  1700. auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);
  1701. const char* output = buffer.GetString();
  1702. //CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());
  1703. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  1704. }
  1705. //主动推送315
  1706. //if (bNew)
  1707. {
  1708. g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,
  1709. pNewAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pNewAlarmInfo->level, loworhigh,
  1710. TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
  1711. }
  1712. //save
  1713. //if (bNew)
  1714. {
  1715. CString sql;
  1716. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  1717. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  1718. pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,
  1719. ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,
  1720. pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val,
  1721. pNewAlarmInfo->sunroof);
  1722. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  1723. CSimpleLog::Error("执行语句失败" + sql);
  1724. else
  1725. {
  1726. uint8_t* pack = nullptr; int len = 0;
  1727. auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);
  1728. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  1729. //g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pNewAlarmInfo->type, pNewAlarmInfo->val, 0, 0);
  1730. delete[] pack;
  1731. pack = nullptr;
  1732. }
  1733. }
  1734. }
  1735. }
  1736. BOOL ConmpareValue(std::map<time_t, int>::const_iterator i, std::map<time_t, int>::const_iterator j, int refer_value, int& hight_num, int& low_num)
  1737. {
  1738. int start_value = 0;
  1739. for (; i != j; i++)
  1740. {
  1741. if (i->second > refer_value)
  1742. {
  1743. if (start_value == 1)
  1744. {
  1745. //原来大于,现在也是大于
  1746. continue;
  1747. }
  1748. else
  1749. {
  1750. //原来小于或者无效,现在大于
  1751. start_value = 1;
  1752. hight_num++;
  1753. }
  1754. }
  1755. else
  1756. {
  1757. if (start_value == -1)
  1758. {
  1759. //原来小于,现在小于等于
  1760. continue;
  1761. }
  1762. else
  1763. {
  1764. //原来大于或者无效,现在小于
  1765. start_value = -1;
  1766. low_num++;
  1767. }
  1768. }
  1769. }
  1770. return TRUE;
  1771. }
  1772. void CResistAlarmMng::ThreadProcAlarmSet(DWORD_PTR param,CString strIniPath)
  1773. {
  1774. auto pService = (CResistAlarmMng*)param;
  1775. Sleep(2000);
  1776. time_t tmNow;
  1777. bool bLock = false;
  1778. char szTemp[100] = { 0 };
  1779. int detectTimeByna = ::GetPrivateProfileInt("SET", "retension_dynamic", 600, strIniPath);//动态保持力检测时间为10分钟 600
  1780. int detectTimeRed = ::GetPrivateProfileInt("SET", "retension_red", 30, strIniPath);//红线保持力检测时间为30秒 30
  1781. int detectFourAlarm = ::GetPrivateProfileInt("SET", "retension_alarm", 14400, strIniPath);//四个小时重复报警,4 * 60 * 60
  1782. time_t detectTimeBynaTime = 0;
  1783. time_t detectFourAlarmTime = 0;
  1784. int detectToday0 = 3000;//定位保持力参考值
  1785. time_t detectTodayTime0=0;
  1786. int detectToday1 = 3000;//反位保持力参考值
  1787. time_t detectTodayTime1=0;
  1788. int detectToday01 = 3000;//保持力参考值
  1789. eDaoChaPosi posiToday = eDaoChaPosi::DCP_FIX; //当日位置
  1790. eDaoChaPosi posiLast = eDaoChaPosi::DCP_FIX; //最近一次过车位置
  1791. int alarmStatus = 1;// 0:板动报警;1:红线报警;2:动态报警; 3:报警恢复
  1792. int test = 0;
  1793. do
  1794. {
  1795. if (bLock)
  1796. {
  1797. g_lockSync.Unlock();
  1798. bLock = false;
  1799. }
  1800. Sleep(1000);
  1801. time(&tmNow);
  1802. if (tmNow == pService->m_lastDetectTime)
  1803. continue;
  1804. pService->m_lastDetectTime = tmNow;
  1805. bLock = true;
  1806. g_lockSync.ReadLock();
  1807. //1秒判断一次
  1808. for (const auto& item : pService->m_alarm_set)
  1809. {
  1810. if (item.second == nullptr) continue;
  1811. if (item.second->enable == false) continue;
  1812. if (item.second->type != eZL_ALARMTYPE::MAX_OVER_LIMIT) //这个逻辑里面只支持这两种
  1813. continue;
  1814. if (item.second->no < 0 || item.second->no > 2) continue;
  1815. int nPos = item.first.find('.');
  1816. if (nPos == -1) continue;
  1817. int nPos2 = item.first.find('.', nPos + 1);
  1818. if (nPos2 == -1) continue;
  1819. string mo = item.first.substr(0, nPos);
  1820. string mp = item.first.substr(nPos + 1, nPos2 - nPos - 1);
  1821. string momp = item.first.substr(0, nPos2);
  1822. bool bNew = false;
  1823. ALARM_INFO *pAlarmInfo = nullptr;
  1824. CTime ctAlarmTime;
  1825. string imei; int idx;
  1826. auto ret = CMonitorObjectMng::Instance()->MOMP2IMEI(momp, imei, idx);
  1827. if (ret == false) continue;
  1828. #ifdef _DEBUG
  1829. if (strcmp("860588048955283", imei.c_str()) != 0) continue;
  1830. #endif
  1831. auto pDevice = CDeviceMng::Instance()->Find(imei);
  1832. if (pDevice == nullptr)
  1833. {
  1834. CSimpleLog::Error(("找不到imei(" + imei + ")" + std::to_string(__LINE__)).c_str());
  1835. continue;
  1836. }
  1837. int desc_type = 0;
  1838. bool bAlarm = false, bWarn = false; int alarm_value = 0; time_t alarm_time = 0;
  1839. eDaoChaPosi posi = eDaoChaPosi::DCP_UNKNOWN;
  1840. int high_alarm_limit = INT_MAX, high_warn_limit = INT_MAX, low_alarm_limit = INT_MIN, low_warn_limit = INT_MIN, alarm_refer = INT_MAX;
  1841. time_t tmNow; time(&tmNow);
  1842. BASE_INFO* pAlarmSet = item.second;
  1843. do{
  1844. Sleep(0);
  1845. lock_guard<mutex> lock(pDevice->m_mtx);
  1846. std::map<time_t, int>* pData = pDevice->GetMapData(idx, item.second->no);
  1847. assert(pData);
  1848. if (pData == nullptr) continue;
  1849. if (pData->size() == 0) continue;
  1850. if (item.second == 0) continue;
  1851. if (item.second->type == eZL_ALARMTYPE::MAX_OVER_LIMIT)
  1852. {
  1853. auto pInfo = (MAX_OVER_LIMIT_INFO*)pAlarmSet;
  1854. #ifdef _DEBUG
  1855. if (pInfo->tmLastCheckTime > pData->rbegin()->first)
  1856. pInfo->tmLastCheckTime = pData->rbegin()->first;
  1857. #endif
  1858. auto it = pData->cbegin();
  1859. if (pInfo->tmLastCheckTime == 0) pInfo->tmLastCheckTime = pData->rbegin()->first;
  1860. else if (pInfo->tmLastCheckTime != 0) it = pData->find(pInfo->tmLastCheckTime);
  1861. if (it == pData->cend())
  1862. {
  1863. it = pData->find(pInfo->tmLastCheckTime / 1000 * 1000);
  1864. if (it == pData->cend())
  1865. {
  1866. pInfo->tmLastCheckTime = pData->rbegin()->first;
  1867. continue;
  1868. }
  1869. }
  1870. if (pInfo->tmLastCheckTime == pData->rbegin()->first) //没有新的数据
  1871. continue;
  1872. #ifdef _DEBUG
  1873. TRACE("%s.%s.%d.%d lastcheck:%s now:%s\r\n", mo.c_str(), mp.c_str(), pInfo->no, (int)eZL_ALARMTYPE::MAX_OVER_LIMIT,
  1874. CTime(pInfo->tmLastCheckTime / 1000).Format("%Y-%m-%d %H:%M:%S"), CTime(pData->rbegin()->first / 1000).Format("%Y-%m-%d %H:%M:%S"));
  1875. #endif // _DEBUG
  1876. time_t tmStartSteady = pInfo->tmLastCheckTime / 1000 - 3; //稳态报警检测开始, 从上次3秒前到当前秒
  1877. if (item.second->no == 2)
  1878. {
  1879. if (pInfo->alarm_high_limit > pInfo->f_alarm_high_limit)
  1880. {//定板反
  1881. high_alarm_limit = pInfo->alarm_high_limit;
  1882. high_warn_limit = pInfo->warn_high_limit;
  1883. low_alarm_limit = pInfo->f_alarm_high_limit;
  1884. low_warn_limit = pInfo->f_warn_high_limit;
  1885. posi = eDaoChaPosi::DCP_FIX2INVERT;
  1886. }
  1887. else
  1888. {//反板定
  1889. low_alarm_limit = pInfo->alarm_high_limit;
  1890. low_warn_limit = pInfo->warn_high_limit;
  1891. high_alarm_limit = pInfo->f_alarm_high_limit;
  1892. high_warn_limit = pInfo->f_warn_high_limit;
  1893. posi = eDaoChaPosi::DCP_FIX2INVERT;
  1894. }
  1895. }
  1896. for (++it; it != pData->cend(); ++it)
  1897. {
  1898. //CString str = CTime(it->first / 1000).Format("%Y-%m-%d %H:%M:%S");
  1899. if (it->second == INVLID_VAL)
  1900. {
  1901. pInfo->tmLastCheckTime = it->first;
  1902. continue;
  1903. }
  1904. if (item.second->no < 2)
  1905. {
  1906. //1,2 锁闭力报警
  1907. if (it->second > pInfo->alarm_high_limit)
  1908. {
  1909. bAlarm = true;
  1910. alarm_refer = pInfo->alarm_high_limit;
  1911. alarm_value = it->second;
  1912. alarm_time = it->first;
  1913. pInfo->tmLastCheckTime = pData->rbegin()->first;
  1914. desc_type = 1;
  1915. break;
  1916. }
  1917. //else if (it->second > pInfo->warn_high_limit) //稳态报警单独判断
  1918. //{
  1919. // bWarn = true;
  1920. // alarm_refer = pInfo->warn_high_limit;
  1921. // alarm_value = it->second;
  1922. // alarm_time = it->first;
  1923. // pInfo->tmLastCheckTime = pData->rbegin()->first;
  1924. //}
  1925. }
  1926. else
  1927. {
  1928. assert(item.second->no == 2);
  1929. if (pInfo->alarm_high_limit == INT_MAX || pInfo->f_alarm_high_limit == INT_MAX || pInfo->alarm_high_limit == pInfo->f_alarm_high_limit)
  1930. break;
  1931. desc_type = 3;
  1932. if (it->second > high_alarm_limit)
  1933. {
  1934. bAlarm = true;
  1935. alarm_refer = high_alarm_limit;
  1936. alarm_value = it->second;
  1937. alarm_time = it->first;
  1938. pInfo->tmLastCheckTime = pData->rbegin()->first;
  1939. break;
  1940. }
  1941. else if (it->second < low_alarm_limit)
  1942. {
  1943. bAlarm = true;
  1944. alarm_refer = low_alarm_limit;
  1945. alarm_value = it->second;
  1946. alarm_time = it->first;
  1947. pInfo->tmLastCheckTime = pData->rbegin()->first;
  1948. break;
  1949. }
  1950. else if (low_warn_limit == INT_MIN || high_warn_limit == INT_MIN)
  1951. {
  1952. //未设置预警值
  1953. }
  1954. else if (it->second > high_warn_limit)
  1955. {
  1956. bWarn = true;
  1957. alarm_refer = high_warn_limit;
  1958. alarm_value = it->second;
  1959. alarm_time = it->first;
  1960. pInfo->tmLastCheckTime = pData->rbegin()->first;
  1961. }
  1962. else if (it->second < low_warn_limit)
  1963. {
  1964. bWarn = true;
  1965. alarm_refer = low_warn_limit;
  1966. alarm_value = it->second;
  1967. alarm_time = it->first;
  1968. pInfo->tmLastCheckTime = pData->rbegin()->first;
  1969. }
  1970. }
  1971. pInfo->tmLastCheckTime = it->first;
  1972. }
  1973. //稳态报警判断
  1974. if (item.second->no < 2 && bAlarm == false)
  1975. {
  1976. time_t tmEnd = pInfo->tmLastCheckTime / 1000;
  1977. int dif = tmEnd - tmStartSteady;
  1978. for (time_t i = tmStartSteady; i < tmEnd - 3; i++)
  1979. {
  1980. #ifdef _DEBUG
  1981. COleDateTime t(i);
  1982. TRACE("%s\r\n", t.Format("%Y-%m-%d %H:%M:%S"));
  1983. #endif // _DEBUG
  1984. auto j = pData->find(i * 1000);
  1985. if (j == pData->end()) continue;
  1986. time_t t2 = (i + 1) * 1000;
  1987. auto k = pData->find(t2);
  1988. if (k == pData->end()) continue;
  1989. t2 = (i + 2) * 1000;
  1990. k = pData->find(t2);
  1991. if (k == pData->end()) continue;
  1992. //连续3秒在线,继续找下一个结束点
  1993. t2 = (i + 3) * 1000;
  1994. auto g = pData->find(t2);
  1995. if (g == pData->end())
  1996. {
  1997. for (++k; k != pData->end(); k++)
  1998. {
  1999. if (k->first >= t2)
  2000. {
  2001. g = k;
  2002. break;
  2003. }
  2004. }
  2005. }
  2006. if (g == pData->end())
  2007. continue;
  2008. int high_num = 0, low_num = 0;
  2009. ConmpareValue(j, g, pInfo->warn_high_limit, high_num, low_num);
  2010. if (high_num > 0 && high_num <= 2)
  2011. {
  2012. bWarn = true;
  2013. desc_type = 2;
  2014. alarm_refer = pInfo->warn_high_limit;
  2015. alarm_value = high_num;
  2016. alarm_time = i * 1000; //报警时间
  2017. pInfo->tmLastCheckTime = pData->rbegin()->first;
  2018. break;
  2019. }
  2020. }
  2021. }
  2022. }
  2023. /* 2024年8月24日 放在move中判断
  2024. else if (item.second->type == eZL_ALARMTYPE::FRICTION_OVER_LIMIT)
  2025. {
  2026. auto pInfo = (FRICTION_OVER_LIMIT_INFO*)item.second;
  2027. #ifdef _DEBUG
  2028. if (pInfo->tmLastCheckTime > pData->rbegin()->first)
  2029. pInfo->tmLastCheckTime = pData->rbegin()->first;
  2030. #endif
  2031. auto it = pData->cbegin();
  2032. if (pInfo->tmLastCheckTime == 0) pInfo->tmLastCheckTime = pData->rbegin()->first;
  2033. else if (pInfo->tmLastCheckTime != 0) it = pData->find(pInfo->tmLastCheckTime);
  2034. if (it == pData->cend())
  2035. {
  2036. it = pData->find(pInfo->tmLastCheckTime / 1000 * 1000);
  2037. if (it == pData->cend())
  2038. {
  2039. pInfo->tmLastCheckTime = pData->rbegin()->first;
  2040. continue;
  2041. }
  2042. }
  2043. if (pInfo->tmLastCheckTime == pData->rbegin()->first) //没有新的数据
  2044. continue;
  2045. if (tmNow * 1000 - pInfo->tmLastCheckTime < 5000) //5秒检测一次
  2046. continue;
  2047. #ifdef _DEBUG
  2048. TRACE("%s.%s.%d.%d lastcheck:%s now:%s\r\n", mo.c_str(), mp.c_str(), pInfo->no, (int)eZL_ALARMTYPE::FRICTION_OVER_LIMIT,
  2049. CTime(pInfo->tmLastCheckTime / 1000).Format("%Y-%m-%d %H:%M:%S"), CTime(pData->rbegin()->first / 1000).Format("%Y-%m-%d %H:%M:%S"));
  2050. #endif // _DEBUG
  2051. if (item.second->no != 2) continue;
  2052. //从检测时间往前取30秒的数据
  2053. static const int dif_resist = 200; //稳定期判定差值
  2054. int up_max_resist = INT_MIN; //上最大值
  2055. time_t up_max_time = 0;
  2056. int up_avg_resist = INT_MIN; //上稳定期平均值
  2057. uint64_t up_stable_sum = 0; //上稳定期的和
  2058. int up_stable_time = 0; //上稳定期的数值个数
  2059. int up_start_resist_stabel = INT_MIN; //上稳定期开始值
  2060. time_t up_start_stable_time = 0; //规定是最大值之后的2秒
  2061. time_t up_end_stable_time = 0;//稳定结束的时间
  2062. int up_dif_time_stable = 0; //上稳定期的时长
  2063. int down_max_resist = INT_MAX; //上最大值
  2064. time_t down_max_time = 0;
  2065. int down_avg_resist = INT_MAX; //上稳定期平均值
  2066. uint64_t down_stable_sum = 0; //上稳定期的和
  2067. int down_stable_time = 0; //上稳定期的数值个数
  2068. int down_start_resist_stabel = INT_MAX; //上稳定期开始值
  2069. time_t down_start_stable_time = 0; //规定是最大值之后的2秒
  2070. int down_dif_time_stable = 0; //上稳定期的时长
  2071. time_t tmEnd = pData->rbegin()->first / 1000 + 1; //结束时间
  2072. time_t tmStart = tmEnd - 36;//开始时间是从上次35秒到当前秒
  2073. std::map<time_t, int>::const_iterator it_start, it_up_max, it_down_min, it_up_stable_start, it_down_stable_start, it_up_stable_end, it_down_stable_end;
  2074. //寻找起始时间
  2075. for (time_t i = tmStart; i < tmEnd; i++)
  2076. {
  2077. #ifdef _DEBUG
  2078. COleDateTime t(i);
  2079. TRACE("%s\r\n", t.Format("%Y-%m-%d %H:%M:%S"));
  2080. #endif // _DEBUG
  2081. it_start = pData->find(i * 1000);
  2082. if (it_start != pData->cend()) break;
  2083. }
  2084. pInfo->tmLastCheckTime = pData->rbegin()->first; //赋值最后的时间
  2085. if (it_start == pData->cend()) break;
  2086. bool bUp = true, bDown = true;
  2087. //先找最大值
  2088. for (auto i = it_start; i != pData->cend(); i++)
  2089. {
  2090. //寻找最大的点
  2091. if (i->second > up_max_resist)
  2092. {
  2093. up_max_resist = i->second;
  2094. it_up_max = i;
  2095. }
  2096. //寻找最小的点
  2097. if (i->second < down_max_resist)
  2098. {
  2099. down_max_resist = i->second;
  2100. it_down_min = i;
  2101. }
  2102. }
  2103. if (pInfo->tmLastCheckTime - it_up_max->first < 17000) bUp = false; //小于17秒
  2104. if (pInfo->tmLastCheckTime - it_down_min->first < 1700) bDown = false; //小于17秒
  2105. if(bUp == false && bDown == false) break;
  2106. //再找稳定开始
  2107. if (bUp)
  2108. {
  2109. it_up_stable_start = it_up_max;
  2110. for (auto i = it_up_max; i != pData->cend(); i++)
  2111. {
  2112. if (i->first - it_up_max->first < 2000) continue;
  2113. else
  2114. {
  2115. it_up_stable_start = i;
  2116. break;
  2117. }
  2118. }
  2119. if (it_up_stable_start == it_up_max) bUp = false;
  2120. }
  2121. if (bDown)
  2122. {
  2123. it_down_stable_start = it_down_min;
  2124. for (auto i = it_down_min; i != pData->cend(); i++)
  2125. {
  2126. if (i->first - it_down_min->first < 2000) continue;
  2127. else
  2128. {
  2129. it_down_stable_start = i;
  2130. break;
  2131. }
  2132. }
  2133. if (it_down_stable_start == it_down_min) bDown = false;
  2134. }
  2135. if (bUp == false && bDown == false) break;
  2136. if (bUp)
  2137. {
  2138. up_start_resist_stabel = it_up_stable_start->second;//稳定期开始的值
  2139. it_up_stable_end = it_up_stable_start;
  2140. for (auto i = it_up_stable_start; i != pData->cend(); i++)
  2141. {
  2142. if (abs(up_start_resist_stabel - i->second) < dif_resist)
  2143. {
  2144. up_stable_sum += i->second;
  2145. up_start_stable_time++;
  2146. it_up_stable_end = i;
  2147. continue;
  2148. }
  2149. else
  2150. {
  2151. break;
  2152. }
  2153. }
  2154. //时间条件限定在 15s-30s 之间
  2155. auto dif = it_up_stable_end->first - it_up_stable_start->first;
  2156. if (dif > 15000 && dif < 30000)
  2157. {
  2158. //平均值
  2159. up_avg_resist = up_stable_sum / up_start_stable_time;
  2160. if (up_avg_resist < pInfo->up_alarm_low_limit)
  2161. {
  2162. bAlarm = true;
  2163. alarm_value = up_avg_resist;
  2164. alarm_time = it_up_stable_start->first;
  2165. alarm_refer = pInfo->up_alarm_low_limit;
  2166. desc_type = 4;
  2167. }
  2168. else if (up_avg_resist < pInfo->up_warn_low_limit)
  2169. {
  2170. bWarn = true;
  2171. alarm_value = up_avg_resist;
  2172. alarm_time = it_up_stable_start->first;
  2173. alarm_refer = pInfo->up_warn_low_limit;
  2174. desc_type = 4;
  2175. }
  2176. }
  2177. }
  2178. if (bDown)
  2179. {
  2180. down_start_resist_stabel = it_down_stable_start->second;//稳定期开始的值
  2181. it_down_stable_end = it_down_stable_start;
  2182. for (auto i = it_down_stable_start; i != pData->cend(); i++)
  2183. {
  2184. if (abs(down_start_resist_stabel - i->second) < dif_resist)
  2185. {
  2186. down_stable_sum += i->second;
  2187. down_start_stable_time++;
  2188. it_down_stable_end = i;
  2189. continue;
  2190. }
  2191. else
  2192. {
  2193. break;
  2194. }
  2195. }
  2196. //时间条件限定在 15s-30s 之间
  2197. auto dif = it_down_stable_end->first - it_down_stable_start->first;
  2198. if (dif > 15000 && dif < 30000)
  2199. {
  2200. //平均值
  2201. down_avg_resist = down_stable_sum / down_start_stable_time;
  2202. if (down_avg_resist > pInfo->dw_alarm_high_limit)
  2203. {
  2204. bAlarm = true;
  2205. alarm_value = down_avg_resist;
  2206. alarm_time = it_down_stable_start->first;
  2207. alarm_refer = pInfo->dw_alarm_high_limit;
  2208. desc_type = 5;
  2209. }
  2210. else if (down_avg_resist > pInfo->dw_warn_high_limit)
  2211. {
  2212. bWarn = true;
  2213. alarm_value = down_avg_resist;
  2214. alarm_time = it_down_stable_start->first;
  2215. alarm_refer = pInfo->dw_warn_high_limit;
  2216. desc_type = 5;
  2217. }
  2218. }
  2219. }
  2220. }*/
  2221. else
  2222. {
  2223. //其他未实现
  2224. //TODO
  2225. assert(0);
  2226. continue;
  2227. }
  2228. }while (false);
  2229. //update
  2230. CString sql;
  2231. sql.Format("update rm_alarm_set SET time = %I64u WHERE mo = '%s' and mp = '%s' and no = %d and type = %d",
  2232. pAlarmSet->tmLastCheckTime, mo.c_str(), mp.c_str(), pAlarmSet->no, pAlarmSet->type);
  2233. if (CDBConnectPool::Instance()->DBExecuteSQL(sql) == FALSE)
  2234. {
  2235. assert(0);
  2236. CSimpleLog::Error("语句执行失败" + sql);
  2237. }
  2238. string name1, name2, name3, out_name, in_name;
  2239. CMonitorObjectMng::Instance()->GetNameByMoMp(momp, name1, name2, name3, out_name, in_name);
  2240. auto pMoMpInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(momp);
  2241. if (item.second->no == 0 || item.second->no == 1)
  2242. {
  2243. if (name1.find("定位") != -1)
  2244. {
  2245. posi = item.second->no == 0 ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT;
  2246. }
  2247. else if (name1.find("反位") != -1)
  2248. {
  2249. posi = item.second->no == 0 ? eDaoChaPosi::DCP_INVERT : eDaoChaPosi::DCP_FIX;
  2250. }
  2251. else if (pMoMpInfo)
  2252. SPDLOG_WARN("{} 未配置定位位关系 {}, {}, {}, {}", momp, name1, name2, pMoMpInfo->name1, pMoMpInfo->name2);
  2253. }
  2254. else if (item.second->no == 2)
  2255. {
  2256. //TODO
  2257. if (posi == eDaoChaPosi::DCP_UNKNOWN)
  2258. posi = eDaoChaPosi::DCP_FIX2INVERT;
  2259. }
  2260. else
  2261. ASSERT(FALSE);
  2262. if (bAlarm == false && bWarn == false) //没有报警
  2263. {
  2264. //恢复报警
  2265. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  2266. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
  2267. {
  2268. auto& alarm = *it;
  2269. if (alarm->no == item.second->no && alarm->type == pAlarmSet->type && alarm->recoveryTime.wYear < 2000
  2270. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)
  2271. {
  2272. auto pAlarmInfo = alarm;
  2273. //1. 更新数据库
  2274. //2. 更新内存数据
  2275. //3. 上送恢复消息
  2276. if (ctAlarmTime.GetTime() == 0)
  2277. ctAlarmTime = CTime::GetCurrentTime();
  2278. string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
  2279. CString sql;
  2280. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
  2281. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  2282. if (pAlarmInfo->ack_result == 1)
  2283. {
  2284. it = pService->m_lstUnConfirmAlarm.erase(it);
  2285. continue;
  2286. }
  2287. else
  2288. {
  2289. ctAlarmTime.GetAsSystemTime(alarm->recoveryTime);
  2290. }
  2291. g_p315ClientManager->GetTcpClient()->SendAlarmData(CMonitorObjectMng::Instance()->GetZZJNO(mo + '.' + mp), 2, CTime(pAlarmInfo->time).GetTime(), ctAlarmTime.GetTime(),
  2292. pAlarmInfo->type, posi, pAlarmInfo->level, eLowHigh::LH_HIGH,
  2293. TIEDA_ACQ_VALUE(alarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);
  2294. }
  2295. ++it;
  2296. }
  2297. continue; //误报警继续下一个循环
  2298. }
  2299. //查找是否原有的报警已存在
  2300. uint8_t level = 0;
  2301. if (bAlarm) level = 1;
  2302. ctAlarmTime = CTime(alarm_time / 1000);
  2303. {
  2304. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  2305. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  2306. {
  2307. if (alarm->no == item.second->no && alarm->type == pAlarmSet->type && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算
  2308. && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)
  2309. {
  2310. pAlarmInfo = alarm;
  2311. break;
  2312. }
  2313. }
  2314. }
  2315. if (pAlarmInfo == nullptr)
  2316. {
  2317. bNew = true;
  2318. pAlarmInfo = new ALARM_INFO;
  2319. pAlarmInfo->event_id = hjfunc_GetGUID();
  2320. pAlarmInfo->id = ++pService->m_nAlarmID;
  2321. pAlarmInfo->level = (bAlarm == 1);
  2322. pAlarmInfo->mo = mo;
  2323. pAlarmInfo->mp = mp;
  2324. pAlarmInfo->no = item.second->no;
  2325. ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);
  2326. pAlarmInfo->time.wMilliseconds = alarm_time % 1000;
  2327. pAlarmInfo->type = item.second->type;
  2328. pAlarmInfo->val = alarm_value;
  2329. pAlarmInfo->refer_val = alarm_refer;
  2330. pAlarmInfo->posi = posi;
  2331. pAlarmInfo->zzjno = CMonitorObjectMng::Instance()->GetZZJNO(momp);
  2332. pAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pAlarmInfo->time);
  2333. char szInfo[200];
  2334. if (desc_type == 1)
  2335. {
  2336. sprintf_s(szInfo, sizeof(szInfo), "瞬时冲击力超限报警,报警值为%dN, 参考值为%dN", alarm_value, alarm_refer);//101 102
  2337. if (pAlarmInfo->type == eZL_ALARMTYPE::MAX_OVER_LIMIT)
  2338. {
  2339. g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 1, CTime(pAlarmInfo->time).GetTime(), 0xFFFFFFFF,
  2340. pAlarmInfo->type, pAlarmInfo->posi, pAlarmInfo->level, eLowHigh::LH_HIGH,
  2341. TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_POLL), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_POLL), 0);
  2342. }
  2343. }
  2344. else if (desc_type == 2)
  2345. sprintf_s(szInfo, sizeof(szInfo), "稳态值超限预警, 超限次数为%d次, 参考值为%dN", alarm_value, alarm_refer);
  2346. else if (desc_type == 3)
  2347. sprintf_s(szInfo, sizeof(szInfo), "转换阻力值超限报警, 报警值为%dN, 参考值为%dN", alarm_value, alarm_refer);
  2348. else if (desc_type == 4)
  2349. {
  2350. sprintf_s(szInfo, sizeof(szInfo), "摩擦力超限%s, 缩进位报警值为%dN, 参考值为:%dN", bAlarm == 1 ? "告警" : "预警", alarm_value, alarm_refer);
  2351. string direct1, direct2;
  2352. CMonitorObjectMng::Instance()->GetDirectByMoMp(mo + '.' + mp, direct1, direct2);
  2353. }
  2354. else if (desc_type == 5)
  2355. {
  2356. sprintf_s(szInfo, sizeof(szInfo), "摩擦力超限%s, 伸出位报警值为%dN, 参考值为:%dN", bAlarm == 1 ? "告警" : "预警", alarm_value, alarm_refer);
  2357. string direct1, direct2;
  2358. CMonitorObjectMng::Instance()->GetDirectByMoMp(mo + '.' + mp, direct1, direct2);
  2359. }
  2360. else
  2361. assert(0);
  2362. pAlarmInfo->desc = szInfo;
  2363. lock_guard<mutex> lock(pService->m_mtxAlarm);
  2364. pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);
  2365. }
  2366. //send
  2367. if (bNew) //不再推送
  2368. {
  2369. rapidjson::StringBuffer buffer;
  2370. auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);
  2371. const char* output = buffer.GetString();
  2372. //CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());
  2373. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  2374. }
  2375. //save
  2376. if (bNew)
  2377. {
  2378. CString sql;
  2379. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  2380. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  2381. pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,
  2382. ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,
  2383. pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val, pAlarmInfo->sunroof);
  2384. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  2385. CSimpleLog::Error("执行语句失败" + sql);
  2386. else
  2387. {
  2388. uint8_t* pack = nullptr; int len = 0;
  2389. auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);
  2390. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  2391. //g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pAlarmInfo->type, pAlarmInfo->val, 0, 0);
  2392. delete[] pack;
  2393. pack = nullptr;
  2394. }
  2395. }
  2396. }
  2397. //保持力下降检测
  2398. if (tmNow - pService->m_lastDetectDrop > detectTimeRed)
  2399. {
  2400. pService->m_lastDetectDrop = tmNow;
  2401. time_t tt;
  2402. time(&tt);
  2403. for (auto it = (&pService->m_alarm_set)->cbegin(); it != (&pService->m_alarm_set)->cend(); it++) {
  2404. auto item = *it;
  2405. if (item.second == nullptr) continue;
  2406. if (item.second->enable == false) continue;
  2407. if (item.second->type != eZL_ALARMTYPE::RETENSION_FORCE) //这个逻辑里面只支持保持力
  2408. continue;
  2409. auto pAlarmSet = (RETENSION_FORCE_DROP*)item.second;
  2410. if ((eSuoBiPosi)item.second->no != eSuoBiPosi::SB_FIX && (eSuoBiPosi)item.second->no != eSuoBiPosi::SB_INVERT)
  2411. continue;
  2412. BOOL isRedAlarm = false;
  2413. string momp = item.second->momp;
  2414. if (momp.empty())
  2415. {
  2416. int nPos = item.first.find('.');
  2417. if (nPos == -1) continue;
  2418. int nPos2 = item.first.find('.', nPos + 1);
  2419. if (nPos2 == -1) continue;
  2420. string mo = item.first.substr(0, nPos);
  2421. string mp = item.first.substr(nPos + 1, nPos2 - nPos - 1);
  2422. momp = item.first.substr(0, nPos2);
  2423. }
  2424. auto pInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(momp);
  2425. if (pInfo == nullptr) continue;
  2426. if (pInfo->pDeivce == nullptr) continue;
  2427. if (isBetweenFiveAndFiveTen()) { //获取当天保持力值
  2428. LoadMoveData(momp, &detectTodayTime0, &detectToday0, 1);
  2429. LoadMoveData(momp, &detectTodayTime1, &detectToday1, 2);
  2430. if (detectToday0 != 3000) {
  2431. SPDLOG_INFO("[动态保持力数据判定]:{},定位保持力:{},定位保持力时间:{},目前道岔位置:{}", momp, detectToday0, (LPCSTR)(CTime(detectTodayTime0 / 1000).Format("%Y-%m-%d %H:%M:%S")), posiLast == eDaoChaPosi::DCP_FIX ? "定位" : "反位");
  2432. }
  2433. if (detectToday1 != 3000) {
  2434. SPDLOG_INFO("[动态保持力数据判定]:{},反位保持力:{},反位保持力时间:{},目前道岔位置:{}", momp, detectToday1, (LPCSTR)(CTime(detectTodayTime1 / 1000).Format("%Y-%m-%d %H:%M:%S")), posiLast == eDaoChaPosi::DCP_FIX ? "定位" : "反位");
  2435. }
  2436. }
  2437. auto pMap0 = pInfo->pDeivce->GetStatInfo(pInfo->idx, 0);
  2438. auto pMap1 = pInfo->pDeivce->GetStatInfo(pInfo->idx, 1);
  2439. std::map<time_t, tagSecondStatInfo>* pMap = nullptr;
  2440. std::map<time_t, tagSecondStatInfo>* mapRedAll = nullptr;
  2441. std::map<time_t, tagSecondStatInfo>* mapDynaAll = nullptr;
  2442. DAOCHA_POSITION posiLastDaocha = CMonitorObjectMng::Instance()->GetZZJEPOS(momp);//上一次道岔位置
  2443. if (posiLastDaocha == DAOCHA_POSITION::MP_FIX) {
  2444. posiLast = eDaoChaPosi::DCP_FIX;
  2445. }
  2446. else if (posiLastDaocha == DAOCHA_POSITION::MP_INVERT) {
  2447. posiLast = eDaoChaPosi::DCP_INVERT;
  2448. }
  2449. else {
  2450. posiLast = eDaoChaPosi::DCP_UNKNOWN;
  2451. SPDLOG_INFO("[道岔位置未知,无法进行保持力报警]:{}.{}",pInfo->mo, pInfo->mp);
  2452. }
  2453. if ((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_FIX && posiLast == eDaoChaPosi::DCP_FIX) {
  2454. if (pInfo->name1.find("定位") != -1) {
  2455. pMap = pMap0;
  2456. }
  2457. if (pInfo->name1.find("反位") != -1) {
  2458. pMap = pMap1;
  2459. }
  2460. }
  2461. else if ((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_FIX && posiLast == eDaoChaPosi::DCP_INVERT) {
  2462. isRedAlarm = true;//只对红线生效
  2463. if (pInfo->name1.find("定位") != -1) {
  2464. pMap = pMap0;
  2465. }
  2466. if (pInfo->name1.find("反位") != -1) {
  2467. pMap = pMap1;
  2468. }
  2469. }
  2470. else if ((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_INVERT && posiLast == eDaoChaPosi::DCP_INVERT) {
  2471. if (pInfo->name1.find("反位") != -1) {
  2472. pMap = pMap0;
  2473. }
  2474. if (pInfo->name1.find("定位") != -1) {
  2475. pMap = pMap1;
  2476. }
  2477. }
  2478. else if ((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_INVERT && posiLast == eDaoChaPosi::DCP_FIX) {
  2479. isRedAlarm = true;//只对红线生效
  2480. if (pInfo->name1.find("反位") != -1) {
  2481. pMap = pMap0;
  2482. }
  2483. if (pInfo->name1.find("定位") != -1) {
  2484. pMap = pMap1;
  2485. }
  2486. }
  2487. else {
  2488. continue;
  2489. }
  2490. if (pMap == nullptr || pMap->size() < 3) {
  2491. if (tmNow - detectTimeBynaTime >= detectTimeByna) {
  2492. if (std::next(it) == (&pService->m_alarm_set)->cend()) {
  2493. detectTimeBynaTime = tmNow;
  2494. }
  2495. }
  2496. continue;
  2497. }
  2498. if (pAlarmSet->tmLastCheckTime >= pMap->rbegin()->first) {
  2499. if (tmNow - detectTimeBynaTime >= detectTimeByna) {
  2500. if (std::next(it) == (&pService->m_alarm_set)->cend()) {
  2501. detectTimeBynaTime = tmNow;
  2502. }
  2503. }
  2504. continue;//不重复检测
  2505. }
  2506. pAlarmSet->tmLastCheckTime = pMap->rbegin()->first;
  2507. time_t tStartRed = pService->m_lastDetectDrop - detectTimeRed;
  2508. for (auto it = pMap->crbegin(); it != pMap->crend(); it++) {
  2509. if (it->first <= tStartRed) {
  2510. if (it == pMap->crbegin()) { //没有新数据
  2511. break;
  2512. }
  2513. if (++it != pMap->crend()) {
  2514. tStartRed = (it)->first;
  2515. }
  2516. else {
  2517. tStartRed = (--it)->first;
  2518. }
  2519. break;
  2520. }
  2521. }
  2522. if (tStartRed == (pService->m_lastDetectDrop - detectTimeRed) && tStartRed <= pMap->begin()->first) {
  2523. tStartRed = pMap->begin()->first;
  2524. }
  2525. mapRedAll = new std::map<time_t, tagSecondStatInfo>((*pMap).find(tStartRed), (*pMap).end());
  2526. if (mapRedAll == nullptr) {
  2527. break;
  2528. }
  2529. time_t redAlarmAll = 0;
  2530. time_t redAlarmRecoveryAll = 0;
  2531. for (auto itR = mapRedAll->cbegin(); itR != mapRedAll->cend(); itR++) {
  2532. if (std::abs(pAlarmSet->dw_alarm_low_drop) > 100000) {
  2533. break;
  2534. }
  2535. auto it0 = itR;
  2536. auto it1 = ++itR;
  2537. if (it1 == mapRedAll->cend()) {
  2538. break;
  2539. }
  2540. auto it2 = ++itR;
  2541. if (it2 == mapRedAll->cend()) {
  2542. break;
  2543. }
  2544. int nMinVal = it2->second.min_val;
  2545. time_t tMinTime = it2->second.min_time;
  2546. if (it0->second.min_val < pAlarmSet->dw_alarm_low_drop &&
  2547. it1->second.min_val < pAlarmSet->dw_alarm_low_drop &&
  2548. it2->second.min_val < pAlarmSet->dw_alarm_low_drop) {
  2549. if (redAlarmAll ==0) {
  2550. alarmStatus = 1;
  2551. redAlarmAll = tMinTime;
  2552. SPDLOG_INFO("[最低值红线保持力报警2]:{}.{},上一包发生时间:{},报警值:{},上两包发生时间:{},报警值:{},参考值:{}",
  2553. pInfo->mo, pInfo->mp, (LPCSTR)(CTime(it1->second.min_time / 1000).Format("%Y-%m-%d %H:%M:%S")), it1->second.min_val, (LPCSTR)(CTime(it0->second.min_time / 1000).Format("%Y-%m-%d %H:%M:%S")), it0->second.min_val, detectToday01);
  2554. JudgeAlarm(pService, pAlarmSet, tMinTime, nMinVal, (eSuoBiPosi)pAlarmSet->no, pInfo->mo, pInfo->mp, pInfo, detectToday01, posiLast, isRedAlarm, alarmStatus);
  2555. }
  2556. }else {
  2557. if((redAlarmAll > redAlarmRecoveryAll) || redAlarmRecoveryAll==0){
  2558. alarmStatus = 31;
  2559. redAlarmRecoveryAll = tMinTime;
  2560. JudgeAlarm(pService, pAlarmSet, tMinTime, nMinVal, (eSuoBiPosi)pAlarmSet->no, pInfo->mo, pInfo->mp, pInfo, detectToday01, posiLast, isRedAlarm, alarmStatus);
  2561. }
  2562. if (redAlarmAll < redAlarmRecoveryAll && redAlarmRecoveryAll != 0 && redAlarmAll != 0) {
  2563. break;
  2564. }
  2565. }
  2566. itR--;
  2567. itR--;
  2568. }
  2569. //动态保持力判定
  2570. if (pAlarmSet->is_page_dyna && tmNow - detectTimeBynaTime > detectTimeByna) {
  2571. if (!(pAlarmSet->alarm_low_percent >= 5 && pAlarmSet->alarm_low_percent <= 95)) {
  2572. break;
  2573. }
  2574. if (!(pAlarmSet->alarm_high_percent >= 5 && pAlarmSet->alarm_high_percent <= 95)) {
  2575. break;
  2576. }
  2577. if (std::next(it)== (&pService->m_alarm_set)->cend()) {
  2578. detectTimeBynaTime = tmNow;
  2579. }
  2580. time_t tStartByna = detectTimeBynaTime - detectTimeByna;
  2581. for (auto it = pMap->crbegin(); it != pMap->crend(); it++) {
  2582. if (it->first <= tStartByna) {
  2583. if (it == pMap->crbegin()) { //没有新数据
  2584. break;
  2585. }
  2586. if (++it != pMap->crend()) {
  2587. tStartByna = (it)->first;
  2588. }
  2589. else {
  2590. tStartByna = (--it)->first;
  2591. }
  2592. break;
  2593. }
  2594. }
  2595. if (tStartByna == (detectTimeBynaTime - detectTimeByna) && tStartByna < pMap->begin()->first) {
  2596. tStartByna = pMap->begin()->first;
  2597. }
  2598. mapDynaAll = new std::map<time_t, tagSecondStatInfo>((*pMap).find(tStartByna), (*pMap).end());
  2599. if (mapDynaAll == nullptr) {
  2600. break;
  2601. }
  2602. auto pMompInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(momp);
  2603. pMompInfo->detectToday0 = detectToday0;
  2604. pMompInfo->detectTodayTime0 = detectTodayTime0;
  2605. pMompInfo->detectToday1 = detectToday1;
  2606. pMompInfo->detectTodayTime1 = detectTodayTime1;
  2607. alarmStatus = 2;
  2608. if (posiLast == eDaoChaPosi::DCP_FIX) {
  2609. detectToday01 = detectToday0;
  2610. }
  2611. else if (posiLast == eDaoChaPosi::DCP_INVERT) {
  2612. detectToday01 = detectToday1;
  2613. }
  2614. if (!(detectToday01 < 40000 && detectToday01 > 3000)) {
  2615. break;
  2616. }
  2617. int redAlarmRecovery = false;
  2618. time_t bynaAlarmAll = 0;
  2619. time_t bynaAlarmRecoveryAll = 0;
  2620. for (auto itD = mapDynaAll->cbegin(); itD != mapDynaAll->cend(); itD++) {
  2621. auto it0 = itD;
  2622. auto it1 = ++itD;
  2623. if (it1 == mapDynaAll->cend()) {
  2624. break;
  2625. }
  2626. auto it2 = ++itD;
  2627. if (it2 == mapDynaAll->cend()) {
  2628. break;
  2629. }
  2630. int nMinVal = it0->second.min_val;
  2631. time_t tMinTime = it0->second.min_time;
  2632. int nRatio0 = nMinVal * 100 / detectToday01;
  2633. int nRatio1 = it1->second.min_val * 100 / detectToday01;
  2634. int nRatio2 = it2->second.min_val * 100 / detectToday01;
  2635. if (it0->second.min_val < pAlarmSet->dw_alarm_low_drop &&
  2636. it1->second.min_val < pAlarmSet->dw_alarm_low_drop &&
  2637. it2->second.min_val < pAlarmSet->dw_alarm_low_drop) {
  2638. break;
  2639. }
  2640. //下降20%或上升40% 进行预警
  2641. if ((std::abs(nRatio0) <= (100 - pAlarmSet->alarm_low_percent) &&
  2642. std::abs(nRatio1) <= (100 - pAlarmSet->alarm_low_percent) &&
  2643. std::abs(nRatio2) <= (100 - pAlarmSet->alarm_low_percent))||
  2644. (std::abs(nRatio0) >= (100 + pAlarmSet->alarm_high_percent) &&
  2645. std::abs(nRatio1) >= (100 + pAlarmSet->alarm_high_percent) &&
  2646. std::abs(nRatio2) >= (100 + pAlarmSet->alarm_high_percent))) {
  2647. if (bynaAlarmAll==0 && !isRedAlarm) {
  2648. alarmStatus = 2;
  2649. SPDLOG_INFO("[动态保持力报警]:{}.{},上一包发生时间:{},报警值:{},上两包发生时间:{},报警值:{}",
  2650. pInfo->mo, pInfo->mp, (LPCSTR)(CTime(it1->second.min_time / 1000).Format("%Y-%m-%d %H:%M:%S")), it1->second.min_val, (LPCSTR)(CTime(it2->second.min_time / 1000).Format("%Y-%m-%d %H:%M:%S")), it2->second.min_val);
  2651. JudgeAlarm(pService, pAlarmSet, tMinTime, nMinVal, (eSuoBiPosi)pAlarmSet->no, pInfo->mo, pInfo->mp, pInfo, detectToday01, posiLast, isRedAlarm, alarmStatus);
  2652. bynaAlarmAll = tMinTime;
  2653. }
  2654. }
  2655. else {
  2656. if (((bynaAlarmAll > bynaAlarmRecoveryAll) || bynaAlarmRecoveryAll == 0)&& !isRedAlarm) {
  2657. alarmStatus = 30;
  2658. bynaAlarmRecoveryAll = tMinTime;
  2659. JudgeAlarm(pService, pAlarmSet, tMinTime, nMinVal, (eSuoBiPosi)pAlarmSet->no, pInfo->mo, pInfo->mp, pInfo, detectToday01, posiLast, isRedAlarm, alarmStatus);
  2660. }
  2661. if (bynaAlarmAll < bynaAlarmRecoveryAll && bynaAlarmRecoveryAll!=0 && bynaAlarmAll !=0) {
  2662. break;
  2663. }
  2664. }
  2665. itD--;
  2666. itD--;
  2667. }
  2668. }
  2669. delete mapRedAll;
  2670. delete mapDynaAll;
  2671. }
  2672. //清理无效位置
  2673. CMonitorObjectMng::Instance()->ClearZZJHistroyEPOS(tt);
  2674. //四个小时未确认的保持力报警需要再次推送
  2675. std::map<int, int> m_lstUnConfirmAlarmTemp;
  2676. if ((tmNow - detectFourAlarmTime) >= detectFourAlarm && detectFourAlarm>0) {
  2677. detectFourAlarmTime = tmNow;
  2678. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  2679. {
  2680. if (alarm->type == eZL_ALARMTYPE::RETENSION_FORCE && alarm->ack_result == 0 && alarm->level == 1
  2681. &&((tmNow - SystemTimeToTimeT(alarm->time)) >= detectFourAlarm))
  2682. {
  2683. auto find = m_lstUnConfirmAlarmTemp.find(alarm->id);
  2684. if (find == m_lstUnConfirmAlarmTemp.end()) {
  2685. m_lstUnConfirmAlarmTemp[alarm->id] = 1;
  2686. }
  2687. else {
  2688. find->second++;
  2689. }
  2690. }
  2691. }
  2692. for (const auto& alarmTemp : m_lstUnConfirmAlarmTemp)
  2693. {
  2694. for (const auto& alarm : pService->m_lstUnConfirmAlarm)
  2695. {
  2696. if (alarmTemp.first==alarm->id && alarmTemp.second<5)
  2697. {
  2698. rapidjson::StringBuffer buffer;
  2699. auto ret = AlarmInfo2Pack(alarm, buffer);
  2700. const char* output = buffer.GetString();
  2701. CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  2702. pService->m_lstUnConfirmAlarm.push_back(alarm);
  2703. break;
  2704. }
  2705. }
  2706. }
  2707. }
  2708. }
  2709. } while (pService->m_bWork);
  2710. if (bLock)
  2711. {
  2712. g_lockSync.Unlock();
  2713. bLock = false;
  2714. }
  2715. }
  2716. typedef struct tagMoMp
  2717. {
  2718. string mo;
  2719. string mp;
  2720. uint8_t no; //传感器的序号
  2721. tagMoMp(string a, string b)
  2722. {
  2723. mo = a;
  2724. mp = b;
  2725. }
  2726. tagMoMp(uint8_t a)
  2727. {
  2728. no = a;
  2729. }
  2730. };
  2731. typedef struct offline_info
  2732. {
  2733. string imei;
  2734. CTime time;
  2735. uint8_t idx = 0;
  2736. std::vector<tagMoMp> vct;
  2737. offline_info(string a, CTime b)
  2738. {
  2739. imei = a;
  2740. time = b;
  2741. }
  2742. offline_info(string a, CTime b, uint8_t c, uint8_t d)
  2743. {
  2744. imei = a;
  2745. time = b;
  2746. idx = c;
  2747. vct.push_back(tagMoMp(d));
  2748. }
  2749. };
  2750. void CResistAlarmMng::ThreadProcDevice(DWORD_PTR param)
  2751. {
  2752. auto pService = (CResistAlarmMng*)param;
  2753. this_thread::sleep_for(chrono::seconds(2));
  2754. static CTimeSpan offline_time(0, 0, 5, 0); //设备离线时间暂定5分钟
  2755. static CTimeSpan offline_limit(30, 0, 0, 0);
  2756. bool bLock = false;
  2757. do
  2758. {
  2759. if (bLock)
  2760. {
  2761. g_lockSync.Unlock();
  2762. bLock = false;
  2763. }
  2764. for (int i = 0; i < 30; i++)
  2765. {
  2766. if (false == pService->m_bWork) break;
  2767. Sleep(1000);
  2768. }
  2769. g_lockSync.ReadLock();
  2770. bLock = true;
  2771. CTime ctNow = CTime::GetCurrentTime();
  2772. //离线设备
  2773. {
  2774. auto& pMap = CMonitorObjectMng::Instance()->m_mapMoMpInfo;
  2775. for (auto& it : pMap)
  2776. {
  2777. auto& pInfo = it.second;
  2778. if (pInfo == nullptr) continue;
  2779. bool bAlarm = false;
  2780. if (!pInfo->pDeivce) continue;
  2781. const auto pDevice = pInfo->pDeivce;
  2782. if (pDevice->m_ctUpdateTime.GetTime() == 0)
  2783. continue;
  2784. if (ctNow - pDevice->m_ctUpdateTime > offline_time)
  2785. bAlarm = true;
  2786. else if (pInfo->bFirstOnline)
  2787. {//第一次上线发送一次315离线报警恢复 因铁大未作报警同步
  2788. pInfo->bFirstOnline = false;
  2789. g_p315ClientManager->GetTcpClient()->SendAlarmData(pInfo->zzjno, 2, pDevice->m_ctUpdateTime.GetTime(), pDevice->m_ctUpdateTime.GetTime(), eZL_ALARMTYPE::EQUIP_OFFLINE,
  2790. eDaoChaPosi::DCP_UNKNOWN, 1, eLowHigh::LH_UNKNOWN, TIEDA_ACQ_VALUE(INT_MIN), TIEDA_ACQ_VALUE(INT_MIN), 0);
  2791. SPDLOG_INFO("{}第一次上线发送一次315离线报警恢复", it.first);
  2792. }
  2793. ALARM_INFO* pAlarmInfo = nullptr;
  2794. bool bNew = false;
  2795. auto ctAlarmTime = ctNow;
  2796. {
  2797. std::lock_guard<mutex> lock(pService->m_mtxAlarm);
  2798. for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
  2799. {
  2800. auto pAlarm = *it;
  2801. if (pAlarm->type == eZL_ALARMTYPE::EQUIP_OFFLINE && pAlarm->recoveryTime.wYear < 2000 &&
  2802. pAlarm->mo.compare(pInfo->mo) == 0 && pAlarm->mp.compare(pInfo->mp) == 0)
  2803. {
  2804. pAlarmInfo = pAlarm;
  2805. if (bAlarm) //连续报警
  2806. {
  2807. break;
  2808. }
  2809. else
  2810. {
  2811. //恢复报警
  2812. //更新数据库
  2813. if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();
  2814. string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
  2815. CString sql;
  2816. sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
  2817. CDBConnectPool::Instance()->DBExecuteSQL(sql);
  2818. //315上送
  2819. g_p315ClientManager->GetTcpClient()->SendAlarmData(pInfo->zzjno, 2, CTime(pAlarm->time).GetTime(), ctAlarmTime.GetTime(), pAlarm->type,
  2820. eDaoChaPosi::DCP_UNKNOWN, pAlarm->level, eLowHigh::LH_UNKNOWN, TIEDA_ACQ_VALUE(INT_MIN), TIEDA_ACQ_VALUE(INT_MIN), 0);
  2821. it = pService->m_lstUnConfirmAlarm.erase(it);
  2822. continue;
  2823. /*if (pAlarm->ack_result == 1)
  2824. {
  2825. it = pService->m_lstUnConfirmAlarm.erase(it);
  2826. continue;
  2827. }
  2828. else
  2829. {
  2830. ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);
  2831. }*/
  2832. }
  2833. }
  2834. ++it;
  2835. }
  2836. }
  2837. if (bAlarm == false) continue;
  2838. if (pAlarmInfo == nullptr)
  2839. {
  2840. bNew = true;
  2841. pAlarmInfo = new ALARM_INFO;
  2842. pAlarmInfo->event_id = hjfunc_GetGUID();
  2843. pAlarmInfo->id = ++pService->m_nAlarmID;
  2844. pAlarmInfo->level = 1;
  2845. pAlarmInfo->mo = pInfo->mo;
  2846. pAlarmInfo->mp = pInfo->mp;
  2847. pAlarmInfo->no = -1;
  2848. ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);
  2849. //pAlarmInfo->time.wMilliseconds = alarm_time % 1000;
  2850. pAlarmInfo->type = eZL_ALARMTYPE::EQUIP_OFFLINE;
  2851. pAlarmInfo->val = 0;
  2852. pAlarmInfo->zzjno = pInfo->zzjno;
  2853. char szInfo[200];
  2854. sprintf_s(szInfo, sizeof(szInfo), "设备离线时间:%s", (LPCSTR)(pDevice->m_ctUpdateTime.Format("%Y-%m-%d %H:%M:%S")));
  2855. pAlarmInfo->desc = szInfo;
  2856. pAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pAlarmInfo->time);
  2857. lock_guard<mutex> lock(pService->m_mtxAlarm);
  2858. pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);
  2859. }
  2860. //send
  2861. if (bNew) //不再推送
  2862. {
  2863. rapidjson::StringBuffer buffer;
  2864. auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);
  2865. const char* output = buffer.GetString();
  2866. //CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());
  2867. }
  2868. //save
  2869. if (bNew)
  2870. {
  2871. CString sql;
  2872. sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
  2873. "VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
  2874. pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,
  2875. (LPCSTR)(ctAlarmTime.Format("%Y-%m-%d %H:%M:%S")), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,
  2876. pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val, pAlarmInfo->sunroof);
  2877. if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
  2878. CSimpleLog::Error("执行语句失败" + sql);
  2879. else
  2880. {
  2881. uint8_t* pack = nullptr; int len = 0;
  2882. auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);
  2883. if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
  2884. g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, pAlarmInfo->type, eDaoChaPosi::DCP_UNKNOWN, 1, eLowHigh::LH_UNKNOWN,
  2885. TIEDA_ACQ_VALUE(INT_MIN), TIEDA_ACQ_VALUE(INT_MIN), 0);
  2886. delete[] pack;
  2887. pack = nullptr;
  2888. }
  2889. }
  2890. }
  2891. }
  2892. } while (pService->m_bWork);
  2893. if (bLock)
  2894. {
  2895. g_lockSync.Unlock();
  2896. bLock = false;
  2897. }
  2898. }
  2899. void CResistAlarmMng::ThreadProcMove(DWORD_PTR param)
  2900. {
  2901. auto pService = (CResistAlarmMng*)param;
  2902. Sleep(2000);
  2903. time_t tmNow;
  2904. auto strIniPath = CSimpleLog::GetAppDir() + "DataServices.ini";
  2905. bool bLock = false;
  2906. do
  2907. {
  2908. if (bLock)
  2909. {
  2910. g_lockSync.Unlock();
  2911. bLock = false;
  2912. }
  2913. Sleep(800);
  2914. time(&tmNow);
  2915. if (pService->m_lastDetectMove > tmNow)
  2916. {
  2917. SPDLOG_INFO("时间有跳变");
  2918. pService->m_lastDetectMove = tmNow;
  2919. }
  2920. //10秒归档一次 扳动判断
  2921. if (tmNow - pService->m_lastDetectMove < 10)
  2922. continue;
  2923. g_lockSync.ReadLock();
  2924. bLock = true;
  2925. pService->m_lastDetectMove = tmNow;
  2926. char szTemp[100] = { 0 };
  2927. ::GetPrivateProfileString("SET", "momp", "", szTemp, sizeof(szTemp), strIniPath);
  2928. g_strMoMp = szTemp;
  2929. //SPDLOG_INFO("扳动判断:{}", g_strMoMp);
  2930. auto& mapDevice = CDeviceMng::Instance()->m_map_devices;
  2931. for (auto& it : mapDevice)
  2932. {
  2933. auto pDevice = it.second;
  2934. for (auto i = 0; i < 3; i++)
  2935. {
  2936. string mo, mp;
  2937. if (FALSE == CMonitorObjectMng::Instance()->IMEI2MOMP(pDevice->imei, i, mo, mp))
  2938. {
  2939. //CSimpleLog::Error(fmt::format("IMEI2MOMP fail. imei:{}, idx:{}, {}:{}", pDevice->imei, i, __FILE__, __LINE__).c_str());
  2940. continue; //没有绑定返回
  2941. }
  2942. std::map<time_t, tagSecondStatInfo> map0, map1, map2;
  2943. std::map<time_t, int>* mapData[3] = { 0 };
  2944. if (i == 0)
  2945. {
  2946. if (tmNow - pDevice->GetUpdateTime(0) < 3) continue; //3秒钟 无数据上送 开始判断
  2947. else if (tmNow - pDevice->m_tmMoveDetectTime0 < 10) continue; //距离上次应大于10秒
  2948. else if (pDevice->m_mapSecondStatInfo00.size() == 0) continue;
  2949. const auto tCheck = pDevice->m_tmMoveDetectTime0;
  2950. lock_guard<mutex> lock(pDevice->m_mtx);
  2951. for (auto it = pDevice->m_mapSecondStatInfo00.rbegin(); it != pDevice->m_mapSecondStatInfo00.rend(); it++)
  2952. {
  2953. if (it->first < tCheck) break;
  2954. map0.insert(*it);
  2955. }
  2956. for (auto it = pDevice->m_mapSecondStatInfo01.rbegin(); it != pDevice->m_mapSecondStatInfo01.rend(); it++)
  2957. {
  2958. if (it->first < tCheck) break;
  2959. map1.insert(*it);
  2960. }
  2961. for (auto it = pDevice->m_mapSecondStatInfo02.rbegin(); it != pDevice->m_mapSecondStatInfo02.rend(); it++)
  2962. {
  2963. if (it->first < tCheck) break;
  2964. map2.insert(*it);
  2965. }
  2966. if (map2.size() > 2)
  2967. { //拷贝原始数据
  2968. time_t tStart = 0;
  2969. std::map<time_t, int>::iterator itStart2;
  2970. if (tCheck)
  2971. {
  2972. for (auto ii = tCheck; ii < tmNow; ii++)
  2973. {
  2974. itStart2 = pDevice->map_resist_idx02.find(ii*1000);
  2975. if (itStart2 != pDevice->map_resist_idx02.end())
  2976. {
  2977. tStart = ii*1000;
  2978. break;
  2979. }
  2980. }
  2981. }
  2982. else
  2983. {
  2984. itStart2 = pDevice->map_resist_idx02.begin();
  2985. tStart = itStart2->first;
  2986. }
  2987. if (tStart)
  2988. {
  2989. mapData[0] = new std::map<time_t, int>(pDevice->map_resist_idx00.find(tStart), pDevice->map_resist_idx00.end());
  2990. mapData[1] = new std::map<time_t, int>(pDevice->map_resist_idx01.find(tStart), pDevice->map_resist_idx01.end());
  2991. mapData[2] = new std::map<time_t, int>(itStart2, pDevice->map_resist_idx02.end());
  2992. }
  2993. else
  2994. ASSERT(0);
  2995. }
  2996. pDevice->m_tmMoveDetectTime0 = tmNow;
  2997. }
  2998. else if (i == 1)
  2999. {
  3000. if (tmNow - pDevice->GetUpdateTime(1) < 3) continue; //3秒钟 无数据上送 开始判断
  3001. else if (tmNow - pDevice->m_tmMoveDetectTime1 < 10) continue; //距离上次应大于10秒
  3002. else if (pDevice->m_mapSecondStatInfo10.size() == 0) continue;
  3003. const auto tCheck = pDevice->m_tmMoveDetectTime1;
  3004. lock_guard<mutex> lock(pDevice->m_mtx);
  3005. for (auto it = pDevice->m_mapSecondStatInfo10.rbegin(); it != pDevice->m_mapSecondStatInfo10.rend(); it++)
  3006. {
  3007. if (it->first < tCheck) break;
  3008. map0.insert(*it);
  3009. }
  3010. for (auto it = pDevice->m_mapSecondStatInfo11.rbegin(); it != pDevice->m_mapSecondStatInfo11.rend(); it++)
  3011. {
  3012. if (it->first < tCheck) break;
  3013. map1.insert(*it);
  3014. }
  3015. for (auto it = pDevice->m_mapSecondStatInfo12.rbegin(); it != pDevice->m_mapSecondStatInfo12.rend(); it++)
  3016. {
  3017. if (it->first < tCheck) break;
  3018. map2.insert(*it);
  3019. }
  3020. if (map2.size() > 2)
  3021. { //拷贝原始数据
  3022. time_t tStart = 0;
  3023. std::map<time_t, int>::iterator itStart2;
  3024. if (tCheck)
  3025. {
  3026. for (auto ii = tCheck; ii < tmNow; ii++)
  3027. {
  3028. itStart2 = pDevice->map_resist_idx12.find(ii*1000);
  3029. if (itStart2 != pDevice->map_resist_idx12.end())
  3030. {
  3031. tStart = ii*1000;
  3032. break;
  3033. }
  3034. }
  3035. }
  3036. else
  3037. {
  3038. itStart2 = pDevice->map_resist_idx12.begin();
  3039. tStart = itStart2->first;
  3040. }
  3041. if (tStart)
  3042. {
  3043. mapData[0] = new std::map<time_t, int>(pDevice->map_resist_idx10.find(tStart), pDevice->map_resist_idx10.end());
  3044. mapData[1] = new std::map<time_t, int>(pDevice->map_resist_idx11.find(tStart), pDevice->map_resist_idx11.end());
  3045. mapData[2] = new std::map<time_t, int>(itStart2, pDevice->map_resist_idx12.end());
  3046. }
  3047. else
  3048. ASSERT(0);
  3049. }
  3050. pDevice->m_tmMoveDetectTime1 = tmNow;
  3051. }
  3052. else
  3053. {
  3054. if (tmNow - pDevice->GetUpdateTime(2) < 3) continue; //3秒钟 无数据上送 开始判断
  3055. else if (tmNow - pDevice->m_tmMoveDetectTime2 < 10) continue; //距离上次应大于10秒
  3056. else if (pDevice->m_mapSecondStatInfo20.size() == 0) continue;
  3057. //else if (pDevice->m_mapSecondStatInfo20.rbegin()->second.dif_val > 100) continue; //最后值需要稳定 2024年5月31日移除
  3058. //else if (pDevice->m_mapSecondStatInfo21.rbegin()->second.dif_val > 100) continue;
  3059. //else if (pDevice->m_mapSecondStatInfo22.rbegin()->second.dif_val > 100) continue;
  3060. const auto tCheck = pDevice->m_tmMoveDetectTime2;
  3061. lock_guard<mutex> lock(pDevice->m_mtx);
  3062. for (auto it = pDevice->m_mapSecondStatInfo20.rbegin(); it != pDevice->m_mapSecondStatInfo20.rend(); it++)
  3063. {
  3064. //RACE("20: first:%s check:%s\r\n", CTime(it->first).Format("%Y-%m-%d %H:%M:%S"), CTime(tCheck).Format("%Y-%m-%d %H:%M:%S"));
  3065. if (it->first < tCheck) break;
  3066. map0.insert(*it);
  3067. }
  3068. for (auto it = pDevice->m_mapSecondStatInfo21.rbegin(); it != pDevice->m_mapSecondStatInfo21.rend(); it++)
  3069. {
  3070. //TRACE("21: first:%s check:%s\r\n", CTime(it->first).Format("%Y-%m-%d %H:%M:%S"), CTime(tCheck).Format("%Y-%m-%d %H:%M:%S"));
  3071. if (it->first < tCheck) break;
  3072. map1.insert(*it);
  3073. }
  3074. for (auto it = pDevice->m_mapSecondStatInfo22.rbegin(); it != pDevice->m_mapSecondStatInfo22.rend(); it++)
  3075. {
  3076. //TRACE("22: first:%s check:%s\r\n", CTime(it->first).Format("%Y-%m-%d %H:%M:%S"), CTime(tCheck).Format("%Y-%m-%d %H:%M:%S"));
  3077. if (it->first < tCheck) break;
  3078. map2.insert(*it);
  3079. }
  3080. if (map2.size() > 2)
  3081. { //拷贝原始数据
  3082. time_t tStart = 0;
  3083. std::map<time_t, int>::iterator itStart2;
  3084. if (tCheck)
  3085. {
  3086. for (auto ii = tCheck; ii < tmNow; ii++)
  3087. {
  3088. itStart2 = pDevice->map_resist_idx22.find(ii*1000);
  3089. if (itStart2 != pDevice->map_resist_idx22.end())
  3090. {
  3091. tStart = ii*1000;
  3092. break;
  3093. }
  3094. }
  3095. }
  3096. else
  3097. {
  3098. itStart2 = pDevice->map_resist_idx22.begin();
  3099. tStart = itStart2->first;
  3100. }
  3101. if (tStart)
  3102. {
  3103. mapData[0] = new std::map<time_t, int>(pDevice->map_resist_idx20.find(tStart), pDevice->map_resist_idx20.end());
  3104. mapData[1] = new std::map<time_t, int>(pDevice->map_resist_idx21.find(tStart), pDevice->map_resist_idx21.end());
  3105. mapData[2] = new std::map<time_t, int>(itStart2, pDevice->map_resist_idx22.end());
  3106. }
  3107. else
  3108. assert(0);
  3109. }
  3110. TRACE("update: m_tmMoveDetectTime2:%s tmNow:%s size:%d\r\n", CTime(pDevice->m_tmMoveDetectTime2).Format("%Y-%m-%d %H:%M:%S"), CTime(tmNow).Format("%Y-%m-%d %H:%M:%S"), map2.size());
  3111. pDevice->m_tmMoveDetectTime2 = tmNow;
  3112. }
  3113. if (map2.size() <= 2) continue;
  3114. if (!mapData[0] && !mapData[1] && !mapData[2]) continue;
  3115. if (mapData[0]->size() != mapData[1]->size() || mapData[1]->size() != mapData[2]->size()) continue;
  3116. SPDLOG_INFO("扳动判断数据{}.{} map:{} 0:{} 1:{} 2:{}", mo, mp, map2.size(), mapData[0]->size(), mapData[1]->size(), mapData[2]->size());
  3117. list<CONVERT_RESIST> lstResit2; //转换力数据
  3118. list<PASS_RESIST> lstPass; //过车数据
  3119. list<FRICTION_RESIST> lstFriction; //摩擦力数据
  3120. std::map<time_t, int64_t> maxlock0, maxlock1;//锁闭力 前面时间戳, 后面 高4位显示值, 低4位报警值
  3121. std::map<time_t, int64_t> retentionforce0, retentionforce1; //保持力 时间戳, 高4位显示值, 低4位报警值
  3122. mg_per_session_data::GetMaxResistNew(map2, lstResit2, mo, mp);
  3123. if (g_bDataCompression)
  3124. {
  3125. SPDLOG_INFO("[过车判断]{}.{} 开始过车判断 size:{}", mo, mp, map0.size());
  3126. mg_per_session_data::GetPassNew(map0, mapData[0], map1, mapData[1], mo, mp, &lstPass);
  3127. SPDLOG_INFO("[过车判断]{}.{} 结束过车判断 size:{} pass:{}", mo, mp, map0.size(), lstPass.size());
  3128. //过车过滤
  3129. for (auto& item : lstPass)
  3130. {
  3131. for (auto it = lstResit2.begin(); it != lstResit2.end();)
  3132. {
  3133. if (it->tmStart * 1000 <= item.show_time && item.show_time <= (it->tmEnd + 1) * 1000)
  3134. {
  3135. it = lstResit2.erase(it);
  3136. break;
  3137. }
  3138. ++it;
  3139. }
  3140. }
  3141. }
  3142. //摩擦力过滤
  3143. for (auto it = lstResit2.begin(); it != lstResit2.end();)
  3144. {
  3145. int first_value = 0, last_value = 0;
  3146. auto ii = map2.find(it->tmStart);
  3147. ASSERT(ii != map2.end());
  3148. first_value = ii->second.first_val;
  3149. ii = map2.find(it->tmEnd);
  3150. if (ii == map2.end())
  3151. ii = map2.find(it->tmEnd - 1);
  3152. ASSERT(ii != map2.end());
  3153. last_value = ii->second.end_val;
  3154. auto dif = last_value - first_value;
  3155. auto strLog = fmt::format("[摩擦力判断]{} first:{} last:{} dif:{}",
  3156. CTime(it->time / 1000).Format("%Y-%m-%d %H:%M:%S"), first_value, last_value, dif);
  3157. if (dif > 1000 || dif < -1000)
  3158. {
  3159. SPDLOG_INFO(strLog);
  3160. if (it->tmEnd - it->tmStart >= 4)
  3161. {
  3162. FRICTION_RESIST info;
  3163. info.peak_time = it->time;
  3164. info.peak_val = it->val;
  3165. info.show_time = ii->first * 1000;
  3166. info.show_val = dif; //稳态值显示差值
  3167. info.curr_val = last_value; //显示的位置
  3168. info.tmStart = it->tmStart;
  3169. info.tmEnd = it->tmEnd;
  3170. info.t = strLog;
  3171. info.bUpOrDown = it->bUpOrDown;
  3172. lstFriction.emplace_back(info);
  3173. }
  3174. it = lstResit2.erase(it);
  3175. }
  3176. else
  3177. ++it;
  3178. }
  3179. if (lstResit2.size())
  3180. {
  3181. mg_per_session_data::GetMaxLockNew(map0, lstResit2, maxlock0, retentionforce0);
  3182. mg_per_session_data::GetMaxLockNew(map1, lstResit2, maxlock1, retentionforce1);
  3183. SPDLOG_INFO("[转换阻力][{}:{}] lock0:{} lock1:{}, resist2:{}", mo, mp, maxlock0.size(), maxlock1.size(), lstResit2.size());
  3184. }
  3185. auto pMompInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(mo + "." + mp);
  3186. ASSERT(pMompInfo);
  3187. //扳动处理逻辑
  3188. if (lstResit2.size())
  3189. {
  3190. //获取报警设置
  3191. //转换阻力报警设置项
  3192. auto pConvertResistOverLimitInfo =
  3193. (CONVERT_RESIST_OVER_LIMIT*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::CONVERT_LIMIT);
  3194. //定位锁闭力报警设置项
  3195. auto pFixSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);
  3196. //反位
  3197. auto pInvertSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);
  3198. //定位保持力报警设置项
  3199. auto pFixConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::RETENSION_FORCE);
  3200. if (pFixConstRetensionForceWaveInfo == nullptr)//默认开启
  3201. {
  3202. //ASSERT(FALSE);
  3203. //pFixConstRetensionForceWaveInfo = new RETENSION_FORCE_DROP;
  3204. ///pService->Insert(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pFixConstRetensionForceWaveInfo);
  3205. }
  3206. //反位
  3207. auto pInvertConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::RETENSION_FORCE);
  3208. if (pInvertConstRetensionForceWaveInfo == nullptr)//默认开启
  3209. {
  3210. //ASSERT(FALSE);
  3211. //pInvertConstRetensionForceWaveInfo = new RETENSION_FORCE_DROP;
  3212. //pService->Insert(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pInvertConstRetensionForceWaveInfo);
  3213. }
  3214. //获取报警设置 end
  3215. eDaoChaPosi posiLock0;
  3216. if (pMompInfo->name1.find("定位") != -1)
  3217. {
  3218. posiLock0 = eDaoChaPosi::DCP_FIX;
  3219. for (auto& it : maxlock0)
  3220. {
  3221. int show_val = (it.second >> 32);
  3222. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,
  3223. (int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));
  3224. JudgeAlarm(pService, pFixSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno);
  3225. }
  3226. for (auto& it : retentionforce0)
  3227. {
  3228. int show_val = (int)it.second;
  3229. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,
  3230. (int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
  3231. JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo,pMompInfo->detectToday0, posiLock0, false, false);
  3232. }
  3233. for (auto& it : maxlock1)
  3234. {
  3235. int show_val = (it.second >> 32);
  3236. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,
  3237. (int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));
  3238. JudgeAlarm(pService, pInvertSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo->zzjno);
  3239. }
  3240. for (auto& it : retentionforce1)
  3241. {
  3242. int show_val = (int)it.second;
  3243. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,
  3244. (int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
  3245. JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo, pMompInfo->detectToday1, posiLock0, false, false);
  3246. }
  3247. }
  3248. else
  3249. {
  3250. posiLock0 = eDaoChaPosi::DCP_INVERT;
  3251. for (auto& it : maxlock0)
  3252. {
  3253. int show_val = (it.second >> 32);
  3254. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,
  3255. (uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));
  3256. JudgeAlarm(pService, pInvertSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo->zzjno);
  3257. }
  3258. for (auto& it : retentionforce0)
  3259. {
  3260. int show_val = (int)it.second;
  3261. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,
  3262. (uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
  3263. JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo, pMompInfo->detectToday0, posiLock0, false, false);
  3264. }
  3265. for (auto& it : maxlock1)
  3266. {
  3267. int show_val = (it.second >> 32);
  3268. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,
  3269. (uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));
  3270. JudgeAlarm(pService, pFixSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno);
  3271. }
  3272. for (auto& it : retentionforce1)
  3273. {
  3274. int show_val = (int)it.second;
  3275. CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,
  3276. (uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
  3277. JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo,pMompInfo->detectToday1, posiLock0, false, false);
  3278. }
  3279. }
  3280. auto mg_315_server = g_p315ClientManager->GetTcpClient();
  3281. //SPDLOG_INFO("扳动判断数据{}.{} 转换力", mo, mp);
  3282. auto eqpno = CMonitorObjectMng::Instance()->GetZZJNO(mo + "." + mp);
  3283. for (auto& it : lstResit2)
  3284. {
  3285. //auto it_start0 = mapData[0]->find(it.tmStart * 1000);
  3286. //auto it_end0 = mapData[0]->find(it.tmEnd * 1000);
  3287. //auto it_start1 = mapData[1]->find(it.tmStart * 1000);
  3288. //auto it_end1 = mapData[1]->find(it.tmEnd * 1000);
  3289. //auto it_start2 = mapData[2]->find(it.tmStart * 1000);
  3290. //auto it_end2 = mapData[2]->find(it.tmEnd * 1000);
  3291. eDaoChaPosi posi = eDaoChaPosi::DCP_UNKNOWN;
  3292. if (posi == eDaoChaPosi::DCP_FIX2INVERT)
  3293. {
  3294. if (pMompInfo->in_name.find("定扳反") != -1)
  3295. {
  3296. CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,
  3297. (uint8_t)eDaoChaPosi::DCP_FIX2INVERT, (uint8_t)ePowerName::PN_MOVE, fmt::format("{}:{}", pMompInfo->in_name, it.fluctuation_val));
  3298. posi = eDaoChaPosi::DCP_FIX2INVERT;
  3299. CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_INVERT);
  3300. JudgeAlarm(pService, pConvertResistOverLimitInfo, it.time, it.fluctuation_val, posi, mo, mp, pMompInfo->zzjno);
  3301. }
  3302. }
  3303. else if(posi == eDaoChaPosi::DCP_INVERT2FIX)
  3304. {
  3305. CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,
  3306. (uint8_t)eDaoChaPosi::DCP_INVERT2FIX, (uint8_t)ePowerName::PN_MOVE, fmt::format("{}:{}", pMompInfo->out_name, it.fluctuation_val));
  3307. posi = eDaoChaPosi::DCP_INVERT2FIX;
  3308. CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_FIX);
  3309. JudgeAlarm(pService, pConvertResistOverLimitInfo, it.time, it.fluctuation_val, posi, mo, mp, pMompInfo->zzjno);
  3310. }
  3311. SPDLOG_INFO("扳动判断数据{}.{} 315 上送", mo, mp);
  3312. if(mapData[0])
  3313. mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);
  3314. SPDLOG_INFO("扳动判断数据结束{}.{} 315 上送", mo, mp);
  3315. }
  3316. }
  3317. //过车处理逻辑
  3318. if (lstPass.size())
  3319. {
  3320. //TODO
  3321. //SPDLOG_INFO("扳动判断数据{}.{} 315 上送", mo, mp);
  3322. //mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);
  3323. //SPDLOG_INFO("扳动判断数据结束{}.{} 315 上送", mo, mp);
  3324. }
  3325. //摩檫力逻辑
  3326. if (lstFriction.size())
  3327. {
  3328. pMompInfo;
  3329. auto pAlarmSet = (FRICTION_OVER_LIMIT_INFO*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::FRICTION_OVER_LIMIT);
  3330. auto mg_315_server = g_p315ClientManager->GetTcpClient();
  3331. for (auto& it : lstFriction)
  3332. {
  3333. CResistAlarmMng::InsertToDBByMove(mo, mp, it.show_time, it.tmStart, it.tmEnd, it.curr_val, it.show_val, 2,
  3334. (uint8_t)eDaoChaPosi::DCP_UNKNOWN, (uint8_t)ePowerName::PN_FRICTION, fmt::format("稳态值:{}", it.show_val));
  3335. //CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_QUARTO); //四开
  3336. JudgeAlarm(pService, pAlarmSet, it.show_time, it.show_val, eDaoChaPosi::DCP_UNKNOWN, it.bUpOrDown, (void*)pMompInfo);
  3337. //发送315曲线数据
  3338. //if (mapData[0])
  3339. // mg_315_server->SendCurveData(pMompInfo->zzjno, eDaoChaPosi::DCP_UNKNOWN, 1, true, mapData, it.tmStart, it.tmEnd);
  3340. }
  3341. }
  3342. delete mapData[0];
  3343. delete mapData[1];
  3344. delete mapData[2];
  3345. }
  3346. }
  3347. } while (pService->m_bWork);
  3348. if (bLock)
  3349. {
  3350. g_lockSync.Unlock();
  3351. bLock = false;
  3352. }
  3353. }
  3354. TIMESTAMP_STRUCT GetLastMoveTimeStamp(COdbcConnect* pDBConn)
  3355. {
  3356. SYSTEMTIME ss;
  3357. GetLocalTime(&ss);
  3358. string table_today = fmt::format("rm_move_{:0>4}{:0>2}", ss.wYear, ss.wMonth);
  3359. TIMESTAMP_STRUCT ts;
  3360. CString sql = ("SELECT MAX(show_time) FROM " + table_today).c_str();
  3361. bool bSucc = false;
  3362. do
  3363. {
  3364. COdbcStatement stmt;
  3365. stmt.SetOdbcConnect(pDBConn);
  3366. int r = stmt.ExecDirect(sql);
  3367. if (!ISODBCSUCCESS(r))
  3368. break;
  3369. stmt.BindTimeStampCol(1, &ts);
  3370. if (stmt.FetchNext() != 0) break;
  3371. bSucc = true;
  3372. } while (false);
  3373. if (!bSucc)
  3374. {
  3375. //如果查询失败就以今天0点开始
  3376. ts.year = ss.wYear;
  3377. ts.month = ss.wMonth;
  3378. ts.day = 1;
  3379. ts.hour = 0;
  3380. ts.minute = 0;
  3381. ts.second = 0;
  3382. ts.fraction = 0;
  3383. }
  3384. return ts;
  3385. }
  3386. void CResistAlarmMng::ThreadProcMoveFromDB(DWORD_PTR param)
  3387. {
  3388. auto pService = (CResistAlarmMng*)param;
  3389. auto pDBConn = CDBConnectPool::Instance()->GetConnection();
  3390. TIMESTAMP_STRUCT tsLast = GetLastMoveTimeStamp(pDBConn);
  3391. Sleep(2000);
  3392. do
  3393. {
  3394. Sleep(200); //每100ms 获取一次
  3395. string table_today = fmt::format("rm_move_{:0>4}{:0>2}", tsLast.year, tsLast.month);
  3396. //加载数据
  3397. CString sql = fmt::format("SELECT mo,mp,show_time,start_time,end_time,curr_val,show_val,\
  3398. idx,posi,mark,type,sunroof FROM {} WHERE sunroof = 0 and show_time > '{:0>4}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}.{}' ORDER BY show_time ASC;",
  3399. table_today, tsLast.year, tsLast.month, tsLast.day, tsLast.hour, tsLast.minute, tsLast.second, tsLast.fraction / 1000000).c_str();
  3400. //用大于号不包含关系 dataservice 不运行时候, 数据不存储外部也就不会产生数据
  3401. COdbcStatement stmt;
  3402. stmt.SetOdbcConnect(pDBConn);
  3403. int r = stmt.ExecDirect(sql);
  3404. if (!ISODBCSUCCESS(r))
  3405. {
  3406. ASSERT(0);
  3407. continue;
  3408. }
  3409. //绑定数据
  3410. int nCol = 1;
  3411. char mo[51], mp[51];
  3412. TIMESTAMP_STRUCT show_time, start_time, end_time;
  3413. int curr_val, show_val;
  3414. uint8_t idx, posi, type, sunroof;
  3415. char mark[100];
  3416. stmt.BindCharCol(nCol++, mo, sizeof(mo));
  3417. stmt.BindCharCol(nCol++, mp, sizeof(mp));
  3418. stmt.BindTimeStampCol(nCol++, &show_time);
  3419. stmt.BindTimeStampCol(nCol++, &start_time);
  3420. stmt.BindTimeStampCol(nCol++, &end_time);
  3421. stmt.BindIntCol(nCol++, &curr_val);
  3422. stmt.BindIntCol(nCol++, &show_val);
  3423. stmt.BindTinyIntCol(nCol++, &idx);
  3424. stmt.BindTinyIntCol(nCol++, &posi);
  3425. stmt.BindCharCol(nCol++, mark, sizeof(mark));
  3426. stmt.BindTinyIntCol(nCol++, &type);
  3427. stmt.BindTinyIntCol(nCol++, &sunroof);
  3428. ST_MOMP_INFO* pMompInfo = nullptr;
  3429. auto mg_315_server = g_p315ClientManager->GetTcpClient();
  3430. int nCount = 0;
  3431. //获取数据
  3432. do
  3433. {
  3434. if (stmt.FetchNext() != 0) break;
  3435. //类型条件语句
  3436. auto ePosi = (eDaoChaPosi)posi;
  3437. auto eType = (ePowerName)type;
  3438. if (pMompInfo == nullptr || pMompInfo->mo.compare(mo) != 0 || pMompInfo->mp.compare(mp) != 0)
  3439. pMompInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(string(mo) + "." + mp);
  3440. if (pMompInfo == nullptr) continue;
  3441. CTime ctAlarm = CTime(show_time.year, show_time.month, show_time.day, show_time.hour, show_time.minute, show_time.second);
  3442. memcpy(&tsLast, &show_time, sizeof(TIMESTAMP_STRUCT)); //赋值最新的时间, 区分查询后面的数据
  3443. time_t show_time_t = ctAlarm.GetTime() * 1000
  3444. + show_time.fraction / 1000000;
  3445. nCount++;
  3446. SPDLOG_INFO("[MOVE]查询到新的数据 {}.{} {:0>2}:{:0>2}:{:0>2}",
  3447. mo, mp, tsLast.hour, tsLast.minute, tsLast.second);
  3448. switch (eType)
  3449. {
  3450. case ePowerName::PN_LOCK:
  3451. {
  3452. //报警判断
  3453. if (ePosi == eDaoChaPosi::DCP_FIX)
  3454. {
  3455. auto pFixSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);
  3456. JudgeAlarm(pService, pFixSuobiOverInfo, show_time_t, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno);
  3457. }
  3458. else if (ePosi == eDaoChaPosi::DCP_INVERT)
  3459. {
  3460. auto pInvertSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);
  3461. JudgeAlarm(pService, pInvertSuobiOverInfo, show_time_t, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo->zzjno);
  3462. }
  3463. }
  3464. break;
  3465. case ePowerName::PN_RETENTION:
  3466. {
  3467. if (ePosi == eDaoChaPosi::DCP_FIX)
  3468. {
  3469. auto pFixConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::RETENSION_FORCE);
  3470. JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, show_time_t, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo, pMompInfo->detectToday0, ePosi, false,false);
  3471. }
  3472. else if (ePosi == eDaoChaPosi::DCP_INVERT)
  3473. {
  3474. auto pInvertConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::RETENSION_FORCE);
  3475. JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, show_time_t, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo, pMompInfo->detectToday1, ePosi, false, false);
  3476. }
  3477. }
  3478. break;
  3479. case ePowerName::PN_MOVE:
  3480. {
  3481. //转换阻力报警设置项
  3482. auto pConvertResistOverLimitInfo =
  3483. (CONVERT_RESIST_OVER_LIMIT*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::CONVERT_LIMIT);
  3484. if (ePosi == eDaoChaPosi::DCP_FIX2INVERT)
  3485. {
  3486. //更新状态
  3487. CMonitorObjectMng::Instance()->UpdateZZJEPOS(string(mo) + "." + mp, DAOCHA_POSITION::MP_INVERT);
  3488. SPDLOG_INFO("[MOVE]{}:{} 更新到反位", mo, mp);
  3489. JudgeAlarm(pService, pConvertResistOverLimitInfo, show_time_t, show_val, ePosi, mo, mp, pMompInfo->zzjno);
  3490. }
  3491. else if (ePosi == eDaoChaPosi::DCP_INVERT2FIX)
  3492. {
  3493. //更新状态
  3494. CMonitorObjectMng::Instance()->UpdateZZJEPOS(string(mo) + "." + mp, DAOCHA_POSITION::MP_FIX);
  3495. SPDLOG_INFO("[MOVE]{}:{} 更新到定位", mo, mp);
  3496. JudgeAlarm(pService, pConvertResistOverLimitInfo, show_time_t, show_val, ePosi, mo, mp, pMompInfo->zzjno);
  3497. }
  3498. //TODO发送315曲线
  3499. // mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);
  3500. }
  3501. break;
  3502. case ePowerName::PN_FRICTION:
  3503. {
  3504. //摩擦力
  3505. auto pAlarmSet = (FRICTION_OVER_LIMIT_INFO*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::FRICTION_OVER_LIMIT);
  3506. JudgeAlarm(pService, pAlarmSet, show_time_t, show_val, eDaoChaPosi::DCP_UNKNOWN, show_val < 0 ? eUpOrDownInfo::UOD_DOWN : eUpOrDownInfo::UOD_UP, pMompInfo);
  3507. //TODO发送315曲线
  3508. //mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);
  3509. }
  3510. break;
  3511. default:
  3512. SPDLOG_WARN("[MOVE][扳动数据有误]{}:{} type:{}", mo, mp, type);
  3513. ASSERT(0);
  3514. break;
  3515. }
  3516. } while (true);
  3517. stmt.Close();
  3518. if (nCount>0) {
  3519. SPDLOG_INFO("[MOVE]外部加载扳动数据:{}条 语句:{}", nCount, sql);
  3520. }
  3521. else
  3522. {
  3523. //考虑到跨月的情况
  3524. SYSTEMTIME ss;
  3525. GetLocalTime(&ss);
  3526. if (ss.wMonth != tsLast.month)
  3527. {
  3528. tsLast.year = ss.wYear;
  3529. tsLast.month = ss.wMonth;
  3530. tsLast.day = ss.wDay;
  3531. tsLast.hour = 0;
  3532. tsLast.minute = 0;
  3533. tsLast.second = 0;
  3534. tsLast.fraction = 0;
  3535. SPDLOG_INFO("[MOVE]外部加载扳动数据: 月份不同,重新加载");
  3536. }
  3537. }
  3538. } while (pService->m_bWork);
  3539. SPDLOG_WARN("[MOVE]ThreadProcMoveFromDB 线程退出.");
  3540. CDBConnectPool::Instance()->FreeConnection(pDBConn);
  3541. }
  3542. BOOL CResistAlarmMng::LoadAlarmSet()
  3543. {
  3544. CString sql = "SELECT [mo],[mp],[no],[type],[conf],[time] FROM [rm_alarm_set]";
  3545. COdbcStatement stmt;
  3546. if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))
  3547. {
  3548. CSimpleLog::Error("执行语句失败" + sql);
  3549. return FALSE;
  3550. }
  3551. for (auto& it : m_alarm_set)
  3552. {
  3553. //delete it.second; //暂时不释放
  3554. it.second = nullptr;
  3555. }
  3556. m_alarm_set.clear();
  3557. char mo[51], mp[51], conf[501];
  3558. uint8_t no, type;
  3559. __time64_t time;
  3560. int nCol = 1;
  3561. stmt.BindCharCol(nCol++, mo, sizeof(mo));
  3562. stmt.BindCharCol(nCol++, mp, sizeof(mp));
  3563. stmt.BindTinyIntCol(nCol++, &no);
  3564. stmt.BindTinyIntCol(nCol++, &type);
  3565. stmt.BindCharCol(nCol++, conf, sizeof(conf));
  3566. stmt.BindBigIntCol(nCol++, &time);
  3567. do
  3568. {
  3569. if (stmt.FetchNext() != 0) break;
  3570. using namespace rapidjson;
  3571. int len = strlen(conf);
  3572. if (len == 0) continue;
  3573. Document doc;
  3574. if (doc.Parse(conf, len).HasParseError())
  3575. {
  3576. CSimpleLog::Error(CString("解析数据出错") + conf);
  3577. continue;
  3578. }
  3579. const auto eType = (eZL_ALARMTYPE)type;
  3580. if (eType == eZL_ALARMTYPE::MAX_OVER_LIMIT)
  3581. {
  3582. if (doc.IsArray() == false)
  3583. {
  3584. CSimpleLog::Error(CString("conf是非数组") + conf);
  3585. continue;
  3586. }
  3587. SizeType n = doc.Size();
  3588. bool enable = false;
  3589. int alarm_high_limit = INT_MAX;
  3590. int warn_high_limit = INT_MAX;
  3591. int f_alarm_high_limit = INT_MAX;
  3592. int f_warn_high_limit = INT_MAX;
  3593. for (SizeType i = 0; i < n; i++)
  3594. {
  3595. if (doc[i].HasMember("name") == false || doc[i].HasMember("val") == false || doc[i]["name"].IsString() == false || doc[i]["val"].IsString() == false)
  3596. {
  3597. assert(false);
  3598. continue;
  3599. }
  3600. string key = doc[i]["name"].GetString();
  3601. string value = doc[i]["val"].GetString();
  3602. if (key.compare("enable") == 0)
  3603. {
  3604. enable = (value.compare("true") == 0);
  3605. }
  3606. else if (key.compare("lock_alarm_high_limit") == 0)
  3607. {
  3608. alarm_high_limit = atoi(value.c_str());
  3609. }
  3610. else if (key.compare("lock_warn_high_limit") == 0)
  3611. {
  3612. warn_high_limit = atoi(value.c_str());
  3613. }
  3614. else if (key.compare("d_alarm_high_limit") == 0)
  3615. {
  3616. alarm_high_limit = atoi(value.c_str());
  3617. }
  3618. else if (key.compare("d_warn_high_limit") == 0)
  3619. {
  3620. warn_high_limit = atoi(value.c_str());
  3621. }
  3622. else if (key.compare("f_alarm_high_limit") == 0)
  3623. {
  3624. f_alarm_high_limit = atoi(value.c_str());
  3625. }
  3626. else if (key.compare("f_warn_high_limit") == 0)
  3627. {
  3628. f_warn_high_limit = atoi(value.c_str());
  3629. }
  3630. else if (key.compare("keep_alarm_high_limit") == 0)
  3631. {
  3632. f_alarm_high_limit = atoi(value.c_str());
  3633. }
  3634. else if (key.compare("keep_warn_high_limit") == 0)
  3635. {
  3636. f_warn_high_limit = atoi(value.c_str());
  3637. }
  3638. else
  3639. {
  3640. assert(0);
  3641. }
  3642. }
  3643. if (alarm_high_limit == INT_MAX || warn_high_limit == INT_MAX) continue;
  3644. auto pInfo = new MAX_OVER_LIMIT_INFO;
  3645. pInfo->enable = enable;
  3646. pInfo->no = no;
  3647. pInfo->type = eType;
  3648. pInfo->alarm_high_limit = alarm_high_limit;
  3649. pInfo->warn_high_limit = warn_high_limit;
  3650. pInfo->f_alarm_high_limit = f_alarm_high_limit;
  3651. pInfo->f_warn_high_limit = f_warn_high_limit;
  3652. pInfo->tmLastCheckTime = time;
  3653. sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);
  3654. stringstream ss;
  3655. ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);
  3656. m_alarm_set[ss.str()] = pInfo;
  3657. }
  3658. else if (eType == eZL_ALARMTYPE::FRICTION_OVER_LIMIT)
  3659. {
  3660. if (doc.IsArray() == false)
  3661. {
  3662. CSimpleLog::Error(CString("conf是非数组") + conf);
  3663. continue;
  3664. }
  3665. SizeType n = doc.Size();
  3666. bool enable = false;
  3667. int up_alarm_low_limit = INT_MAX;
  3668. int up_warn_low_limit = INT_MAX;
  3669. int dw_alarm_high_limit = INT_MIN;
  3670. int dw_warn_high_limit = INT_MIN;
  3671. for (SizeType i = 0; i < n; i++)
  3672. {
  3673. if (doc[i].HasMember("name") == false || doc[i].HasMember("val") == false || doc[i]["name"].IsString() == false || doc[i]["val"].IsString() == false)
  3674. {
  3675. assert(false);
  3676. continue;
  3677. }
  3678. string key = doc[i]["name"].GetString();
  3679. string value = doc[i]["val"].GetString();
  3680. if (key.compare("enable") == 0)
  3681. {
  3682. enable = (value.compare("true") == 0);
  3683. }
  3684. else if (key.compare("up_alarm_low_limit") == 0)
  3685. {
  3686. up_alarm_low_limit = atoi(value.c_str());
  3687. }
  3688. else if (key.compare("up_warn_low_limit") == 0)
  3689. {
  3690. up_warn_low_limit = atoi(value.c_str());
  3691. }
  3692. else if (key.compare("dw_alarm_high_limit") == 0)
  3693. {
  3694. dw_alarm_high_limit = atoi(value.c_str());
  3695. }
  3696. else if (key.compare("dw_warn_high_limit") == 0)
  3697. {
  3698. dw_warn_high_limit = atoi(value.c_str());
  3699. }
  3700. else
  3701. {
  3702. assert(0);
  3703. }
  3704. }
  3705. auto pInfo = new FRICTION_OVER_LIMIT_INFO;
  3706. pInfo->enable = enable;
  3707. pInfo->no = no;
  3708. pInfo->type = eType;
  3709. pInfo->up_alarm_low_limit = up_alarm_low_limit;
  3710. pInfo->up_warn_low_limit = up_warn_low_limit;
  3711. pInfo->dw_alarm_high_limit = dw_alarm_high_limit;
  3712. pInfo->dw_warn_high_limit = dw_warn_high_limit;
  3713. pInfo->tmLastCheckTime = time;
  3714. sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);
  3715. stringstream ss;
  3716. ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);
  3717. m_alarm_set[ss.str()] = pInfo;
  3718. }
  3719. else if (eType == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT)
  3720. {
  3721. auto doc = yyjson_read(conf, len, 0);
  3722. if (doc == nullptr) continue;
  3723. auto root = yyjson_doc_get_root(doc);
  3724. auto pInfo = new SUOBI_OVER_LIMIT_INFO;
  3725. pInfo->type = eZL_ALARMTYPE::SUOBI_LOCK_LIMIT;
  3726. pInfo->no = no;
  3727. pInfo->enable = yyjson_get_bool(yyjson_obj_get(root, "enable"));
  3728. pInfo->alarm_low_limit = yyjson_get_int(yyjson_obj_get(root, "alarm_low_limit"));
  3729. pInfo->warn_low_limit = yyjson_get_int(yyjson_obj_get(root, "warn_low_limit"));
  3730. pInfo->alarm_high_limit = yyjson_get_int(yyjson_obj_get(root, "alarm_high_limit"));
  3731. pInfo->warn_high_limit = yyjson_get_int(yyjson_obj_get(root, "warn_high_limit"));
  3732. sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);
  3733. stringstream ss;
  3734. ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);
  3735. m_alarm_set[ss.str()] = pInfo;
  3736. yyjson_doc_free(doc);
  3737. }
  3738. else if (eType == eZL_ALARMTYPE::CONVERT_LIMIT)
  3739. {
  3740. auto doc = yyjson_read(conf, len, 0);
  3741. if (doc == nullptr) continue;
  3742. auto root = yyjson_doc_get_root(doc);
  3743. auto pInfo = new CONVERT_RESIST_OVER_LIMIT;
  3744. pInfo->type = eZL_ALARMTYPE::CONVERT_LIMIT;
  3745. pInfo->no = 2;
  3746. pInfo->enable = yyjson_get_bool(yyjson_obj_get(root, "enable"));
  3747. pInfo->dw_alarm_low_limit = yyjson_get_int(yyjson_obj_get(root, "dw_alarm_low_limit"));
  3748. pInfo->dw_warn_low_limit = yyjson_get_int(yyjson_obj_get(root, "dw_warn_low_limit"));
  3749. pInfo->up_alarm_high_limit = yyjson_get_int(yyjson_obj_get(root, "up_alarm_high_limit"));
  3750. pInfo->up_warn_high_limit = yyjson_get_int(yyjson_obj_get(root, "up_warn_high_limit"));
  3751. sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);
  3752. stringstream ss;
  3753. ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);
  3754. m_alarm_set[ss.str()] = pInfo;
  3755. yyjson_doc_free(doc);
  3756. }
  3757. else if (eType == eZL_ALARMTYPE::RETENSION_FORCE)
  3758. {
  3759. auto doc = yyjson_read(conf, len, 0);
  3760. if (doc == nullptr) continue;
  3761. auto root = yyjson_doc_get_root(doc);
  3762. auto pInfo = new RETENSION_FORCE_DROP;
  3763. pInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;
  3764. pInfo->no = no;
  3765. pInfo->enable = yyjson_get_bool(yyjson_obj_get(root, "enable"));
  3766. pInfo->dw_alarm_low_drop = yyjson_get_int(yyjson_obj_get(root, "dw_alarm_low_drop"));
  3767. pInfo->alarm_high_percent = yyjson_get_int(yyjson_obj_get(root, "alarm_high_percent"));
  3768. pInfo->alarm_low_percent = yyjson_get_int(yyjson_obj_get(root, "alarm_low_percent"));
  3769. sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);
  3770. stringstream ss;
  3771. ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);
  3772. m_alarm_set[ss.str()] = pInfo;
  3773. yyjson_doc_free(doc);
  3774. }
  3775. else
  3776. {
  3777. ASSERT(0);
  3778. }
  3779. } while (true);
  3780. //2024年8月23日 开启默认开启最低3000N报警
  3781. const auto& mapInfo = CMonitorObjectMng::Instance()->m_mapMoMpInfo;
  3782. for (auto& it : mapInfo)
  3783. {
  3784. auto pAlarmSetFix = (RETENSION_FORCE_DROP*)Find(it.second->mo, it.second->mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::RETENSION_FORCE);
  3785. if (pAlarmSetFix)
  3786. {
  3787. if (((pAlarmSetFix->alarm_low_percent <= 95 && pAlarmSetFix->alarm_low_percent >= 5)
  3788. || (pAlarmSetFix->alarm_high_percent <= 95 && pAlarmSetFix->alarm_high_percent >= 5))) {
  3789. pAlarmSetFix->is_page_dyna = true;
  3790. if (!(pAlarmSetFix->dw_alarm_low_drop > 0 && pAlarmSetFix->dw_alarm_low_drop <= 40000)) {
  3791. pAlarmSetFix->dw_alarm_low_drop = 3000;
  3792. }
  3793. }
  3794. }
  3795. /*else
  3796. {
  3797. auto pInfo = new RETENSION_FORCE_DROP;
  3798. pInfo->no = (uint8_t)eSuoBiPosi::SB_FIX;
  3799. pInfo->enable = true;
  3800. pInfo->dw_alarm_low_drop = 3000;
  3801. pInfo->is_page_dyna = false;
  3802. sprintf_s(pInfo->momp, 20, "%s.%s", it.second->mo.c_str(), it.second->mp.c_str());
  3803. Insert(it.second->mo, it.second->mp, pInfo->no, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pInfo);
  3804. }*/
  3805. auto pAlarmSetInvert = (RETENSION_FORCE_DROP*)Find(it.second->mo, it.second->mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::RETENSION_FORCE);
  3806. if (pAlarmSetInvert)
  3807. {
  3808. if (((pAlarmSetInvert->alarm_low_percent <= 95 && pAlarmSetInvert->alarm_low_percent >= 5)
  3809. || (pAlarmSetInvert->alarm_high_percent <= 95 && pAlarmSetInvert->alarm_high_percent >= 5))) {
  3810. pAlarmSetInvert->is_page_dyna = true;
  3811. if (!(pAlarmSetInvert->dw_alarm_low_drop > 0 && pAlarmSetInvert->dw_alarm_low_drop <= 40000)) {
  3812. pAlarmSetInvert->dw_alarm_low_drop = 3000;
  3813. }
  3814. }
  3815. }
  3816. /*else
  3817. {
  3818. auto pInfo = new RETENSION_FORCE_DROP;
  3819. pInfo->no = (uint8_t)eSuoBiPosi::SB_INVERT;
  3820. pInfo->enable = true;
  3821. pInfo->dw_alarm_low_drop = 3000;
  3822. pInfo->is_page_dyna = false;
  3823. sprintf_s(pInfo->momp, 20, "%s.%s", it.second->mo.c_str(), it.second->mp.c_str());
  3824. Insert(it.second->mo, it.second->mp, pInfo->no, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pInfo);
  3825. }*/
  3826. }
  3827. CSimpleLog::Info(fmt::format("一共加载到{}条报警规则:{}", m_alarm_set.size(), sql).c_str());
  3828. return TRUE;
  3829. }
  3830. BOOL CResistAlarmMng::LoadAlarmID()
  3831. {
  3832. CString sql = "SELECT TOP 1 ID FROM RM_ALARM ORDER BY ID DESC";
  3833. COdbcStatement stmt;
  3834. if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))
  3835. {
  3836. CSimpleLog::Error("执行语句失败" + sql);
  3837. return FALSE;
  3838. }
  3839. int alarm_id;
  3840. int nCol = 1;
  3841. stmt.BindIntCol(nCol++, &alarm_id);
  3842. do
  3843. {
  3844. if (stmt.FetchNext() != 0) break;
  3845. m_nAlarmID = alarm_id;
  3846. } while (false);
  3847. stmt.Close();
  3848. return TRUE;
  3849. }
  3850. BOOL CResistAlarmMng::LoadMoveData(string momp, time_t* showTime,int* showVal, int posi)
  3851. {
  3852. SYSTEMTIME tmNow;
  3853. GetLocalTime(&tmNow);
  3854. string table_name = fmt::format("rm_move_{:0>4}{:0>2}", tmNow.wYear, tmNow.wMonth);
  3855. CString sql = fmt::format("SELECT TOP 1 show_time,show_val FROM {} WHERE mo +'.'+ mp = '{}' and type = 2 and posi = {} ORDER BY show_time DESC;", table_name, momp,posi).c_str();
  3856. COdbcStatement stmt;
  3857. if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))
  3858. {
  3859. CSimpleLog::Error("执行语句失败" + sql);
  3860. return FALSE;
  3861. }
  3862. TIMESTAMP_STRUCT showTimeT;
  3863. int nCol = 1;
  3864. int showValT;
  3865. stmt.BindTimeStampCol(nCol++, &showTimeT);
  3866. stmt.BindIntCol(nCol++, &showValT);
  3867. int i = 0;
  3868. do
  3869. {
  3870. if (stmt.FetchNext() != 0) {
  3871. return false;
  3872. }
  3873. *showTime = CTime(showTimeT.year, showTimeT.month, showTimeT.day, showTimeT.hour, showTimeT.minute, showTimeT.second).GetTime() * 1000 + showTimeT.fraction / 1000000;
  3874. *showVal = showValT;
  3875. } while (false);
  3876. stmt.Close();
  3877. return true;
  3878. }
  3879. BOOL CResistAlarmMng::isBetweenFiveAndFiveTen() {
  3880. int hour = 5;
  3881. int minuteStart = 0;
  3882. int minuteEnd = 15;
  3883. auto now = std::chrono::system_clock::now();
  3884. std::time_t now_c = std::chrono::system_clock::to_time_t(now);
  3885. std::tm* now_tm = std::localtime(&now_c);
  3886. bool is_between = (now_tm->tm_hour == hour) && (now_tm->tm_min >= minuteStart) && (now_tm->tm_min <= minuteEnd);
  3887. return is_between;
  3888. }
  3889. BOOL CResistAlarmMng::JudgePass(string mo,string mp) {
  3890. bool is_pass = false;
  3891. time_t tmNow;
  3892. std::map<time_t, tagSecondStatInfo>* map0 = nullptr;
  3893. std::map<time_t, tagSecondStatInfo>* map1 = nullptr;
  3894. std::map<time_t, int>* mapData[2] = { 0 };
  3895. string imei; int idx;
  3896. auto ret = CMonitorObjectMng::Instance()->MOMP2IMEI(mo,mp, imei, idx);
  3897. if (ret == false) return is_pass;
  3898. #ifdef _DEBUG
  3899. if (strcmp("0000000100000001", imei.c_str()) != 0) return is_pass;
  3900. #endif
  3901. auto pDevice = CDeviceMng::Instance()->Find(imei);
  3902. if (pDevice == nullptr)
  3903. {
  3904. CSimpleLog::Error(("找不到imei(" + imei + ")" + std::to_string(__LINE__)).c_str());
  3905. return is_pass;
  3906. }
  3907. Sleep(30000); // 30*1000
  3908. time(&tmNow);
  3909. if (tmNow - pDevice->GetUpdateTime(idx) < 0) return is_pass; //30秒钟无数据上送说明过车已经结束开始判断
  3910. else if (pDevice->m_mapSecondStatInfo00.size() == 0) return is_pass;
  3911. lock_guard<mutex> lock(pDevice->m_mtx);
  3912. //拷贝原始数据,30秒
  3913. time_t tStart = (tmNow - 30)*1000;
  3914. for (auto it = (&(pDevice->map_resist_idx00))->crbegin(); it != (&(pDevice->map_resist_idx00))->crend(); it++) {
  3915. if (it->first < tStart) {
  3916. if (it == (&(pDevice->map_resist_idx00))->crbegin()) {
  3917. break;
  3918. }
  3919. tStart = (--it)->first;
  3920. break;
  3921. }
  3922. }
  3923. if (tStart== (tmNow - 30) * 1000) {
  3924. tStart = (&(pDevice->map_resist_idx00))->begin()->first;
  3925. }
  3926. mapData[0] = new std::map<time_t, int>(pDevice->map_resist_idx00.find(tStart), pDevice->map_resist_idx00.end());
  3927. mapData[1] = new std::map<time_t, int>(pDevice->map_resist_idx01.find(tStart), pDevice->map_resist_idx01.end());
  3928. map0 = new std::map<time_t, tagSecondStatInfo>(pDevice->m_mapSecondStatInfo00.find(tStart/1000), pDevice->m_mapSecondStatInfo00.end());
  3929. map1 = new std::map<time_t, tagSecondStatInfo>(pDevice->m_mapSecondStatInfo01.find(tStart/1000), pDevice->m_mapSecondStatInfo01.end());
  3930. if (!mapData[0] && !mapData[1]) return is_pass;
  3931. if (mapData[0]->size() != mapData[1]->size()) return is_pass;
  3932. if (!map0 && !map1) return is_pass;
  3933. if ((map0->size() != map1->size())|| map0->size()<=3 || map1->size()<=3) return is_pass;
  3934. list<PASS_RESIST> lstPass; //过车数据
  3935. std::map<time_t, tagSecondStatInfo> mapStatInfo0;
  3936. std::map<time_t, tagSecondStatInfo>* mapStatInfo1 = nullptr;
  3937. auto it = (*map0).cbegin();
  3938. mapStatInfo0.emplace(it->first, it->second);
  3939. time_t tLastIt = it->first;
  3940. BOOL bForContinue = TRUE;
  3941. do {
  3942. it++;
  3943. if (it != (*map0).cend()) {
  3944. if (it->first - tLastIt < 2) //单位秒
  3945. {
  3946. mapStatInfo0.emplace(it->first, it->second);
  3947. tLastIt = it->first;
  3948. continue;
  3949. }
  3950. else {
  3951. tLastIt = it->first;
  3952. }
  3953. }
  3954. else {
  3955. bForContinue = FALSE;//遍历结束
  3956. }
  3957. } while (bForContinue);
  3958. if (mapStatInfo0.size() <= 3) //过车不小于3秒
  3959. return is_pass;
  3960. mapStatInfo1 = new std::map<time_t, tagSecondStatInfo>((*map1).find(mapStatInfo0.cbegin()->first), ((*map1).find(mapStatInfo0.crbegin()->first)));
  3961. int nDifCount0 = 0, nDifCount1 = 0;
  3962. for (auto it = (&mapStatInfo0)->cbegin(); it != (&mapStatInfo0)->cend(); it++){
  3963. if (it->second.dif_val > 100) nDifCount0++;
  3964. }
  3965. for (auto it = mapStatInfo1->cbegin(); it != mapStatInfo1->cend(); it++){
  3966. if (it->second.dif_val > 100) nDifCount1++;
  3967. }
  3968. if (std::max(nDifCount0, nDifCount1) <= 3) return is_pass; //波动小于等于3秒
  3969. int iUpNum = 0; //上升次数
  3970. int iDwNum = 0; //下降次数
  3971. int iMaxDif = 0;
  3972. int nMaxValue = 0;
  3973. time_t tMaxTime;
  3974. time_t tsStartTime = (&mapStatInfo0)->begin()->first;
  3975. time_t tsEndTime = (&mapStatInfo0)->crbegin()->first + 1; //结束时间加1秒,后面判断过车时间[tsStartTime, tsEndTime)
  3976. auto dif = tsEndTime - tsStartTime;
  3977. auto sStart = CTime(tsStartTime).Format("%Y-%m-%d %H:%M:%S");
  3978. auto sEnd = CTime(tsEndTime).Format("%Y-%m-%d %H:%M:%S");
  3979. TRACE("pass: tsStartTime:%s tsEndTime:%s dif:%d \r\n", sStart, sEnd, dif);
  3980. SPDLOG_INFO("pass: nDifCount0:{} nDifCount1:{} tsStartTime:{} tsEndTime:{} dif:{}", nDifCount0, nDifCount1, sStart, sEnd, dif);
  3981. if (nDifCount0 > nDifCount1)
  3982. CompareValuePass(mapData[0], tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue);
  3983. else
  3984. CompareValuePass(mapData[1], tsStartTime, tsEndTime, iUpNum, iDwNum, 5, iMaxDif, tMaxTime, nMaxValue);
  3985. if ((dif >= 4 && dif < 7 && iUpNum >= 22 && iDwNum >= 22)
  3986. || (dif == 7 && iUpNum >= 30 && iDwNum >= 30)
  3987. || (dif >= 8 && iUpNum >= 45 && iDwNum >= 45))
  3988. {
  3989. is_pass = TRUE;
  3990. }
  3991. SPDLOG_INFO("[红线保持力过车判断]{}.{} 开始时间 {} 结束时间 {} 经过时间 {}秒 向上波动 {} 向下波动 {} maxdif:{} 是否过车:{}",
  3992. mo, mp, sStart, sEnd, dif, iUpNum, iDwNum, iMaxDif, is_pass ? "是" : "否");
  3993. delete mapStatInfo1;
  3994. if (mapStatInfo0.size()) mapStatInfo0.clear();
  3995. delete map0;
  3996. delete map1;
  3997. return is_pass;
  3998. }
  3999. time_t CResistAlarmMng::SystemTimeToTimeT(const SYSTEMTIME& st) {
  4000. struct tm t = { 0 };
  4001. t.tm_year = st.wYear - 1900; // 年份减去1900,因为tm结构中的年份是从1900年开始计算的
  4002. t.tm_mon = st.wMonth - 1; // 月份从0开始,所以需要减1
  4003. t.tm_mday = st.wDay; // 日
  4004. t.tm_hour = st.wHour; // 小时
  4005. t.tm_min = st.wMinute; // 分钟
  4006. t.tm_sec = st.wSecond; // 秒
  4007. time_t time = mktime(&t); // mktime会将tm结构转换为自1970年1月1日以来的秒数
  4008. return time;
  4009. }
  4010. // 格式化时间,精确到毫秒
  4011. string CResistAlarmMng::getTimeString()
  4012. {
  4013. auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
  4014. std::stringstream ss;
  4015. ss << std::put_time(std::localtime(&t), "%Y-%m-%d %H:%M:%S");
  4016. auto tNow = std::chrono::system_clock::now();
  4017. auto tMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(tNow.time_since_epoch());
  4018. auto tSeconds = std::chrono::duration_cast<std::chrono::seconds>(tNow.time_since_epoch());
  4019. auto ms = tMilliseconds - tSeconds;
  4020. ss << "." << std::setfill('0') << std::setw(3) << ms.count();
  4021. return ss.str();
  4022. }
  4023. BOOL CResistAlarmMng::CompareValuePass(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)
  4024. {
  4025. auto it = pData->find(tsStartTime * 1000);
  4026. if (it == pData->end()) return false;
  4027. int signal = 0;
  4028. tMaxTime = 0;
  4029. int startvalue = it->second / 10;
  4030. int lastvalue = startvalue;
  4031. int lastVV = lastvalue;
  4032. time_t lastTT = it->first;
  4033. int iMax = startvalue;
  4034. std::map<time_t, int> mapMaxValue;
  4035. hight_num = 0;
  4036. low_num = 0;
  4037. for (it; it != pData->end() && it->first < tsEndTime * 1000; it++)
  4038. {
  4039. auto val = it->second / 10;
  4040. if (val > lastvalue)//上升
  4041. {
  4042. if (signal == 1)
  4043. {
  4044. //原来大于,现在也是大于
  4045. //continue;
  4046. }
  4047. else
  4048. {
  4049. //原来小于或者无效,现在大于
  4050. signal = 1;
  4051. startvalue = lastvalue;
  4052. if (iMax - startvalue > threshold)
  4053. low_num++;
  4054. }
  4055. }
  4056. else if (val < lastvalue)//下降
  4057. {
  4058. if (signal == -1)
  4059. {
  4060. //原来小于,现在小于等于
  4061. //continue;
  4062. }
  4063. else
  4064. {
  4065. //原来大于或者无效,现在小于
  4066. signal = -1;
  4067. iMax = lastvalue;
  4068. if (iMax - startvalue > threshold) //相差阈值计数
  4069. {
  4070. mapMaxValue[lastTT] = lastVV;
  4071. hight_num++;
  4072. }
  4073. }
  4074. }
  4075. lastvalue = val;
  4076. lastTT = it->first;
  4077. lastVV = it->second;
  4078. }
  4079. iMax = INT_MIN;
  4080. int iMin = INT_MAX;
  4081. for (auto& it : mapMaxValue)
  4082. {
  4083. if (it.second > iMax)
  4084. {
  4085. iMax = it.second;
  4086. tMaxTime = it.first;
  4087. }
  4088. if (it.second < iMin) iMin = it.second;
  4089. }
  4090. iMaxDif = iMax - iMin;
  4091. nMaxValue = iMax;
  4092. return TRUE;
  4093. }
  4094. //加载未受理和未恢复的报警
  4095. BOOL CResistAlarmMng::LoadUnAck()
  4096. {
  4097. //只加载31天内非天窗期的报警
  4098. CString sql = " SELECT [ID],a.[mo],a.[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],[posi],[loworhigh],[referval],[recovery_time],[sunroof],zzjno,[ack_result] FROM [rm_alarm] as A \
  4099. LEFT JOIN(SELECT mo, mp, zzjno FROM rm_map) AS B ON a.mo = b.mo and a.mp = b.mp \
  4100. WHERE DATEADD(dd, -31, getdate()) < occur_time and sunroof = 0 and type !=32 and (ack_result = 0 OR [recovery_time] < '2000') \
  4101. ORDER BY occur_time ASC; ";
  4102. COdbcStatement stmt;
  4103. if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))
  4104. {
  4105. ASSERT(FALSE);
  4106. CSimpleLog::Error("执行语句失败" + sql);
  4107. return FALSE;
  4108. }
  4109. char mo[51], mp[51], desc[200], suggest[200], event_id[37] = { 0 }, rel_id[37] = { 0 };
  4110. uint8_t no, type, level, posi, loworhigh, sunroof;
  4111. int val;
  4112. int id;
  4113. int zzjno;
  4114. int ackResult;
  4115. TIMESTAMP_STRUCT ts,tsRecovery;
  4116. int referval;
  4117. int nCol = 1;
  4118. stmt.BindIntCol(nCol++, &id);
  4119. stmt.BindCharCol(nCol++, mo, sizeof(mo));
  4120. stmt.BindCharCol(nCol++, mp, sizeof(mp));
  4121. stmt.BindTinyIntCol(nCol++, &no);
  4122. stmt.BindTinyIntCol(nCol++, &type);
  4123. stmt.BindTimeStampCol(nCol++, &ts);
  4124. stmt.BindTinyIntCol(nCol++, &level);
  4125. stmt.BindCharCol(nCol++, desc, sizeof(desc));
  4126. stmt.BindCharCol(nCol++, suggest, sizeof(suggest));
  4127. stmt.BindIntCol(nCol++, &val);
  4128. stmt.BindCharCol(nCol++, event_id, 36);
  4129. stmt.BindCharCol(nCol++, rel_id, 36);
  4130. stmt.BindTinyIntCol(nCol++, &posi);
  4131. stmt.BindTinyIntCol(nCol++, &loworhigh);
  4132. stmt.BindIntCol(nCol++, &referval);
  4133. stmt.BindTimeStampCol(nCol++, &tsRecovery);
  4134. stmt.BindTinyIntCol(nCol++, &sunroof);
  4135. stmt.BindIntCol(nCol++, &zzjno);
  4136. stmt.BindIntCol(nCol++, &ackResult);
  4137. do
  4138. {
  4139. if (stmt.FetchNext() != 0) break;
  4140. ALARM_INFO *pAlarm = new ALARM_INFO;
  4141. pAlarm->event_id = event_id;
  4142. if (rel_id[0] != 0x20)
  4143. pAlarm->rel_id = rel_id;
  4144. pAlarm->id = id;
  4145. pAlarm->mo = mo;
  4146. pAlarm->mp = mp;
  4147. pAlarm->no = no;
  4148. pAlarm->type = (eZL_ALARMTYPE)type;
  4149. ConvertData(ts, pAlarm->time);
  4150. pAlarm->val = val;
  4151. pAlarm->level = level;
  4152. pAlarm->desc = desc;
  4153. pAlarm->suggest = suggest;
  4154. pAlarm->posi = (eDaoChaPosi)posi;
  4155. pAlarm->loworhigh = (eLowHigh)loworhigh;
  4156. pAlarm->refer_val = referval;
  4157. ConvertData(tsRecovery, pAlarm->recoveryTime);
  4158. pAlarm->sunroof = sunroof;
  4159. pAlarm->zzjno = zzjno;
  4160. pAlarm->ack_result = ackResult;
  4161. m_lstUnConfirmAlarm.push_back(pAlarm);
  4162. } while (true);
  4163. stmt.Close();
  4164. CSimpleLog::Info(("一共加载(" + to_string(m_lstUnConfirmAlarm.size()) + ")条未受理和未恢复的报警").c_str());
  4165. return TRUE;
  4166. }