LAPTOP-SNT8I5JK\Boounion
2025-08-11 5edb485d226790306097e40ea954efb2ed90dd21
SourceCode/Bond/Servo/AlarmManager.cpp
@@ -33,12 +33,6 @@
    }
}
// 设置数据库连接
void AlarmManager::setDatabase(BL::Database* db) {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_pDB = db;
}
// 初始化报警表
bool AlarmManager::initAlarmTable() {
    char path[MAX_PATH];
@@ -89,7 +83,7 @@
            unit_id TEXT NOT NULL,
            description TEXT NOT NULL,
            start_time DATETIME NOT NULL,
            end_time DATETIME NOT NULL,
            end_time DATETIME,
            FOREIGN KEY (device_id) REFERENCES devices(device_id),
            FOREIGN KEY (unit_id) REFERENCES units(unit_id)
        )
@@ -127,7 +121,7 @@
    // 插入单元数据
    for (int i = 1; i <= 3; ++i) {
        for (int j = 1; j <= 3; ++j) {
        for (int j = 0; j <= 3; ++j) {
            int unitId = j;
            std::string deviceId = std::to_string(i);
            std::string unitName = "Unit" + std::to_string(j);
@@ -144,6 +138,7 @@
        }
    }
    /*
    // 初始化随机数生成器
    std::random_device rd;
    std::mt19937 gen(rd());
@@ -181,28 +176,84 @@
            std::cerr << "Failed to insert alarm data." << std::endl;
        }
    }
    */
}
// 添加报警信息
bool AlarmManager::addAlarm(const AlarmData& alarmData) {
bool AlarmManager::addAlarm(const AlarmData& alarmData, int& alarmEventId) {
    if (!m_pDB) {
        return false;
    }
    // 构建插入查询
    std::ostringstream query;
    query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) VALUES ("
        << alarmData.nId << ", "              // 错误码
        << alarmData.nSeverityLevel << ", "   // 报警等级
        << alarmData.nDeviceId << ", "        // 设备ID
        << alarmData.nUnitId << ", '"         // 单元ID
        << alarmData.strDescription << "', '" // 描述
        << alarmData.strStartTime << "', '"   // 开始时间
        << alarmData.strEndTime << "')";      // 结束时间
    #if 0
        // 开始事务
        m_pDB->executeQuery("BEGIN TRANSACTION;");
        // 构建插入查询
        std::ostringstream query;
        query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) VALUES ("
            << alarmData.nId << ", "              // 错误码
            << alarmData.nSeverityLevel << ", "   // 报警等级
            << alarmData.nDeviceId << ", "        // 设备ID
            << alarmData.nUnitId << ", '"         // 单元ID
            << alarmData.strDescription << "', '" // 描述
            << alarmData.strStartTime << "', '"   // 开始时间
            << alarmData.strEndTime << "')";      // 结束时间
        // 使用锁保护多线程安全
        std::lock_guard<std::mutex> lock(m_mutex);
        // 执行插入查询
        bool result = m_pDB->executeQuery(query.str());
        if (result) {
            alarmEventId = getLastInsertId();
            m_alarmCache[alarmEventId] = alarmData;
        }
        // 提交事务
        m_pDB->executeQuery("COMMIT;");
        return result;
    #else
        for (AlarmDataMap::const_iterator it = m_mapCache.begin(); it != m_mapCache.end(); ++it) {
            const AlarmData& alarm = it->second;
            if (alarm.nId == alarmData.nId &&
                alarm.nDeviceId == alarmData.nDeviceId &&
                alarm.nUnitId == alarmData.nUnitId) {
    // 使用锁保护多线程安全
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_pDB->executeQuery(query.str());
                alarmEventId = it->first;
                return false;
            }
        }
        // 构建插入查询并使用 RETURNING 获取插入后的 alarm_event_id
        std::ostringstream query;
        query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) "
            << "VALUES (" << alarmData.nId << ", " << alarmData.nSeverityLevel << ", " << alarmData.nDeviceId << ", "
            << alarmData.nUnitId << ", '" << alarmData.strDescription << "', '" << alarmData.strStartTime << "', '"
            << alarmData.strEndTime << "') RETURNING alarm_event_id;";
        // 使用锁保护多线程安全
        std::lock_guard<std::mutex> lock(m_mutex);
        // 执行查询并获取结果
        auto results = m_pDB->fetchResults(query.str());
        if (!results.empty() && !results[0].empty()) {
            try {
                // 提取并转换 alarm_event_id
                alarmEventId = std::stoi(results[0][0]);
                // 将插入的报警数据添加到缓存
                m_mapCache[alarmEventId] = alarmData;
                return true;
            }
            catch (const std::exception& e) {
                std::cerr << "Error parsing alarm_event_id: " << e.what() << std::endl;
                return false;
            }
        }
        return false;
    #endif
}
// 查询所有报警数据
@@ -636,6 +687,79 @@
    return result[0][0];  // 返回查询到的单元名称
}
// 获取最近插入的 alarm_event_id
int AlarmManager::getLastInsertId() {
    std::string query = "SELECT last_insert_rowid();";
    auto results = m_pDB->fetchResults(query);
    if (results.empty() || results[0].empty()) {
        return -1;
    }
    // 从查询结果中获取最后插入的 ID
    int lastInsertId = std::stoi(results[0][0]);
    return lastInsertId;
}
// 通过 alarm_event_id 解除报警(更新结束时间)
bool AlarmManager::clearAlarmByEventId(int alarmEventId, const std::string& endTime) {
    if (!m_pDB) {
        return false;
    }
    bool result = true;
    auto it = m_mapCache.find(alarmEventId);
    if (it != m_mapCache.end()) {
        std::lock_guard<std::mutex> lock(m_mutex);
        std::ostringstream query;
        query << "UPDATE alarms SET end_time = '" << endTime << "' WHERE alarm_event_id = " << alarmEventId << ";";
        bool result = m_pDB->executeQuery(query.str());
        if (result) {
            m_mapCache.erase(it);
        }
    }
    return result;
}
// 通过多个属性查找并解除报警(更新结束时间)
bool AlarmManager::clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime) {
    if (!m_pDB) {
        return false;
    }
    std::lock_guard<std::mutex> lock(m_mutex);
    // 先在缓存中查找匹配的 alarm_event_id
    int alarmEventId = -1;
    for (AlarmDataMap::const_iterator it = m_mapCache.begin(); it != m_mapCache.end(); ++it) {
        const AlarmData& alarm = it->second;
        if (alarm.nId == nId &&
            alarm.nDeviceId == nDeviceId &&
            alarm.nUnitId == nUnitId) {
            alarmEventId = it->first;
            break;
        }
    }
    // 如果没找到匹配的记录,则直接返回 false
    if (alarmEventId == -1) {
        return false;
    }
    // 构建 SQL 语句,使用找到的 alarm_event_id 来更新结束时间
    std::ostringstream query;
    query << "UPDATE alarms SET end_time = '" << endTime << "' WHERE alarm_event_id = " << alarmEventId << ";";
    bool result = m_pDB->executeQuery(query.str());
    if (result) {
        m_mapCache.erase(alarmEventId);
    }
    return result;
}
// 读取报警文件
bool AlarmManager::readAlarmFile(const std::string& filename) {
    std::ifstream file(filename);
@@ -657,23 +781,32 @@
        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 = 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, ',');
        try {
            // 逐字段解析并验证
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: No");
            if (!std::getline(ss, alarm.strUnitID, ',')) throw std::runtime_error("Missing field: UnitID");
            if (!std::getline(ss, alarm.strUnitNo, ',')) throw std::runtime_error("Missing field: UnitNo");
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmLevel");
            alarm.nAlarmLevel = std::stoi(cell);
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmCode");
            alarm.nAlarmCode = std::stoi(cell);
            if (!std::getline(ss, cell, ',')) throw std::runtime_error("Missing field: AlarmID");
            alarm.nAlarmID = std::stoi(cell);
            if (!std::getline(ss, alarm.strAlarmText, ',')) throw std::runtime_error("Missing field: AlarmText");
            if (!std::getline(ss, alarm.strDescription, ',')) throw std::runtime_error("Missing field: Description");
        if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) {
            m_mapAlarm[alarm.nAlarmID] = alarm;
            // 检查是否重复
            if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) {
                m_mapAlarm[alarm.nAlarmID] = alarm;
            }
            else {
                std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl;
            }
        }
        else {
            std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl;
        catch (const std::exception& e) {
            // 捕获并记录解析错误
            std::cerr << "Error parsing line: " << line << " - " << e.what() << std::endl;
            continue;
        }
    }
@@ -731,7 +864,7 @@
        auto it = m_mapAlarm.find(alarmID);
        if (it != m_mapAlarm.end()) {
            alarms.push_back(it->second);
        }
        }
        else {
            std::cerr << "未找到 AlarmID: " << alarmID << std::endl;
        }