#include "stdafx.h" #include "ResistAlarm.h" #include "MonitorObject.h" #include "Device.h" #include #include #include #include #include #include #include #include "AppService.h" #include #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; 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 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 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; //g_p315ClientManager->GetTcpClient()->SendAlarmData(pInfo->no, 2, CTime(pInfo->time).GetTime(), time.GetTime(), (WORD)pInfo->type, pInfo->val, 0, 0); return true; } } return false; } bool CResistAlarmMng::HandleAlarm(int alarm_id) { lock_guard 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 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 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 vctAlarmID; vector vctEventID; //ALARM_INFO tmpalarm; { std::lock_guard 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 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 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 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 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 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 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 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 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 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::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 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 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 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) { ASSERT(pConstRetensionForceWaveInfo); 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); } } } ASSERT(pConstRetensionForceWaveInfo); 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 (nOldVal < 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 (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 (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 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 lock(pService->m_mtxAlarm); pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo); } //主动推送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 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(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 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 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 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::const_iterator i, std::map::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 && 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); 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 lock(pDevice->m_mtx); std::map* 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; } } } } 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::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 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 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 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* 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 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 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); 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 int ii = 0; ALARM_INFO* pAlarmInfo = nullptr; bool bNew = false; auto ctAlarmTime = ctNow; { std::lock_guard 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 { //恢复报警 //更新数据库 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 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, (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 map0, map1, map2; std::map* 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 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::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(pDevice->map_resist_idx00.find(tStart), pDevice->map_resist_idx00.end()); mapData[1] = new std::map(pDevice->map_resist_idx01.find(tStart), pDevice->map_resist_idx01.end()); mapData[2] = new std::map(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 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::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(pDevice->map_resist_idx10.find(tStart), pDevice->map_resist_idx10.end()); mapData[1] = new std::map(pDevice->map_resist_idx11.find(tStart), pDevice->map_resist_idx11.end()); mapData[2] = new std::map(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 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::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(pDevice->map_resist_idx20.find(tStart), pDevice->map_resist_idx20.end()); mapData[1] = new std::map(pDevice->map_resist_idx21.find(tStart), pDevice->map_resist_idx21.end()); mapData[2] = new std::map(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 lstResit2; //转换力数据 list lstPass; //过车数据 std::map maxlock0, maxlock1;//锁闭力 前面时间戳, 后面 高4位显示值, 低4位报警值 std::map 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; } } } 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_RESIST, 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_RESIST, 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_RESIST, 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_RESIST, 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); } delete mapData[0]; delete mapData[1]; delete mapData[2]; } } } while (pService->m_bWork); if (bLock) { g_lockSync.Unlock(); bLock = false; } } 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年7月18日 取消默认开启 /* 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; 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; 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; }