#include "stdafx.h" #include "AlarmManager.h" #include #include #include #include #include #include #include // ³£Á¿ const std::string DATABASE_FILE = R"(AlarmManager.db)"; // ¾²Ì¬³ÉÔ±³õʼ»¯ std::mutex AlarmManager::m_mutex; // »ñÈ¡µ¥ÀýʵÀý AlarmManager& AlarmManager::getInstance() { static AlarmManager instance; return instance; } // ¹¹Ô캯Êý AlarmManager::AlarmManager() { m_pDB = new BL::SQLiteDatabase(); } // Îö¹¹º¯Êý AlarmManager::~AlarmManager() { if (m_pDB != nullptr) { delete m_pDB; m_pDB = nullptr; } } // ÉèÖÃÊý¾Ý¿âÁ¬½Ó void AlarmManager::setDatabase(BL::Database* db) { std::lock_guard lock(m_mutex); m_pDB = db; } // ³õʼ»¯±¨¾¯±í bool AlarmManager::initAlarmTable() { char path[MAX_PATH]; GetModuleFileName(NULL, path, MAX_PATH); std::string exePath(path); std::string dbFileDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB"; if (!CreateDirectory(dbFileDir.c_str(), NULL) && ERROR_ALREADY_EXISTS != GetLastError()) { throw std::runtime_error("Failed to create database directory."); } std::string dbFilePath = dbFileDir + "\\" + DATABASE_FILE; if (!m_pDB->connect(dbFilePath, true)) { throw std::runtime_error("Failed to connect to database."); } // ´´½¨É豸±í const std::string createDevicesTableQuery = R"( CREATE TABLE IF NOT EXISTS devices ( device_id TEXT PRIMARY KEY NOT NULL, device_name TEXT NOT NULL ) )"; if (!m_pDB->executeQuery(createDevicesTableQuery)) { return false; } // ´´½¨µ¥Ôª±í£¬É豸IDºÍµ¥ÔªID×éºÏ×÷ΪÖ÷¼ü const std::string createUnitsTableQuery = R"( CREATE TABLE IF NOT EXISTS units ( device_id TEXT NOT NULL, unit_id TEXT NOT NULL, unit_name TEXT NOT NULL, PRIMARY KEY (device_id, unit_id), FOREIGN KEY (device_id) REFERENCES devices(device_id) ) )"; if (!m_pDB->executeQuery(createUnitsTableQuery)) { return false; } // ´´½¨±¨¾¯±í£¬±¨¾¯¼Ç¼µÄalarm_event_idÊÇÖ÷¼ü const std::string createAlarmsTableQuery = R"( CREATE TABLE IF NOT EXISTS alarms ( alarm_event_id INTEGER PRIMARY KEY AUTOINCREMENT, id TEXT NOT NULL, device_id TEXT NOT NULL, unit_id TEXT NOT NULL, description TEXT NOT NULL, start_time DATETIME NOT NULL, end_time DATETIME NOT NULL, FOREIGN KEY (device_id) REFERENCES devices(device_id), FOREIGN KEY (unit_id) REFERENCES units(unit_id) ) )"; return m_pDB->executeQuery(createAlarmsTableQuery); } // Ïú»Ù±¨¾¯±í void AlarmManager::termAlarmTable() { if (m_pDB != nullptr) { m_pDB->disconnect(); } } // Ïú»Ù±¨¾¯±í bool AlarmManager::destroyAlarmTable() { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } const std::string dropTableQuery = "DROP TABLE IF EXISTS alarms"; return m_pDB->executeQuery(dropTableQuery); } // ²åÈëÄ£ÄâÊý¾Ý void AlarmManager::insertMockData() { // ²åÈëÉ豸Êý¾Ý for (int i = 1; i <= 3; ++i) { std::string deviceName = "Device" + std::to_string(i); std::stringstream query; query << "INSERT INTO devices (device_id, device_name) VALUES (" << i << ", '" << deviceName << "');"; if (!m_pDB->executeQuery(query.str())) { std::cerr << "Failed to insert device: " << i << std::endl; } } // ²åÈëµ¥ÔªÊý¾Ý for (int i = 1; i <= 3; ++i) { for (int j = 1; j <= 3; ++j) { int unitId = (i - 1) * 3 + j; std::string unitName = "Unit" + std::to_string(j); std::stringstream query; query << "INSERT INTO units (device_id, unit_id, unit_name) VALUES (" << i << "', " << unitId << ", '" << unitName << ");"; if (!m_pDB->executeQuery(query.str())) { std::cerr << "Failed to insert unit: " << unitId << std::endl; } } } // ³õʼ»¯Ëæ»úÊýÉú³ÉÆ÷ std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> deviceDis(1, 3); std::uniform_int_distribution<> unitDis(1, 9); std::uniform_int_distribution<> errorCodeDis(1, 3); std::vector descriptions = { "Overheat", "Sensor failure", "Power outage" }; // ʱ¼äÏà¹Ø auto now = std::chrono::system_clock::now(); auto start_time = std::chrono::system_clock::to_time_t(now); auto end_time = std::chrono::system_clock::to_time_t(now + std::chrono::minutes(10)); std::tm start_tm = {}; std::tm end_tm = {}; localtime_s(&start_tm, &start_time); localtime_s(&end_tm, &end_time); // ²åÈëÄ£ÄâÊý¾Ý for (int i = 0; i < 10; ++i) { int deviceId = deviceDis(gen); // Ëæ»úÉ豸ID int unitId = unitDis(gen); // Ëæ»úµ¥ÔªID int errorCode = errorCodeDis(gen); // Ëæ»ú´íÎóÂë std::string description = descriptions[errorCodeDis(gen) % descriptions.size()]; // Ëæ»ú±¨¾¯ÃèÊö std::stringstream query; query << "INSERT INTO alarms (id, device_id, unit_id, description, start_time, end_time) " << "VALUES (" << errorCode << ", " << deviceId << ", " << unitId << ", '" << description << "', " << "'" << std::put_time(&start_tm, "%Y-%m-%d %H:%M:%S") << "', " << "'" << std::put_time(&end_tm, "%Y-%m-%d %H:%M:%S") << "');"; if (!m_pDB->executeQuery(query.str())) { std::cerr << "Failed to insert alarm data." << std::endl; } } } // Ìí¼Ó±¨¾¯ bool AlarmManager::addAlarm(const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& endTime) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "INSERT INTO alarms (id, device_name, description, start_time, end_time) VALUES (" << "'" << id << "', " << "'" << deviceName << "', " << "'" << description << "', " << "'" << startTime << "', " << "'" << endTime << "')"; std::lock_guard lock(m_mutex); return m_pDB->executeQuery(query.str()); } // ²éѯËùÓб¨¾¯Êý¾Ý std::vector> AlarmManager::getAllAlarms() { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } const std::string query = "SELECT id, device_name, description, start_time, end_time FROM alarms"; return m_pDB->fetchResults(query); } // ¸ù¾Ý±¨¾¯ID²éѯ±¨¾¯ std::vector> AlarmManager::getAlarmsById(const std::string& id) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE id = '" << id << "'"; return m_pDB->fetchResults(query.str()); } // ¸ù¾ÝÃèÊö²éѯ±¨¾¯ std::vector> AlarmManager::getAlarmsByDescription(const std::string& description) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE description LIKE '%" << description << "%'"; return m_pDB->fetchResults(query.str()); } // ¸ù¾Ýʱ¼ä·¶Î§²éѯ±¨¾¯ std::vector> AlarmManager::getAlarmsByTimeRange( const std::string& startTime, const std::string& endTime) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE 1=1"; if (!startTime.empty()) { query << " AND start_time >= '" << startTime << "'"; } if (!endTime.empty()) { query << " AND end_time <= '" << endTime << "'"; } return m_pDB->fetchResults(query.str()); } // ¸ù¾ÝID¡¢¿ªÊ¼Ê±¼äºÍ½áÊøÊ±¼ä²éѯ±¨¾¯ std::vector> AlarmManager::getAlarmsByIdAndTimeRange( const std::string& id, const std::string& startTime, const std::string& endTime) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE id = '" << id << "'"; if (!startTime.empty()) { query << " AND start_time >= '" << startTime << "'"; } if (!endTime.empty()) { query << " AND end_time <= '" << endTime << "'"; } return m_pDB->fetchResults(query.str()); } // ·ÖÒ³²éѯ±¨¾¯Êý¾Ý std::vector> AlarmManager::getAlarms(int startPosition, int count) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "SELECT id, device_name, description, start_time, end_time FROM alarms LIMIT " << count << " OFFSET " << startPosition; return m_pDB->fetchResults(query.str()); } // ɸѡ±¨¾¯Êý¾Ý std::vector> AlarmManager::getFilteredAlarms( const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE 1=1"; if (!id.empty()) { query << " AND id = '" << id << "'"; } if (!deviceName.empty()) { query << " AND device_name LIKE '%" << deviceName << "%'"; } if (!description.empty()) { query << " AND description LIKE '%" << description << "%'"; } if (!startTime.empty()) { query << " AND start_time >= '" << startTime << "'"; } if (!endTime.empty()) { query << " AND end_time <= '" << endTime << "'"; } int offset = (pageNumber - 1) * pageSize; query << " ORDER BY start_time DESC LIMIT " << pageSize << " OFFSET " << offset; return m_pDB->fetchResults(query.str()); } // »ñÈ¡·ûºÏÌõ¼þµÄ±¨¾¯×ÜÊý int AlarmManager::getTotalAlarmCount( const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& endTime) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "SELECT COUNT(*) FROM alarms WHERE 1=1"; if (!id.empty()) { query << " AND id = '" << id << "'"; } if (!deviceName.empty()) { query << " AND device_name LIKE '%" << deviceName << "%'"; } if (!description.empty()) { query << " AND description LIKE '%" << description << "%'"; } if (!startTime.empty()) { query << " AND start_time >= '" << startTime << "'"; } if (!endTime.empty()) { query << " AND end_time <= '" << endTime << "'"; } auto results = m_pDB->fetchResults(query.str()); return (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0; } // ¸üб¨¾¯µÄ½áÊøÊ±¼ä bool AlarmManager::updateAlarmEndTime(const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& newEndTime) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "UPDATE alarms SET end_time = '" << newEndTime << "'" << " WHERE id = '" << id << "'" << " AND device_name = '" << deviceName << "'" << " AND description = '" << description << "'" << " AND start_time = '" << startTime << "'"; return m_pDB->executeQuery(query.str()); } // ÇåÀí¾É±¨¾¯Êý¾Ý void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceName) { if (!m_pDB) { throw std::runtime_error("Database connection is not set."); } std::ostringstream query; query << "DELETE FROM alarms WHERE end_time < datetime('now', '-" << daysToKeep << " days')"; if (!deviceName.empty()) { query << " AND device_name = '" << deviceName << "'"; } m_pDB->executeQuery(query.str()); } // ¶ÁÈ¡±¨¾¯Îļþ bool AlarmManager::readAlarmFile(const std::string& filename) { std::ifstream file(filename); std::string line; bool first_line = true; if (!file.is_open()) { std::cerr << "Error opening file!" << std::endl; return false; } while (std::getline(file, line)) { if (first_line) { first_line = false; continue; } std::stringstream ss(line); std::string cell; AlarmInfo alarm; std::getline(ss, cell, ','); std::getline(ss, alarm.strUnitID, ','); std::getline(ss, alarm.strUnitNo, ','); std::getline(ss, cell, ','); alarm.nAlarmLevel = 0;// std::stoi(cell); std::getline(ss, cell, ','); alarm.nAlarmCode = std::stoi(cell); std::getline(ss, cell, ','); alarm.nAlarmID = std::stoi(cell); std::getline(ss, alarm.strAlarmText, ','); std::getline(ss, alarm.strDescription, ','); if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) { m_mapAlarm[alarm.nAlarmID] = alarm; } else { std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl; } } file.close(); return true; } // ½«±¨¾¯Êý¾Ý±£´æµ½Îļþ bool AlarmManager::saveAlarmFile(const std::string& filename) { std::ofstream file(filename); if (!file.is_open()) { std::cerr << "´ò¿ªÎļþдÈëʧ°Ü!" << std::endl; return false; } // дÈë±êÌâÐÐ file << "No,UNIT ID,UNIT NO,Alarm Level,Alarm Code,AlarmID,Alarm Text,Description\n"; // дÈ뱨¾¯Êý¾Ý int nIndex = 1; for (const auto& pair : m_mapAlarm) { const AlarmInfo& alarm = pair.second; file << nIndex++ << "," << alarm.strUnitID << "," << alarm.strUnitNo << "," << alarm.nAlarmLevel << "," << alarm.nAlarmCode << "," << alarm.nAlarmID << "," << alarm.strAlarmText << "," << alarm.strDescription << "\n"; } file.close(); return true; } // ͨ¹ý AlarmID ²éѯ¶ÔÓ¦µÄ±¨¾¯ÐÅÏ¢ const AlarmInfo* AlarmManager::getAlarmInfoByID(int nAlarmID) const { auto it = m_mapAlarm.find(nAlarmID); if (it != m_mapAlarm.end()) { return &(it->second); } else { std::cerr << "δÕÒµ½ AlarmID: " << nAlarmID << std::endl; return nullptr; } } // ͨ¹ý¶à¸ö AlarmID ²éѯ¶ÔÓ¦µÄ±¨¾¯ÐÅÏ¢ std::vector AlarmManager::getAlarmsInfoByIDs(const std::vector& alarmIDs) const { std::vector alarms; for (int alarmID : alarmIDs) { auto it = m_mapAlarm.find(alarmID); if (it != m_mapAlarm.end()) { alarms.push_back(it->second); } else { std::cerr << "δÕÒµ½ AlarmID: " << alarmID << std::endl; } } return alarms; }