| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918 | #include "stdafx.h"#include "ResistAlarm.h"#include "MonitorObject.h"#include "Device.h"#include <ODBC/DBConnectPool.h>#include <rapidjson/document.h>#include <rapidjson/writer.h>#include <rapidjson/stringbuffer.h>#include <Simplelog.h>#include <sstream>#include <gbk2utf8.h>#include "AppService.h"#include <yyjson.h>#include <315ClientManager.h>#include "SkylightMng.h"CResistAlarm::CResistAlarm(){}CResistAlarm::~CResistAlarm(){}CResistAlarmMng::CResistAlarmMng(){}CResistAlarmMng::~CResistAlarmMng(){}BOOL CResistAlarmMng::Start(){	LoadAlarmSet();	if (FALSE == LoadAlarmID()) return FALSE;	LoadUnAck();	m_bWork = true;	m_pThreadAlarmSet = new thread(CResistAlarmMng::ThreadProcAlarmSet, (DWORD_PTR)this);	if (m_pThreadAlarmSet == nullptr) return FALSE;	//离线报警	m_pThreadDevice = new thread(CResistAlarmMng::ThreadProcDevice, (DWORD_PTR)this);	if (m_pThreadDevice == nullptr) return FALSE;	if (g_bExternalData)	{		m_pThreadMove = new thread(CResistAlarmMng::ThreadProcMoveFromDB, (DWORD_PTR)this);		if (m_pThreadMove == nullptr) return FALSE;	}	else	{		m_pThreadMove = new thread(CResistAlarmMng::ThreadProcMove, (DWORD_PTR)this);		if (m_pThreadMove == nullptr) return FALSE;	}	return TRUE;}void CResistAlarmMng::Stop(){	m_bWork = false;	if (m_pThreadAlarmSet)	{		m_pThreadAlarmSet->join();		delete m_pThreadAlarmSet;		m_pThreadAlarmSet = nullptr;	}	if (m_pThreadDevice)	{		m_pThreadDevice->join();		delete m_pThreadDevice;		m_pThreadDevice = nullptr;	}	if (m_pThreadMove)	{		m_pThreadMove->join();		delete m_pThreadMove;		m_pThreadMove = nullptr;	}	for (auto& it : m_alarm_set)	{		if (it.second)		{			if (it.second->type == eZL_ALARMTYPE::MAX_OVER_LIMIT)			{				delete (MAX_OVER_LIMIT_INFO*)it.second;				it.second = nullptr;			}			else if (it.second->type == eZL_ALARMTYPE::FRICTION_OVER_LIMIT)			{				delete (FRICTION_OVER_LIMIT_INFO*)it.second;				it.second = nullptr;			}			else if (it.second->type == eZL_ALARMTYPE::CONVERT_LIMIT)			{				delete (CONVERT_RESIST_OVER_LIMIT*)it.second;				it.second = nullptr;			}			else if (it.second->type == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT)			{				delete (SUOBI_OVER_LIMIT_INFO*)it.second;				it.second = nullptr;			}			else			{				assert(0);			}		}	}	m_alarm_set.clear();	for (auto& it : m_lstUnConfirmAlarm) delete it;	m_lstUnConfirmAlarm.clear();}//BASE_INFO* CResistAlarmMng::Find(string momp, uint8_t no, uint8_t type)//{//	stringstream ss;//	ss << momp << '.' << to_string(no) << '.' << to_string(type);//	auto it = m_alarm_set.find(ss.str());//	if (it != m_alarm_set.end())//	{//		return it->second;//	}//	return nullptr;//}BASE_INFO* CResistAlarmMng::Find(string mo, string mp, uint8_t no, eZL_ALARMTYPE type){	stringstream ss;	ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string((uint8_t)type);	auto it = m_alarm_set.find(ss.str());	if (it != m_alarm_set.end())	{		return it->second;	}	return nullptr;}//bool CResistAlarmMng::Insert(const string& momp, uint8_t no, uint8_t type, BASE_INFO* info)//{//	auto it = m_alarm_set.insert(make_pair(momp + '.' + to_string(no) + '.' + to_string(type), info));//	return it.second;//}bool CResistAlarmMng::Insert(string mo, string mp, uint8_t no, uint8_t type, BASE_INFO* info){	auto it = m_alarm_set.insert(make_pair(mo + '.' + mp + '.' + to_string(no) + '.' + to_string(type), info));	return it.second;}//bool CResistAlarmMng::ConfirmAlarm(string mo, string mp, uint8_t no, uint8_t type, const SYSTEMTIME& st)//{//	lock_guard<mutex> lock(m_mtxAlarm);//	auto it = m_lstUnConfirmAlarm.begin();//	for (it; it != m_lstUnConfirmAlarm.end(); ++it)//	{//		const auto& pInfo = *it;//		if (pInfo->mo.compare(mo) == 0 && pInfo->mp.compare(mp) == 0 && pInfo->no == no && pInfo->type == type && pInfo->time.wYear == st.wYear &&//			pInfo->time.wMonth == st.wMonth && pInfo->time.wDay == st.wDay && pInfo->time.wHour == st.wHour && pInfo->time.wMinute == st.wMinute)//		{//			m_lstUnConfirmAlarm.erase(it);//			return true;//		}//	}//	return false;//}bool CResistAlarmMng::AckAlarm(int alarm_id, string& name, CTime& time){	lock_guard<mutex> lock(m_mtxAlarm);	auto it = m_lstUnConfirmAlarm.begin();	auto pInfo = *it;	bool result = false;	for (it; it != m_lstUnConfirmAlarm.end(); ++it)	{		pInfo = *it;		if (alarm_id == pInfo->id)		{			result = true;			break;			//g_p315ClientManager->GetTcpClient()->SendAlarmData(pInfo->no, 2, CTime(pInfo->time).GetTime(), time.GetTime(), (WORD)pInfo->type, pInfo->val, 0, 0);					}	}	if (!result) return false;	auto itNew = m_lstUnConfirmAlarm.begin();	for (itNew;itNew != m_lstUnConfirmAlarm.end();++itNew) {		auto& pInfoNew = *itNew;		if (pInfo->mo == pInfoNew->mo			&& pInfo->mp == pInfoNew->mp			&& pInfo->no == pInfoNew->no			&& pInfo->type == pInfoNew->type) {			pInfoNew->ack_result = 1;			pInfoNew->ack_name = name;			pInfoNew->ack_time = time;		}	}	return true;}bool CResistAlarmMng::HandleAlarm(int alarm_id){	lock_guard<mutex> lock(m_mtxAlarm);	auto it = m_lstUnConfirmAlarm.begin();	for (it; it != m_lstUnConfirmAlarm.end(); ++it)	{		const auto& pInfo = *it;		if (pInfo->id == alarm_id && pInfo->ack_result == 1 && pInfo->recoveryTime.wYear > 2000)		{			m_lstUnConfirmAlarm.erase(it);			return true;		}	}	return true;}void CResistAlarmMng::GeneralAlarm(string mo, string mp, uint8_t no, eZL_ALARMTYPE type, uint8_t level, SYSTEMTIME& tAlarm){	ALARM_INFO* pAlarmInfo = nullptr;	bool bNew = false;	{		std::lock_guard<mutex> lock(m_mtxAlarm);		for (const auto& alarm : m_lstUnConfirmAlarm)		{			if (alarm->type == type && alarm->mo.compare(mo) == 0 && alarm->recoveryTime.wYear < 2000				&& alarm->mp.compare(mp) == 0 && no == alarm->no) //跟上次报警时间超过1小时,则算新报警			{				pAlarmInfo = alarm;				break;			}		}	}	if (pAlarmInfo == nullptr)	{		bNew = true;		pAlarmInfo = new ALARM_INFO;		pAlarmInfo->event_id = hjfunc_GetGUID();		pAlarmInfo->id = ++m_nAlarmID;		pAlarmInfo->level = 1;		pAlarmInfo->mo = mo;		pAlarmInfo->mp = mp;		pAlarmInfo->no = no;		pAlarmInfo->time = tAlarm;		pAlarmInfo->type = type;		pAlarmInfo->val = 0;		char szInfo[200];		sprintf_s(szInfo, sizeof(szInfo), "传感器异常时间:%04d-%02d-%02d %02d:%02d:%02d", 			tAlarm.wYear, tAlarm.wMonth, tAlarm.wDay, tAlarm.wHour, tAlarm.wMinute, tAlarm.wSecond);		pAlarmInfo->desc = szInfo;		lock_guard<mutex> lock(m_mtxAlarm);		m_lstUnConfirmAlarm.push_back(pAlarmInfo);	}	//send	if (bNew) //不再推送	{		rapidjson::StringBuffer buffer;		auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);		const char* output = buffer.GetString();		//CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());		CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());	}	//save	if (bNew)	{		CTime ctAlarmTime(tAlarm);		CString sql;		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]) "\			"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",			pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, (int)pAlarmInfo->type,			(LPCSTR)(ctAlarmTime.Format("%Y-%m-%d %H:%M:%S")), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,			pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val, pAlarmInfo->sunroof);		if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))			CSimpleLog::Error("执行语句失败" + sql);		else		{			uint8_t* pack = nullptr; int len = 0;			auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);			if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);			//g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pAlarmInfo->type, pAlarmInfo->val, 0, 0);			delete[] pack;			pack = nullptr;		}	}}//报警恢复,  报警恢复逻辑与受理确认逻辑分开void CResistAlarmMng::RecoverAlarm(const string mo, const string mp, const uint8_t no, const eZL_ALARMTYPE type, const uint8_t level, const SYSTEMTIME& tAlarm){	vector<uint32_t> vctAlarmID;	vector<string> vctEventID;	//ALARM_INFO tmpalarm;	{		std::lock_guard<mutex> lock(m_mtxAlarm);		for (auto it = m_lstUnConfirmAlarm.begin(); it != m_lstUnConfirmAlarm.end();)		{			auto pAlarm = *it;			if (pAlarm->type == type && pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0 && no == pAlarm->no && level == pAlarm->level				&& pAlarm->recoveryTime.wYear < 2000)			{				vctAlarmID.emplace_back(pAlarm->id);				vctEventID.emplace_back(pAlarm->event_id);				//CopyMemory(&tmpalarm, *it, sizeof(tmpalarm));  有string 不能拷贝				//tmpalarm = *pAlarm;				if (pAlarm->ack_result == 1)//如果已确认则可以删除				{					it = m_lstUnConfirmAlarm.erase(it);					continue;				}				else					memcpy(&pAlarm->recoveryTime, &tAlarm, sizeof(SYSTEMTIME));			}			it++;		}	}	if (vctAlarmID.size() == 0)		return;	CTime ctAlarm(tAlarm);	string recovery_time = ctAlarm.Format("%Y-%m-%d %H:%M:%S");	//g_p315ClientManager->GetTcpClient()->SendAlarmData(tmpalarm.no, 2, CTime(tmpalarm.time).GetTime(), ctAlarm.GetTime(), (WORD)tmpalarm.type, tmpalarm.val, 0, 0);	//更新数据库	{		CString sql;		for (auto& it : vctAlarmID)		{			sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), it);			CDBConnectPool::Instance()->DBExecuteSQL(sql);		}		//for (auto& it : vctEventID)		//{		//	sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE [event_id] = '%s';", recovery_time.c_str(), it);		//	CDBConnectPool::Instance()->DBExecuteSQL(sql);		//}	}	//恢复暂时不通知	//auto doc = yyjson_mut_doc_new(nullptr);	//auto root = yyjson_mut_obj(doc);	//yyjson_mut_doc_set_root(doc, root);	//yyjson_mut_obj_add_str(doc, root, "cmd", "alm_ack");	//yyjson_mut_obj_add_uint(doc, root, "alarm_id", alarm_id);	//yyjson_mut_obj_add_strcpy(doc, root, "ack_time", recovery_time.c_str());	//yyjson_mut_obj_add_strcpy(doc, root, "ack_name", ANSItoUTF8("系统").c_str());	//size_t len;	//auto json = yyjson_mut_write(doc, 0, &len);	//if (json)	//{	//	CAppService::Instance()->GetMgServer()->SendToAllClient(json, len);	//	free(json);	//}	//yyjson_mut_doc_free(doc);}eZL_MP_STAT CResistAlarmMng::GetAlarmStat(string& mo, string& mp, SYSTEMTIME& stAlarm){	eZL_MP_STAT stat = eZL_MP_STAT::MP_STAT_UNKNOW;	lock_guard<mutex> lock(m_mtxAlarm);	auto it = m_lstUnConfirmAlarm.rbegin();	for (it; it != m_lstUnConfirmAlarm.rend(); ++it)	{		const auto& pInfo = *it;		if (pInfo->ack_result) continue;//受理了暂时放过		if (pInfo->mo.compare(mo) == 0 && pInfo->mp.compare(mp) == 0 && pInfo->recoveryTime.wYear < 2000)		{			if (pInfo->type == eZL_ALARMTYPE::EQUIP_OFFLINE || pInfo->type == eZL_ALARMTYPE::SENSOR_ABNORMAL)			{				stat = eZL_MP_STAT::MP_STAT_OFFLINE_GRAY;				break;			}			else if (pInfo->level == 1)			{				stAlarm = pInfo->time;				stat = eZL_MP_STAT::MP_STAT_ALARM_RED;				break;			}			else if (pInfo->level == 0)			{				stAlarm = pInfo->time;				stat = eZL_MP_STAT::MP_STAT_WARN_ORANGE;				break;			}		}	}	return stat;}uint32_t CResistAlarmMng::GeneralAlarmSet(uint8_t** pack, int* len){	auto doc = yyjson_mut_doc_new(nullptr);	auto root = yyjson_mut_arr(doc);	yyjson_mut_doc_set_root(doc, root);	for (const auto& it : m_alarm_set)	{		auto obj = yyjson_mut_obj(doc);		yyjson_mut_arr_add_val(root, obj);		auto ss = it.second;		auto kk = it.first;		int nPos = kk.find('.');		int nPos2 = kk.find('.', nPos + 1);		string mo = kk.substr(0, nPos);		string mp = kk.substr(nPos + 1, nPos2 - nPos - 1);		string momp = kk.substr(0, nPos2);		string mmomp_name, station;		CMonitorObjectMng::Instance()->GetStationNameByMomP(momp, station, mmomp_name);		yyjson_mut_obj_add_strcpy(doc, obj, "mo", mo.c_str());		yyjson_mut_obj_add_strcpy(doc, obj, "mp", mp.c_str());		yyjson_mut_obj_add_strcpy(doc, obj, "station", station.c_str());		yyjson_mut_obj_add_int(doc, obj, "no", ss->no);		yyjson_mut_obj_add_int(doc, obj, "type", uint8_t(ss->type));		switch (ss->type)		{		case eZL_ALARMTYPE::MAX_OVER_LIMIT:		{			auto conf = yyjson_mut_arr(doc);			yyjson_mut_obj_add_val(doc, obj, "conf", conf);			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				yyjson_mut_obj_add_str(doc, object, "name", "enable");				yyjson_mut_obj_add_str(doc, object, "val", ss->enable ? "true" : "false");			}			auto pInfo = (MAX_OVER_LIMIT_INFO*)ss;			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				if (ss->no == 2)					yyjson_mut_obj_add_str(doc, object, "name", "d_alarm_high_limit");				else					yyjson_mut_obj_add_str(doc, object, "name", "lock_alarm_high_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->alarm_high_limit).c_str());			}			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				if (ss->no == 2)					yyjson_mut_obj_add_str(doc, object, "name", "d_warn_high_limit");				else 					yyjson_mut_obj_add_str(doc, object, "name", "lock_warn_high_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->warn_high_limit).c_str());			}			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				if (ss->no == 2)					yyjson_mut_obj_add_str(doc, object, "name", "f_alarm_high_limit");				else					yyjson_mut_obj_add_str(doc, object, "name", "keep_alarm_high_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->f_alarm_high_limit).c_str());			}			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				if (ss->no == 2)					yyjson_mut_obj_add_str(doc, object, "name", "keep_warn_high_limit");				else					yyjson_mut_obj_add_str(doc, object, "name", "f_warn_high_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->f_warn_high_limit).c_str());			}		}			break;		case eZL_ALARMTYPE::FRICTION_OVER_LIMIT:		{			auto conf = yyjson_mut_arr(doc);			yyjson_mut_obj_add_val(doc, obj, "conf", conf);			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				yyjson_mut_obj_add_str(doc, object, "name", "enable");				yyjson_mut_obj_add_str(doc, object, "val", ss->enable ? "true" : "false");			}			auto pInfo = (FRICTION_OVER_LIMIT_INFO*)ss;			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				yyjson_mut_obj_add_str(doc, object, "name", "up_alarm_low_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->up_alarm_low_limit).c_str());			}			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				yyjson_mut_obj_add_str(doc, object, "name", "up_warn_low_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->up_warn_low_limit).c_str());			}			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				yyjson_mut_obj_add_str(doc, object, "name", "dw_alarm_high_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->dw_alarm_high_limit).c_str());			}			{				auto object = yyjson_mut_obj(doc);				yyjson_mut_arr_add_val(conf, object);				yyjson_mut_obj_add_str(doc, object, "name", "dw_warn_high_limit");				yyjson_mut_obj_add_strcpy(doc, object, "val", to_string(pInfo->dw_warn_high_limit).c_str());			}		}			break;		case eZL_ALARMTYPE::SUOBI_LOCK_LIMIT:		{			auto conf = yyjson_mut_obj(doc);			yyjson_mut_obj_add_val(doc, obj, "conf", conf);			auto pInfo = (SUOBI_OVER_LIMIT_INFO*)ss;			yyjson_mut_obj_add_bool(doc, conf, "enable", pInfo->enable);			yyjson_mut_obj_add_int(doc, conf, "alarm_low_limit", pInfo->alarm_low_limit);			yyjson_mut_obj_add_int(doc, conf, "warn_low_limit", pInfo->warn_low_limit);			yyjson_mut_obj_add_int(doc, conf, "alarm_high_limit", pInfo->alarm_high_limit);			yyjson_mut_obj_add_int(doc, conf, "warn_high_limit", pInfo->warn_high_limit);		}			break;		case eZL_ALARMTYPE::CONVERT_LIMIT:		{			auto conf = yyjson_mut_obj(doc);			yyjson_mut_obj_add_val(doc, obj, "conf", conf);			auto pInfo = (CONVERT_RESIST_OVER_LIMIT*)ss; 			yyjson_mut_obj_add_bool(doc, conf, "enable", pInfo->enable);			yyjson_mut_obj_add_int(doc, conf, "dw_alarm_low_limit", pInfo->dw_alarm_low_limit);			yyjson_mut_obj_add_int(doc, conf, "dw_warn_low_limit", pInfo->dw_warn_low_limit);			yyjson_mut_obj_add_int(doc, conf, "up_alarm_high_limit", pInfo->up_alarm_high_limit);			yyjson_mut_obj_add_int(doc, conf, "up_warn_high_limit", pInfo->up_warn_high_limit);		}		break;		default:			ASSERT(0);			break;		}	}	size_t json_len;	auto json = yyjson_mut_write(doc, 0, &json_len);	yyjson_mut_doc_free(doc);	*len = json_len + sizeof(HJDATAHEAD2) + 2;	*pack = new uint8_t[*len];	auto no = CAppService::Instance()->GetPackNo();	CHjDataConver::conver_sendpack(*pack, (LPBYTE)json, json_len, 0, no, E_ZL_PROTOCAL::ZL_ALARM_SET,		OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_SYNC));	free(json);	return no;}uint32_t CResistAlarmMng::GeneralUnAck(uint8_t** pack, int* len){	auto doc = yyjson_mut_doc_new(nullptr);	auto root = yyjson_mut_arr(doc);	yyjson_mut_doc_set_root(doc, root);	{		//查询数据库近一天的数据		lock_guard<mutex> lock(m_mtxAlarm);		auto it = m_lstUnConfirmAlarm.begin();		for (it; it != m_lstUnConfirmAlarm.end(); ++it)		{			auto& pInfo = *it;			auto obj = yyjson_mut_obj(doc);			yyjson_mut_arr_add_val(root, obj);			yyjson_mut_obj_add_uint(doc, obj, "id", pInfo->id);			yyjson_mut_obj_add_strcpy(doc, obj, "mo", pInfo->mo.c_str());			yyjson_mut_obj_add_strcpy(doc, obj, "mp", pInfo->mp.c_str());			yyjson_mut_obj_add_int(doc, obj, "no", pInfo->no);			yyjson_mut_obj_add_int(doc, obj, "type", int(pInfo->type));			yyjson_mut_obj_add_int(doc, obj, "level", pInfo->level);			yyjson_mut_obj_add_strcpy(doc, obj, "time", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}", 				pInfo->time.wYear, pInfo->time.wMonth, pInfo->time.wDay, pInfo->time.wHour, pInfo->time.wMinute, pInfo->time.wSecond).c_str());			yyjson_mut_obj_add_strcpy(doc, obj, "desc", pInfo->desc.c_str());			yyjson_mut_obj_add_strcpy(doc, obj, "desc", pInfo->suggest.c_str());			yyjson_mut_obj_add_int(doc, obj, "val", pInfo->val);			yyjson_mut_obj_add_int(doc, obj, "ack_result", pInfo->ack_result);			yyjson_mut_obj_add_strcpy(doc, obj, "ack_name", pInfo->ack_name.c_str());			yyjson_mut_obj_add_int(doc, obj, "ack_time", pInfo->ack_time.GetTime());			yyjson_mut_obj_add_strcpy(doc, obj, "event_id", pInfo->event_id.c_str());			yyjson_mut_obj_add_strcpy(doc, obj, "rel_id", pInfo->rel_id.c_str());			yyjson_mut_obj_add_strcpy(doc, obj, "recoverytime", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}",				pInfo->recoveryTime.wYear, pInfo->recoveryTime.wMonth, pInfo->recoveryTime.wDay, pInfo->recoveryTime.wHour, pInfo->recoveryTime.wMinute, pInfo->recoveryTime.wSecond).c_str());		}	}	size_t json_len;	auto json = yyjson_mut_write(doc, 0, &json_len);	yyjson_mut_doc_free(doc);	*len = json_len + sizeof(HJDATAHEAD2) + 2;	*pack = new uint8_t[*len];	auto no = CAppService::Instance()->GetPackNo();	CHjDataConver::conver_sendpack(*pack, (LPBYTE)json, json_len, 0, no, E_ZL_PROTOCAL::ZL_ALARM_UNACK,		OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_SYNC));	free(json);	return no;}uint32_t CResistAlarmMng::GeneralNewAlarmData(ALARM_INFO* pInfo, uint8_t** pack, int* len){	auto doc = yyjson_mut_doc_new(nullptr);	auto root = yyjson_mut_arr(doc);	yyjson_mut_doc_set_root(doc, root);	auto obj = yyjson_mut_obj(doc);	yyjson_mut_arr_add_val(root, obj);	yyjson_mut_obj_add_uint(doc, obj, "id", pInfo->id);	yyjson_mut_obj_add_strcpy(doc, obj, "mo", pInfo->mo.c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "mp", pInfo->mp.c_str());	yyjson_mut_obj_add_int(doc, obj, "no", pInfo->no);	yyjson_mut_obj_add_int(doc, obj, "type", int(pInfo->type));	yyjson_mut_obj_add_int(doc, obj, "level", pInfo->level);	yyjson_mut_obj_add_strcpy(doc, obj, "time", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}",		pInfo->time.wYear, pInfo->time.wMonth, pInfo->time.wDay, pInfo->time.wHour, pInfo->time.wMinute, pInfo->time.wSecond).c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "desc", pInfo->desc.c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "suggest", pInfo->suggest.c_str());	yyjson_mut_obj_add_int(doc, obj, "val", pInfo->val);	yyjson_mut_obj_add_int(doc, obj, "ack_result", pInfo->ack_result);	yyjson_mut_obj_add_strcpy(doc, obj, "ack_name", pInfo->ack_name.c_str());	yyjson_mut_obj_add_int(doc, obj, "ack_time", pInfo->ack_time.GetTime());	yyjson_mut_obj_add_strcpy(doc, obj, "event_id", pInfo->event_id.c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "rel_id", pInfo->rel_id.c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "recoverytime", fmt::format("{}-{:0>2}-{:0>2} {:0>2}:{:0>2}:{:0>2}",		pInfo->recoveryTime.wYear, pInfo->recoveryTime.wMonth, pInfo->recoveryTime.wDay, pInfo->recoveryTime.wHour, pInfo->recoveryTime.wMinute, pInfo->recoveryTime.wSecond).c_str());	size_t json_len;	auto json = yyjson_mut_write(doc, 0, &json_len);	yyjson_mut_doc_free(doc);	*len = json_len + sizeof(HJDATAHEAD2) + 2;	*pack = new uint8_t[*len];	auto no = CAppService::Instance()->GetPackNo();	CHjDataConver::conver_sendpack(*pack, (LPBYTE)json, json_len, 0, no, E_ZL_PROTOCAL::ZL_ALARM_DATA,		OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_ADD));	free(json);	return no;}bool CResistAlarmMng::AlarmInfo2Pack(const ALARM_INFO* pAlarmInfo, rapidjson::StringBuffer& buffer, bool bGb2312 /*= false*/){	char szInfo[200];	char szUtf[200];	using namespace rapidjson;	Writer<StringBuffer> writer(buffer);	writer.StartObject();	writer.Key("cmd");	writer.String("new_alarm"); 	writer.Key("type");	//if (pAlarmInfo->type == MAX_OVER_LIMIT) writer.String("monitor.alarm.max_over_limit");	//else if (pAlarmInfo->type == EQUIP_OFFLINE) writer.String("monitor.alarm.equip_offline");	//else if (pAlarmInfo->type == SENSOR_ABNORMAL) writer.String("monitor.alarm.sensor_abnormal");	//else writer.String("");	writer.Int((int)pAlarmInfo->type);	writer.Key("tag");	writer.String((pAlarmInfo->mo + '.' + pAlarmInfo->mp + '.' + to_string(pAlarmInfo->no + 1) + "#").c_str());		string up, momp_name, up_name;	string momp = pAlarmInfo->mo + "." + pAlarmInfo->mp;	CMonitorObjectMng::Instance()->GetStationNameByMomP(momp, up, momp_name);	auto pObject = CMonitorObjectMng::Instance()->GetTreeByID(up);	if (pObject) up_name = pObject->name;	string name1, name2, name3;	CMonitorObjectMng::Instance()->GetNameByMoMp(momp, name1, name2, name3); 	if (pAlarmInfo->no == 0 && name1.length() == 0) name1 = "1号测力点";	else if (pAlarmInfo->no == 1 && name2.length() == 0) name2 = "2号测力点";	else if (pAlarmInfo->no == 2 && name3.length() == 0) name3 = "3号测力点";	sprintf_s(szInfo, 200, "%s.%s.%s.%s%s", up_name.c_str(), momp_name.c_str(),		pAlarmInfo->no == 0 ? name1.c_str() : pAlarmInfo->no == 1 ? name2.c_str() : pAlarmInfo->no == 2 ? name3.c_str() : "",		GetAlarmName(pAlarmInfo->type).c_str(),		pAlarmInfo->level == 1 ? "报警" : "预警"	);	gbk2utf8(szUtf, sizeof(szUtf), szInfo);	writer.Key("title");	writer.String(szUtf);	gbk2utf8(szUtf, sizeof(szUtf), up.c_str());	writer.Key("up");	writer.String(szUtf);	gbk2utf8(szUtf, sizeof(szUtf), up_name.c_str());	writer.Key("up_name");	writer.String(szUtf);	writer.Key("alarm_id");	writer.Uint(pAlarmInfo->id);	writer.Key("event_id");	writer.String(pAlarmInfo->event_id.c_str());	writer.Key("rel_id");	writer.String(pAlarmInfo->rel_id.c_str());	writer.Key("sunroof");	writer.Int(pAlarmInfo->sunroof);	writer.Key("level");	if (pAlarmInfo->level)		writer.String("alarm");	else		writer.String("warn");	writer.Key("occur_time");	sprintf_s(szInfo, sizeof(szInfo), "%04d-%02d-%02d %02d:%02d:%02d.%03d",		pAlarmInfo->time.wYear, pAlarmInfo->time.wMonth, pAlarmInfo->time.wDay,		pAlarmInfo->time.wHour, pAlarmInfo->time.wMinute, pAlarmInfo->time.wSecond, pAlarmInfo->time.wMilliseconds);	writer.String(szInfo);	writer.Key("val");	if (pAlarmInfo->type == eZL_ALARMTYPE::EQUIP_OFFLINE || pAlarmInfo->type == eZL_ALARMTYPE::SENSOR_ABNORMAL)		writer.String("-");	else		writer.String(to_string(pAlarmInfo->val).c_str());	writer.String("desc");	gbk2utf8(szInfo, sizeof(szInfo), pAlarmInfo->desc.c_str());	writer.String(szInfo);	writer.Key("suggest");	writer.String("");	if (pAlarmInfo->ack_result) 	{		//已受理的报警		writer.String("ack_result");		writer.Int(pAlarmInfo->ack_result);		writer.Key("ack_name");		writer.String(ANSItoUTF8(pAlarmInfo->ack_name).c_str());		writer.Key("ack_time");		writer.String(pAlarmInfo->ack_time.Format("%Y-%m-%d %H:%M:%S"));	}	if (pAlarmInfo->recoveryTime.wYear != 1900)	{		writer.Key("recoverytime");		sprintf_s(szInfo, sizeof(szInfo), "%04d-%02d-%02d %02d:%02d:%02d.%03d",			pAlarmInfo->recoveryTime.wYear, pAlarmInfo->recoveryTime.wMonth, pAlarmInfo->recoveryTime.wDay,			pAlarmInfo->recoveryTime.wHour, pAlarmInfo->recoveryTime.wMinute, pAlarmInfo->recoveryTime.wSecond, pAlarmInfo->recoveryTime.wMilliseconds);		writer.String(szInfo);	}	writer.EndObject();	return true;}CResistAlarmMng CResistAlarmMng::obj;void CResistAlarmMng::InsertToDBByMove(string mo, string mp, time_t show_time, time_t start_time, time_t end_time, 	int curr_val, int show_val, uint8_t idx, uint8_t posi, uint8_t type, 	string mark){	if (show_time == 0) return;	CTime ctShowTime(show_time / 1000);	uint8_t sunroof = CSkylightMng::GetInstance()->IsSkylight(&ctShowTime);  //2024年6月9日 添加天窗	string table_name = fmt::format("rm_move_{:0>4}{:0>2}", ctShowTime.GetYear(), ctShowTime.GetMonth());	auto strShowTime = (LPCSTR)ctShowTime.Format("%Y-%m-%d %H:%M:%S.") + to_string(show_time % 1000);	auto strStartTime = start_time ? CTime(start_time).Format("%Y-%m-%d %H:%M:%S") : "";	auto strEndTime = end_time ? CTime(end_time).Format("%Y-%m-%d %H:%M:%S") : "";	CString sql = fmt::format("INSERT INTO {} (mo,mp,show_time,start_time,end_time,curr_val,show_val,idx,posi,type,sunroof,mark) values ('{}', '{}', '{}', '{}','{}', {}, {}, {}, {}, {}, {}, '{}');",		table_name, mo, mp, strShowTime, strStartTime, strEndTime, curr_val, show_val, idx, posi, type, sunroof, mark).c_str();	if (CDBConnectPool::Instance()->DBExecuteSQL(sql) == FALSE)		CSimpleLog::Error(sql);	//上送	//组装数据	auto doc = yyjson_mut_doc_new(nullptr);	auto root = yyjson_mut_arr(doc);	yyjson_mut_doc_set_root(doc, root);	//添加数据	auto obj = yyjson_mut_obj(doc);	yyjson_mut_arr_add_val(root, obj);	yyjson_mut_obj_add_strcpy(doc, obj, "mo", mo.c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "mp", mp.c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "show_time", strShowTime.c_str());	yyjson_mut_obj_add_strcpy(doc, obj, "start_time", strStartTime);	yyjson_mut_obj_add_strcpy(doc, obj, "end_time", strEndTime);	yyjson_mut_obj_add_strcpy(doc, obj, "mark", mark.c_str());	yyjson_mut_obj_add_int(doc, obj, "curr_val", curr_val);	yyjson_mut_obj_add_int(doc, obj, "show_val", show_val);	yyjson_mut_obj_add_int(doc, obj, "idx", idx);	yyjson_mut_obj_add_int(doc, obj, "posi", posi);	yyjson_mut_obj_add_int(doc, obj, "sunroof", sunroof);	size_t json_len;	auto json = yyjson_mut_write(doc, 0, &json_len);	auto send_len = json_len + sizeof(HJDATAHEAD2) + 2;	auto pack = new uint8_t[send_len];	auto packno = CAppService::Instance()->GetPackNo();	CHjDataConver::conver_sendpack(pack, (LPBYTE)json, json_len, 0, packno, E_ZL_PROTOCAL::ZL_MOVE,		OR_DATA_INFO(0, 0, 1, 2, OPT_TYPE::OPT_ADD));	CSuperManager::Instance()->SendPack(pack, send_len, packno, E_ZL_PROTOCAL::ZL_MOVE, true);	delete[] pack;	pack = nullptr;	free(json);	yyjson_mut_doc_free(doc);}//判断锁闭力是否超限void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, SUOBI_OVER_LIMIT_INFO* pSuobiOverInfo, 	time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, uint32_t zzjno){	if (pSuobiOverInfo == nullptr || pSuobiOverInfo->enable == false) return;	bool bNew = false;	ALARM_INFO* pAlarmInfo = nullptr;	bool bAlarm = false, bWarn = false; int alarm_value = 0, alarm_refer; time_t alarm_time = show_time;	CTime ctAlarmTime = CTime(alarm_time / 1000);	eLowHigh loworhigh = eLowHigh::LH_UNKNOWN; //0:最小值  1:最大值	{		if (show_val < pSuobiOverInfo->alarm_low_limit)		{			bAlarm = true;			alarm_refer = pSuobiOverInfo->alarm_low_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_LOW;		}		else if (show_val < pSuobiOverInfo->warn_low_limit)		{			bWarn = true;			alarm_refer = pSuobiOverInfo->warn_low_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_LOW;		}		if (show_val > pSuobiOverInfo->alarm_high_limit)		{			bAlarm = true;			alarm_refer = pSuobiOverInfo->alarm_high_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_HIGH;		}		else if (show_val > pSuobiOverInfo->warn_high_limit)		{			bWarn = true;			alarm_refer = pSuobiOverInfo->warn_high_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_HIGH;		}		if (bAlarm == false && bWarn == false)		{			{				std::lock_guard<mutex> lock(pService->m_mtxAlarm);				for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)				{					auto pAlarm = *it;					if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT && pAlarm->recoveryTime.wYear < 2000 //预警和报警单独计算						&& pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0) 					{						pAlarmInfo = pAlarm;						if (pAlarmInfo)						{							//恢复							//1. 更新数据库							//2. 更新内存数据							//3. 上送恢复消息							if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();							string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");							CString sql;							sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);							CDBConnectPool::Instance()->DBExecuteSQL(sql);							if (pAlarmInfo->ack_result == 1)							{								it = pService->m_lstUnConfirmAlarm.erase(it);								continue;							}							else							{								ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);							}							g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,								pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh, 							   TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);						}					}					it++;				}			}			return;		}		//查找是否原有的报警已存在		uint8_t level = 0;		if (bAlarm) level = 1;		{			std::lock_guard<mutex> lock(pService->m_mtxAlarm);			for (const auto& alarm : pService->m_lstUnConfirmAlarm)			{				if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算					&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)				{					pAlarmInfo = alarm;					break;				}			}		}		ALARM_INFO *pNewAlarmInfo = nullptr;		{			bNew = true;			pNewAlarmInfo = new ALARM_INFO;			pNewAlarmInfo->event_id = hjfunc_GetGUID();			pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";			pNewAlarmInfo->id = ++pService->m_nAlarmID;			pNewAlarmInfo->level = (bAlarm == 1);			pNewAlarmInfo->mo = mo;			pNewAlarmInfo->mp = mp;			pNewAlarmInfo->no = (uint8_t)posi;			ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);			pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;			pNewAlarmInfo->type = eZL_ALARMTYPE::SUOBI_LOCK_LIMIT;			pNewAlarmInfo->val = alarm_value;			pNewAlarmInfo->refer_val = alarm_refer;			pNewAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);			pNewAlarmInfo->loworhigh = loworhigh;			pNewAlarmInfo->zzjno = zzjno;			pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);			char szInfo[200] = { 0 };			sprintf_s(szInfo, sizeof(szInfo), "锁闭力超限,位置:%s, 报警值为%dN, 参考值为%dN",				posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", alarm_value, alarm_refer);			pNewAlarmInfo->desc = szInfo;			lock_guard<mutex> lock(pService->m_mtxAlarm);			pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);		}		//send		//if (bNew) //不再推送		{			rapidjson::StringBuffer buffer;			auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);			const char* output = buffer.GetString();			//CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());			CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());		}		//主动推送315		//if (bNew)		{			g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,				pNewAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pNewAlarmInfo->level, loworhigh,				TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_MOVEING), 0);		}		//save		//if (bNew)		{			CString sql;			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]) "\				"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",				pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,				ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,				pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val, 				pNewAlarmInfo->sunroof);			if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))				CSimpleLog::Error("执行语句失败" + sql);			else			{				uint8_t* pack = nullptr; int len = 0;				auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);				if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);				//g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pNewAlarmInfo->type, pNewAlarmInfo->val, 0, 0);				delete[] pack;				pack = nullptr;			}		}	}}//判断转换阻力是否超限void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, CONVERT_RESIST_OVER_LIMIT* pConvertOverLimit, 	time_t show_time, int show_val, eDaoChaPosi posi, eUpOrDownInfo eUpOrDown, string mo, string mp, uint32_t zzjno){	if (pConvertOverLimit == nullptr || pConvertOverLimit->enable == false) return;	bool bNew = false;	ALARM_INFO* pAlarmInfo = nullptr;	bool bAlarm = false, bWarn = false; int alarm_value = show_val, alarm_refer; time_t alarm_time = show_time;	CTime ctAlarmTime = CTime(alarm_time / 1000);	{		if (eUpOrDown == eUpOrDownInfo::UOD_UP)//缩进		{			if (show_val > pConvertOverLimit->up_alarm_high_limit)			{				bAlarm = true;				alarm_refer = pConvertOverLimit->up_alarm_high_limit;			}			else if (show_val > pConvertOverLimit->up_warn_high_limit)			{				bWarn = true;				alarm_refer = pConvertOverLimit->up_warn_high_limit;			}		}		else if (eUpOrDown == eUpOrDownInfo::UOD_DOWN)		{			if (show_val > pConvertOverLimit->dw_alarm_low_limit)			{				bAlarm = true;				alarm_refer = pConvertOverLimit->dw_alarm_low_limit;			}			else if (show_val > pConvertOverLimit->dw_warn_low_limit)			{				bWarn = true;				alarm_refer = pConvertOverLimit->dw_warn_low_limit;			}		}		if (bAlarm == false && bWarn == false)		{			{				string strPosi= "方向:";				strPosi += (posi == eDaoChaPosi::DCP_FIX2INVERT ? "定扳反" : "反扳定");				std::lock_guard<mutex> lock(pService->m_mtxAlarm);				for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)				{					auto alarm = *it;					if (alarm->no == 2 && alarm->type == eZL_ALARMTYPE::CONVERT_LIMIT  //预警和报警单独计算  //						&& alarm->posi == posi && alarm->recoveryTime.wYear < 2000						&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0) //跟上次报警时间超过1小时,则算新报警					{												pAlarmInfo = alarm;						if (pAlarmInfo)						{							//恢复							//1. 更新数据库							//2. 更新内存数据							//3. 上送恢复消息							if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();							string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");							CString sql;							sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);							CDBConnectPool::Instance()->DBExecuteSQL(sql);							if (pAlarmInfo->ack_result == 1)							{								it = pService->m_lstUnConfirmAlarm.erase(it);								continue;							}							else							{								ctAlarmTime.GetAsSystemTime(alarm->recoveryTime);							}							g_p315ClientManager->GetTcpClient()->SendAlarmData(alarm->zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,								pAlarmInfo->type, posi,  pAlarmInfo->level, eLowHigh::LH_HIGH, 								TIEDA_ACQ_VALUE(alarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);						}					}					++it;				}			}			return;		}		//查找是否原有的报警已存在		uint8_t level = 0;		if (bAlarm) level = 1;		{			std::lock_guard<mutex> lock(pService->m_mtxAlarm);			for (const auto& alarm : pService->m_lstUnConfirmAlarm)			{				if (alarm->no == 2 && alarm->type == eZL_ALARMTYPE::CONVERT_LIMIT && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算					&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0) 				{					pAlarmInfo = alarm;					break;				}			}		}		ALARM_INFO* pNewAlarmInfo = nullptr;		{			bNew = true;			pNewAlarmInfo = new ALARM_INFO;			pNewAlarmInfo->event_id = hjfunc_GetGUID();			pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";			pNewAlarmInfo->id = ++pService->m_nAlarmID;			pNewAlarmInfo->level = (bAlarm == 1);			pNewAlarmInfo->mo = mo;			pNewAlarmInfo->mp = mp;			pNewAlarmInfo->no = 2;			ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);			pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;			pNewAlarmInfo->type = eZL_ALARMTYPE::CONVERT_LIMIT;			pNewAlarmInfo->val = alarm_value;			pNewAlarmInfo->refer_val = alarm_refer;			pNewAlarmInfo->posi = posi;			pNewAlarmInfo->zzjno = zzjno;			pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);			char szInfo[200] = { 0 };			sprintf_s(szInfo, sizeof(szInfo), "转换阻力超限,方向:%s, 报警值为%dN, 参考值为%dN",				posi == eDaoChaPosi::DCP_FIX2INVERT ? "定扳反" : "反扳定", alarm_value, alarm_refer);			pNewAlarmInfo->desc = szInfo;			lock_guard<mutex> lock(pService->m_mtxAlarm);			pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);		}		//send		//if (bNew) //不再推送		{			rapidjson::StringBuffer buffer;			auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);			const char* output = buffer.GetString();			//CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());			CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());		}		//主动推送315		//if (bNew)		{			g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,				pNewAlarmInfo->type, posi, pNewAlarmInfo->level, eLowHigh::LH_HIGH,				TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_MOVEING), 0);		}		//save		{			CString sql;			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]) "\				"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",				pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,				ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,				pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val,				pNewAlarmInfo->sunroof);			if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))				CSimpleLog::Error("执行语句失败" + sql);			else			{				uint8_t* pack = nullptr; int len = 0;				auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);				if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);				//g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pNewAlarmInfo->type, pNewAlarmInfo->val, 0, 0);				delete[] pack;				pack = nullptr;			}		}	}}void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, FRICTION_OVER_LIMIT_INFO* pAlarmSet, time_t show_time, int showval, eDaoChaPosi posi, eUpOrDownInfo eUpOrDown, void* pMoMpInfo){	if (pAlarmSet == nullptr || pAlarmSet->enable == false) return;	auto pInfo = (ST_MOMP_INFO*)pMoMpInfo;		bool bNew = false;	ALARM_INFO* pAlarmInfo = nullptr;	int show_val = showval < 0 ? -showval : showval;	bool bAlarm = false, bWarn = false; int alarm_value = show_val, alarm_refer; time_t alarm_time = show_time;	CTime ctAlarmTime = CTime(alarm_time / 1000);	eLowHigh loworhigh = eLowHigh::LH_UNKNOWN; //0:最小值  1:最大值	{		if (show_val >= pAlarmSet->up_alarm_low_limit)		{			bAlarm = true;			alarm_refer = pAlarmSet->up_alarm_low_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_HIGH;		}		else if (show_val <= pAlarmSet->dw_alarm_high_limit)		{			bAlarm = true;			alarm_refer = pAlarmSet->dw_alarm_high_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_LOW;		}		else if (show_val >= pAlarmSet->up_warn_low_limit)		{			bWarn = true;			alarm_refer = pAlarmSet->up_warn_low_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_HIGH;		}		else if (show_val <= pAlarmSet->dw_warn_high_limit)		{			bWarn = true;			alarm_refer = pAlarmSet->dw_warn_high_limit;			alarm_value = show_val;			loworhigh = eLowHigh::LH_LOW;		}		if (bAlarm == false && bWarn == false)		{			{				std::lock_guard<mutex> lock(pService->m_mtxAlarm);				for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)				{					auto alarm = *it;					if (alarm->no == 2 && alarm->type == pAlarmSet->type //预警和报警单独计算  //						&& alarm->posi == posi && alarm->recoveryTime.wYear < 2000						&& alarm->mo.compare(pInfo->mo) == 0 && alarm->mp.compare(pInfo->mp) == 0) //跟上次报警时间超过1小时,则算新报警					{						pAlarmInfo = alarm;						if (pAlarmInfo)						{							//恢复							//1. 更新数据库							//2. 更新内存数据							//3. 上送恢复消息							if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();							string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");							CString sql;							sql.Format("UPDATE rm_alarm SET recovery_time='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);							CDBConnectPool::Instance()->DBExecuteSQL(sql);							if (pAlarmInfo->ack_result == 1)							{								it = pService->m_lstUnConfirmAlarm.erase(it);								continue;							}							else							{								ctAlarmTime.GetAsSystemTime(alarm->recoveryTime);							}							g_p315ClientManager->GetTcpClient()->SendAlarmData(alarm->zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,								pAlarmInfo->type, posi, pAlarmInfo->level, loworhigh,								TIEDA_ACQ_VALUE(alarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);						}					}					++it;				}			}			return;		}		//查找是否原有的报警已存在		uint8_t level = 0;		if (bAlarm) level = 1;		{			std::lock_guard<mutex> lock(pService->m_mtxAlarm);			for (const auto& alarm : pService->m_lstUnConfirmAlarm)			{				if (alarm->no == 2 && alarm->type == pAlarmSet->type && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算					&& alarm->mo.compare(pInfo->mo) == 0 && alarm->mp.compare(pInfo->mp) == 0)				{					pAlarmInfo = alarm;					break;				}			}		}		ALARM_INFO* pNewAlarmInfo = nullptr;		{			bNew = true;			pNewAlarmInfo = new ALARM_INFO;			pNewAlarmInfo->event_id = hjfunc_GetGUID();			pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";			pNewAlarmInfo->id = ++pService->m_nAlarmID;			pNewAlarmInfo->level = (bAlarm == 1);			pNewAlarmInfo->mo = pInfo->mo;			pNewAlarmInfo->mp = pInfo->mp;			pNewAlarmInfo->no = 2;			ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);			pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;			pNewAlarmInfo->type = pAlarmSet->type;			pNewAlarmInfo->val = alarm_value;			pNewAlarmInfo->refer_val = alarm_refer;			pNewAlarmInfo->posi = posi;			pNewAlarmInfo->zzjno = pInfo->zzjno;			pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);			char szInfo[200] = { 0 };			sprintf_s(szInfo, sizeof(szInfo), "摩擦力稳态值%s超限,报警值为%dN, 参考值为%dN",				loworhigh == eLowHigh::LH_LOW ? "下" : "上", alarm_value, alarm_refer);			pNewAlarmInfo->desc = szInfo;			lock_guard<mutex> lock(pService->m_mtxAlarm);			pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);		}		//send		if (bNew) //不再推送		{			rapidjson::StringBuffer buffer;			auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);			const char* output = buffer.GetString();			CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());		}		//主动推送315		if (bNew)		{			g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,				pNewAlarmInfo->type, posi, pNewAlarmInfo->level, loworhigh,				TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_MOVEING), 0);		}		//save		{			CString sql;			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]) "\				"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",				pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,				ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,				pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val,				pNewAlarmInfo->sunroof);			if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))				CSimpleLog::Error("执行语句失败" + sql);			else			{				uint8_t* pack = nullptr; int len = 0;				auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);				if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);				delete[] pack;				pack = nullptr;			}		}	}}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){	if (pRetensionForceDropInfo == nullptr || pRetensionForceDropInfo->enable == false) return;	bool bNew = false;	ALARM_INFO* pAlarmInfo = nullptr;	bool bAlarm = false, bWarn = false; int alarm_value = 0, alarm_refer; time_t alarm_time = show_time;	CTime ctAlarmTime = CTime(alarm_time / 1000);	eLowHigh loworhigh = eLowHigh::LH_HIGH; //0:最小值  1:最大值	{		if (show_val < pRetensionForceDropInfo->dw_alarm_low_drop)		{			bWarn = true;			alarm_refer = pRetensionForceDropInfo->dw_alarm_low_drop;			alarm_value = show_val;			//loworhigh = eLowHigh::LH_LOW;		}		if (bAlarm == false && bWarn == false)		{			if (g_strMoMp.compare(mo + "." + mp) == 0)				SPDLOG_INFO("[保持力下降]{}.{} 未检测到下降. {} ", mo, mp, show_val);			{				std::lock_guard<mutex> lock(pService->m_mtxAlarm);				for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)				{					auto pAlarm = *it;					if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::RETENSION_FORCE && pAlarm->recoveryTime.wYear < 2000 //预警和报警统一恢复						&& pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0)					{						pAlarmInfo = pAlarm;						if (pAlarmInfo)						{							//恢复							//1. 更新数据库							//2. 更新内存数据							//3. 上送恢复消息							if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();							string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");							CString sql;							sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);							CDBConnectPool::Instance()->DBExecuteSQL(sql);							if (pAlarmInfo->ack_result == 1)							{								it = pService->m_lstUnConfirmAlarm.erase(it);								continue;							}							else							{								ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);							}							g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), ctAlarmTime.GetTime(),								pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,								TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);						}					}					it++;				}			}			return;		}		SPDLOG_INFO("[保持力下降]{}.{} 检测到下降. {} ", mo, mp, show_val);		//查找是否原有的报警已存在		uint8_t level = 0;		if (bAlarm) level = 1;		{			std::lock_guard<mutex> lock(pService->m_mtxAlarm);			for (const auto& alarm : pService->m_lstUnConfirmAlarm)			{				if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::RETENSION_FORCE && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算					&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)				{					pAlarmInfo = alarm;					break;				}			}		}		if (pAlarmInfo == nullptr)		{			bNew = true;			pAlarmInfo = new ALARM_INFO;			pAlarmInfo->event_id = hjfunc_GetGUID();			pAlarmInfo->id = ++pService->m_nAlarmID;			pAlarmInfo->level = (bAlarm == 1);			pAlarmInfo->mo = mo;			pAlarmInfo->mp = mp;			pAlarmInfo->no = (uint8_t)posi;			ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);			pAlarmInfo->time.wMilliseconds = alarm_time % 1000;			pAlarmInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;			pAlarmInfo->val = alarm_value;			pAlarmInfo->refer_val = alarm_refer;			pAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);			pAlarmInfo->loworhigh = loworhigh;			pAlarmInfo->zzjno = zzjno;			pAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pAlarmInfo->time);			char szInfo[200] = { 0 };			sprintf_s(szInfo, sizeof(szInfo), "保持力下降,位置:%s, 报警值为%dN, 参考值为%dN",				posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", alarm_value, alarm_refer);			pAlarmInfo->desc = szInfo;			lock_guard<mutex> lock(pService->m_mtxAlarm);			pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);		}		//send		if (bNew) //不再推送		{			rapidjson::StringBuffer buffer;			auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);			const char* output = buffer.GetString();			//CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());			CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());		}		//主动推送315		if (bNew)		{			g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 1, CTime(pAlarmInfo->time).GetTime(), 0xFFFFFFFF,				pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, loworhigh,				TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);		}		//save		if (bNew)		{			CString sql;			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]) "\				"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",				pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,				ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,				pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val,				pAlarmInfo->sunroof);			if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))				CSimpleLog::Error("执行语句失败" + sql);			else			{				uint8_t* pack = nullptr; int len = 0;				auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);				if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);				delete[] pack;				pack = nullptr;			}		}	}}void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pConstRetensionForceWaveInfo, 	time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, void* pInfo){	if (pConstRetensionForceWaveInfo == nullptr) return;	ST_MOMP_INFO* pMoMpInfo = (ST_MOMP_INFO*)pInfo;	CTime ctShowTime(show_time / 1000);	bool bSkylight = CSkylightMng::GetInstance()->IsSkylight(&ctShowTime);	int nOldVal = INT_MIN;	if (bSkylight && show_val == 0)	{		if (posi == eSuoBiPosi::SB_FIX)		{			pMoMpInfo->fix_const_retension_force = INT_MIN;		}		else		{			pMoMpInfo->invert_const_retension_force = INT_MIN;		}	}	else	{		if (posi == eSuoBiPosi::SB_FIX)		{			nOldVal = pMoMpInfo->fix_const_retension_force;			if (nOldVal == INT_MIN)			{				pMoMpInfo->fix_const_retension_force = show_val;				SPDLOG_INFO("[常态保持力]标定{}.{} {} {}N", mo, mp, "定位", show_val);			}		}		else		{			nOldVal = pMoMpInfo->invert_const_retension_force;			if (nOldVal == INT_MIN)			{				pMoMpInfo->invert_const_retension_force = show_val;				SPDLOG_INFO("[常态保持力]标定{}.{} {} {}N", mo, mp, "反位", show_val);			}		}	}	if (pConstRetensionForceWaveInfo->enable == false) return;	if (nOldVal == INT_MIN)		return;	eLowHigh loworhigh = eLowHigh::LH_UNKNOWN;	int alarm_refer = 0, alarm_value = 0;	bool bAlarm = false, bWarn = false;	if (show_val < pConstRetensionForceWaveInfo->dw_alarm_low_drop) //当前值小于预警值	{		bWarn = true;		alarm_refer = pConstRetensionForceWaveInfo->dw_alarm_low_drop;		alarm_value = show_val;		loworhigh = eLowHigh::LH_LOW;	}	if (loworhigh == eLowHigh::LH_UNKNOWN && nOldVal != 0)	{		int nRatio = show_val * 100 / nOldVal;		//下降20%或上升40% 进行预警		if (pConstRetensionForceWaveInfo->alarm_low_percent > 0 && 			nRatio <= (100 - pConstRetensionForceWaveInfo->alarm_low_percent))		{			bWarn = true;			loworhigh = eLowHigh::LH_LOW;			alarm_value = show_val;			alarm_refer = nOldVal * (100 - pConstRetensionForceWaveInfo->alarm_low_percent) / 100;		}		else if (pConstRetensionForceWaveInfo->alarm_high_percent > 0 && 			nRatio >= (100 + pConstRetensionForceWaveInfo->alarm_high_percent))		{			bWarn = true;			loworhigh = eLowHigh::LH_HIGH;			alarm_value = show_val;			alarm_refer = nOldVal * (100 + pConstRetensionForceWaveInfo->alarm_high_percent) / 100;		}	}	ALARM_INFO* pAlarmInfo = nullptr;	CTime ctAlarmTime(show_time / 1000);	bool bNew = false;	//产生预警	if (loworhigh != eLowHigh::LH_UNKNOWN)	{		//查找是否原有的报警已存在		int level = bAlarm ? 1 : 0;// 预警		{			std::lock_guard<mutex> lock(pService->m_mtxAlarm);			for (const auto& alarm : pService->m_lstUnConfirmAlarm)			{				if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::RETENSION_FORCE					&& level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算					&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)				{					pAlarmInfo = alarm;					break;				}			}		}		if (pAlarmInfo == nullptr)		{			bNew = true;			pAlarmInfo = new ALARM_INFO;			pAlarmInfo->event_id = hjfunc_GetGUID();			pAlarmInfo->id = ++pService->m_nAlarmID;			pAlarmInfo->level = level;// 预警			pAlarmInfo->mo = mo;			pAlarmInfo->mp = mp;			pAlarmInfo->no = (uint8_t)posi;			ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);			pAlarmInfo->time.wMilliseconds = show_time % 1000;			pAlarmInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;			pAlarmInfo->val = alarm_value;			pAlarmInfo->refer_val = alarm_refer;			pAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);			pAlarmInfo->loworhigh = loworhigh;			pAlarmInfo->zzjno = pMoMpInfo->zzjno;			pAlarmInfo->sunroof = bSkylight;			char szInfo[200] = { 0 };			sprintf_s(szInfo, sizeof(szInfo), "保持力异常预警,位置:%s, 报警值为%dN, 上一次值:%dN, 参考值为%dN",				posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, nOldVal, alarm_refer);			pAlarmInfo->desc = szInfo;			lock_guard<mutex> lock(pService->m_mtxAlarm);			pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);		}		//send		if (bNew) //不再推送		{			rapidjson::StringBuffer buffer;			auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);			const char* output = buffer.GetString();			CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());		}		//主动推送315		if (bNew)		{			g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 1, CTime(pAlarmInfo->time).GetTime(), 0xFFFFFFFF,				pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, loworhigh,				TIEDA_ACQ_VALUE(pAlarmInfo->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarmInfo->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);		}		if (bNew)		{			CString sql;			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]) "\				"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",				pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,				ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,				pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val,				pAlarmInfo->sunroof);			if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))				CSimpleLog::Error("执行语句失败" + sql);			else			{				uint8_t* pack = nullptr; int len = 0;				auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);				if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);				delete[] pack;				pack = nullptr;			}		}	}	else	{		//恢复		{			std::lock_guard<mutex> lock(pService->m_mtxAlarm);			for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)			{				auto pAlarm = *it;				if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::RETENSION_FORCE && pAlarm->recoveryTime.wYear < 2000 //预警和报警单独计算					&& pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0)				{					pAlarmInfo = pAlarm;					if (pAlarmInfo)					{						//恢复						//1. 更新数据库						//2. 更新内存数据						//3. 上送恢复消息						if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();						string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");						CString sql;						sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);						CDBConnectPool::Instance()->DBExecuteSQL(sql);						if (pAlarmInfo->ack_result == 1)						{							it = pService->m_lstUnConfirmAlarm.erase(it);							continue;						}						else						{							ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);						}						//TODO 发送给客户端						g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 2, CTime(pAlarmInfo->time).GetTime(), ctAlarmTime.GetTime(),							pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,							TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);					}				}				it++;			}		}		return;	}}void CResistAlarmMng::JudgeAlarm3(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pRetensionForceDropInfo, time_t show_time, int show_val, 	eSuoBiPosi posi, string mo, string mp, uint32_t zzjno){	if (pRetensionForceDropInfo == nullptr || pRetensionForceDropInfo->enable == false) return;	bool bNew = false;	ALARM_INFO* pAlarmInfo = nullptr;	bool bAlarm = false, bWarn = false; int alarm_value = 0, alarm_refer; time_t alarm_time = show_time;	CTime ctAlarmTime = CTime(alarm_time / 1000);	eLowHigh loworhigh = eLowHigh::LH_HIGH; //0:最小值  1:最大值	{		if (show_val < pRetensionForceDropInfo->dw_alarm_low_drop)		{			bAlarm = true;			alarm_refer = pRetensionForceDropInfo->dw_alarm_low_drop;			alarm_value = show_val;			//loworhigh = eLowHigh::LH_LOW;		}		if (bAlarm == false && bWarn == false)		{			{				std::lock_guard<mutex> lock(pService->m_mtxAlarm);				for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)				{					auto pAlarm = *it;					if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::RETENSION_FORCE && pAlarm->recoveryTime.wYear < 2000 //预警和报警统一恢复						&& pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0)					{						pAlarmInfo = pAlarm;						if (pAlarmInfo)						{							//恢复							//1. 更新数据库							//2. 更新内存数据							//3. 上送恢复消息							if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();							string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");							CString sql;							sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);							CDBConnectPool::Instance()->DBExecuteSQL(sql);							if (pAlarmInfo->ack_result == 1)							{								it = pService->m_lstUnConfirmAlarm.erase(it);								continue;							}							else							{								ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);							}							g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,								pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,								TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);						}					}					it++;				}			}			return;		}		//查找是否原有的报警已存在		uint8_t level = 0;		if (bAlarm) level = 1;		{			std::lock_guard<mutex> lock(pService->m_mtxAlarm);			for (const auto& alarm : pService->m_lstUnConfirmAlarm)			{				if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::RETENSION_FORCE && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算					&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)				{					pAlarmInfo = alarm;					break;				}			}		}		ALARM_INFO* pNewAlarmInfo = nullptr;		{			bNew = true;			pNewAlarmInfo = new ALARM_INFO;			pNewAlarmInfo->event_id = hjfunc_GetGUID();			pNewAlarmInfo->rel_id = pAlarmInfo ? pAlarmInfo->event_id : "";			pNewAlarmInfo->id = ++pService->m_nAlarmID;			pNewAlarmInfo->level = (bAlarm == 1);			pNewAlarmInfo->mo = mo;			pNewAlarmInfo->mp = mp;			pNewAlarmInfo->no = (uint8_t)posi;			ctAlarmTime.GetAsSystemTime(pNewAlarmInfo->time);			pNewAlarmInfo->time.wMilliseconds = alarm_time % 1000;			pNewAlarmInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;			pNewAlarmInfo->val = alarm_value;			pNewAlarmInfo->refer_val = alarm_refer;			pNewAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);			pNewAlarmInfo->loworhigh = loworhigh;			pNewAlarmInfo->zzjno = zzjno;			pNewAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pNewAlarmInfo->time);			char szInfo[200] = { 0 };			sprintf_s(szInfo, sizeof(szInfo), "保持力下降,位置:%s, 报警值为%dN, 参考值为%dN",				posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", alarm_value, alarm_refer);			pNewAlarmInfo->desc = szInfo;			lock_guard<mutex> lock(pService->m_mtxAlarm);			pService->m_lstUnConfirmAlarm.push_back(pNewAlarmInfo);		}		//send		//if (bNew) //不再推送		{			rapidjson::StringBuffer buffer;			auto ret = AlarmInfo2Pack(pNewAlarmInfo, buffer);			const char* output = buffer.GetString();			//CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());			CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());		}		//主动推送315		//if (bNew)		{			g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 1, CTime(pNewAlarmInfo->time).GetTime(), 0xFFFFFFFF,				pNewAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pNewAlarmInfo->level, loworhigh,				TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);		}		//save		//if (bNew)		{			CString sql;			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]) "\				"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",				pNewAlarmInfo->id, pNewAlarmInfo->mo.c_str(), pNewAlarmInfo->mp.c_str(), pNewAlarmInfo->no, pNewAlarmInfo->type,				ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pNewAlarmInfo->level, pNewAlarmInfo->desc.c_str(), pNewAlarmInfo->suggest.c_str(), pNewAlarmInfo->val,				pNewAlarmInfo->event_id.c_str(), pNewAlarmInfo->rel_id.c_str(), uint8_t(pNewAlarmInfo->posi), uint8_t(pNewAlarmInfo->loworhigh), pNewAlarmInfo->refer_val,				pNewAlarmInfo->sunroof);			if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))				CSimpleLog::Error("执行语句失败" + sql);			else			{				uint8_t* pack = nullptr; int len = 0;				auto packno = CResistAlarmMng::GeneralNewAlarmData(pNewAlarmInfo, &pack, &len);				if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);				//g_p315ClientManager->GetTcpClient()->SendAlarmData(pNewAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pNewAlarmInfo->type, pNewAlarmInfo->val, 0, 0);				delete[] pack;				pack = nullptr;			}		}	}}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){	int start_value = 0;	for (; i != j; i++)	{		if (i->second > refer_value)		{			if (start_value == 1)			{				//原来大于,现在也是大于				continue;			}			else			{				//原来小于或者无效,现在大于				start_value = 1;				hight_num++;			}		}		else		{			if (start_value == -1)			{				//原来小于,现在小于等于				continue;			}			else			{				//原来大于或者无效,现在小于				start_value = -1;				low_num++;			}		}	}	return TRUE;}void CResistAlarmMng::ThreadProcAlarmSet(DWORD_PTR param){	auto pService = (CResistAlarmMng*)param;	Sleep(2000);	time_t tmNow;	bool bLock = false;	do 	{		if (bLock)		{			g_lockSync.Unlock();			bLock = false;		}		Sleep(800);		time(&tmNow);		if (tmNow == pService->m_lastDetectTime)			continue;		pService->m_lastDetectTime = tmNow;		bLock = true;		g_lockSync.ReadLock();		//1秒判断一次		for (const auto& item : pService->m_alarm_set)		{			if (item.second == nullptr) continue;			if (item.second->enable == false) continue;			if (item.second->type != eZL_ALARMTYPE::MAX_OVER_LIMIT) //这个逻辑里面只支持这两种				continue;			if (item.second->no < 0 || item.second->no > 2) continue;			int nPos = item.first.find('.');							if (nPos == -1) continue;			int nPos2 = item.first.find('.', nPos + 1);			if (nPos2 == -1) continue;			string mo = item.first.substr(0, nPos);			string mp = item.first.substr(nPos + 1, nPos2 - nPos - 1);			string momp = item.first.substr(0, nPos2);			bool bNew = false;			ALARM_INFO *pAlarmInfo = nullptr;			CTime ctAlarmTime;			string imei; int idx;			auto ret = CMonitorObjectMng::Instance()->MOMP2IMEI(momp, imei, idx);			if (ret == false) continue;#ifdef _DEBUG			if (strcmp("860588048955283", imei.c_str()) != 0) continue;#endif			auto pDevice = CDeviceMng::Instance()->Find(imei);			if (pDevice == nullptr)			{				CSimpleLog::Error(("找不到imei(" + imei + ")" + std::to_string(__LINE__)).c_str());				continue;			}			int desc_type = 0;			bool bAlarm = false, bWarn = false; int alarm_value = 0; time_t alarm_time = 0;			eDaoChaPosi posi = eDaoChaPosi::DCP_UNKNOWN;			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;			time_t tmNow; time(&tmNow);			BASE_INFO* pAlarmSet = item.second;			do{				Sleep(0);				lock_guard<mutex> lock(pDevice->m_mtx);				std::map<time_t, int>* pData = pDevice->GetMapData(idx, item.second->no);				assert(pData);				if (pData == nullptr) continue;				if (pData->size() == 0) continue;				if (item.second == 0) continue;				if (item.second->type == eZL_ALARMTYPE::MAX_OVER_LIMIT)				{					auto pInfo = (MAX_OVER_LIMIT_INFO*)pAlarmSet;#ifdef _DEBUG					if (pInfo->tmLastCheckTime > pData->rbegin()->first)						pInfo->tmLastCheckTime = pData->rbegin()->first;#endif					auto it = pData->cbegin();					if (pInfo->tmLastCheckTime == 0) pInfo->tmLastCheckTime = pData->rbegin()->first;					else if (pInfo->tmLastCheckTime != 0) it = pData->find(pInfo->tmLastCheckTime);					if (it == pData->cend())					{						it = pData->find(pInfo->tmLastCheckTime / 1000 * 1000);						if (it == pData->cend())						{							pInfo->tmLastCheckTime = pData->rbegin()->first;							continue;						}					}					if (pInfo->tmLastCheckTime == pData->rbegin()->first) //没有新的数据						continue;#ifdef _DEBUG					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,						CTime(pInfo->tmLastCheckTime / 1000).Format("%Y-%m-%d %H:%M:%S"), CTime(pData->rbegin()->first / 1000).Format("%Y-%m-%d %H:%M:%S"));#endif // _DEBUG					time_t tmStartSteady = pInfo->tmLastCheckTime / 1000 - 3; //稳态报警检测开始, 从上次3秒前到当前秒					if (item.second->no == 2)					{						if (pInfo->alarm_high_limit > pInfo->f_alarm_high_limit)						{//定板反							high_alarm_limit = pInfo->alarm_high_limit;							high_warn_limit = pInfo->warn_high_limit;							low_alarm_limit = pInfo->f_alarm_high_limit;							low_warn_limit = pInfo->f_warn_high_limit;							posi = eDaoChaPosi::DCP_FIX2INVERT;						}						else						{//反板定							low_alarm_limit = pInfo->alarm_high_limit;							low_warn_limit = pInfo->warn_high_limit;							high_alarm_limit = pInfo->f_alarm_high_limit;							high_warn_limit = pInfo->f_warn_high_limit;							posi = eDaoChaPosi::DCP_FIX2INVERT;						}					}					for (++it; it != pData->cend(); ++it)					{						//CString str = CTime(it->first / 1000).Format("%Y-%m-%d %H:%M:%S");						if (it->second == INVLID_VAL)						{							pInfo->tmLastCheckTime = it->first;							continue;						}						if (item.second->no < 2)						{							//1,2 锁闭力报警							if (it->second > pInfo->alarm_high_limit)							{								bAlarm = true;								alarm_refer = pInfo->alarm_high_limit;								alarm_value = it->second;								alarm_time = it->first;								pInfo->tmLastCheckTime = pData->rbegin()->first;								desc_type = 1;								break;							}							//else if (it->second > pInfo->warn_high_limit) //稳态报警单独判断							//{							//	bWarn = true;							//	alarm_refer = pInfo->warn_high_limit;							//	alarm_value = it->second;							//	alarm_time = it->first;							//	pInfo->tmLastCheckTime = pData->rbegin()->first;							//}						}						else						{							assert(item.second->no == 2);							if (pInfo->alarm_high_limit == INT_MAX || pInfo->f_alarm_high_limit == INT_MAX || pInfo->alarm_high_limit == pInfo->f_alarm_high_limit)								break;							desc_type = 3;							if (it->second > high_alarm_limit)							{								bAlarm = true;								alarm_refer = high_alarm_limit;								alarm_value = it->second;								alarm_time = it->first;								pInfo->tmLastCheckTime = pData->rbegin()->first;								break;							}							else if (it->second < low_alarm_limit)							{								bAlarm = true;								alarm_refer = low_alarm_limit;								alarm_value = it->second;								alarm_time = it->first;								pInfo->tmLastCheckTime = pData->rbegin()->first;								break;							}							else if (low_warn_limit == INT_MIN || high_warn_limit == INT_MIN)							{								//未设置预警值							}							else if (it->second > high_warn_limit)							{								bWarn = true;								alarm_refer = high_warn_limit;								alarm_value = it->second;								alarm_time = it->first;								pInfo->tmLastCheckTime = pData->rbegin()->first;							}							else if (it->second < low_warn_limit)							{								bWarn = true;								alarm_refer = low_warn_limit;								alarm_value = it->second;								alarm_time = it->first;								pInfo->tmLastCheckTime = pData->rbegin()->first;							}						}						pInfo->tmLastCheckTime = it->first;					}					//稳态报警判断					if (item.second->no < 2 && bAlarm == false)					{						time_t tmEnd = pInfo->tmLastCheckTime / 1000;						int dif = tmEnd - tmStartSteady;						for (time_t i = tmStartSteady; i < tmEnd - 3; i++)						{#ifdef _DEBUG							COleDateTime t(i);							TRACE("%s\r\n", t.Format("%Y-%m-%d %H:%M:%S"));#endif // _DEBUG							auto j = pData->find(i * 1000);							if (j == pData->end()) continue;							time_t t2 = (i + 1) * 1000;							auto k = pData->find(t2);							if (k == pData->end()) continue;							t2 = (i + 2) * 1000;							k = pData->find(t2);							if (k == pData->end()) continue;							//连续3秒在线,继续找下一个结束点							t2 = (i + 3) * 1000;							auto g = pData->find(t2);							if (g == pData->end())							{								for (++k; k != pData->end(); k++)								{									if (k->first >= t2)									{										g = k;										break;									}								}							}							if (g == pData->end())								continue;							int high_num = 0, low_num = 0;							ConmpareValue(j, g, pInfo->warn_high_limit, high_num, low_num);							if (high_num > 0 && high_num <= 2)							{								bWarn = true;								desc_type = 2;								alarm_refer = pInfo->warn_high_limit;								alarm_value = high_num;								alarm_time = i * 1000; //报警时间								pInfo->tmLastCheckTime = pData->rbegin()->first;								break;							}						}					}				}				/* 2024年8月24日 放在move中判断				else if (item.second->type == eZL_ALARMTYPE::FRICTION_OVER_LIMIT)				{				auto pInfo = (FRICTION_OVER_LIMIT_INFO*)item.second;#ifdef _DEBUG				if (pInfo->tmLastCheckTime > pData->rbegin()->first)					pInfo->tmLastCheckTime = pData->rbegin()->first;#endif				auto it = pData->cbegin();				if (pInfo->tmLastCheckTime == 0) pInfo->tmLastCheckTime = pData->rbegin()->first;				else if (pInfo->tmLastCheckTime != 0) it = pData->find(pInfo->tmLastCheckTime);				if (it == pData->cend())				{					it = pData->find(pInfo->tmLastCheckTime / 1000 * 1000);					if (it == pData->cend())					{						pInfo->tmLastCheckTime = pData->rbegin()->first;						continue;					}				}				if (pInfo->tmLastCheckTime == pData->rbegin()->first) //没有新的数据					continue;				if (tmNow * 1000 - pInfo->tmLastCheckTime < 5000) //5秒检测一次					continue;#ifdef _DEBUG				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,					CTime(pInfo->tmLastCheckTime / 1000).Format("%Y-%m-%d %H:%M:%S"), CTime(pData->rbegin()->first / 1000).Format("%Y-%m-%d %H:%M:%S"));#endif // _DEBUG				if (item.second->no	!= 2) continue;				//从检测时间往前取30秒的数据				static const int dif_resist = 200; //稳定期判定差值				int up_max_resist = INT_MIN; //上最大值				time_t up_max_time = 0;				int up_avg_resist = INT_MIN; //上稳定期平均值				uint64_t up_stable_sum = 0; //上稳定期的和				int up_stable_time = 0;	//上稳定期的数值个数				int up_start_resist_stabel = INT_MIN; //上稳定期开始值				time_t up_start_stable_time = 0; //规定是最大值之后的2秒				time_t up_end_stable_time = 0;//稳定结束的时间				int up_dif_time_stable = 0; //上稳定期的时长				int down_max_resist = INT_MAX; //上最大值				time_t down_max_time = 0;				int down_avg_resist = INT_MAX; //上稳定期平均值				uint64_t down_stable_sum = 0; //上稳定期的和				int down_stable_time = 0;	//上稳定期的数值个数				int down_start_resist_stabel = INT_MAX; //上稳定期开始值				time_t down_start_stable_time = 0; //规定是最大值之后的2秒				int down_dif_time_stable = 0; //上稳定期的时长				time_t tmEnd = pData->rbegin()->first / 1000 + 1; //结束时间				time_t tmStart = tmEnd - 36;//开始时间是从上次35秒到当前秒				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;				//寻找起始时间				for (time_t i = tmStart; i < tmEnd; i++)				{#ifdef _DEBUG					COleDateTime t(i);					TRACE("%s\r\n", t.Format("%Y-%m-%d %H:%M:%S"));#endif // _DEBUG					it_start = pData->find(i * 1000);					if (it_start != pData->cend()) break;				}				pInfo->tmLastCheckTime = pData->rbegin()->first; //赋值最后的时间				if (it_start == pData->cend()) break;				bool bUp = true, bDown = true;				//先找最大值				for (auto i = it_start; i != pData->cend(); i++)				{					//寻找最大的点					if (i->second > up_max_resist)					{						up_max_resist = i->second;						it_up_max = i;					}					//寻找最小的点					if (i->second < down_max_resist)					{						down_max_resist = i->second;						it_down_min = i;					}				}				if (pInfo->tmLastCheckTime - it_up_max->first < 17000) bUp = false; //小于17秒				if (pInfo->tmLastCheckTime - it_down_min->first < 1700) bDown = false; //小于17秒				if(bUp == false && bDown == false) break;				//再找稳定开始				if (bUp)				{					it_up_stable_start = it_up_max;					for (auto i = it_up_max; i != pData->cend(); i++)					{						if (i->first - it_up_max->first < 2000) continue;						else						{							it_up_stable_start = i;							break;						}					}					if (it_up_stable_start == it_up_max) bUp = false;				}				if (bDown)				{					it_down_stable_start = it_down_min;					for (auto i = it_down_min; i != pData->cend(); i++)					{						if (i->first - it_down_min->first < 2000) continue;						else						{							it_down_stable_start = i;							break;						}					}					if (it_down_stable_start == it_down_min) bDown = false;				}				if (bUp == false && bDown == false) break;				if (bUp)				{					up_start_resist_stabel = it_up_stable_start->second;//稳定期开始的值					it_up_stable_end = it_up_stable_start;					for (auto i = it_up_stable_start; i != pData->cend(); i++)					{						if (abs(up_start_resist_stabel - i->second) < dif_resist)						{							up_stable_sum += i->second;							up_start_stable_time++;							it_up_stable_end = i;							continue;						}						else						{							break;						}					}					//时间条件限定在 15s-30s 之间					auto dif = it_up_stable_end->first - it_up_stable_start->first;					if (dif > 15000 && dif < 30000)					{						//平均值						up_avg_resist = up_stable_sum / up_start_stable_time;						if (up_avg_resist < pInfo->up_alarm_low_limit)						{							bAlarm = true;							alarm_value = up_avg_resist;							alarm_time = it_up_stable_start->first;							alarm_refer = pInfo->up_alarm_low_limit;							desc_type = 4;						}						else if (up_avg_resist < pInfo->up_warn_low_limit)						{							bWarn = true;							alarm_value = up_avg_resist;							alarm_time = it_up_stable_start->first;							alarm_refer = pInfo->up_warn_low_limit;							desc_type = 4;						}					}				}				if (bDown)				{					down_start_resist_stabel = it_down_stable_start->second;//稳定期开始的值					it_down_stable_end = it_down_stable_start;					for (auto i = it_down_stable_start; i != pData->cend(); i++)					{						if (abs(down_start_resist_stabel - i->second) < dif_resist)						{							down_stable_sum += i->second;							down_start_stable_time++;							it_down_stable_end = i;							continue;						}						else						{							break;						}					}					//时间条件限定在 15s-30s 之间					auto dif = it_down_stable_end->first - it_down_stable_start->first;					if (dif > 15000 && dif < 30000)					{						//平均值						down_avg_resist = down_stable_sum / down_start_stable_time;						if (down_avg_resist > pInfo->dw_alarm_high_limit)						{							bAlarm = true;							alarm_value = down_avg_resist;							alarm_time = it_down_stable_start->first;							alarm_refer = pInfo->dw_alarm_high_limit;							desc_type = 5;						}						else if (down_avg_resist > pInfo->dw_warn_high_limit)						{							bWarn = true;							alarm_value = down_avg_resist;							alarm_time = it_down_stable_start->first;							alarm_refer = pInfo->dw_warn_high_limit;							desc_type = 5;						}					}				}				}*/				else				{					//其他未实现					//TODO					assert(0);					continue;				}			}while (false);			//update			CString sql;			sql.Format("update rm_alarm_set SET time = %I64u WHERE mo = '%s' and mp = '%s' and no = %d and type = %d",				pAlarmSet->tmLastCheckTime, mo.c_str(), mp.c_str(), pAlarmSet->no, pAlarmSet->type);			if (CDBConnectPool::Instance()->DBExecuteSQL(sql) == FALSE)			{				assert(0);				CSimpleLog::Error("语句执行失败" + sql);			}			string name1, name2, name3, out_name, in_name;			CMonitorObjectMng::Instance()->GetNameByMoMp(momp, name1, name2, name3, out_name, in_name);			auto pMoMpInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(momp);			if (item.second->no == 0 || item.second->no == 1)			{				if (name1.find("定位") != -1)				{					posi = item.second->no == 0 ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT;				}				else if (name1.find("反位") != -1)				{					posi = item.second->no == 0 ? eDaoChaPosi::DCP_INVERT : eDaoChaPosi::DCP_FIX;				}				else if (pMoMpInfo)					SPDLOG_WARN("{} 未配置定位位关系 {}, {}, {}, {}", momp, name1, name2, pMoMpInfo->name1, pMoMpInfo->name2);			}			else if (item.second->no == 2)			{				//TODO				if (posi == eDaoChaPosi::DCP_UNKNOWN)					posi = eDaoChaPosi::DCP_FIX2INVERT;			}			else				ASSERT(FALSE);			if (bAlarm == false && bWarn == false) //没有报警			{				//恢复报警				std::lock_guard<mutex> lock(pService->m_mtxAlarm);				for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)				{					auto& alarm = *it;					if (alarm->no == item.second->no && alarm->type == pAlarmSet->type && alarm->recoveryTime.wYear < 2000						&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)					{						auto pAlarmInfo = alarm;						//1. 更新数据库						//2. 更新内存数据						//3. 上送恢复消息						if (ctAlarmTime.GetTime() == 0) 							ctAlarmTime = CTime::GetCurrentTime();						string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");						CString sql;						sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);						CDBConnectPool::Instance()->DBExecuteSQL(sql);						if (pAlarmInfo->ack_result == 1)						{							it = pService->m_lstUnConfirmAlarm.erase(it);							continue;						}						else						{							ctAlarmTime.GetAsSystemTime(alarm->recoveryTime);						}						g_p315ClientManager->GetTcpClient()->SendAlarmData(CMonitorObjectMng::Instance()->GetZZJNO(mo + '.' + mp), 2, CTime(pAlarmInfo->time).GetTime(), ctAlarmTime.GetTime(),							pAlarmInfo->type, posi, pAlarmInfo->level, eLowHigh::LH_HIGH,							TIEDA_ACQ_VALUE(alarm->val, TIEDA_VAL_STATE::TVS_MOVEING), TIEDA_ACQ_VALUE(alarm->refer_val, TIEDA_VAL_STATE::TVS_MOVEING), 0);					}					++it;				}				continue; //误报警继续下一个循环			}			//查找是否原有的报警已存在			uint8_t level = 0;			if (bAlarm) level = 1;			ctAlarmTime = CTime(alarm_time / 1000);			{				std::lock_guard<mutex> lock(pService->m_mtxAlarm);				for (const auto& alarm : pService->m_lstUnConfirmAlarm)				{					if (alarm->no == item.second->no && alarm->type == pAlarmSet->type && level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算						&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0) 					{						pAlarmInfo = alarm;						break;					}				}			}			if (pAlarmInfo == nullptr)			{				bNew = true;				pAlarmInfo = new ALARM_INFO;				pAlarmInfo->event_id = hjfunc_GetGUID();				pAlarmInfo->id = ++pService->m_nAlarmID;				pAlarmInfo->level = (bAlarm == 1);				pAlarmInfo->mo = mo;				pAlarmInfo->mp = mp;				pAlarmInfo->no = item.second->no;				ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);				pAlarmInfo->time.wMilliseconds = alarm_time % 1000;				pAlarmInfo->type = item.second->type;				pAlarmInfo->val = alarm_value;				pAlarmInfo->refer_val = alarm_refer;				pAlarmInfo->posi = posi;				pAlarmInfo->zzjno = CMonitorObjectMng::Instance()->GetZZJNO(momp);				pAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pAlarmInfo->time);				char szInfo[200];				if (desc_type == 1)				{					sprintf_s(szInfo, sizeof(szInfo), "瞬时冲击力超限报警,报警值为%dN, 参考值为%dN", alarm_value, alarm_refer);//101 102					if (pAlarmInfo->type == eZL_ALARMTYPE::MAX_OVER_LIMIT)					{							g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 1, CTime(pAlarmInfo->time).GetTime(), 0xFFFFFFFF,							pAlarmInfo->type, pAlarmInfo->posi, pAlarmInfo->level, eLowHigh::LH_HIGH, 							TIEDA_ACQ_VALUE(alarm_value, TIEDA_VAL_STATE::TVS_POLL), TIEDA_ACQ_VALUE(alarm_refer, TIEDA_VAL_STATE::TVS_POLL), 0);					}				}				else if (desc_type == 2)					sprintf_s(szInfo, sizeof(szInfo), "稳态值超限预警, 超限次数为%d次, 参考值为%dN", alarm_value, alarm_refer);				else if (desc_type == 3)					sprintf_s(szInfo, sizeof(szInfo), "转换阻力值超限报警, 报警值为%dN, 参考值为%dN", alarm_value, alarm_refer);				else if (desc_type == 4)				{					sprintf_s(szInfo, sizeof(szInfo), "摩擦力超限%s, 缩进位报警值为%dN, 参考值为:%dN", bAlarm == 1 ? "告警" : "预警", alarm_value, alarm_refer);					string direct1, direct2;					CMonitorObjectMng::Instance()->GetDirectByMoMp(mo + '.' + mp, direct1, direct2);				}				else if (desc_type == 5)				{					sprintf_s(szInfo, sizeof(szInfo), "摩擦力超限%s, 伸出位报警值为%dN, 参考值为:%dN", bAlarm == 1 ? "告警" : "预警", alarm_value, alarm_refer);					string direct1, direct2;					CMonitorObjectMng::Instance()->GetDirectByMoMp(mo + '.' + mp, direct1, direct2);				}				else					assert(0);				pAlarmInfo->desc = szInfo;				lock_guard<mutex> lock(pService->m_mtxAlarm);				pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);			}			//send			if (bNew) //不再推送			{				rapidjson::StringBuffer buffer;				auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);				const char* output = buffer.GetString();				//CAppService::Instance()->GetLwsServer()->SendPackToALLClient_with_noEncode((uint8_t*)output, buffer.GetLength());				CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());			}			//save			if (bNew)			{				CString sql;				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]) "\					"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",					pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,					ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,					pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val, pAlarmInfo->sunroof);				if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))					CSimpleLog::Error("执行语句失败" + sql);				else				{					uint8_t* pack = nullptr; int len = 0;					auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);					if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);					//g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->no, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, (WORD)pAlarmInfo->type, pAlarmInfo->val, 0, 0);					delete[] pack;					pack = nullptr;				}			}		}		//保持力下降检测		if (tmNow - pService->m_lastDetectDrop >= 30)		{			pService->m_lastDetectDrop = tmNow;			time_t tt;			time(&tt);			for (const auto& item : pService->m_alarm_set)			{				if (item.second == nullptr) continue;				if (item.second->enable == false) continue;				if (item.second->type != eZL_ALARMTYPE::RETENSION_FORCE) //这个逻辑里面只支持保持力					continue;				if ((eSuoBiPosi)item.second->no != eSuoBiPosi::SB_FIX && (eSuoBiPosi)item.second->no != eSuoBiPosi::SB_INVERT)					continue;				string momp = item.second->momp;				if (momp.empty())				{					int nPos = item.first.find('.');					if (nPos == -1) continue;					int nPos2 = item.first.find('.', nPos + 1);					if (nPos2 == -1) continue;					string mo = item.first.substr(0, nPos);					string mp = item.first.substr(nPos + 1, nPos2 - nPos - 1);					momp = item.first.substr(0, nPos2);				}				auto pInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(momp);				if (pInfo == nullptr) continue;				if (pInfo->pDeivce == nullptr) continue;				auto pAlarmSet = (RETENSION_FORCE_DROP*)item.second;				auto pMap0 = pInfo->pDeivce->GetStatInfo(pInfo->idx, 0);				auto pMap1 = pInfo->pDeivce->GetStatInfo(pInfo->idx, 1);				if (pMap0->size() < 2) continue;				if (pAlarmSet->tmLastCheckTime >= pMap0->rbegin()->first) continue;//不重复检测				pAlarmSet->tmLastCheckTime = pMap0->rbegin()->first;				std::map<time_t, tagSecondStatInfo>* pMap = nullptr;				if (((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_FIX && pInfo->name1.find("定位") != -1) || 					((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_INVERT && pInfo->name1.find("反位") != -1))				{					pMap = pMap0;				}				else if(((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_FIX && pInfo->name2.find("定位") != -1) ||					((eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_INVERT && pInfo->name2.find("反位") != -1))				{					pMap = pMap1;				}				else					continue;				//zzj位置是否变化				bool bEPOSChanged = CMonitorObjectMng::Instance()->IsZZJEPOSChanged(momp,					(eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_FIX ? DAOCHA_POSITION::MP_FIX : DAOCHA_POSITION::MP_INVERT, tt);				//位置变化后不能使用				if (bEPOSChanged) continue;				int  nMinVal = INT_MAX;				time_t tMinTime = 0;				{					lock_guard<mutex> lock(pInfo->pDeivce->m_mtx);					auto it = pMap->end();					auto it0 = --it;					auto it1 = --it;					if (momp.compare(g_strMoMp) == 0)						SPDLOG_INFO("[保持力下降]{} 波动值. {} {}", momp, it1->second.dif_val, it0->second.dif_val);					if (it0->second.dif_val < 200 && it1->second.dif_val < 200 /*&& (it0->first - it1->first) > 2*/)					{						nMinVal = it0->second.min_val;						tMinTime = it0->second.min_time;						if (it1->second.max_val > nMinVal)						{							nMinVal = it1->second.min_val;							tMinTime = it1->second.min_time;						}						//else if (it2->second.max_val < nMinVal)						//{						//	nMinVal = it2->second.min_val;						//	tMinTime = it2->second.min_time;						//}					}				}				if (nMinVal != INT_MAX)					JudgeAlarm(pService, pAlarmSet, tMinTime, nMinVal, (eSuoBiPosi)pAlarmSet->no, pInfo->mo, pInfo->mp, pInfo);			}			//清理无效位置			CMonitorObjectMng::Instance()->ClearZZJHistroyEPOS(tt);		}	} while (pService->m_bWork);	if (bLock)	{		g_lockSync.Unlock();		bLock = false;	}}typedef struct tagMoMp{	string mo;	string mp;	uint8_t no;  //传感器的序号	tagMoMp(string a, string b)	{		mo = a;		mp = b;	}	tagMoMp(uint8_t a)	{		no = a;	}};typedef struct offline_info{	string imei;	CTime time;	uint8_t idx = 0;	std::vector<tagMoMp> vct;	offline_info(string a, CTime b) 	{		imei = a;		time = b;	}	offline_info(string a, CTime b, uint8_t c, uint8_t d)	{		imei = a;		time = b;		idx = c;		vct.push_back(tagMoMp(d));	}};void CResistAlarmMng::ThreadProcDevice(DWORD_PTR param){	auto pService = (CResistAlarmMng*)param;	this_thread::sleep_for(chrono::seconds(2));	static CTimeSpan offline_time(0, 0, 5, 0); //设备离线时间暂定5分钟	static CTimeSpan offline_limit(30, 0, 0, 0);	bool bLock = false;	do	{		if (bLock)		{			g_lockSync.Unlock();			bLock = false;		}		for (int i = 0; i < 30; i++)		{			if (false == pService->m_bWork) break;			Sleep(1000);		}		g_lockSync.ReadLock();		bLock = true;		CTime ctNow = CTime::GetCurrentTime();		//离线设备		{			auto& pMap = CMonitorObjectMng::Instance()->m_mapMoMpInfo;			for (auto& it : pMap)			{				auto& pInfo = it.second;				if (pInfo == nullptr) continue;				bool bAlarm = false;				if (!pInfo->pDeivce) continue;				const auto pDevice = pInfo->pDeivce;				if (pDevice->m_ctUpdateTime.GetTime() == 0)					continue;				if (ctNow - pDevice->m_ctUpdateTime > offline_time)					bAlarm = true;				else if (pInfo->bFirstOnline)				{//第一次上线发送一次315离线报警恢复 因铁大未作报警同步					pInfo->bFirstOnline = false;					g_p315ClientManager->GetTcpClient()->SendAlarmData(pInfo->zzjno, 2, pDevice->m_ctUpdateTime.GetTime(), pDevice->m_ctUpdateTime.GetTime(), eZL_ALARMTYPE::EQUIP_OFFLINE,						eDaoChaPosi::DCP_UNKNOWN, 1, eLowHigh::LH_UNKNOWN, TIEDA_ACQ_VALUE(INT_MIN), TIEDA_ACQ_VALUE(INT_MIN), 0);					SPDLOG_INFO("{}第一次上线发送一次315离线报警恢复", it.first);				}				ALARM_INFO* pAlarmInfo = nullptr;				bool bNew = false;				auto ctAlarmTime = ctNow;				{					std::lock_guard<mutex> lock(pService->m_mtxAlarm);					for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)					{						auto pAlarm = *it;						if (pAlarm->type == eZL_ALARMTYPE::EQUIP_OFFLINE && pAlarm->recoveryTime.wYear < 2000 &&							pAlarm->mo.compare(pInfo->mo) == 0 && pAlarm->mp.compare(pInfo->mp) == 0)						{							pAlarmInfo = pAlarm;							if (bAlarm) //连续报警							{								break;							}							else							{								//恢复报警								//更新数据库								if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();								string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");								CString sql;								sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);								CDBConnectPool::Instance()->DBExecuteSQL(sql);								//315上送								g_p315ClientManager->GetTcpClient()->SendAlarmData(pInfo->zzjno, 2, CTime(pAlarm->time).GetTime(), ctAlarmTime.GetTime(), pAlarm->type, 									eDaoChaPosi::DCP_UNKNOWN, pAlarm->level, eLowHigh::LH_UNKNOWN, TIEDA_ACQ_VALUE(INT_MIN), TIEDA_ACQ_VALUE(INT_MIN), 0);								if (pAlarm->ack_result == 1)								{									it = pService->m_lstUnConfirmAlarm.erase(it);									continue;								}								else								{									ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);								}							}						}						++it;					}				}				if (bAlarm == false) continue;				if (pAlarmInfo == nullptr)				{					bNew = true;					pAlarmInfo = new ALARM_INFO;					pAlarmInfo->event_id = hjfunc_GetGUID();					pAlarmInfo->id = ++pService->m_nAlarmID;					pAlarmInfo->level = 1;					pAlarmInfo->mo = pInfo->mo;					pAlarmInfo->mp = pInfo->mp;					pAlarmInfo->no = -1;					ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);					//pAlarmInfo->time.wMilliseconds = alarm_time % 1000;					pAlarmInfo->type = eZL_ALARMTYPE::EQUIP_OFFLINE;					pAlarmInfo->val = 0;					pAlarmInfo->zzjno = pInfo->zzjno;					char szInfo[200];					sprintf_s(szInfo, sizeof(szInfo), "设备离线时间:%s", (LPCSTR)(pDevice->m_ctUpdateTime.Format("%Y-%m-%d %H:%M:%S")));					pAlarmInfo->desc = szInfo;					pAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pAlarmInfo->time);					lock_guard<mutex> lock(pService->m_mtxAlarm);					pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);				}				//send				if (bNew) //不再推送				{					rapidjson::StringBuffer buffer;					auto ret = AlarmInfo2Pack(pAlarmInfo, buffer);					const char* output = buffer.GetString();					CAppService::Instance()->GetMgServer()->SendToAllClient(output, buffer.GetLength());				}				//save				if (bNew)				{					CString sql;					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]) "\						"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",						pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,						(LPCSTR)(ctAlarmTime.Format("%Y-%m-%d %H:%M:%S")), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,						pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val, pAlarmInfo->sunroof);										if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))						CSimpleLog::Error("执行语句失败" + sql);					else					{						uint8_t* pack = nullptr; int len = 0;						auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);						if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);						g_p315ClientManager->GetTcpClient()->SendAlarmData(pAlarmInfo->zzjno, 1, ctAlarmTime.GetTime(), 0xFFFFFFFF, pAlarmInfo->type, eDaoChaPosi::DCP_UNKNOWN, 1, eLowHigh::LH_UNKNOWN,							TIEDA_ACQ_VALUE(INT_MIN), TIEDA_ACQ_VALUE(INT_MIN), 0);						delete[] pack;						pack = nullptr;					}				}			}		}	} while (pService->m_bWork);	if (bLock)	{		g_lockSync.Unlock();		bLock = false;	}}void CResistAlarmMng::ThreadProcMove(DWORD_PTR param){	auto pService = (CResistAlarmMng*)param;	Sleep(2000);	time_t tmNow;	auto strIniPath = CSimpleLog::GetAppDir() + "DataServices.ini";	bool bLock = false;	do	{		if (bLock)		{			g_lockSync.Unlock();			bLock = false;		}		Sleep(800);		time(&tmNow);		if (pService->m_lastDetectMove > tmNow)		{			SPDLOG_INFO("时间有跳变");			pService->m_lastDetectMove = tmNow;		}		//10秒归档一次 扳动判断		if (tmNow - pService->m_lastDetectMove < 10)			continue;		g_lockSync.ReadLock();		bLock = true;		pService->m_lastDetectMove = tmNow;		char szTemp[100] = { 0 };		::GetPrivateProfileString("SET", "momp", "", szTemp, sizeof(szTemp), strIniPath);		g_strMoMp = szTemp;		//SPDLOG_INFO("扳动判断:{}", g_strMoMp);		auto& mapDevice = CDeviceMng::Instance()->m_map_devices;		for (auto& it : mapDevice)		{			auto pDevice = it.second;			for (auto i = 0; i < 3; i++)			{				string mo, mp;				if (FALSE == CMonitorObjectMng::Instance()->IMEI2MOMP(pDevice->imei, i, mo, mp))				{					//CSimpleLog::Error(fmt::format("IMEI2MOMP fail. imei:{}, idx:{}, {}:{}", pDevice->imei, i, __FILE__, __LINE__).c_str());					continue;  //没有绑定返回				}				std::map<time_t, tagSecondStatInfo> map0, map1, map2;				std::map<time_t, int>* mapData[3] = { 0 };				if (i == 0)				{					if (tmNow - pDevice->GetUpdateTime(0) < 3) continue; //3秒钟 无数据上送 开始判断					else if (tmNow - pDevice->m_tmMoveDetectTime0 < 10) continue; //距离上次应大于10秒					else if (pDevice->m_mapSecondStatInfo00.size() == 0) continue;					const auto tCheck = pDevice->m_tmMoveDetectTime0;					lock_guard<mutex> lock(pDevice->m_mtx);					for (auto it = pDevice->m_mapSecondStatInfo00.rbegin(); it != pDevice->m_mapSecondStatInfo00.rend(); it++)					{						if (it->first < tCheck) break;						map0.insert(*it);					}					for (auto it = pDevice->m_mapSecondStatInfo01.rbegin(); it != pDevice->m_mapSecondStatInfo01.rend(); it++)					{						if (it->first < tCheck) break;						map1.insert(*it);					}					for (auto it = pDevice->m_mapSecondStatInfo02.rbegin(); it != pDevice->m_mapSecondStatInfo02.rend(); it++)					{						if (it->first < tCheck) break;						map2.insert(*it);					}					if (map2.size() > 2)					{ //拷贝原始数据						time_t tStart = 0;						std::map<time_t, int>::iterator itStart2;						if (tCheck)						{							for (auto ii = tCheck; ii < tmNow; ii++)							{								itStart2 = pDevice->map_resist_idx02.find(ii*1000);								if (itStart2 != pDevice->map_resist_idx02.end())								{									tStart = ii*1000;									break;								}							}						}						else						{							itStart2 = pDevice->map_resist_idx02.begin();							tStart = itStart2->first;						}						if (tStart)						{							mapData[0] = new std::map<time_t, int>(pDevice->map_resist_idx00.find(tStart), pDevice->map_resist_idx00.end());							mapData[1] = new std::map<time_t, int>(pDevice->map_resist_idx01.find(tStart), pDevice->map_resist_idx01.end());							mapData[2] = new std::map<time_t, int>(itStart2, pDevice->map_resist_idx02.end());						}						else							ASSERT(0);					}					pDevice->m_tmMoveDetectTime0 = tmNow;				}				else if (i == 1)				{					if (tmNow - pDevice->GetUpdateTime(1) < 3) continue; //3秒钟 无数据上送 开始判断					else if (tmNow - pDevice->m_tmMoveDetectTime1 < 10) continue; //距离上次应大于10秒					else if (pDevice->m_mapSecondStatInfo10.size() == 0) continue;					const auto tCheck = pDevice->m_tmMoveDetectTime1;					lock_guard<mutex> lock(pDevice->m_mtx);					for (auto it = pDevice->m_mapSecondStatInfo10.rbegin(); it != pDevice->m_mapSecondStatInfo10.rend(); it++)					{						if (it->first < tCheck) break;						map0.insert(*it);					}					for (auto it = pDevice->m_mapSecondStatInfo11.rbegin(); it != pDevice->m_mapSecondStatInfo11.rend(); it++)					{						if (it->first < tCheck) break;						map1.insert(*it);					}					for (auto it = pDevice->m_mapSecondStatInfo12.rbegin(); it != pDevice->m_mapSecondStatInfo12.rend(); it++)					{						if (it->first < tCheck) break;						map2.insert(*it);					}					if (map2.size() > 2)					{ //拷贝原始数据						time_t tStart = 0;						std::map<time_t, int>::iterator itStart2;						if (tCheck)						{							for (auto ii = tCheck; ii < tmNow; ii++)							{								itStart2 = pDevice->map_resist_idx12.find(ii*1000);								if (itStart2 != pDevice->map_resist_idx12.end())								{									tStart = ii*1000;									break;								}							}						}						else						{							itStart2 = pDevice->map_resist_idx12.begin();							tStart = itStart2->first;						}						if (tStart)						{							mapData[0] = new std::map<time_t, int>(pDevice->map_resist_idx10.find(tStart), pDevice->map_resist_idx10.end());							mapData[1] = new std::map<time_t, int>(pDevice->map_resist_idx11.find(tStart), pDevice->map_resist_idx11.end());							mapData[2] = new std::map<time_t, int>(itStart2, pDevice->map_resist_idx12.end());						}						else							ASSERT(0);					}					pDevice->m_tmMoveDetectTime1 = tmNow;				}				else				{					if (tmNow - pDevice->GetUpdateTime(2) < 3) continue; //3秒钟 无数据上送 开始判断					else if (tmNow - pDevice->m_tmMoveDetectTime2 < 10) continue; //距离上次应大于10秒					else if (pDevice->m_mapSecondStatInfo20.size() == 0) continue;					//else if (pDevice->m_mapSecondStatInfo20.rbegin()->second.dif_val > 100) continue;  //最后值需要稳定  2024年5月31日移除					//else if (pDevice->m_mapSecondStatInfo21.rbegin()->second.dif_val > 100) continue;					//else if (pDevice->m_mapSecondStatInfo22.rbegin()->second.dif_val > 100) continue;					const auto tCheck = pDevice->m_tmMoveDetectTime2;					lock_guard<mutex> lock(pDevice->m_mtx);					for (auto it = pDevice->m_mapSecondStatInfo20.rbegin(); it != pDevice->m_mapSecondStatInfo20.rend(); it++)					{						//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"));						if (it->first < tCheck) break;						map0.insert(*it);					}					for (auto it = pDevice->m_mapSecondStatInfo21.rbegin(); it != pDevice->m_mapSecondStatInfo21.rend(); it++)					{						//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"));						if (it->first < tCheck) break;						map1.insert(*it);					}					for (auto it = pDevice->m_mapSecondStatInfo22.rbegin(); it != pDevice->m_mapSecondStatInfo22.rend(); it++)					{						//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"));						if (it->first < tCheck) break;						map2.insert(*it);					}					if (map2.size() > 2)					{ //拷贝原始数据						time_t tStart = 0;						std::map<time_t, int>::iterator itStart2;						if (tCheck)						{							for (auto ii = tCheck; ii < tmNow; ii++)							{								itStart2 = pDevice->map_resist_idx22.find(ii*1000);								if (itStart2 != pDevice->map_resist_idx22.end())								{									tStart = ii*1000;									break;								}							}						}						else						{							itStart2 = pDevice->map_resist_idx22.begin();							tStart = itStart2->first;						}						if (tStart)						{							mapData[0] = new std::map<time_t, int>(pDevice->map_resist_idx20.find(tStart), pDevice->map_resist_idx20.end());							mapData[1] = new std::map<time_t, int>(pDevice->map_resist_idx21.find(tStart), pDevice->map_resist_idx21.end());							mapData[2] = new std::map<time_t, int>(itStart2, pDevice->map_resist_idx22.end());						}						else							assert(0);					}					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());					pDevice->m_tmMoveDetectTime2 = tmNow;				}								if (map2.size() <= 2) continue;				if (!mapData[0] && !mapData[1] && !mapData[2]) continue;				if (mapData[0]->size() != mapData[1]->size() || mapData[1]->size() != mapData[2]->size()) continue;				SPDLOG_INFO("扳动判断数据{}.{} map:{} 0:{} 1:{} 2:{}", mo, mp, map2.size(), mapData[0]->size(), mapData[1]->size(), mapData[2]->size());				list<CONVERT_RESIST> lstResit2;   //转换力数据				list<PASS_RESIST> lstPass;   //过车数据				list<FRICTION_RESIST> lstFriction; //摩擦力数据				std::map<time_t, int64_t> maxlock0, maxlock1;//锁闭力 前面时间戳, 后面 高4位显示值,  低4位报警值				std::map<time_t, int64_t>  retentionforce0, retentionforce1; //保持力 时间戳,  高4位显示值, 低4位报警值				mg_per_session_data::GetMaxResistNew(map2, lstResit2, mo, mp);				if (g_bDataCompression)				{					SPDLOG_INFO("[过车判断]{}.{} 开始过车判断 size:{}", mo, mp, map0.size());					mg_per_session_data::GetPassNew(map0, mapData[0], map1, mapData[1], mo, mp, &lstPass);					SPDLOG_INFO("[过车判断]{}.{} 结束过车判断 size:{} pass:{}", mo, mp, map0.size(), lstPass.size());					//过车过滤					for (auto& item : lstPass)					{						for (auto it = lstResit2.begin(); it != lstResit2.end();)						{							if (it->tmStart * 1000 <= item.show_time && item.show_time <= (it->tmEnd + 1) * 1000)							{								it = lstResit2.erase(it);								break;							}							++it;						}					}				}				//摩擦力过滤				for (auto it = lstResit2.begin(); it != lstResit2.end();)				{					int first_value = 0, last_value = 0;					auto ii = map2.find(it->tmStart);					ASSERT(ii != map2.end());					first_value = ii->second.first_val;					ii = map2.find(it->tmEnd);					if (ii == map2.end())						ii = map2.find(it->tmEnd - 1);					ASSERT(ii != map2.end());					last_value = ii->second.end_val;					auto dif = last_value - first_value;					auto strLog = fmt::format("[摩擦力判断]{}  first:{}  last:{} dif:{}",						CTime(it->time / 1000).Format("%Y-%m-%d %H:%M:%S"), first_value, last_value, dif);					if (dif > 1000 || dif < -1000)					{						SPDLOG_INFO(strLog);						if (it->tmEnd - it->tmStart >= 4)						{							FRICTION_RESIST info;							info.peak_time = it->time;							info.peak_val = it->val;							info.show_time = ii->first * 1000;							info.show_val = dif;  //稳态值显示差值							info.curr_val = last_value;  //显示的位置							info.tmStart = it->tmStart;							info.tmEnd = it->tmEnd;							info.t = strLog;							info.bUpOrDown = it->bUpOrDown;							lstFriction.emplace_back(info);						}						it = lstResit2.erase(it);					}					else						++it;				}				if (lstResit2.size())				{					mg_per_session_data::GetMaxLockNew(map0, lstResit2, maxlock0, retentionforce0);					mg_per_session_data::GetMaxLockNew(map1, lstResit2, maxlock1, retentionforce1);					SPDLOG_INFO("[转换阻力][{}:{}] lock0:{}  lock1:{}, resist2:{}", mo, mp, maxlock0.size(), maxlock1.size(), lstResit2.size());				}				auto pMompInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(mo + "." + mp);				ASSERT(pMompInfo);				//扳动处理逻辑				if (lstResit2.size())				{					//获取报警设置					//转换阻力报警设置项					auto pConvertResistOverLimitInfo =						(CONVERT_RESIST_OVER_LIMIT*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::CONVERT_LIMIT);					//定位锁闭力报警设置项					auto pFixSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);					//反位					auto pInvertSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);					//定位保持力报警设置项					auto pFixConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::RETENSION_FORCE);					if (pFixConstRetensionForceWaveInfo == nullptr)//默认开启					{						//ASSERT(FALSE);						//pFixConstRetensionForceWaveInfo = new RETENSION_FORCE_DROP;						///pService->Insert(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pFixConstRetensionForceWaveInfo);					}					//反位					auto pInvertConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::RETENSION_FORCE);					if (pInvertConstRetensionForceWaveInfo == nullptr)//默认开启					{						//ASSERT(FALSE);						//pInvertConstRetensionForceWaveInfo = new RETENSION_FORCE_DROP;						//pService->Insert(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pInvertConstRetensionForceWaveInfo);					}					//获取报警设置 end					eDaoChaPosi posiLock0;					if (pMompInfo->name1.find("定位") != -1)					{						posiLock0 = eDaoChaPosi::DCP_FIX;						for (auto& it : maxlock0)						{							int show_val = (it.second >> 32);							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,								(int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));							JudgeAlarm(pService, pFixSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno);						}						for (auto& it : retentionforce0)						{							int show_val = (int)it.second;							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,								(int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));							JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo);						}						for (auto& it : maxlock1)						{							int show_val = (it.second >> 32);							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,								(int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));							JudgeAlarm(pService, pInvertSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo->zzjno);						}						for (auto& it : retentionforce1)						{							int show_val = (int)it.second;							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,								(int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));							JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo);						}					}					else					{						posiLock0 = eDaoChaPosi::DCP_INVERT;						for (auto& it : maxlock0)						{							int show_val = (it.second >> 32);							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,								(uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));							JudgeAlarm(pService, pInvertSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo->zzjno);						}						for (auto& it : retentionforce0)						{							int show_val = (int)it.second;							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,								(uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));							JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo);						}						for (auto& it : maxlock1)						{							int show_val = (it.second >> 32);							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,								(uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_LOCK, fmt::format("锁闭力:{}", show_val));							JudgeAlarm(pService, pFixSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno);						}						for (auto& it : retentionforce1)						{							int show_val = (int)it.second;							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,								(uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));							JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo);						}					}					auto mg_315_server = g_p315ClientManager->GetTcpClient();					//SPDLOG_INFO("扳动判断数据{}.{} 转换力", mo, mp);					auto eqpno = CMonitorObjectMng::Instance()->GetZZJNO(mo + "." + mp);					for (auto& it : lstResit2)					{						//auto it_start0 = mapData[0]->find(it.tmStart * 1000);						//auto it_end0 = mapData[0]->find(it.tmEnd * 1000);						//auto it_start1 = mapData[1]->find(it.tmStart * 1000);						//auto it_end1 = mapData[1]->find(it.tmEnd * 1000);						//auto it_start2 = mapData[2]->find(it.tmStart * 1000);						//auto it_end2 = mapData[2]->find(it.tmEnd * 1000);						eDaoChaPosi posi = eDaoChaPosi::DCP_UNKNOWN;						if (it.bUpOrDown == eUpOrDownInfo::UOD_UP)						{							if (pMompInfo->in_name.find("定扳反") != -1)							{								CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,									(uint8_t)eDaoChaPosi::DCP_FIX2INVERT, (uint8_t)ePowerName::PN_MOVE, fmt::format("{}:{}", pMompInfo->in_name, it.fluctuation_val));								posi = eDaoChaPosi::DCP_FIX2INVERT;								CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_INVERT);								JudgeAlarm(pService, pConvertResistOverLimitInfo, it.time, it.fluctuation_val, posi, it.bUpOrDown, mo, mp, pMompInfo->zzjno);							}							else							{								CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,									(uint8_t)eDaoChaPosi::DCP_INVERT2FIX, (uint8_t)ePowerName::PN_MOVE, fmt::format("{}:{}", pMompInfo->in_name, it.fluctuation_val));								posi = eDaoChaPosi::DCP_INVERT2FIX;								CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_FIX);								JudgeAlarm(pService, pConvertResistOverLimitInfo, it.time, it.fluctuation_val, posi, it.bUpOrDown, mo, mp, pMompInfo->zzjno);							}						}						else						{							if (pMompInfo->out_name.find("定扳反") != -1)							{								CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,									(uint8_t)eDaoChaPosi::DCP_FIX2INVERT, (uint8_t)ePowerName::PN_MOVE, fmt::format("{}:{}", pMompInfo->out_name, it.fluctuation_val));								posi = eDaoChaPosi::DCP_FIX2INVERT;								CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_INVERT);								JudgeAlarm(pService, pConvertResistOverLimitInfo, it.time, it.fluctuation_val, posi, it.bUpOrDown, mo, mp, pMompInfo->zzjno);							}							else							{								CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,									(uint8_t)eDaoChaPosi::DCP_INVERT2FIX, (uint8_t)ePowerName::PN_MOVE, fmt::format("{}:{}", pMompInfo->out_name, it.fluctuation_val));								posi = eDaoChaPosi::DCP_INVERT2FIX;								CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_FIX);								JudgeAlarm(pService, pConvertResistOverLimitInfo, it.time, it.fluctuation_val, posi, it.bUpOrDown, mo, mp, pMompInfo->zzjno);							}						}						SPDLOG_INFO("扳动判断数据{}.{} 315 上送", mo, mp);						if(mapData[0])							mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);						SPDLOG_INFO("扳动判断数据结束{}.{} 315 上送", mo, mp);					}				}				//过车处理逻辑				if (lstPass.size())				{					//TODO					//SPDLOG_INFO("扳动判断数据{}.{} 315 上送", mo, mp);					//mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);					//SPDLOG_INFO("扳动判断数据结束{}.{} 315 上送", mo, mp);				}				//摩檫力逻辑				if (lstFriction.size())				{					pMompInfo;					auto pAlarmSet = (FRICTION_OVER_LIMIT_INFO*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::FRICTION_OVER_LIMIT);					auto mg_315_server = g_p315ClientManager->GetTcpClient();					for (auto& it : lstFriction)					{						CResistAlarmMng::InsertToDBByMove(mo, mp, it.show_time, it.tmStart, it.tmEnd, it.curr_val, it.show_val, 2,							(uint8_t)eDaoChaPosi::DCP_UNKNOWN, (uint8_t)ePowerName::PN_FRICTION, fmt::format("稳态值:{}", it.show_val));						//CMonitorObjectMng::Instance()->UpdateZZJEPOS(mo + "." + mp, DAOCHA_POSITION::MP_QUARTO); //四开						JudgeAlarm(pService, pAlarmSet, it.show_time, it.show_val, eDaoChaPosi::DCP_UNKNOWN, it.bUpOrDown, (void*)pMompInfo);						//发送315曲线数据						//if (mapData[0])						//	mg_315_server->SendCurveData(pMompInfo->zzjno, eDaoChaPosi::DCP_UNKNOWN, 1, true, mapData, it.tmStart, it.tmEnd);					}				}				delete mapData[0];				delete mapData[1];				delete mapData[2];			}		}	} while (pService->m_bWork);	if (bLock)	{		g_lockSync.Unlock();		bLock = false;	}}void CResistAlarmMng::ThreadProcMoveFromDB(DWORD_PTR param){	auto pService = (CResistAlarmMng*)param;	auto ctLast = CTime::GetCurrentTime();	Sleep(2000);	auto pDBConn = CDBConnectPool::Instance()->GetConnection();	do 	{		Sleep(100);   //每100ms 获取一次		string table_today = fmt::format("rm_move_{:0>4}{:0>2}", ctLast.GetYear(), ctLast.GetMonth());		auto ctNow = CTime::GetCurrentTime();		//加载数据		CString sql = fmt::format("SELECT mo,mp,show_time,start_time,end_time,curr_val,show_val,\			idx,posi,mark,type,sunroof FROM {} WHERE show_time >= '{}' ORDER BY show_time ASC;", table_today, ctLast.Format("%Y-%m-%d %H:%M:%S")).c_str();		ctLast = ctNow;       COdbcStatement stmt;	   if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))	   {		   ASSERT(0);		   continue;	   }	   //绑定数据	   int nCol = 1;	   char mo[51], mp[51];	   TIMESTAMP_STRUCT show_time, start_time, end_time;	   int curr_val, show_val;	   uint8_t idx, posi, type, sunroof;	   char mark[100];	   stmt.BindCharCol(nCol++, mo, sizeof(mo));	   stmt.BindCharCol(nCol++, mp, sizeof(mp));	   stmt.BindTimeStampCol(nCol++, &show_time);	   stmt.BindTimeStampCol(nCol++, &start_time);	   stmt.BindTimeStampCol(nCol++, &end_time);	   stmt.BindIntCol(nCol++, &curr_val);	   stmt.BindIntCol(nCol++, &show_val);	   stmt.BindTinyIntCol(nCol++, &idx);	   stmt.BindTinyIntCol(nCol++, &posi);	   stmt.BindCharCol(nCol++, mark, sizeof(mark));	   stmt.BindTinyIntCol(nCol++, &type);	   stmt.BindTinyIntCol(nCol++, &sunroof);	   ST_MOMP_INFO* pMompInfo = nullptr;	   auto mg_315_server = g_p315ClientManager->GetTcpClient();	   int nCount = 0;	   //获取数据	   do	   {		   if (stmt.FetchNext() != 0) break;		   //类型条件语句		   auto ePosi = (eDaoChaPosi)posi;		   auto eType = (ePowerName)type;		   if (pMompInfo == nullptr || pMompInfo->mo.compare(mo) != 0 || pMompInfo->mp.compare(mp) != 0)			   pMompInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(string(mo) + "." + mp);		   if (pMompInfo == nullptr) continue;		   CTime ctAlarm = CTime(show_time.year, show_time.month, show_time.day, show_time.hour, show_time.minute, show_time.second);		   time_t show_time_t = ctAlarm.GetTime() * 1000			   + show_time.fraction / 1000000;		   nCount++;		   switch (eType)		   {		   case ePowerName::PN_LOCK:		   {			   //报警判断			   if (ePosi == eDaoChaPosi::DCP_FIX)			   {				   auto pFixSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);				   JudgeAlarm(pService, pFixSuobiOverInfo, show_time_t, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno);			   }			   else if (ePosi == eDaoChaPosi::DCP_INVERT)			   {				   auto pInvertSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);				   JudgeAlarm(pService, pInvertSuobiOverInfo, show_time_t, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo->zzjno);			   }		   }			   break;		   case ePowerName::PN_RETENTION:		   {			   if (ePosi == eDaoChaPosi::DCP_FIX)			   {				   auto pFixConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::RETENSION_FORCE);				   JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, show_time_t, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo);			   }			   else if (ePosi == eDaoChaPosi::DCP_INVERT)			   {				   auto pInvertConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::RETENSION_FORCE);				   JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, show_time_t, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo);			   }		   }			   break;		   case ePowerName::PN_MOVE:		   {			   //转换阻力报警设置项			   auto pConvertResistOverLimitInfo =				   (CONVERT_RESIST_OVER_LIMIT*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::CONVERT_LIMIT);			   if (ePosi == eDaoChaPosi::DCP_FIX2INVERT)			   {				   //更新状态				   CMonitorObjectMng::Instance()->UpdateZZJEPOS(string(mo) + "." + mp, DAOCHA_POSITION::MP_INVERT);				   SPDLOG_INFO("{}:{} 更新到反位", mo, mp);				   if (pMompInfo->out_name.find("定扳反") != -1)						JudgeAlarm(pService, pConvertResistOverLimitInfo, show_time_t, show_val, ePosi, eUpOrDownInfo::UOD_DOWN, mo, mp, pMompInfo->zzjno);				   else if (pMompInfo->in_name.find("定扳反") != -1)					   JudgeAlarm(pService, pConvertResistOverLimitInfo, show_time_t, show_val, ePosi, eUpOrDownInfo::UOD_UP, mo, mp, pMompInfo->zzjno);			   }			   else if (ePosi == eDaoChaPosi::DCP_INVERT2FIX)			   {				   //更新状态				   CMonitorObjectMng::Instance()->UpdateZZJEPOS(string(mo) + "." + mp, DAOCHA_POSITION::MP_FIX);				   SPDLOG_INFO("{}:{} 更新到定位", mo, mp);				   if (pMompInfo->out_name.find("反扳定") != -1)					   JudgeAlarm(pService, pConvertResistOverLimitInfo, show_time_t, show_val, ePosi, eUpOrDownInfo::UOD_DOWN, mo, mp, pMompInfo->zzjno);				   else if (pMompInfo->in_name.find("反扳定") != -1)					   JudgeAlarm(pService, pConvertResistOverLimitInfo, show_time_t, show_val, ePosi, eUpOrDownInfo::UOD_UP, mo, mp, pMompInfo->zzjno);			   }				//TODO发送315曲线				// mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);		   }			   break;		   case ePowerName::PN_FRICTION:		   {			   //摩擦力			   auto pAlarmSet = (FRICTION_OVER_LIMIT_INFO*)pService->Find(mo, mp, 2, eZL_ALARMTYPE::FRICTION_OVER_LIMIT);			   JudgeAlarm(pService, pAlarmSet, show_time_t, show_val, eDaoChaPosi::DCP_UNKNOWN, show_val < 0 ? eUpOrDownInfo::UOD_DOWN : eUpOrDownInfo::UOD_UP, pMompInfo);			   //TODO发送315曲线			   //mg_315_server->SendCurveData(pMompInfo->zzjno, posi, 1, true, mapData, it.tmStart, it.tmEnd);		   }			   break;		   default:			   SPDLOG_WARN("[扳动数据有误]{}:{} type:{}", mo, mp, type);			   ASSERT(0);			   break;		   }	   } while (true);	   stmt.Close();	   SPDLOG_INFO("外部加载扳动数据:{}条 语句:{}", nCount, sql);	} while (pService->m_bWork);	CDBConnectPool::Instance()->FreeConnection(pDBConn);}BOOL CResistAlarmMng::LoadAlarmSet(){	CString sql = "SELECT [mo],[mp],[no],[type],[conf],[time] FROM [rm_alarm_set]";	COdbcStatement stmt;	if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))	{		CSimpleLog::Error("执行语句失败" + sql);		return FALSE;	}	for (auto& it : m_alarm_set)	{		//delete it.second; //暂时不释放		it.second = nullptr;	}	m_alarm_set.clear();	char mo[51], mp[51], conf[501];	uint8_t no, type;	__time64_t time;	int nCol = 1;	stmt.BindCharCol(nCol++, mo, sizeof(mo));	stmt.BindCharCol(nCol++, mp, sizeof(mp));	stmt.BindTinyIntCol(nCol++, &no);	stmt.BindTinyIntCol(nCol++, &type);	stmt.BindCharCol(nCol++, conf, sizeof(conf));	stmt.BindBigIntCol(nCol++, &time);	do 	{		if (stmt.FetchNext() != 0) break;		using namespace rapidjson;		int len = strlen(conf);		if (len == 0) continue;		Document doc;		if (doc.Parse(conf, len).HasParseError())		{			CSimpleLog::Error(CString("解析数据出错") + conf);			continue;		}		const auto eType = (eZL_ALARMTYPE)type;		if (eType == eZL_ALARMTYPE::MAX_OVER_LIMIT)		{			if (doc.IsArray() == false)			{				CSimpleLog::Error(CString("conf是非数组") + conf);				continue;			}			SizeType n = doc.Size();			bool enable = false;			int alarm_high_limit = INT_MAX;			int warn_high_limit = INT_MAX;			int f_alarm_high_limit = INT_MAX;			int f_warn_high_limit = INT_MAX;			for (SizeType i = 0; i < n; i++)			{				if (doc[i].HasMember("name") == false || doc[i].HasMember("val") == false || doc[i]["name"].IsString() == false || doc[i]["val"].IsString() == false)				{					assert(false);					continue;				}				string key = doc[i]["name"].GetString();				string value = doc[i]["val"].GetString();				if (key.compare("enable") == 0)				{					enable = (value.compare("true") == 0);				}				else if (key.compare("lock_alarm_high_limit") == 0)				{					alarm_high_limit = atoi(value.c_str());				}				else if (key.compare("lock_warn_high_limit") == 0)				{					warn_high_limit = atoi(value.c_str());				}				else if (key.compare("d_alarm_high_limit") == 0)				{					alarm_high_limit = atoi(value.c_str());				}				else if (key.compare("d_warn_high_limit") == 0)				{					warn_high_limit = atoi(value.c_str());				}				else if (key.compare("f_alarm_high_limit") == 0)				{					f_alarm_high_limit = atoi(value.c_str());				}				else if (key.compare("f_warn_high_limit") == 0)				{					f_warn_high_limit = atoi(value.c_str());				}				else if (key.compare("keep_alarm_high_limit") == 0)				{					f_alarm_high_limit = atoi(value.c_str());				}				else if (key.compare("keep_warn_high_limit") == 0)				{					f_warn_high_limit = atoi(value.c_str());				}				else				{					assert(0);				}			}			if (alarm_high_limit == INT_MAX || warn_high_limit == INT_MAX) continue;			auto pInfo = new MAX_OVER_LIMIT_INFO;			pInfo->enable = enable;			pInfo->no = no;			pInfo->type = eType;			pInfo->alarm_high_limit = alarm_high_limit;			pInfo->warn_high_limit = warn_high_limit;			pInfo->f_alarm_high_limit = f_alarm_high_limit;			pInfo->f_warn_high_limit = f_warn_high_limit;			pInfo->tmLastCheckTime = time;			sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);			stringstream ss;			ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);			m_alarm_set[ss.str()] = pInfo;		}		else if (eType == eZL_ALARMTYPE::FRICTION_OVER_LIMIT)		{			if (doc.IsArray() == false)			{				CSimpleLog::Error(CString("conf是非数组") + conf);				continue;			}			SizeType n = doc.Size();			bool enable = false;			int up_alarm_low_limit = INT_MAX;			int up_warn_low_limit = INT_MAX;			int dw_alarm_high_limit = INT_MIN;			int dw_warn_high_limit = INT_MIN;			for (SizeType i = 0; i < n; i++)			{				if (doc[i].HasMember("name") == false || doc[i].HasMember("val") == false || doc[i]["name"].IsString() == false || doc[i]["val"].IsString() == false)				{					assert(false);					continue;				}				string key = doc[i]["name"].GetString();				string value = doc[i]["val"].GetString();				if (key.compare("enable") == 0)				{					enable = (value.compare("true") == 0);				}				else if (key.compare("up_alarm_low_limit") == 0)				{					up_alarm_low_limit = atoi(value.c_str());				}				else if (key.compare("up_warn_low_limit") == 0)				{					up_warn_low_limit = atoi(value.c_str());				}				else if (key.compare("dw_alarm_high_limit") == 0)				{					dw_alarm_high_limit = atoi(value.c_str());				}				else if (key.compare("dw_warn_high_limit") == 0)				{					dw_warn_high_limit = atoi(value.c_str());				}				else				{					assert(0);				}			}			auto pInfo = new FRICTION_OVER_LIMIT_INFO;			pInfo->enable = enable;			pInfo->no = no;			pInfo->type = eType;			pInfo->up_alarm_low_limit = up_alarm_low_limit;			pInfo->up_warn_low_limit = up_warn_low_limit;			pInfo->dw_alarm_high_limit = dw_alarm_high_limit;			pInfo->dw_warn_high_limit = dw_warn_high_limit;			pInfo->tmLastCheckTime = time;			sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);			stringstream ss;			ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);			m_alarm_set[ss.str()] = pInfo;		}		else if (eType == eZL_ALARMTYPE::SUOBI_LOCK_LIMIT)		{			auto doc = yyjson_read(conf, len, 0);			if (doc == nullptr) continue;			auto root = yyjson_doc_get_root(doc);			auto pInfo = new SUOBI_OVER_LIMIT_INFO;			pInfo->type = eZL_ALARMTYPE::SUOBI_LOCK_LIMIT;			pInfo->no = no;			pInfo->enable = yyjson_get_bool(yyjson_obj_get(root, "enable"));			pInfo->alarm_low_limit = yyjson_get_int(yyjson_obj_get(root, "alarm_low_limit"));			pInfo->warn_low_limit = yyjson_get_int(yyjson_obj_get(root, "warn_low_limit"));			pInfo->alarm_high_limit = yyjson_get_int(yyjson_obj_get(root, "alarm_high_limit"));			pInfo->warn_high_limit = yyjson_get_int(yyjson_obj_get(root, "warn_high_limit"));			sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);			stringstream ss;			ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);			m_alarm_set[ss.str()] = pInfo;			yyjson_doc_free(doc);		}		else if (eType == eZL_ALARMTYPE::CONVERT_LIMIT)		{			auto doc = yyjson_read(conf, len, 0);			if (doc == nullptr) continue;			auto root = yyjson_doc_get_root(doc);			auto pInfo = new CONVERT_RESIST_OVER_LIMIT;			pInfo->type = eZL_ALARMTYPE::CONVERT_LIMIT;			pInfo->no = 2;			pInfo->enable = yyjson_get_bool(yyjson_obj_get(root, "enable"));			pInfo->dw_alarm_low_limit = yyjson_get_int(yyjson_obj_get(root, "dw_alarm_low_limit"));			pInfo->dw_warn_low_limit = yyjson_get_int(yyjson_obj_get(root, "dw_warn_low_limit"));			pInfo->up_alarm_high_limit = yyjson_get_int(yyjson_obj_get(root, "up_alarm_high_limit"));			pInfo->up_warn_high_limit = yyjson_get_int(yyjson_obj_get(root, "up_warn_high_limit"));			sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);			stringstream ss;			ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);			m_alarm_set[ss.str()] = pInfo;			yyjson_doc_free(doc);		}		else if (eType == eZL_ALARMTYPE::RETENSION_FORCE)		{			auto doc = yyjson_read(conf, len, 0);			if (doc == nullptr) continue;			auto root = yyjson_doc_get_root(doc);			auto pInfo = new RETENSION_FORCE_DROP;			pInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;			pInfo->no = no;			pInfo->enable = yyjson_get_bool(yyjson_obj_get(root, "enable"));			pInfo->dw_alarm_low_drop = yyjson_get_int(yyjson_obj_get(root, "dw_alarm_low_drop"));			pInfo->alarm_high_percent = yyjson_get_int(yyjson_obj_get(root, "alarm_high_percent"));			pInfo->alarm_low_percent = yyjson_get_int(yyjson_obj_get(root, "alarm_low_percent"));			sprintf_s(pInfo->momp, 20, "%s.%s", mo, mp);			stringstream ss;			ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);			m_alarm_set[ss.str()] = pInfo;			yyjson_doc_free(doc);		}		else		{			ASSERT(0);		}	} while (true);	//2024年8月23日 开启默认开启最低3000N报警	const auto& mapInfo = CMonitorObjectMng::Instance()->m_mapMoMpInfo;	for (auto& it : mapInfo)	{		if (Find(it.second->mo, it.second->mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::RETENSION_FORCE))		{		}		else		{			auto pInfo = new RETENSION_FORCE_DROP;			pInfo->no = (uint8_t)eSuoBiPosi::SB_FIX;			pInfo->enable = true;			pInfo->dw_alarm_low_drop = 3000;			sprintf_s(pInfo->momp, 20, "%s.%s", it.second->mo.c_str(), it.second->mp.c_str());			Insert(it.second->mo, it.second->mp, pInfo->no, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pInfo);		}		if (Find(it.second->mo, it.second->mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::RETENSION_FORCE))		{		}		else		{			auto pInfo = new RETENSION_FORCE_DROP;			pInfo->no = (uint8_t)eSuoBiPosi::SB_INVERT;			pInfo->enable = true;			pInfo->dw_alarm_low_drop = 3000;			sprintf_s(pInfo->momp, 20, "%s.%s", it.second->mo.c_str(), it.second->mp.c_str());			Insert(it.second->mo, it.second->mp, pInfo->no, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pInfo);		}	}	CSimpleLog::Info(fmt::format("一共加载到{}条报警规则:{}", m_alarm_set.size(), sql).c_str());	return TRUE;}BOOL CResistAlarmMng::LoadAlarmID(){	CString sql = "SELECT TOP 1 ID FROM RM_ALARM ORDER BY ID DESC";	COdbcStatement stmt;	if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))	{		CSimpleLog::Error("执行语句失败" + sql);		return FALSE;	}	int alarm_id;	int nCol = 1;	stmt.BindIntCol(nCol++, &alarm_id);	do	{		if (stmt.FetchNext() != 0) break;		m_nAlarmID = alarm_id;	} while (false);	stmt.Close();	return TRUE;}//加载未受理和未恢复的报警BOOL CResistAlarmMng::LoadUnAck(){	//只加载31天内的报警	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 \		LEFT JOIN(SELECT mo, mp, zzjno FROM rm_map) AS B ON a.mo = b.mo and a.mp = b.mp \		WHERE DATEADD(dd, -31, getdate()) < occur_time and (ack_result = 0 OR [recovery_time] < '2000') \		ORDER BY ID; ";	COdbcStatement stmt;	if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))	{		ASSERT(FALSE);		CSimpleLog::Error("执行语句失败" + sql);		return FALSE;	}	char mo[51], mp[51], desc[200], suggest[200], event_id[37] = { 0 }, rel_id[37] = { 0 };	uint8_t no, type, level, posi, loworhigh, sunroof;	int val;	int id;	int zzjno;	TIMESTAMP_STRUCT ts,tsRecovery;	int referval;	int nCol = 1;	stmt.BindIntCol(nCol++, &id);	stmt.BindCharCol(nCol++, mo, sizeof(mo));	stmt.BindCharCol(nCol++, mp, sizeof(mp));	stmt.BindTinyIntCol(nCol++, &no);	stmt.BindTinyIntCol(nCol++, &type);	stmt.BindTimeStampCol(nCol++, &ts);	stmt.BindTinyIntCol(nCol++, &level);	stmt.BindCharCol(nCol++, desc, sizeof(desc));	stmt.BindCharCol(nCol++, suggest, sizeof(suggest));	stmt.BindIntCol(nCol++, &val);	stmt.BindCharCol(nCol++, event_id, 36);	stmt.BindCharCol(nCol++, rel_id, 36);	stmt.BindTinyIntCol(nCol++, &posi);	stmt.BindTinyIntCol(nCol++, &loworhigh);	stmt.BindIntCol(nCol++, &referval);	stmt.BindTimeStampCol(nCol++, &tsRecovery);	stmt.BindTinyIntCol(nCol++, &sunroof);	stmt.BindIntCol(nCol++, &zzjno);	do	{		if (stmt.FetchNext() != 0) break;		ALARM_INFO *pAlarm = new ALARM_INFO;		pAlarm->event_id = event_id;		if (rel_id[0] != 0x20)			pAlarm->rel_id = rel_id;		pAlarm->id = id;		pAlarm->mo = mo;		pAlarm->mp = mp;		pAlarm->no = no;		pAlarm->type = (eZL_ALARMTYPE)type;		ConvertData(ts, pAlarm->time);		pAlarm->val = val;		pAlarm->level = level;		pAlarm->desc = desc;		pAlarm->suggest = suggest;		pAlarm->posi = (eDaoChaPosi)posi;		pAlarm->loworhigh = (eLowHigh)loworhigh;		pAlarm->refer_val = referval;		ConvertData(tsRecovery, pAlarm->recoveryTime);		pAlarm->sunroof = sunroof;		pAlarm->zzjno = zzjno;		m_lstUnConfirmAlarm.push_back(pAlarm);	} while (true);	stmt.Close();	CSimpleLog::Info(("一共加载(" + to_string(m_lstUnConfirmAlarm.size()) + ")条未受理和未恢复的报警").c_str());	return TRUE;}
 |