| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865 | 
							- #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>
 
- 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;
 
- 	*/
 
- 	return TRUE;
 
- }
 
- void CResistAlarmMng::Stop()
 
- {
 
- 	m_bWork = false;
 
- 	if (m_pThreadAlarmSet)
 
- 	{
 
- 		m_pThreadAlarmSet->join();
 
- 		delete m_pThreadAlarmSet;
 
- 		m_pThreadAlarmSet = 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
 
- 			{
 
- 				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();
 
- 	for (it; it != m_lstUnConfirmAlarm.end(); ++it)
 
- 	{
 
- 		auto& pInfo = *it;
 
- 		if (alarm_id == pInfo->id)
 
- 		{
 
- 			pInfo->ack_result = 1;
 
- 			pInfo->ack_name = name;
 
- 			pInfo->ack_time = time;
 
- 			return true;
 
- 		}
 
- 	}
 
- 	return false;
 
- }
 
- 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)
 
- 		{
 
- 			m_lstUnConfirmAlarm.erase(it);
 
- 			return true;
 
- 		}
 
- 	}
 
- 	return false;
 
- }
 
- 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 == eZL_ALARMTYPE::SENSOR_ABNORMAL && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0 && no == alarm->no/* && ctAlarmTime - CTime(alarm->time) < cts*/) //跟上次报警时间超过1小时,则算新报警
 
- 			{
 
- 				pAlarmInfo = alarm;
 
- 				break;
 
- 			}
 
- 		}
 
- 	}
 
- 	if (pAlarmInfo == nullptr)
 
- 	{
 
- 		bNew = true;
 
- 		pAlarmInfo = new ALARM_INFO;
 
- 		pAlarmInfo->id = ++m_nAlarmID;
 
- 		pAlarmInfo->level = 1;
 
- 		pAlarmInfo->mo = mo;
 
- 		pAlarmInfo->mp = mp;
 
- 		pAlarmInfo->no = no;
 
- 		pAlarmInfo->time = tAlarm;
 
- 		//pAlarmInfo->time.wMilliseconds = alarm_time % 1000;
 
- 		pAlarmInfo->type = eZL_ALARMTYPE::SENSOR_ABNORMAL;
 
- 		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]) "\
 
- 			"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %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);
 
- 		if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
 
- 		{
 
- 			CSimpleLog::Error("执行语句失败" + sql);
 
- 		}
 
- 	}
 
- }
 
- void CResistAlarmMng::RecoverAlarm(const string mo, const string mp, const uint8_t no, const eZL_ALARMTYPE type, const uint8_t level, const SYSTEMTIME& tAlarm)
 
- {
 
- 	uint32_t alarm_id = -1;
 
- 	{
 
- 		std::lock_guard<mutex> lock(m_mtxAlarm);
 
- 		for (auto it = m_lstUnConfirmAlarm.begin(); it != m_lstUnConfirmAlarm.end(); it++)
 
- 		{
 
- 			auto alarm = *it;
 
- 			if (alarm->type == type && alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0 && no == alarm->no && level == alarm->level/* && ctAlarmTime - CTime(alarm->time) < cts*/) //跟上次报警时间超过1小时,则算新报警
 
- 			{
 
- 				alarm_id = alarm->id;
 
- 				m_lstUnConfirmAlarm.erase(it);
 
- 				break;
 
- 			}
 
- 		}
 
- 	}
 
- 	if (alarm_id == -1)
 
- 		return;
 
- 	CTime ctAlarm(tAlarm);
 
- 	string ack_time = ctAlarm.Format("%Y-%m-%d %H:%M:%S");
 
- 	//更新数据库
 
- 	{
 
- 		CString sql;
 
- 		sql.Format("UPDATE [rm_alarm] SET ack_result = 1, ack_name='%s', ack_time='%s' WHERE ID = %d;",
 
- 			"系统", ack_time.c_str(), alarm_id);
 
- 		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", ack_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_NORMAL_GREEN;
 
- 	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)
 
- 		{
 
- 			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;
 
- }
 
- 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("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"));
 
- 	}
 
- 	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, string mark)
 
- {
 
- 	if (show_time == 0) return;
 
- 	CTime ctShowTime(show_time / 1000);
 
- 	string table_name = fmt::format("rm_move_{:0>4}{:0>2}", ctShowTime.GetYear(), ctShowTime.GetMonth());
 
- 	CString sql = fmt::format("INSERT INTO {} (mo,mp,show_time,start_time,end_time,curr_val,show_val,idx,posi,mark) values ('{}', '{}', '{}', '{}','{}', {}, {}, {}, {}, '{}');",
 
- 		table_name, mo, mp, (LPCSTR)ctShowTime.Format("%Y-%m-%d %H:%M:%S.") + to_string(show_time % 1000),
 
- 		start_time ? CTime(start_time).Format("%Y-%m-%d %H:%M:%S") : "", end_time ? CTime(end_time).Format("%Y-%m-%d %H:%M:%S") : "", curr_val, show_val, idx, posi, mark).c_str();
 
- 	if (CDBConnectPool::Instance()->DBExecuteSQL(sql) == FALSE)
 
- 		SPDLOG_ERROR(sql);
 
- }
 
- BOOL ConmpareValue(std::map<time_t, int>::const_iterator i, std::map<time_t, int>::const_iterator j, short refer_value, int& hight_num, int low_num)
 
- {
 
- 	int start_value = 0;
 
- 	for (i; 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;
 
- 	do 
 
- 	{
 
- 		Sleep(100);
 
- 		time(&tmNow);
 
- 		if (tmNow == pService->m_lastDetectTime)
 
- 			continue;
 
- 		pService->m_lastDetectTime = tmNow;
 
- 		//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 && item.second->type != eZL_ALARMTYPE::FRICTION_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); //TODO
 
- 			//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;
 
- 			short high_alarm_limit = SHORT_MAX, high_warn_limit = SHORT_MAX, low_alarm_limit = -SHORT_MAX, low_warn_limit = -SHORT_MAX, alarm_refer = SHORT_MAX;
 
- 			time_t tmNow; time(&tmNow);
 
- 			BASE_INFO* pAlarmSet = item.second;
 
- 			do{
 
- 				Sleep(100);
 
- 				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->type == eZL_ALARMTYPE::MAX_OVER_LIMIT)
 
- 				{
 
- 					auto pInfo = (MAX_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;
 
- #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;
 
- 						}
 
- 						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;
 
- 						}
 
- 					}
 
- 					for (++it; it != pData->cend(); ++it)
 
- 					{
 
- 						//CString str = CTime(it->first / 1000).Format("%Y-%m-%d %H:%M:%S");
 
- 						if (it->second == INVALID_RESIST)
 
- 						{
 
- 							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 == SHORT_MAX || pInfo->f_alarm_high_limit == SHORT_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 == SHORT_MAX || high_warn_limit == SHORT_MAX)
 
- 							{
 
- 								//未设置预警值
 
- 							}
 
- 							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;
 
- 							}
 
- 						}
 
- 					}
 
- 				}
 
- 				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);
 
- 			}
 
- 			if (bAlarm == false && bWarn == false) 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)
 
- 				{
 
- 					static CTimeSpan cts(0, 6, 0, 0); //报警间隔6小时重新生成报警
 
- 					if (alarm->no == item.second->no && alarm->type == pAlarmSet->type && level == alarm->level //预警和报警单独计算
 
- 						&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0 && ctAlarmTime - CTime(alarm->time) < cts) //跟上次报警时间超过1小时,则算新报警
 
- 					{
 
- 						pAlarmInfo = alarm;
 
- 						break;
 
- 					}
 
- 				}
 
- 			}
 
- 			if (pAlarmInfo == nullptr)
 
- 			{
 
- 				bNew = true;
 
- 				pAlarmInfo = new ALARM_INFO;
 
- 				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;
 
- 				char szInfo[200];
 
- 				if (desc_type == 1)
 
- 					sprintf_s(szInfo, sizeof(szInfo), "瞬时冲击力超限报警,报警值为%dN, 参考值为%dN", alarm_value, alarm_refer);
 
- 				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);
 
- 				else if (desc_type == 5)
 
- 					sprintf_s(szInfo, sizeof(szInfo), "摩擦力超限%s, 伸出位报警值为%dN, 参考值为:%dN", bAlarm == 1 ? "告警" : "预警", alarm_value, alarm_refer);
 
- 				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]) "\
 
- 					"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %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);
 
- 				if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
 
- 				{
 
- 					CSimpleLog::Error("执行语句失败" + sql);
 
- 				}
 
- 			}
 
- 		}
 
- 		//10秒归档一次
 
- 		/*采用滑动方式检测.每次检测15秒的数据.每次滑动10秒.
 
- 			即0分20秒时 取 0 - 15秒的数据, 下一次检测时间 0分30秒, 取10 - 25秒的数据.
 
- 			再下一次检测时间0分40秒, 取20 - 35秒数据.
 
- 		*/
 
- 		/*
 
- 		if (tmNow % 10 != 0) continue;
 
- 		
 
- 		auto& mapDevice = CDeviceMng::Instance()->m_map_devices;
 
- 		for (auto& it : mapDevice)
 
- 		{
 
- 			auto pDevice = it.second;
 
- 			if (pDevice->m_tmMoveDetectTime == 0)
 
- 				continue;
 
- 			time_t tmStart = pDevice->m_tmMoveDetectTime - 20; time_t tmEnd = pDevice->m_tmMoveDetectTime - 2;
 
- #ifdef _DEBUG
 
- 			string strStart = CTime(tmStart).Format("%Y-%m-%d %H:%M:%S");
 
- 			string strEnd = CTime(tmEnd).Format("%Y-%m-%d %H:%M:%S");
 
- 			TRACE("%s-%s\r\n", strStart.c_str(), strEnd.c_str());
 
- #endif // _DEBUG
 
- 			pDevice->m_tmMoveDetectTime += 10;
 
- 			for (auto i = 0; i < 3; i++)
 
- 			{
 
- 				std::map<time_t, tagSecondStatInfo> map0, map1, map2;
 
- 				if (pDevice->GetSendStatInfo(tmStart, tmEnd, i, map0, map1, map2) == FALSE) continue;
 
- 				list<CONVERT_RESIST> lstResit2;
 
- 				std::map<time_t, int64_t> maxlock0, maxlock1;
 
- 				mg_per_session_data::GetMaxResist(map2, lstResit2);
 
- 				if (lstResit2.size())
 
- 				{
 
- 					mg_per_session_data::GetMaxLockNew(map0, lstResit2, maxlock0);
 
- 					mg_per_session_data::GetMaxLockNew(map1, lstResit2, maxlock1);
 
- 				}
 
- 				string mo, mp;
 
- 				if (FALSE == CMonitorObjectMng::Instance()->IMEI2MOMP(pDevice->imei, i, mo, mp))
 
- 				{
 
- 					CSimpleLog::Error(fmt::format("IMEI2MOMP fail. imei:{}, idx:{}", pDevice->imei, i).c_str());
 
- 					continue;
 
- 				}
 
- 				string name1, name2, name3, out_name, in_name;
 
- 				CMonitorObjectMng::Instance()->GetNameByMoMp(mo + "." + mp, name1, name2, name3, out_name, in_name);
 
- 				for (auto& it : maxlock0)
 
- 				{
 
- 					if (name1.find("定位") != -1)
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_FIX, fmt::format("定位密贴锁闭力值:{}", (it.second >> 32)));
 
- 					else
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_INVERT, fmt::format("反位密贴锁闭力值:{}", (it.second >> 32)));
 
- 				}
 
- 				for (auto& it : maxlock1)
 
- 				{
 
- 					if (name2.find("定位") != -1)
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_FIX, fmt::format("定位密贴锁闭力值:{}", (it.second >> 32)));
 
- 					else
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_INVERT, fmt::format("反位密贴锁闭力值:{}", (it.second >> 32)));
 
- 				}
 
- 				for (auto& it : lstResit2)
 
- 				{
 
- 					if (it.bUpOrDown == 1)
 
- 					{
 
- 						if (in_name.find("定扳反") != -1)
 
- 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.val, it.fluctuation_val, i,
 
- 								(uint8_t)eDaoChaPosi::DCP_FIX2INVERT, fmt::format("{}转换值:{}", in_name, it.fluctuation_val));
 
- 						else
 
- 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.val, it.fluctuation_val, i,
 
- 								(uint8_t)eDaoChaPosi::DCP_INVERT2FIX, fmt::format("{}转换值:{}", in_name, it.fluctuation_val));
 
- 					}
 
- 					else
 
- 					{
 
- 						if (out_name.find("定扳反") != -1)
 
- 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.val, it.fluctuation_val, i,
 
- 								(uint8_t)eDaoChaPosi::DCP_FIX2INVERT, fmt::format("{}转换值:{}", out_name, it.fluctuation_val));
 
- 						else
 
- 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.val, it.fluctuation_val, i,
 
- 								(uint8_t)eDaoChaPosi::DCP_INVERT2FIX, fmt::format("{}转换值:{}", out_name, it.fluctuation_val));
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 		*/
 
- 		//10秒归档一次
 
- 		if (tmNow % 10 != 0) continue;
 
- 		time_t tt;
 
- 		time(&tt);
 
- 		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)) //TODO
 
- 				{
 
- 					//CSimpleLog::Error(fmt::format("IMEI2MOMP fail. imei:{}, idx:{}, {}:{}", pDevice->imei, i, __FILE__, __LINE__).c_str());
 
- 					continue;  //没有绑定返回
 
- 				}
 
- 				std::map<time_t, tagSecondStatInfo> map0, map1, map2;
 
- 				if (i == 0)
 
- 				{
 
- 					if (pDevice->m_mapSecondStatInfo00.size() == 0) continue;
 
- 					else if (tt - pDevice->m_tmMoveDetectTime0 < 20) continue;
 
- 					else if (pDevice->m_mapSecondStatInfo00.rbegin()->second.dif_val > 100) continue;  //最后值需要稳定
 
- 					lock_guard<mutex> lock(pDevice->m_mtx);
 
- 					swap(pDevice->m_mapSecondStatInfo00, map0);
 
- 					swap(pDevice->m_mapSecondStatInfo01, map1);
 
- 					swap(pDevice->m_mapSecondStatInfo02, map2);
 
- 				}
 
- 				else if (i == 1)
 
- 				{
 
- 					if (pDevice->m_mapSecondStatInfo10.size() == 0) continue;
 
- 					else if (tt - pDevice->m_tmMoveDetectTime1 < 20) continue;
 
- 					else if (pDevice->m_mapSecondStatInfo10.rbegin()->second.dif_val > 100) continue;  //最后值需要稳定
 
- 					lock_guard<mutex> lock(pDevice->m_mtx);
 
- 					swap(pDevice->m_mapSecondStatInfo10, map0);
 
- 					swap(pDevice->m_mapSecondStatInfo11, map1);
 
- 					swap(pDevice->m_mapSecondStatInfo12, map2);
 
- 				}
 
- 				else
 
- 				{
 
- 					if (pDevice->m_mapSecondStatInfo20.size() == 0) continue;
 
- 					else if (tt - pDevice->m_tmMoveDetectTime2 < 20) continue;
 
- 					else if (pDevice->m_mapSecondStatInfo20.rbegin()->second.dif_val > 100) continue;  //最后值需要稳定
 
- 					lock_guard<mutex> lock(pDevice->m_mtx);
 
- 					swap(pDevice->m_mapSecondStatInfo20, map0);
 
- 					swap(pDevice->m_mapSecondStatInfo21, map1);
 
- 					swap(pDevice->m_mapSecondStatInfo22, map2);
 
- 				}
 
- 				list<CONVERT_RESIST> lstResit2;
 
- 				std::map<time_t, int64_t> maxlock0, maxlock1;
 
- 				mg_per_session_data::GetMaxResistNew(map2, lstResit2, mo, mp);
 
- 				if (lstResit2.size())
 
- 				{
 
- 					mg_per_session_data::GetMaxLockNew(map0, lstResit2, maxlock0);
 
- 					mg_per_session_data::GetMaxLockNew(map1, lstResit2, maxlock1);
 
- 					SPDLOG_INFO("[转换阻力][{}:{}] lock0:{}  lock1:{}, resist2:{}", 
 
- 						mo, mp, maxlock0.size(), maxlock1.size(), lstResit2.size());
 
- 				}
 
- 				else
 
- 					continue;   //没有检查到转换阻力
 
- 				string name1, name2, name3, out_name, in_name;
 
- 				CMonitorObjectMng::Instance()->GetNameByMoMp(mo + "." + mp, name1, name2, name3, out_name, in_name);
 
- 				for (auto& it : maxlock0)
 
- 				{
 
- 					if (name1.find("定位") != -1)
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_FIX, fmt::format("锁闭力:{}", (it.second >> 32)));
 
- 					else
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_INVERT, fmt::format("锁闭力:{}", (it.second >> 32)));
 
- 				}
 
- 				for (auto& it : maxlock1)
 
- 				{
 
- 					if (name2.find("定位") != -1)
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_FIX, fmt::format("锁闭力:{}", (it.second >> 32)));
 
- 					else
 
- 						CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, (it.second >> 32), i,
 
- 							(uint8_t)eDaoChaPosi::DCP_INVERT, fmt::format("锁闭力:{}", (it.second >> 32)));
 
- 				}
 
- 				for (auto& it : lstResit2)
 
- 				{
 
- 					if (it.bUpOrDown == 1)
 
- 					{
 
- 						if (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, fmt::format("{}:{}", in_name, it.fluctuation_val));
 
- 						else
 
- 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,
 
- 								(uint8_t)eDaoChaPosi::DCP_INVERT2FIX, fmt::format("{}:{}", in_name, it.fluctuation_val));
 
- 					}
 
- 					else
 
- 					{
 
- 						if (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, fmt::format("{}:{}", out_name, it.fluctuation_val));
 
- 						else
 
- 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.time, it.tmStart, it.tmEnd, it.val, it.fluctuation_val, i,
 
- 								(uint8_t)eDaoChaPosi::DCP_INVERT2FIX, fmt::format("{}:{}", out_name, it.fluctuation_val));
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 	} while (pService->m_bWork);
 
- }
 
- 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, 3, 0); //设备离线时间暂定5分钟
 
- 	static CTimeSpan offline_limit(30, 0, 0, 0);
 
- 	do
 
- 	{
 
- 		for (int i = 0; i < 30; i++)
 
- 		{
 
- 			if (false == pService->m_bWork) break;
 
- 			this_thread::sleep_for(chrono::seconds(1));
 
- 		}
 
- 		CTime ctNow = CTime::GetCurrentTime();
 
- 		//传感器异常检测
 
- 		{
 
- 			std::vector<offline_info> vct;
 
- 			{
 
- 				lock_guard<mutex> lock(CDeviceMng::Instance()->m_mtx);
 
- 				const auto& pDevices = CDeviceMng::Instance()->m_map_devices;
 
- 				for (const auto& it : pDevices)
 
- 				{
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx00;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 0, 0));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx01;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 0, 1));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx02;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 0, 2));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx10;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 1, 0));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx11;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 1, 1));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx12;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 1, 2));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx20;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 2, 0));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx21;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 2, 1));
 
- 						}
 
- 					}
 
- 					{
 
- 						const auto& item = it.second->map_resist_idx22;
 
- 						if (item.size() && item.rbegin()->second == INVALID_RESIST)
 
- 						{
 
- 							vct.push_back(offline_info(it.first, (item.rbegin()->first / 1000), 2, 2));
 
- 						}
 
- 					}
 
- 				}
 
- 			}
 
- 		
 
- 			//转换成momp
 
- 			for (auto it = vct.begin(); it != vct.end();)
 
- 			{
 
- 				string mo, mp;
 
- 				//if (CMonitorObjectMng::Instance()->IMEI2MOMP(it->imei, it->idx, mo, mp) && it->vct.size() >= 1)  //TODO
 
- 				{
 
- 					it->vct[0].mo = mo;
 
- 					it->vct[0].mp = mp;
 
- 					it++;
 
- 				}
 
- 				//else
 
- 				{
 
- 					it = vct.erase(it);
 
- 					//CString strLog;
 
- 					//strLog.Format("imei(%s)(%d) 转换成 mo, mp 失败.请检查是否绑定.size;(%d) %s:%d", it.imei.c_str(), it.idx, (int)it.vct.size(), __FUNCTION__, __LINE__);
 
- 					//CSimpleLog::Warn(strLog);
 
- 				}
 
- 			}
 
- 			CTime ctAlarmTime = ctNow;
 
- 			for (const auto& it : vct)
 
- 			{
 
- 				for (const auto& it_mo_mp : it.vct)
 
- 				{
 
- 					ALARM_INFO* pAlarmInfo = nullptr;
 
- 					bool bNew = false;
 
- 					{
 
- 						std::lock_guard<mutex> lock(pService->m_mtxAlarm);
 
- 						for (const auto& alarm : pService->m_lstUnConfirmAlarm)
 
- 						{
 
- 							if (alarm->type == eZL_ALARMTYPE::SENSOR_ABNORMAL && alarm->mo.compare(it_mo_mp.mo) == 0 && alarm->mp.compare(it_mo_mp.mp) == 0 && it_mo_mp.no == alarm->no/* && ctAlarmTime - CTime(alarm->time) < cts*/) //跟上次报警时间超过1小时,则算新报警
 
- 							{
 
- 								pAlarmInfo = alarm;
 
- 								break;
 
- 							}
 
- 						}
 
- 					}
 
- 					if (pAlarmInfo == nullptr)
 
- 					{
 
- 						bNew = true;
 
- 						pAlarmInfo = new ALARM_INFO;
 
- 						pAlarmInfo->id = ++pService->m_nAlarmID;
 
- 						pAlarmInfo->level = 1;
 
- 						pAlarmInfo->mo = it_mo_mp.mo;
 
- 						pAlarmInfo->mp = it_mo_mp.mp;
 
- 						pAlarmInfo->no = it_mo_mp.no;
 
- 						ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);
 
- 						//pAlarmInfo->time.wMilliseconds = alarm_time % 1000;
 
- 						pAlarmInfo->type = eZL_ALARMTYPE::SENSOR_ABNORMAL;
 
- 						pAlarmInfo->val = 0;
 
- 						char szInfo[200];
 
- 						sprintf_s(szInfo, sizeof(szInfo), "传感器异常时间:%s", (LPCSTR)(it.time.Format("%Y-%m-%d %H:%M:%S")));
 
- 						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]) "\
 
- 							"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %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);
 
- 						if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
 
- 						{
 
- 							CSimpleLog::Error("执行语句失败" + sql);
 
- 						}
 
- 					}
 
- 				}
 
- 			}
 
- 		
 
- 		}
 
- 		{
 
- 			//离线设备
 
- 			std::vector<offline_info> vct;
 
- 			{
 
- 				lock_guard<mutex> lock(CDeviceMng::Instance()->m_mtx);
 
- 				const auto& pDevices = CDeviceMng::Instance()->m_map_devices;
 
- 				for (const auto& it : pDevices)
 
- 					if (it.second->m_ctUpdateTime != 0 && ctNow - it.second->m_ctUpdateTime > offline_time && ctNow - it.second->m_ctUpdateTime < offline_limit)
 
- 					{
 
- 						vct.push_back(offline_info(it.first, it.second->m_ctUpdateTime));
 
- 					}
 
- 			}
 
- 			for (auto& it : vct)
 
- 			{
 
- 				for (int i = 0; i < 3; i++)
 
- 				{
 
- 					string mo, mp;
 
- 					//if (CMonitorObjectMng::Instance()->IMEI2MOMP(it.imei, i, mo, mp))  //TODO
 
- 					{
 
- 						it.vct.push_back(tagMoMp(mo, mp));
 
- 					}
 
- 					//else
 
- 					{
 
-                         //CString strLog;
 
-                         //strLog.Format("imei(%s)(%d) 转换成 mo, mp 失败.请检查是否绑定. size;(%d) %s:%d", it.imei.c_str(), i, (int)it.vct.size(), __FUNCTION__, __LINE__);
 
-                         //CSimpleLog::Warn(strLog);
 
- 					}
 
- 				}
 
- 			}
 
- 			CTime ctAlarmTime = ctNow;
 
- 			for (const auto& it : vct)
 
- 			{
 
- 				for (const auto& it_mo_mp : it.vct)
 
- 				{
 
- 					ALARM_INFO* pAlarmInfo = nullptr;
 
- 					bool bNew = false;
 
- 					{
 
- 						std::lock_guard<mutex> lock(pService->m_mtxAlarm);
 
- 						for (const auto& alarm : pService->m_lstUnConfirmAlarm)
 
- 						{
 
- 							static CTimeSpan cts(0, 6, 0, 0); //报警间隔6小时重新生成报警
 
- 							if (alarm->type == eZL_ALARMTYPE::EQUIP_OFFLINE && alarm->mo.compare(it_mo_mp.mo) == 0 && alarm->mp.compare(it_mo_mp.mp) == 0/* && ctAlarmTime - CTime(alarm->time) < cts*/) //跟上次报警时间超过1小时,则算新报警
 
- 							{
 
- 								pAlarmInfo = alarm;
 
- 								break;
 
- 							}
 
- 						}
 
- 					}
 
- 					if (pAlarmInfo == nullptr)
 
- 					{
 
- 						bNew = true;
 
- 						pAlarmInfo = new ALARM_INFO;
 
- 						pAlarmInfo->id = ++pService->m_nAlarmID;
 
- 						pAlarmInfo->level = 1;
 
- 						pAlarmInfo->mo = it_mo_mp.mo;
 
- 						pAlarmInfo->mp = it_mo_mp.mp;
 
- 						pAlarmInfo->no = -1;
 
- 						ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);
 
- 						//pAlarmInfo->time.wMilliseconds = alarm_time % 1000;
 
- 						pAlarmInfo->type = eZL_ALARMTYPE::EQUIP_OFFLINE;
 
- 						pAlarmInfo->val = 0;
 
- 						char szInfo[200];
 
- 						sprintf_s(szInfo, sizeof(szInfo), "设备离线时间:%s", (LPCSTR)(it.time.Format("%Y-%m-%d %H:%M:%S")));
 
- 						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]) "\
 
- 							"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %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);
 
- 						if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
 
- 						{
 
- 							CSimpleLog::Error("执行语句失败" + sql);
 
- 						}
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 	} while (pService->m_bWork);
 
- }
 
- 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;
 
- 			short alarm_high_limit = MAXSHORT;
 
- 			short warn_high_limit = MAXSHORT;
 
- 			short f_alarm_high_limit = MAXSHORT;
 
- 			short f_warn_high_limit = MAXSHORT;
 
- 			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 == MAXSHORT || warn_high_limit == MAXSHORT) 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;
 
- 			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;
 
- 			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->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"));
 
- 			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"));
 
- 			stringstream ss;
 
- 			ss << mo << '.' << mp << '.' << to_string(no) << '.' << to_string(type);
 
- 			m_alarm_set[ss.str()] = pInfo;
 
- 		}
 
- 		else
 
- 		{
 
- 			ASSERT(0);
 
- 		}
 
- 	} while (true);
 
- 	SPDLOG_INFO("一共加载到{}条报警规则:{}", m_alarm_set.size(), sql);
 
- 	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()
 
- {
 
- 	CString sql = "SELECT [ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id] FROM [rm_alarm] WHERE ack_result = 0 ORDER BY ID;";
 
- 	COdbcStatement stmt;
 
- 	if (!CDBConnectPool::Instance()->DBQuery(stmt, sql))
 
- 	{
 
- 		SPDLOG_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;
 
- 	short val;
 
- 	int id;
 
- 	TIMESTAMP_STRUCT ts;
 
- 	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.BindSmallIntCol(nCol++, &val);
 
- 	stmt.BindCharCol(nCol++, event_id, 36);
 
- 	stmt.BindCharCol(nCol++, rel_id, 36);
 
- 	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;
 
- 		pAlarm->time.wYear = ts.year;
 
- 		pAlarm->time.wMonth = ts.month;
 
- 		pAlarm->time.wDay = ts.day;
 
- 		pAlarm->time.wHour = ts.hour;
 
- 		pAlarm->time.wMinute = ts.minute;
 
- 		pAlarm->time.wSecond = ts.second;
 
- 		pAlarm->time.wMilliseconds = ts.fraction;
 
- 		pAlarm->val = val;
 
- 		pAlarm->level = level;
 
- 		pAlarm->desc = desc;
 
- 		pAlarm->suggest = suggest;
 
- 		m_lstUnConfirmAlarm.push_back(pAlarm);
 
- 	} while (true);
 
- 	stmt.Close();
 
- 	SPDLOG_INFO("一共加载({})条未处理报警", m_lstUnConfirmAlarm.size());
 
- 	return TRUE;
 
- }
 
 
  |