From 847a34f02bfe00475735fb5bfbefea2db28c8ad6 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期六, 24 一月 2026 17:15:48 +0800
Subject: [PATCH] 1.修复前烘-b, 后烘-b没有进入b分支导致数据没有推送到显示端的问题;
---
SourceCode/Bond/Servo/AlarmManager.cpp | 628 +++++++++++++++++++++++++++++++++++---------------------
1 files changed, 390 insertions(+), 238 deletions(-)
diff --git a/SourceCode/Bond/Servo/AlarmManager.cpp b/SourceCode/Bond/Servo/AlarmManager.cpp
index 74b1006..8cd9acb 100644
--- a/SourceCode/Bond/Servo/AlarmManager.cpp
+++ b/SourceCode/Bond/Servo/AlarmManager.cpp
@@ -1,5 +1,7 @@
-#include "stdafx.h"
+锘�#include "stdafx.h"
+#include "Common.h"
#include "AlarmManager.h"
+#include "Log.h"
#include <sstream>
#include <fstream>
#include <iostream>
@@ -7,25 +9,26 @@
#include <ctime>
#include <iomanip>
#include <random>
+#include <chrono>
-// 常量
+// 甯搁噺
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;
@@ -33,13 +36,7 @@
}
}
-// 设置数据库连接
-void AlarmManager::setDatabase(BL::Database* db) {
- std::lock_guard<std::mutex> lock(m_mutex);
- m_pDB = db;
-}
-
-// 初始化报警表
+// 鍒濆鍖栨姤璀﹁〃
bool AlarmManager::initAlarmTable() {
char path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH);
@@ -54,7 +51,7 @@
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,
@@ -65,7 +62,7 @@
return false;
}
- // 创建单元表,设备ID和单元ID组合作为主键
+ // 鍒涘缓鍗曞厓琛紝璁惧ID鍜屽崟鍏僆D缁勫悎浣滀负涓婚敭
const std::string createUnitsTableQuery = R"(
CREATE TABLE IF NOT EXISTS units (
device_id TEXT NOT NULL,
@@ -79,7 +76,7 @@
return false;
}
- // 创建报警表,报警记录的alarm_event_id是主键
+ // 鍒涘缓鎶ヨ琛紝鎶ヨ璁板綍鐨刟larm_event_id鏄富閿�
const std::string createAlarmsTableQuery = R"(
CREATE TABLE IF NOT EXISTS alarms (
alarm_event_id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -89,22 +86,69 @@
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)
)
)";
- return m_pDB->executeQuery(createAlarmsTableQuery);
+ if (!m_pDB->executeQuery(createAlarmsTableQuery)) {
+ return false;
+ }
+
+ // 璁惧鍒楄〃 (ID -> 鍚嶇О)
+ std::vector<std::pair<int, std::string>> devices = {
+ {0, "Software"},
+ {EQ_ID_LOADPORT1, EQ_NAME_LOADPORT1},
+ {EQ_ID_LOADPORT2, EQ_NAME_LOADPORT2},
+ {EQ_ID_LOADPORT3, EQ_NAME_LOADPORT3},
+ {EQ_ID_LOADPORT4, EQ_NAME_LOADPORT4},
+ {EQ_ID_ARM_TRAY1, EQ_NAME_ARM_TRAY1},
+ {EQ_ID_ARM_TRAY2, EQ_NAME_ARM_TRAY2},
+ {EQ_ID_ALIGNER, EQ_NAME_ALIGNER},
+ {EQ_ID_FLIPER, EQ_NAME_FLIPER},
+ {EQ_ID_VACUUMBAKE, EQ_NAME_VACUUMBAKE},
+ {EQ_ID_Bonder1, EQ_NAME_BONDER1},
+ {EQ_ID_Bonder2, EQ_NAME_BONDER2},
+ {EQ_ID_BAKE_COOLING, EQ_NAME_BAKE_COOLING},
+ {EQ_ID_MEASUREMENT, EQ_NAME_MEASUREMENT},
+ {EQ_ID_EFEM, EQ_NAME_EFEM},
+ {EQ_ID_ARM, EQ_NAME_ARM},
+ {EQ_ID_OPERATOR_REMOVE, EQ_NAME_OPERATOR_REMOVE}
+ };
+
+ // 鎻掑叆 devices 鍜屽搴旂殑榛樿 unit
+ for (const auto& dev : devices) {
+ int nDeviceId = dev.first;
+ const std::string& strDeviceName = dev.second;
+
+ // 鎻掑叆璁惧
+ std::ostringstream ossDev;
+ ossDev << "INSERT OR IGNORE INTO devices (device_id, device_name) VALUES("
+ << nDeviceId << ", '" << strDeviceName << "')";
+ if (!m_pDB->executeQuery(ossDev.str())) {
+ return false;
+ }
+
+ // 鎻掑叆榛樿鍗曞厓 (unit_id = 0, unit_name = device_name)
+ std::ostringstream ossUnit;
+ ossUnit << "INSERT OR IGNORE INTO units (device_id, unit_id, unit_name) VALUES("
+ << nDeviceId << ", 0, '" << strDeviceName << "')";
+ if (!m_pDB->executeQuery(ossUnit.str())) {
+ return false;
+ }
+ }
+
+ return true;
}
-// 销毁报警表
+// 閿�姣佹姤璀﹁〃
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.");
@@ -113,9 +157,9 @@
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;
@@ -125,17 +169,17 @@
}
}
- // 插入单元数据
+ // 鎻掑叆鍗曞厓鏁版嵁
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);
std::stringstream query;
query << "INSERT INTO units (device_id, unit_id, unit_name) VALUES ('"
- << deviceId << "', '" // 插入设备ID,确保是字符串
- << unitId << "', '" // 插入单元ID,确保是字符串
+ << deviceId << "', '" // 鎻掑叆璁惧ID锛岀‘淇濇槸瀛楃涓�
+ << unitId << "', '" // 鎻掑叆鍗曞厓ID锛岀‘淇濇槸瀛楃涓�
<< unitName << "');";
if (!m_pDB->executeQuery(query.str())) {
@@ -144,7 +188,8 @@
}
}
- // 初始化随机数生成器
+ /*
+ // 鍒濆鍖栭殢鏈烘暟鐢熸垚鍣�
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> deviceDis(1, 3);
@@ -153,7 +198,7 @@
std::uniform_int_distribution<> severityDis(0, 3);
std::vector<std::string> 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));
@@ -163,13 +208,13 @@
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); // 随机错误码
- int severityLevel = severityDis(gen); // 随机生成报警等级
- std::string description = descriptions[errorCodeDis(gen) % descriptions.size()]; // 随机报警描述
+ int deviceId = deviceDis(gen); // 闅忔満璁惧ID
+ int unitId = unitDis(gen); // 闅忔満鍗曞厓ID
+ int errorCode = errorCodeDis(gen); // 闅忔満閿欒鐮�
+ int severityLevel = severityDis(gen); // 闅忔満鐢熸垚鎶ヨ绛夌骇
+ std::string description = descriptions[errorCodeDis(gen) % descriptions.size()]; // 闅忔満鎶ヨ鎻忚堪
std::stringstream query;
query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) "
@@ -181,61 +226,73 @@
std::cerr << "Failed to insert alarm data." << std::endl;
}
}
+ */
}
-// 添加报警信息
+// 娣诲姞鎶ヨ淇℃伅
bool AlarmManager::addAlarm(const AlarmData& alarmData, int& alarmEventId) {
if (!m_pDB) {
return false;
}
#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 << "')"; // 结束时间
+ << 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
- // 构建插入查询并使用 RETURNING 获取插入后的 alarm_event_id
+ 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) {
+
+ 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
+ // 鎻愬彇骞惰浆鎹� alarm_event_id
alarmEventId = std::stoi(results[0][0]);
- // 将插入的报警数据添加到缓存
+ // 灏嗘彃鍏ョ殑鎶ヨ鏁版嵁娣诲姞鍒扮紦瀛�
m_mapCache[alarmEventId] = alarmData;
return true;
}
@@ -249,13 +306,13 @@
#endif
}
-// 查询所有报警数据
+// 鏌ヨ鎵�鏈夋姤璀︽暟鎹�
std::vector<AlarmData> AlarmManager::getAllAlarms() {
if (!m_pDB) {
return {};
}
- // 查询所有报警数据(包括设备名称和单元名称)
+ // 鏌ヨ鎵�鏈夋姤璀︽暟鎹紙鍖呮嫭璁惧鍚嶇О鍜屽崟鍏冨悕绉帮級
const std::string query = R"(
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
FROM alarms a
@@ -265,19 +322,19 @@
auto results = m_pDB->fetchResults(query);
- // 遍历查询结果,填充 AlarmData 结构体
+ // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� AlarmData 缁撴瀯浣�
std::vector<AlarmData> alarms;
for (const auto& row : results) {
AlarmData alarmData;
- alarmData.nId = std::stoi(row[0]); // 错误码
- alarmData.nSeverityLevel = std::stoi(row[1]); // 报警等级
- alarmData.nDeviceId = std::stoi(row[2]); // 设备ID
- alarmData.nUnitId = std::stoi(row[3]); // 单元ID
- alarmData.strDeviceName = row[4]; // 设备名称
- alarmData.strUnitName = row[5]; // 单元名称
- alarmData.strDescription = row[6]; // 描述
- alarmData.strStartTime = row[7]; // 开始时间
- alarmData.strEndTime = row[8]; // 结束时间
+ alarmData.nId = std::stoi(row[0]); // 閿欒鐮�
+ alarmData.nSeverityLevel = std::stoi(row[1]); // 鎶ヨ绛夌骇
+ alarmData.nDeviceId = std::stoi(row[2]); // 璁惧ID
+ alarmData.nUnitId = std::stoi(row[3]); // 鍗曞厓ID
+ alarmData.strDeviceName = row[4]; // 璁惧鍚嶇О
+ alarmData.strUnitName = row[5]; // 鍗曞厓鍚嶇О
+ alarmData.strDescription = row[6]; // 鎻忚堪
+ alarmData.strStartTime = row[7]; // 寮�濮嬫椂闂�
+ alarmData.strEndTime = row[8]; // 缁撴潫鏃堕棿
alarms.push_back(alarmData);
}
@@ -285,7 +342,7 @@
return alarms;
}
-// 根据报警ID查询报警
+// 鏍规嵁鎶ヨID鏌ヨ鎶ヨ
std::vector<AlarmData> AlarmManager::getAlarmsById(const std::string& id) {
if (!m_pDB) {
return {};
@@ -301,19 +358,19 @@
auto results = m_pDB->fetchResults(query.str());
- // 遍历查询结果,填充 AlarmData 结构体
+ // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� AlarmData 缁撴瀯浣�
std::vector<AlarmData> alarms;
for (const auto& row : results) {
AlarmData alarmData;
- alarmData.nId = std::stoi(row[0]); // 错误码
- alarmData.nSeverityLevel = std::stoi(row[1]); // 报警等级
- alarmData.nDeviceId = std::stoi(row[2]); // 设备ID
- alarmData.nUnitId = std::stoi(row[3]); // 单元ID
- alarmData.strDeviceName = row[4]; // 设备名称
- alarmData.strUnitName = row[5]; // 单元名称
- alarmData.strDescription = row[6]; // 描述
- alarmData.strStartTime = row[7]; // 开始时间
- alarmData.strEndTime = row[8]; // 结束时间
+ alarmData.nId = std::stoi(row[0]); // 閿欒鐮�
+ alarmData.nSeverityLevel = std::stoi(row[1]); // 鎶ヨ绛夌骇
+ alarmData.nDeviceId = std::stoi(row[2]); // 璁惧ID
+ alarmData.nUnitId = std::stoi(row[3]); // 鍗曞厓ID
+ alarmData.strDeviceName = row[4]; // 璁惧鍚嶇О
+ alarmData.strUnitName = row[5]; // 鍗曞厓鍚嶇О
+ alarmData.strDescription = row[6]; // 鎻忚堪
+ alarmData.strStartTime = row[7]; // 寮�濮嬫椂闂�
+ alarmData.strEndTime = row[8]; // 缁撴潫鏃堕棿
alarms.push_back(alarmData);
}
@@ -321,7 +378,7 @@
return alarms;
}
-// 根据描述查询报警
+// 鏍规嵁鎻忚堪鏌ヨ鎶ヨ
std::vector<AlarmData> AlarmManager::getAlarmsByDescription(const std::string& description) {
if (!m_pDB) {
return {};
@@ -337,19 +394,19 @@
auto results = m_pDB->fetchResults(query.str());
- // 遍历查询结果,填充 AlarmData 结构体
+ // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� AlarmData 缁撴瀯浣�
std::vector<AlarmData> alarms;
for (const auto& row : results) {
AlarmData alarmData;
- alarmData.nId = std::stoi(row[0]); // 错误码
- alarmData.nSeverityLevel = std::stoi(row[1]); // 报警等级
- alarmData.nDeviceId = std::stoi(row[2]); // 设备ID
- alarmData.nUnitId = std::stoi(row[3]); // 单元ID
- alarmData.strDeviceName = row[4]; // 设备名称
- alarmData.strUnitName = row[5]; // 单元名称
- alarmData.strDescription = row[6]; // 描述
- alarmData.strStartTime = row[7]; // 开始时间
- alarmData.strEndTime = row[8]; // 结束时间
+ alarmData.nId = std::stoi(row[0]); // 閿欒鐮�
+ alarmData.nSeverityLevel = std::stoi(row[1]); // 鎶ヨ绛夌骇
+ alarmData.nDeviceId = std::stoi(row[2]); // 璁惧ID
+ alarmData.nUnitId = std::stoi(row[3]); // 鍗曞厓ID
+ alarmData.strDeviceName = row[4]; // 璁惧鍚嶇О
+ alarmData.strUnitName = row[5]; // 鍗曞厓鍚嶇О
+ alarmData.strDescription = row[6]; // 鎻忚堪
+ alarmData.strStartTime = row[7]; // 寮�濮嬫椂闂�
+ alarmData.strEndTime = row[8]; // 缁撴潫鏃堕棿
alarms.push_back(alarmData);
}
@@ -357,7 +414,7 @@
return alarms;
}
-// 根据时间范围查询报警
+// 鏍规嵁鏃堕棿鑼冨洿鏌ヨ鎶ヨ
std::vector<AlarmData> AlarmManager::getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime) {
if (!m_pDB) {
return {};
@@ -380,19 +437,19 @@
auto results = m_pDB->fetchResults(query.str());
- // 遍历查询结果,填充 AlarmData 结构体
+ // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� AlarmData 缁撴瀯浣�
std::vector<AlarmData> alarms;
for (const auto& row : results) {
AlarmData alarmData;
- alarmData.nId = std::stoi(row[0]); // 错误码
- alarmData.nSeverityLevel = std::stoi(row[1]); // 报警等级
- alarmData.nDeviceId = std::stoi(row[2]); // 设备ID
- alarmData.nUnitId = std::stoi(row[3]); // 单元ID
- alarmData.strDeviceName = row[4]; // 设备名称
- alarmData.strUnitName = row[5]; // 单元名称
- alarmData.strDescription = row[6]; // 描述
- alarmData.strStartTime = row[7]; // 开始时间
- alarmData.strEndTime = row[8]; // 结束时间
+ alarmData.nId = std::stoi(row[0]); // 閿欒鐮�
+ alarmData.nSeverityLevel = std::stoi(row[1]); // 鎶ヨ绛夌骇
+ alarmData.nDeviceId = std::stoi(row[2]); // 璁惧ID
+ alarmData.nUnitId = std::stoi(row[3]); // 鍗曞厓ID
+ alarmData.strDeviceName = row[4]; // 璁惧鍚嶇О
+ alarmData.strUnitName = row[5]; // 鍗曞厓鍚嶇О
+ alarmData.strDescription = row[6]; // 鎻忚堪
+ alarmData.strStartTime = row[7]; // 寮�濮嬫椂闂�
+ alarmData.strEndTime = row[8]; // 缁撴潫鏃堕棿
alarms.push_back(alarmData);
}
@@ -400,7 +457,7 @@
return alarms;
}
-// 根据ID、开始时间和结束时间查询报警
+// 鏍规嵁ID銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿鏌ヨ鎶ヨ
std::vector<AlarmData> AlarmManager::getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime) {
if (!m_pDB) {
return {};
@@ -423,19 +480,19 @@
auto results = m_pDB->fetchResults(query.str());
- // 遍历查询结果,填充 AlarmData 结构体
+ // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� AlarmData 缁撴瀯浣�
std::vector<AlarmData> alarms;
for (const auto& row : results) {
AlarmData alarmData;
- alarmData.nId = std::stoi(row[0]); // 错误码
- alarmData.nSeverityLevel = std::stoi(row[1]); // 报警等级
- alarmData.nDeviceId = std::stoi(row[2]); // 设备ID
- alarmData.nUnitId = std::stoi(row[3]); // 单元ID
- alarmData.strDeviceName = row[4]; // 设备名称
- alarmData.strUnitName = row[5]; // 单元名称
- alarmData.strDescription = row[6]; // 描述
- alarmData.strStartTime = row[7]; // 开始时间
- alarmData.strEndTime = row[8]; // 结束时间
+ alarmData.nId = std::stoi(row[0]); // 閿欒鐮�
+ alarmData.nSeverityLevel = std::stoi(row[1]); // 鎶ヨ绛夌骇
+ alarmData.nDeviceId = std::stoi(row[2]); // 璁惧ID
+ alarmData.nUnitId = std::stoi(row[3]); // 鍗曞厓ID
+ alarmData.strDeviceName = row[4]; // 璁惧鍚嶇О
+ alarmData.strUnitName = row[5]; // 鍗曞厓鍚嶇О
+ alarmData.strDescription = row[6]; // 鎻忚堪
+ alarmData.strStartTime = row[7]; // 寮�濮嬫椂闂�
+ alarmData.strEndTime = row[8]; // 缁撴潫鏃堕棿
alarms.push_back(alarmData);
}
@@ -443,7 +500,7 @@
return alarms;
}
-// 分页查询报警数据
+// 鍒嗛〉鏌ヨ鎶ヨ鏁版嵁
std::vector<AlarmData> AlarmManager::getAlarms(int startPosition, int count) {
if (!m_pDB) {
return {};
@@ -459,19 +516,19 @@
auto results = m_pDB->fetchResults(query.str());
- // 遍历查询结果,填充 AlarmData 结构体
+ // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� AlarmData 缁撴瀯浣�
std::vector<AlarmData> alarms;
for (const auto& row : results) {
AlarmData alarmData;
- alarmData.nId = std::stoi(row[0]); // 错误码
- alarmData.nSeverityLevel = std::stoi(row[1]); // 报警等级
- alarmData.nDeviceId = std::stoi(row[2]); // 设备ID
- alarmData.nUnitId = std::stoi(row[3]); // 单元ID
- alarmData.strDeviceName = row[4]; // 设备名称
- alarmData.strUnitName = row[5]; // 单元名称
- alarmData.strDescription = row[6]; // 描述
- alarmData.strStartTime = row[7]; // 开始时间
- alarmData.strEndTime = row[8]; // 结束时间
+ alarmData.nId = std::stoi(row[0]); // 閿欒鐮�
+ alarmData.nSeverityLevel = std::stoi(row[1]); // 鎶ヨ绛夌骇
+ alarmData.nDeviceId = std::stoi(row[2]); // 璁惧ID
+ alarmData.nUnitId = std::stoi(row[3]); // 鍗曞厓ID
+ alarmData.strDeviceName = row[4]; // 璁惧鍚嶇О
+ alarmData.strUnitName = row[5]; // 鍗曞厓鍚嶇О
+ alarmData.strDescription = row[6]; // 鎻忚堪
+ alarmData.strStartTime = row[7]; // 寮�濮嬫椂闂�
+ alarmData.strEndTime = row[8]; // 缁撴潫鏃堕棿
alarms.push_back(alarmData);
}
@@ -479,18 +536,87 @@
return alarms;
}
-// 筛选报警数据
-std::vector<AlarmData> AlarmManager::getFilteredAlarms(
- const std::string& id,
- const std::string& severityLevel,
- const std::string& deviceName,
- const std::string& unitName,
- const std::string& description,
- const std::string& startTime,
- const std::string& endTime,
- int pageNumber,
- int pageSize) {
+// 鑾峰彇褰撳墠鏈粨鏉熺殑鎶ヨ锛坋nd_time 涓虹┖锛夛紝骞跺彲鎸� start_time 鏈�杩� N 灏忔椂杩囨护
+std::vector<AlarmData> AlarmManager::getActiveAlarms(int recentHours /*=12*/) {
+ if (!m_pDB) {
+ return {};
+ }
+ // 璁$畻鏃堕棿闃堝�硷細褰撳墠鏃堕棿鍑� recentHours
+ std::string cutoffTime;
+ if (recentHours > 0) {
+ using namespace std::chrono;
+ auto cutoff = system_clock::now() - hours(recentHours);
+ std::time_t t = system_clock::to_time_t(cutoff);
+ std::tm tm {};
+ localtime_s(&tm, &t);
+ char buf[32] = { 0 };
+ std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
+ cutoffTime = buf;
+ }
+
+ std::ostringstream query;
+ query << R"(
+ SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
+ FROM alarms a
+ JOIN devices d ON a.device_id = d.device_id
+ JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
+ WHERE a.end_time IS NULL OR a.end_time = ''
+ )";
+ if (!cutoffTime.empty()) {
+ query << " AND a.start_time >= '" << cutoffTime << "'";
+ }
+ query << " ORDER BY a.start_time DESC";
+
+ auto lastErrStr = []() -> std::string {
+ DWORD gle = GetLastError();
+ if (gle == 0) return {};
+ LPSTR buf = nullptr;
+ size_t len = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, gle, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, nullptr);
+ std::string s = (buf && len > 0) ? std::string(buf, len) : "";
+ if (buf) LocalFree(buf);
+ return s;
+ };
+ std::vector<std::vector<std::string>> results;
+ try {
+ results = m_pDB->fetchResults(query.str());
+ }
+ catch (const std::exception& ex) {
+ DWORD gle = GetLastError();
+ auto errStr = lastErrStr();
+ LOGE("<AlarmManager>getActiveAlarms failed: %s, GLE=%lu (%s)", ex.what(), gle, errStr.c_str());
+ return {};
+ }
+ std::vector<AlarmData> alarms;
+ auto toInt = [](const std::string& s) -> int {
+ try {
+ return std::stoi(s);
+ }
+ catch (...) {
+ return 0;
+ }
+ };
+ for (const auto& row : results) {
+ if (row.size() < 9) continue;
+ AlarmData alarmData;
+ alarmData.nId = toInt(row[0]);
+ alarmData.nSeverityLevel = toInt(row[1]);
+ alarmData.nDeviceId = toInt(row[2]);
+ alarmData.nUnitId = toInt(row[3]);
+ alarmData.strDeviceName = row[4];
+ alarmData.strUnitName = row[5];
+ alarmData.strDescription = row[6];
+ alarmData.strStartTime = row[7];
+ alarmData.strEndTime = row[8];
+ alarms.push_back(alarmData);
+ }
+
+ return alarms;
+}
+
+// 绛涢�夋姤璀︽暟鎹�
+std::vector<AlarmData> AlarmManager::getFilteredAlarms(const std::string& keyword, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize) {
if (!m_pDB) {
return {};
}
@@ -500,25 +626,20 @@
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
FROM alarms a
JOIN devices d ON a.device_id = d.device_id
- JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
+ JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
WHERE 1=1)";
- // 传入的过滤条件
- if (!id.empty()) {
- query << " AND a.id = '" << id << "'";
+ // 缁熶竴鍏抽敭瀛楁ā绯婃煡璇�
+ if (!keyword.empty()) {
+ query << " AND ("
+ << "a.id LIKE '%" << keyword << "%' OR "
+ << "a.severity_level LIKE '%" << keyword << "%' OR "
+ << "d.device_name LIKE '%" << keyword << "%' OR "
+ << "u.unit_name LIKE '%" << keyword << "%' OR "
+ << "a.description LIKE '%" << keyword << "%')";
}
- if (!severityLevel.empty()) {
- query << " AND a.severity_level = '" << severityLevel << "'";
- }
- if (!deviceName.empty()) {
- query << " AND d.device_name LIKE '%" << deviceName << "%'";
- }
- if (!unitName.empty()) {
- query << " AND u.unit_name LIKE '%" << unitName << "%'";
- }
- if (!description.empty()) {
- query << " AND a.description LIKE '%" << description << "%'";
- }
+
+ // 鏃堕棿鏉′欢
if (!startTime.empty()) {
query << " AND a.start_time >= '" << startTime << "'";
}
@@ -526,25 +647,26 @@
query << " AND a.end_time <= '" << endTime << "'";
}
- // 分页设置
- int offset = (pageNumber - 1) * pageSize;
- query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
+ // 鍒嗛〉璁剧疆
+ int nOffset = (pageNumber - 1) * pageSize;
+ query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << nOffset;
+ // 鏌ヨ
auto results = m_pDB->fetchResults(query.str());
- // 遍历查询结果,填充 AlarmData 结构体
+ // 閬嶅巻鏌ヨ缁撴灉锛屽~鍏� AlarmData 缁撴瀯浣�
std::vector<AlarmData> alarms;
for (const auto& row : results) {
AlarmData alarmData;
- alarmData.nId = std::stoi(row[0]); // 错误码
- alarmData.nSeverityLevel = std::stoi(row[1]); // 报警等级 (字符串)
- alarmData.nDeviceId = std::stoi(row[2]); // 设备ID
- alarmData.nUnitId = std::stoi(row[3]); // 单元ID
- alarmData.strDeviceName = row[4]; // 设备名称
- alarmData.strUnitName = row[5]; // 单元名称
- alarmData.strDescription = row[6]; // 描述
- alarmData.strStartTime = row[7]; // 开始时间
- alarmData.strEndTime = row[8]; // 结束时间
+ alarmData.nId = std::stoi(row[0]); // 閿欒鐮�
+ alarmData.nSeverityLevel = std::stoi(row[1]); // 鎶ヨ绛夌骇 (瀛楃涓�)
+ alarmData.nDeviceId = std::stoi(row[2]); // 璁惧ID
+ alarmData.nUnitId = std::stoi(row[3]); // 鍗曞厓ID
+ alarmData.strDeviceName = row[4]; // 璁惧鍚嶇О
+ alarmData.strUnitName = row[5]; // 鍗曞厓鍚嶇О
+ alarmData.strDescription = row[6]; // 鎻忚堪
+ alarmData.strStartTime = row[7]; // 寮�濮嬫椂闂�
+ alarmData.strEndTime = row[8]; // 缁撴潫鏃堕棿
alarms.push_back(alarmData);
}
@@ -552,42 +674,31 @@
return alarms;
}
-// 获取符合条件的报警总数
-int AlarmManager::getTotalAlarmCount(
- const std::string& id,
- const std::string& severityLevel,
- const std::string& deviceName,
- const std::string& unitName,
- const std::string& description,
- const std::string& startTime,
- const std::string& endTime) {
-
+// 鑾峰彇绗﹀悎鏉′欢鐨勬姤璀︽�绘暟
+int AlarmManager::getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime) {
if (!m_pDB) {
return 0;
}
std::ostringstream query;
- query << "SELECT COUNT(*) FROM alarms a "
- << "JOIN devices d ON a.device_id = d.device_id "
- << "JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id "
- << "WHERE 1=1";
+ query << R"(
+ SELECT COUNT(*)
+ FROM alarms a
+ JOIN devices d ON a.device_id = d.device_id
+ JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
+ WHERE 1=1)";
- // 添加过滤条件
- if (!id.empty()) {
- query << " AND a.id = '" << id << "'";
+ // 缁熶竴鍏抽敭瀛楁ā绯婃煡璇�
+ if (!keyword.empty()) {
+ query << " AND ("
+ << "a.id LIKE '%" << keyword << "%' OR "
+ << "a.severity_level LIKE '%" << keyword << "%' OR "
+ << "d.device_name LIKE '%" << keyword << "%' OR "
+ << "u.unit_name LIKE '%" << keyword << "%' OR "
+ << "a.description LIKE '%" << keyword << "%')";
}
- if (!severityLevel.empty()) {
- query << " AND a.severity_level = '" << severityLevel << "'";
- }
- if (!deviceName.empty()) {
- query << " AND d.device_name LIKE '%" << deviceName << "%'";
- }
- if (!unitName.empty()) {
- query << " AND u.unit_name LIKE '%" << unitName << "%'";
- }
- if (!description.empty()) {
- query << " AND a.description LIKE '%" << description << "%'";
- }
+
+ // 鏃堕棿鏉′欢
if (!startTime.empty()) {
query << " AND a.start_time >= '" << startTime << "'";
}
@@ -599,7 +710,7 @@
return (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0;
}
-// 更新报警的结束时间
+// 鏇存柊鎶ヨ鐨勭粨鏉熸椂闂�
bool AlarmManager::updateAlarmEndTime(
const std::string& id,
const std::string& severityLevel,
@@ -613,7 +724,7 @@
return false;
}
- // 更新报警结束时间
+ // 鏇存柊鎶ヨ缁撴潫鏃堕棿
std::ostringstream updateQuery;
updateQuery << "UPDATE alarms SET end_time = '" << newEndTime << "'"
<< " WHERE id = '" << id << "'"
@@ -626,7 +737,7 @@
return m_pDB->executeQuery(updateQuery.str());
}
-// 清理旧报警数据
+// 娓呯悊鏃ф姤璀︽暟鎹�
void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceId, const std::string& unitId) {
if (!m_pDB) {
return;
@@ -645,7 +756,7 @@
m_pDB->executeQuery(query.str());
}
-// 通过设备ID获取设备名称
+// 閫氳繃璁惧ID鑾峰彇璁惧鍚嶇О
std::string AlarmManager::getDeviceNameById(int deviceId) {
if (!m_pDB) {
return "";
@@ -659,10 +770,10 @@
return "";
}
- return result[0][0]; // 返回查询到的设备名称
+ return result[0][0]; // 杩斿洖鏌ヨ鍒扮殑璁惧鍚嶇О
}
-// 通过设备ID和单元ID获取单元名称
+// 閫氳繃璁惧ID鍜屽崟鍏僆D鑾峰彇鍗曞厓鍚嶇О
std::string AlarmManager::getUnitNameById(int deviceId, int unitId) {
if (!m_pDB) {
return "";
@@ -677,10 +788,10 @@
return "";
}
- return result[0][0]; // 返回查询到的单元名称
+ return result[0][0]; // 杩斿洖鏌ヨ鍒扮殑鍗曞厓鍚嶇О
}
-// 获取最近插入的 alarm_event_id
+// 鑾峰彇鏈�杩戞彃鍏ョ殑 alarm_event_id
int AlarmManager::getLastInsertId() {
std::string query = "SELECT last_insert_rowid();";
auto results = m_pDB->fetchResults(query);
@@ -689,12 +800,12 @@
return -1;
}
- // 从查询结果中获取最后插入的 ID
+ // 浠庢煡璇㈢粨鏋滀腑鑾峰彇鏈�鍚庢彃鍏ョ殑 ID
int lastInsertId = std::stoi(results[0][0]);
return lastInsertId;
}
-// 通过 alarm_event_id 解除报警(更新结束时间)
+// 閫氳繃 alarm_event_id 瑙i櫎鎶ヨ锛堟洿鏂扮粨鏉熸椂闂达級
bool AlarmManager::clearAlarmByEventId(int alarmEventId, const std::string& endTime) {
if (!m_pDB) {
return false;
@@ -716,35 +827,53 @@
return result;
}
-// 通过多个属性查找并解除报警(更新结束时间)
-bool AlarmManager::clearAlarmByAttributes(int nId, int nSeverityLevel, int nDeviceId, int nUnitId, const std::string& strDescription, const std::string& endTime) {
+// 閫氳繃澶氫釜灞炴�ф煡鎵惧苟瑙i櫎鎶ヨ锛堟洿鏂扮粨鏉熸椂闂达級
+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
+ // 鍏堝湪缂撳瓨涓煡鎵惧尮閰嶇殑 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.nSeverityLevel == nSeverityLevel &&
alarm.nDeviceId == nDeviceId &&
- alarm.nUnitId == nUnitId &&
- alarm.strDescription == strDescription) {
+ alarm.nUnitId == nUnitId) {
alarmEventId = it->first;
break;
}
}
- // 如果没找到匹配的记录,则直接返回 false
- if (alarmEventId == -1) {
- return false;
- }
+ // 缂撳瓨鏈懡涓椂锛屼粠鏁版嵁搴撴煡鎵句粛鏈粨鏉熺殑璁板綍锛堝彇鏈�鏂颁竴鏉★級
+ if (alarmEventId == -1) {
+ std::ostringstream querySel;
+ querySel << "SELECT alarm_event_id FROM alarms WHERE "
+ << "id = " << nId
+ << " AND device_id = " << nDeviceId
+ << " AND unit_id = " << nUnitId
+ << " AND (end_time IS NULL OR end_time = '') "
+ << "ORDER BY start_time DESC LIMIT 1;";
+ auto results = m_pDB->fetchResults(querySel.str());
+ if (!results.empty() && !results[0].empty()) {
+ try {
+ alarmEventId = std::stoi(results[0][0]);
+ }
+ catch (...) {
+ alarmEventId = -1;
+ }
+ }
+ }
- // 构建 SQL 语句,使用找到的 alarm_event_id 来更新结束时间
+ // 濡傛灉娌℃壘鍒板尮閰嶇殑璁板綍锛屽垯鐩存帴杩斿洖 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());
@@ -755,18 +884,35 @@
return result;
}
-// 读取报警文件
+// 璇诲彇鎶ヨ鏂囦欢
bool AlarmManager::readAlarmFile(const std::string& filename) {
- std::ifstream file(filename);
- std::string line;
- bool first_line = true;
-
+ std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Error opening file!" << std::endl;
return false;
}
- while (std::getline(file, line)) {
+ auto getline_cross = [](std::ifstream& f, std::string& out) -> bool {
+ out.clear();
+ char ch;
+ while (f.get(ch)) {
+ if (ch == '\r') {
+ // 澶勭悊 \r\n 鎴� 鍗曠嫭 \r
+ if (f.peek() == '\n') f.get();
+ break;
+ }
+ else if (ch == '\n') {
+ break;
+ }
+ out.push_back(ch);
+ }
+ return !out.empty() || !f.eof();
+ };
+
+ std::string line;
+ bool first_line = true;
+
+ while (getline_cross(file, line)) {
if (first_line) {
first_line = false;
continue;
@@ -776,23 +922,29 @@
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;
}
}
@@ -800,19 +952,19 @@
return true;
}
-// 将报警数据保存到文件
+// 灏嗘姤璀︽暟鎹繚瀛樺埌鏂囦欢
bool AlarmManager::saveAlarmFile(const std::string& filename) {
std::ofstream file(filename);
if (!file.is_open()) {
- std::cerr << "打开文件写入失败!" << std::endl;
+ 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;
@@ -830,19 +982,19 @@
return true;
}
-// 通过 AlarmID 查询对应的报警信息
+// 閫氳繃 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;
+ std::cerr << "鏈壘鍒� AlarmID: " << nAlarmID << std::endl;
return nullptr;
}
}
-// 通过多个 AlarmID 查询对应的报警信息
+// 閫氳繃澶氫釜 AlarmID 鏌ヨ瀵瑰簲鐨勬姤璀︿俊鎭�
std::vector<AlarmInfo> AlarmManager::getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const {
std::vector<AlarmInfo> alarms;
@@ -852,7 +1004,7 @@
alarms.push_back(it->second);
}
else {
- std::cerr << "未找到 AlarmID: " << alarmID << std::endl;
+ std::cerr << "鏈壘鍒� AlarmID: " << alarmID << std::endl;
}
}
--
Gitblit v1.9.3