| | |
| | | #include "Common.h" |
| | | #include "CBonder.h" |
| | | #include "Log.h" |
| | | #include "ToolUnits.h" |
| | | |
| | | #define ALARM_MAX 200 |
| | | |
| | | CAlarmMonitor::CAlarmMonitor() |
| | | { |
| | | m_nBeginAddr = 0; |
| | | m_nLastId = 0; |
| | | m_nLastLevel = 0; |
| | | m_pRawData = new char[512]; |
| | | memset(m_pRawData, 0, 512); |
| | | } |
| | | |
| | | |
| | | CAlarmMonitor::~CAlarmMonitor() |
| | | { |
| | | if (m_pRawData != nullptr) { |
| | | delete[] m_pRawData; |
| | | m_pRawData = nullptr; |
| | | } |
| | | |
| | | for (auto item : m_mapAlarmTemplate) { |
| | | delete item.second; |
| | | } |
| | | m_mapAlarmTemplate.clear(); |
| | | |
| | | for (auto item : m_mapAlarming) { |
| | | item.second->release(); |
| | | } |
| | | m_mapAlarming.clear(); |
| | | } |
| | | |
| | | std::string& CAlarmMonitor::getClassName() |
| | |
| | | void CAlarmMonitor::onData(int id, const void* pData, int size) |
| | | { |
| | | const char* pszData = (const char*)pData; |
| | | if (m_nIndex + 1 == id) { |
| | | int addr = m_nBeginAddr * 2; |
| | | int alarmId = (pszData[addr] & 0xff) | (pszData[addr + 1] & 0xff) << 8; |
| | | int alarmLevel = (pszData[addr + 2] & 0xff) | (pszData[addr + 3] & 0xff) << 8; |
| | | if (m_nLastId != alarmId) { |
| | | LOGI("<CAlarmMonitor-%d>AlarmId:%d, AlarmLevel:%d", m_nIndex, alarmId, alarmLevel); |
| | | Alarm(alarmId, alarmLevel); |
| | | if (MONITOR_ID_ALARM != id) { |
| | | return; |
| | | } |
| | | |
| | | // 比较有没有变化 |
| | | if (compareData(m_pRawData, (const char*)pData, size)) { |
| | | return; |
| | | } |
| | | memcpy(m_pRawData, (const char*)pData, size); |
| | | |
| | | |
| | | // 找到On的报警并缓存 |
| | | std::vector<int> alarmIds; |
| | | for (auto item : m_mapAlarmTemplate) { |
| | | if (isAlarmOn(item.first)) { |
| | | alarmIds.push_back(item.first); |
| | | } |
| | | } |
| | | |
| | | |
| | | // 发生警告: |
| | | // 比较新加的ON的警告 |
| | | // 即m_mapAlarming无,alarmIds有 |
| | | for (auto item : alarmIds) { |
| | | if (m_mapAlarming.find(item) == m_mapAlarming.end()) { |
| | | auto iter = m_mapAlarmTemplate.find(item); |
| | | if (iter != m_mapAlarmTemplate.end()) { |
| | | CAlarm* pAlarm = new CAlarm(iter->second); |
| | | pAlarm->alarmOn(); |
| | | pAlarm->addRef(); |
| | | m_mapAlarming[item] = pAlarm; |
| | | LOGE("发生了警告:%s", pAlarm->toString().c_str()); |
| | | |
| | | // 警告信息发出,以使界面显示和历史记录保存 |
| | | SendBroadcast(&CIntent(BC_CODE_ALARM_ON, "", pAlarm)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 削除警告: |
| | | // 比较得到原来ON(m_mapAlarming有), 现在OFF的警告(alarmIds无) |
| | | for (auto iter = m_mapAlarming.begin(); iter != m_mapAlarming.end();/* iter++*/) { |
| | | if (!findAlarm(alarmIds, iter->first)) { |
| | | // 消除警告, 同时将信息发出,以使界面显示和历史记录保存 |
| | | CAlarm* pAlarm = iter->second; |
| | | pAlarm->alarmOff(); |
| | | addAlarmToHistoryRecord(pAlarm); |
| | | m_mapAlarming.erase(iter++); |
| | | |
| | | LOGE("消除了警告:%s", pAlarm->toString().c_str()); |
| | | SendBroadcast(&CIntent(BC_CODE_ALARM_OFF, "", pAlarm)); |
| | | pAlarm->release(); |
| | | } |
| | | else { |
| | | iter++; |
| | | } |
| | | } |
| | | } |
| | |
| | | return -1; |
| | | } |
| | | |
| | | CString strLine, strNumber, strDescription; |
| | | CString strLine, strNumber, strLevel, strDescription; |
| | | int number, level; |
| | | while (file.ReadString(strLine)) { |
| | | int index = strLine.Find(","); |
| | | if (index <= 0) continue; |
| | | if (!AfxExtractSubString(strNumber, (LPCTSTR)strLine, 0, ',')) |
| | | continue; |
| | | if (!AfxExtractSubString(strLevel, (LPCTSTR)strLine, 1, ',')) |
| | | continue; |
| | | if (!AfxExtractSubString(strDescription, (LPCTSTR)strLine, 2, ',')) |
| | | continue; |
| | | |
| | | strNumber = strLine.Left(index).Trim(); |
| | | strDescription = strLine.Right(strLine.GetLength() - index - 1).Trim(); |
| | | try { |
| | | number = std::stoi((LPTSTR)(LPCTSTR)strNumber); |
| | | level = std::stoi((LPTSTR)(LPCTSTR)strLevel); |
| | | } |
| | | catch (...) { |
| | | continue; |
| | | } |
| | | |
| | | int number = atoi(strNumber); |
| | | m_mapAlarmText[number] = std::string((LPTSTR)(LPCTSTR)strDescription); |
| | | addAlarmTemplate(number, level, (LPTSTR)(LPCTSTR)strDescription); |
| | | } |
| | | |
| | | file.Close(); |
| | | return (int)m_mapAlarmText.size(); |
| | | return (int)m_mapAlarmTemplate.size(); |
| | | } |
| | | |
| | | void CAlarmMonitor::init() |
| | |
| | | |
| | | void CAlarmMonitor::term() |
| | | { |
| | | for (auto item : m_alarms) { |
| | | item->release(); |
| | | } |
| | | } |
| | | |
| | | void CAlarmMonitor::setBeginAddr(int nAddr) |
| | | { |
| | | m_nBeginAddr = nAddr; |
| | | } |
| | | |
| | | void CAlarmMonitor::OnTimer(UINT nTimerid) |
| | |
| | | |
| | | const char* CAlarmMonitor::getAlarmText(int nID) |
| | | { |
| | | auto iter = m_mapAlarmText.find(nID); |
| | | if (iter == m_mapAlarmText.end()) return ""; |
| | | |
| | | return iter->second.c_str(); |
| | | } |
| | | |
| | | void CAlarmMonitor::Alarm(int id, int level) |
| | | { |
| | | BEQ::IUnit* pUnit = m_pBonder->getUnit(m_nIndex); |
| | | ASSERT(pUnit); |
| | | |
| | | if (id != 0) { |
| | | // 警告 |
| | | pUnit->setAlarm(id, level, getAlarmText(id)); |
| | | LOGI("<CAlarmMonitor-%d>设备告警(%d, %d).", m_nIndex, id, level); |
| | | |
| | | CAlarm* pAlarm = new CAlarm(m_nIndex, 1, id, level, getAlarmText(id)); |
| | | AddAlarm(pAlarm); |
| | | SendBroadcast(&CIntent(BC_CODE_ALARM_EVENT, "", pAlarm)); |
| | | m_nLastId = id; |
| | | m_nLastLevel = level; |
| | | } |
| | | else { |
| | | // 解除警告 |
| | | pUnit->setAlarm(0, 0, ""); |
| | | LOGI("<CAlarmMonitor-%d>解除设备告警(%d, %d).", m_nIndex, m_nLastId, m_nLastLevel); |
| | | |
| | | CAlarm* pAlarm = new CAlarm(m_nIndex, 2, m_nLastId, m_nLastLevel, getAlarmText(m_nLastId)); |
| | | AddAlarm(pAlarm); |
| | | SendBroadcast(&CIntent(BC_CODE_ALARM_EVENT, "", pAlarm)); |
| | | m_nLastId = 0; |
| | | m_nLastLevel = 0; |
| | | } |
| | | auto iter = m_mapAlarmTemplate.find(nID); |
| | | if (iter == m_mapAlarmTemplate.end()) return ""; |
| | | return iter->second->getText().c_str(); |
| | | } |
| | | |
| | | void CAlarmMonitor::Serialize(CArchive& ar) |
| | | { |
| | | if (ar.IsStoring()) |
| | | { |
| | | Lock(); |
| | | int count = (int)m_alarms.size(); |
| | | ar << count; |
| | | for (auto item : m_alarms) { |
| | | item->Serialize(ar); |
| | | } |
| | | Unlock(); |
| | | if (ar.IsStoring()) { |
| | | } |
| | | else |
| | | { |
| | | Lock(); |
| | | int count; |
| | | ar >> count; |
| | | for (int i = 0; i < count; i++) { |
| | | CAlarm* pAlarm = new CAlarm(); |
| | | pAlarm->addRef(); |
| | | pAlarm->Serialize(ar); |
| | | AddAlarm(pAlarm); |
| | | pAlarm->release(); |
| | | |
| | | } |
| | | Unlock(); |
| | | else { |
| | | } |
| | | } |
| | | |
| | | void CAlarmMonitor::AddAlarm(CAlarm* pAlarm) |
| | | std::map<int, CAlarm*>& CAlarmMonitor::getAlarmingMap() |
| | | { |
| | | return m_mapAlarming; |
| | | } |
| | | |
| | | BOOL CAlarmMonitor::isAlarming() |
| | | { |
| | | Lock(); |
| | | BOOL bAlarming = !m_mapAlarming.empty(); |
| | | Unlock(); |
| | | return bAlarming; |
| | | } |
| | | |
| | | CAlarm* CAlarmMonitor::getActiveAlarm() |
| | | { |
| | | Lock(); |
| | | if (m_mapAlarming.empty()) { |
| | | Unlock(); |
| | | return nullptr; |
| | | } |
| | | auto iter = m_mapAlarming.begin(); |
| | | Unlock(); |
| | | |
| | | return iter->second; |
| | | } |
| | | |
| | | BOOL CAlarmMonitor::compareData(const char* pScrData, const char* pTarData, int len) |
| | | { |
| | | for (int i = 0; i < len; i++) { |
| | | if (pScrData[i] != pTarData[i]) { |
| | | return FALSE; |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | int CAlarmMonitor::addAlarmTemplate(int id, int level, const char* pszDescription) |
| | | { |
| | | auto iter = m_mapAlarmTemplate.find(id); |
| | | if (iter != m_mapAlarmTemplate.end()) return -1; |
| | | |
| | | CAlarm* pAlarm = new CAlarm(id, level, pszDescription); |
| | | m_mapAlarmTemplate[id] = pAlarm; |
| | | return 0; |
| | | } |
| | | |
| | | BOOL CAlarmMonitor::isAlarmOn(int id) |
| | | { |
| | | int byteIndex, bitIndex; |
| | | byteIndex = (id - 1) / 8; |
| | | bitIndex = (id - 1) % 8; |
| | | |
| | | return CToolUnits::getBit(m_pRawData[byteIndex], bitIndex); |
| | | } |
| | | |
| | | BOOL CAlarmMonitor::findAlarm(std::vector<int>& ids, int id) |
| | | { |
| | | for (auto item : ids) { |
| | | if (item == id) return TRUE; |
| | | } |
| | | |
| | | return FALSE; |
| | | } |
| | | |
| | | void CAlarmMonitor::addAlarmToHistoryRecord(CAlarm* pAlarm) |
| | | { |
| | | // 加入数据库 |
| | | AlarmManager::getInstance().addAlarm( |
| | | std::to_string(pAlarm->getId()).c_str(), |
| | | getAlarmText(pAlarm->getId()), |
| | | CToolUnits::timeToString2(pAlarm->getOnTime()).c_str(), |
| | | CToolUnits::timeToString2(pAlarm->getOffTime()).c_str()); |
| | | } |
| | | |
| | | BOOL CAlarmMonitor::addAlarming(CAlarm* pAlarm) |
| | | { |
| | | auto iter = m_mapAlarming.find(pAlarm->getId()); |
| | | if (iter != m_mapAlarming.end()) return FALSE; |
| | | |
| | | pAlarm->addRef(); |
| | | m_alarms.push_back(pAlarm); |
| | | if (m_alarms.size() > ALARM_MAX) { |
| | | CAlarm* pTemp = m_alarms.front(); |
| | | pTemp->release(); |
| | | m_alarms.pop_front(); |
| | | } |
| | | Unlock(); |
| | | } |
| | | m_mapAlarming[pAlarm->getId()] = pAlarm; |
| | | |
| | | void CAlarmMonitor::getAlarmList(std::list<CAlarm*>& list) |
| | | { |
| | | Lock(); |
| | | list = m_alarms; |
| | | Unlock(); |
| | | return TRUE; |
| | | } |