ResistAlarm.cpp 123 KB

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