ResistAlarm.cpp 132 KB

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