From bfffbdb8a6d7a3b4805c45583f8bf2101e7b2ad4 Mon Sep 17 00:00:00 2001
From: chenluhua1980 <Chenluhua@qq.com>
Date: 星期三, 21 一月 2026 11:34:38 +0800
Subject: [PATCH] 1.警告信息对话框显示;
---
SourceCode/Bond/Servo/Servo.vcxproj | 2
SourceCode/Bond/Servo/AlarmManager.cpp | 420 ++++++++++------
SourceCode/Bond/Servo/Servo.vcxproj.filters | 2
SourceCode/Bond/Servo/resource.h | 23
SourceCode/Bond/Servo/AlarmManager.h | 205 ++++----
SourceCode/Bond/Servo/Servo.rc | 33 +
SourceCode/Bond/Servo/CMaster.cpp | 252 +++++-----
SourceCode/Bond/Servo/AlarmPopupDlg.cpp | 278 +++++++++++
SourceCode/Bond/Servo/ServoDlg.cpp | 130 +++++
SourceCode/Bond/Servo/AlarmPopupDlg.h | 53 ++
SourceCode/Bond/Servo/Common.h | 21
SourceCode/Bond/Servo/ServoDlg.h | 14
12 files changed, 1,034 insertions(+), 399 deletions(-)
diff --git a/SourceCode/Bond/Servo/AlarmManager.cpp b/SourceCode/Bond/Servo/AlarmManager.cpp
index 56d6cbb..8cd9acb 100644
--- a/SourceCode/Bond/Servo/AlarmManager.cpp
+++ b/SourceCode/Bond/Servo/AlarmManager.cpp
@@ -1,6 +1,7 @@
-#include "stdafx.h"
+锘�#include "stdafx.h"
#include "Common.h"
#include "AlarmManager.h"
+#include "Log.h"
#include <sstream>
#include <fstream>
#include <iostream>
@@ -8,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;
@@ -34,7 +36,7 @@
}
}
-// 初始化报警表
+// 鍒濆鍖栨姤璀﹁〃
bool AlarmManager::initAlarmTable() {
char path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH);
@@ -49,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,
@@ -60,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,
@@ -74,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,
@@ -93,8 +95,9 @@
return false;
}
- // 设备列表 (ID -> 名称)
+ // 璁惧鍒楄〃 (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},
@@ -113,12 +116,12 @@
{EQ_ID_OPERATOR_REMOVE, EQ_NAME_OPERATOR_REMOVE}
};
- // 插入 devices 和对应的默认 unit
+ // 鎻掑叆 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 << "')";
@@ -126,7 +129,7 @@
return false;
}
- // 插入默认单元 (unit_id = 0, unit_name = device_name)
+ // 鎻掑叆榛樿鍗曞厓 (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 << "')";
@@ -138,14 +141,14 @@
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.");
@@ -154,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;
@@ -166,7 +169,7 @@
}
}
- // 插入单元数据
+ // 鎻掑叆鍗曞厓鏁版嵁
for (int i = 1; i <= 3; ++i) {
for (int j = 0; j <= 3; ++j) {
int unitId = j;
@@ -175,8 +178,8 @@
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())) {
@@ -186,7 +189,7 @@
}
/*
- // 初始化随机数生成器
+ // 鍒濆鍖栭殢鏈烘暟鐢熸垚鍣�
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> deviceDis(1, 3);
@@ -195,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));
@@ -205,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) "
@@ -226,38 +229,38 @@
*/
}
-// 添加报警信息
+// 娣诲姞鎶ヨ淇℃伅
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;
@@ -273,23 +276,23 @@
}
}
- // 构建插入查询并使用 RETURNING 获取插入后的 alarm_event_id
+ // 鏋勫缓鎻掑叆鏌ヨ骞朵娇鐢� 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;
}
@@ -303,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
@@ -319,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);
}
@@ -339,7 +342,7 @@
return alarms;
}
-// 根据报警ID查询报警
+// 鏍规嵁鎶ヨID鏌ヨ鎶ヨ
std::vector<AlarmData> AlarmManager::getAlarmsById(const std::string& id) {
if (!m_pDB) {
return {};
@@ -355,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);
}
@@ -375,7 +378,7 @@
return alarms;
}
-// 根据描述查询报警
+// 鏍规嵁鎻忚堪鏌ヨ鎶ヨ
std::vector<AlarmData> AlarmManager::getAlarmsByDescription(const std::string& description) {
if (!m_pDB) {
return {};
@@ -391,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);
}
@@ -411,7 +414,7 @@
return alarms;
}
-// 根据时间范围查询报警
+// 鏍规嵁鏃堕棿鑼冨洿鏌ヨ鎶ヨ
std::vector<AlarmData> AlarmManager::getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime) {
if (!m_pDB) {
return {};
@@ -434,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);
}
@@ -454,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 {};
@@ -477,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);
}
@@ -497,7 +500,7 @@
return alarms;
}
-// 分页查询报警数据
+// 鍒嗛〉鏌ヨ鎶ヨ鏁版嵁
std::vector<AlarmData> AlarmManager::getAlarms(int startPosition, int count) {
if (!m_pDB) {
return {};
@@ -513,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);
}
@@ -533,7 +536,86 @@
return alarms;
}
-// 筛选报警数据
+// 鑾峰彇褰撳墠鏈粨鏉熺殑鎶ヨ锛坋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 {};
@@ -547,7 +629,7 @@
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
WHERE 1=1)";
- // 统一关键字模糊查询
+ // 缁熶竴鍏抽敭瀛楁ā绯婃煡璇�
if (!keyword.empty()) {
query << " AND ("
<< "a.id LIKE '%" << keyword << "%' OR "
@@ -557,7 +639,7 @@
<< "a.description LIKE '%" << keyword << "%')";
}
- // 时间条件
+ // 鏃堕棿鏉′欢
if (!startTime.empty()) {
query << " AND a.start_time >= '" << startTime << "'";
}
@@ -565,26 +647,26 @@
query << " AND a.end_time <= '" << endTime << "'";
}
- // 分页设置
+ // 鍒嗛〉璁剧疆
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);
}
@@ -592,7 +674,7 @@
return alarms;
}
-// 获取符合条件的报警总数
+// 鑾峰彇绗﹀悎鏉′欢鐨勬姤璀︽�绘暟
int AlarmManager::getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime) {
if (!m_pDB) {
return 0;
@@ -606,7 +688,7 @@
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
WHERE 1=1)";
- // 统一关键字模糊查询
+ // 缁熶竴鍏抽敭瀛楁ā绯婃煡璇�
if (!keyword.empty()) {
query << " AND ("
<< "a.id LIKE '%" << keyword << "%' OR "
@@ -616,7 +698,7 @@
<< "a.description LIKE '%" << keyword << "%')";
}
- // 时间条件
+ // 鏃堕棿鏉′欢
if (!startTime.empty()) {
query << " AND a.start_time >= '" << startTime << "'";
}
@@ -628,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,
@@ -642,7 +724,7 @@
return false;
}
- // 更新报警结束时间
+ // 鏇存柊鎶ヨ缁撴潫鏃堕棿
std::ostringstream updateQuery;
updateQuery << "UPDATE alarms SET end_time = '" << newEndTime << "'"
<< " WHERE id = '" << id << "'"
@@ -655,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;
@@ -674,7 +756,7 @@
m_pDB->executeQuery(query.str());
}
-// 通过设备ID获取设备名称
+// 閫氳繃璁惧ID鑾峰彇璁惧鍚嶇О
std::string AlarmManager::getDeviceNameById(int deviceId) {
if (!m_pDB) {
return "";
@@ -688,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 "";
@@ -706,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);
@@ -718,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;
@@ -745,7 +827,7 @@
return result;
}
-// 通过多个属性查找并解除报警(更新结束时间)
+// 閫氳繃澶氫釜灞炴�ф煡鎵惧苟瑙i櫎鎶ヨ锛堟洿鏂扮粨鏉熸椂闂达級
bool AlarmManager::clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime) {
if (!m_pDB) {
return false;
@@ -753,7 +835,7 @@
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;
@@ -766,12 +848,32 @@
}
}
- // 如果没找到匹配的记录,则直接返回 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());
@@ -782,7 +884,7 @@
return result;
}
-// 读取报警文件
+// 璇诲彇鎶ヨ鏂囦欢
bool AlarmManager::readAlarmFile(const std::string& filename) {
std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
@@ -795,7 +897,7 @@
char ch;
while (f.get(ch)) {
if (ch == '\r') {
- // 处理 \r\n 或 单独 \r
+ // 澶勭悊 \r\n 鎴� 鍗曠嫭 \r
if (f.peek() == '\n') f.get();
break;
}
@@ -850,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;
@@ -880,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;
@@ -902,7 +1004,7 @@
alarms.push_back(it->second);
}
else {
- std::cerr << "未找到 AlarmID: " << alarmID << std::endl;
+ std::cerr << "鏈壘鍒� AlarmID: " << alarmID << std::endl;
}
}
diff --git a/SourceCode/Bond/Servo/AlarmManager.h b/SourceCode/Bond/Servo/AlarmManager.h
index d98fce9..1cd55a9 100644
--- a/SourceCode/Bond/Servo/AlarmManager.h
+++ b/SourceCode/Bond/Servo/AlarmManager.h
@@ -1,4 +1,4 @@
-#ifndef ALARM_MANAGER_H
+锘�#ifndef ALARM_MANAGER_H
#define ALARM_MANAGER_H
#include <string>
@@ -18,15 +18,15 @@
};
struct AlarmData {
- int nId; // 错误码
- int nSeverityLevel; // 报警等级
- int nDeviceId; // 设备ID
- int nUnitId; // 单元ID
- std::string strDeviceName; // 设备名称
- std::string strUnitName; // 单元名称
- std::string strDescription; // 描述
- std::string strStartTime; // 开始时间
- std::string strEndTime; // 结束时间
+ int nId; // 閿欒鐮�
+ int nSeverityLevel; // 鎶ヨ绛夌骇
+ int nDeviceId; // 璁惧ID
+ int nUnitId; // 鍗曞厓ID
+ std::string strDeviceName; // 璁惧鍚嶇О
+ std::string strUnitName; // 鍗曞厓鍚嶇О
+ std::string strDescription; // 鎻忚堪
+ std::string strStartTime; // 寮�濮嬫椂闂�
+ std::string strEndTime; // 缁撴潫鏃堕棿
};
using AlarmInfoMap = std::unordered_map<int, AlarmInfo>;
@@ -35,116 +35,117 @@
class AlarmManager {
public:
/**
- * 获取单例实例
- * @return AlarmManager实例的引用
+ * 鑾峰彇鍗曚緥瀹炰緥
+ * @return AlarmManager瀹炰緥鐨勫紩鐢�
*/
static AlarmManager& getInstance();
/**
- * 初始化报警表
- * @return 成功返回true,失败返回false
+ * 鍒濆鍖栨姤璀﹁〃
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool initAlarmTable();
/**
- * 销毁报警表
+ * 閿�姣佹姤璀﹁〃
*/
void termAlarmTable();
/**
- * 销毁报警表
- * @return 成功返回true,失败返回false
+ * 閿�姣佹姤璀﹁〃
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool destroyAlarmTable();
/**
- * 插入模拟数据
+ * 鎻掑叆妯℃嫙鏁版嵁
*/
void insertMockData();
/**
- * 添加报警
- * @param alarmData 报警数据的结构体
- * @param alarmEventId 最近插入的 alarm_event_id
- * @return 成功返回true,失败返回false
+ * 娣诲姞鎶ヨ
+ * @param alarmData 鎶ヨ鏁版嵁鐨勭粨鏋勪綋
+ * @param alarmEventId 鏈�杩戞彃鍏ョ殑 alarm_event_id
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool addAlarm(const AlarmData& alarmData, int& alarmEventId);
/**
- * 查询所有报警数据
- * @return 包含所有报警数据的结构体
+ * 鏌ヨ鎵�鏈夋姤璀︽暟鎹�
+ * @return 鍖呭惈鎵�鏈夋姤璀︽暟鎹殑缁撴瀯浣�
*/
std::vector<AlarmData> getAllAlarms();
/**
- * 根据报警ID查询报警
- * @param id 报警ID
- * @return 包含筛选后报警数据的结构体
+ * 鏍规嵁鎶ヨID鏌ヨ鎶ヨ
+ * @param id 鎶ヨID
+ * @return 鍖呭惈绛涢�夊悗鎶ヨ鏁版嵁鐨勭粨鏋勪綋
*/
std::vector<AlarmData> getAlarmsById(const std::string& id);
/**
- * 根据描述查询报警
- * @param description 报警描述的筛选条件
- * @return 包含筛选后报警数据的结构体
+ * 鏍规嵁鎻忚堪鏌ヨ鎶ヨ
+ * @param description 鎶ヨ鎻忚堪鐨勭瓫閫夋潯浠�
+ * @return 鍖呭惈绛涢�夊悗鎶ヨ鏁版嵁鐨勭粨鏋勪綋
*/
std::vector<AlarmData> getAlarmsByDescription(const std::string& description);
/**
- * 根据时间范围查询报警
- * @param startTime 起始时间
- * @param endTime 结束时间
- * @return 包含查询结果的报警数据
+ * 鏍规嵁鏃堕棿鑼冨洿鏌ヨ鎶ヨ
+ * @param startTime 璧峰鏃堕棿
+ * @param endTime 缁撴潫鏃堕棿
+ * @return 鍖呭惈鏌ヨ缁撴灉鐨勬姤璀︽暟鎹�
*/
std::vector<AlarmData> getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime);
/**
- * 根据ID和时间范围查询报警
- * @param id 报警ID
- * @param startTime 起始时间
- * @param endTime 结束时间
- * @return 包含查询结果的报警数据
+ * 鏍规嵁ID鍜屾椂闂磋寖鍥存煡璇㈡姤璀�
+ * @param id 鎶ヨID
+ * @param startTime 璧峰鏃堕棿
+ * @param endTime 缁撴潫鏃堕棿
+ * @return 鍖呭惈鏌ヨ缁撴灉鐨勬姤璀︽暟鎹�
*/
std::vector<AlarmData> getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime);
/**
- * 获取报警数据
- * @param startPosition 起始位置
- * @param count 获取的记录数量
- * @return 包含查询结果的报警数据
+ * 鑾峰彇鎶ヨ鏁版嵁
+ * @param startPosition 璧峰浣嶇疆
+ * @param count 鑾峰彇鐨勮褰曟暟閲�
+ * @return 鍖呭惈鏌ヨ缁撴灉鐨勬姤璀︽暟鎹�
*/
std::vector<AlarmData> getAlarms(int startPosition, int count);
+ std::vector<AlarmData> getActiveAlarms(int recentHours = 12);
/**
- * 筛选报警数据
- * @param keyword 关键字筛选条件
- * @param startTime 起始时间筛选条件
- * @param endTime 结束时间筛选条件
- * @param pageNumber 页码
- * @param pageSize 每页记录数
- * @return 包含筛选后报警数据的结构体
+ * 绛涢�夋姤璀︽暟鎹�
+ * @param keyword 鍏抽敭瀛楃瓫閫夋潯浠�
+ * @param startTime 璧峰鏃堕棿绛涢�夋潯浠�
+ * @param endTime 缁撴潫鏃堕棿绛涢�夋潯浠�
+ * @param pageNumber 椤电爜
+ * @param pageSize 姣忛〉璁板綍鏁�
+ * @return 鍖呭惈绛涢�夊悗鎶ヨ鏁版嵁鐨勭粨鏋勪綋
*/
std::vector<AlarmData> getFilteredAlarms(const std::string& keyword, const std::string& startTime, const std::string& endTime, int pageNumber, int pageSize);
/**
- * 获取符合条件的报警总数
- * @param keyword 关键字筛选条件
- * @param startTime 起始时间筛选条件
- * @param endTime 结束时间筛选条件
- * @return 符合条件的报警总数
+ * 鑾峰彇绗﹀悎鏉′欢鐨勬姤璀︽�绘暟
+ * @param keyword 鍏抽敭瀛楃瓫閫夋潯浠�
+ * @param startTime 璧峰鏃堕棿绛涢�夋潯浠�
+ * @param endTime 缁撴潫鏃堕棿绛涢�夋潯浠�
+ * @return 绗﹀悎鏉′欢鐨勬姤璀︽�绘暟
*/
int getTotalAlarmCount(const std::string& keyword, const std::string& startTime, const std::string& endTime);
/**
- * 更新报警结束时间
- * @param id 报警ID
- * @param severityLevel 报警等级筛选条件
- * @param deviceId 设备ID
- * @param unitId 单元ID
- * @param description 报警描述
- * @param startTime 报警开始时间
- * @param newEndTime 新的报警结束时间
- * @return 成功返回true,失败返回false
+ * 鏇存柊鎶ヨ缁撴潫鏃堕棿
+ * @param id 鎶ヨID
+ * @param severityLevel 鎶ヨ绛夌骇绛涢�夋潯浠�
+ * @param deviceId 璁惧ID
+ * @param unitId 鍗曞厓ID
+ * @param description 鎶ヨ鎻忚堪
+ * @param startTime 鎶ヨ寮�濮嬫椂闂�
+ * @param newEndTime 鏂扮殑鎶ヨ缁撴潫鏃堕棿
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool updateAlarmEndTime(
const std::string& id,
@@ -156,79 +157,79 @@
const std::string& newEndTime);
/**
- * 清理旧报警
- * @param daysToKeep 保留的天数
- * @param deviceId 设备ID
- * @param unitId 单元ID
+ * 娓呯悊鏃ф姤璀�
+ * @param daysToKeep 淇濈暀鐨勫ぉ鏁�
+ * @param deviceId 璁惧ID
+ * @param unitId 鍗曞厓ID
*/
void cleanOldAlarms(int daysToKeep = 30, const std::string& deviceId = "", const std::string& unitId = "");
/**
- * 通过设备ID获取设备名称
- * @param deviceId 设备ID
- * @return 成功返回设备名称,失败返回空
+ * 閫氳繃璁惧ID鑾峰彇璁惧鍚嶇О
+ * @param deviceId 璁惧ID
+ * @return 鎴愬姛杩斿洖璁惧鍚嶇О锛屽け璐ヨ繑鍥炵┖
*/
std::string getDeviceNameById(int deviceId);
/**
- * 通过设备ID和单元ID获取单元名称
- * @param deviceId 设备ID
- * @param unitId 单元ID
- * @return 成功返回单元名称,失败返回空
+ * 閫氳繃璁惧ID鍜屽崟鍏僆D鑾峰彇鍗曞厓鍚嶇О
+ * @param deviceId 璁惧ID
+ * @param unitId 鍗曞厓ID
+ * @return 鎴愬姛杩斿洖鍗曞厓鍚嶇О锛屽け璐ヨ繑鍥炵┖
*/
std::string getUnitNameById(int deviceId, int unitId);
/**
- * 获取最近插入的 alarm_event_id
- * @return 失败返回-1,成功返回最近插入的 alarm_event_id
+ * 鑾峰彇鏈�杩戞彃鍏ョ殑 alarm_event_id
+ * @return 澶辫触杩斿洖-1锛屾垚鍔熻繑鍥炴渶杩戞彃鍏ョ殑 alarm_event_id
*/
int getLastInsertId();
/**
- * 通过事件id解除报警(更新结束时间)
- * @param alarmEventId 事件ID
- * @param endTime 结束时间
- * @return 成功返回true,失败返回false
+ * 閫氳繃浜嬩欢id瑙i櫎鎶ヨ锛堟洿鏂扮粨鏉熸椂闂达級
+ * @param alarmEventId 浜嬩欢ID
+ * @param endTime 缁撴潫鏃堕棿
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool clearAlarmByEventId(int alarmEventId, const std::string& endTime);
/**
- * 通过多个属性查找并解除报警(更新结束时间)
- * @param nId 报警ID
- * @param nSeverityLevel 报警等级
- * @param nDeviceId 设备ID
- * @param nUnitId 单元ID
- * @param strDescription 描述
- * @param endTime 结束时间
- * @return 成功返回true,失败返回false
+ * 閫氳繃澶氫釜灞炴�ф煡鎵惧苟瑙i櫎鎶ヨ锛堟洿鏂扮粨鏉熸椂闂达級
+ * @param nId 鎶ヨID
+ * @param nSeverityLevel 鎶ヨ绛夌骇
+ * @param nDeviceId 璁惧ID
+ * @param nUnitId 鍗曞厓ID
+ * @param strDescription 鎻忚堪
+ * @param endTime 缁撴潫鏃堕棿
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime);
/**
- * 读取报警文件
- * @param filename 文件名
- * @return 成功返回true,失败返回false
+ * 璇诲彇鎶ヨ鏂囦欢
+ * @param filename 鏂囦欢鍚�
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool readAlarmFile(const std::string& filename);
/**
- * 保存报警文件
- * @param filename 文件名
- * @return 成功返回true,失败返回false
+ * 淇濆瓨鎶ヨ鏂囦欢
+ * @param filename 鏂囦欢鍚�
+ * @return 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse
*/
bool saveAlarmFile(const std::string& filename);
/**
- * 通过报警ID查询报警信息
- * @param nAlarmID 报警ID
- * @return 报警信息的指针
+ * 閫氳繃鎶ヨID鏌ヨ鎶ヨ淇℃伅
+ * @param nAlarmID 鎶ヨID
+ * @return 鎶ヨ淇℃伅鐨勬寚閽�
*/
const AlarmInfo* getAlarmInfoByID(int nAlarmID) const;
/**
- * 通过多个报警ID查询对应的报警信息
- * @param alarmIDs 多个报警ID
- * @return 返回多个报警信息
+ * 閫氳繃澶氫釜鎶ヨID鏌ヨ瀵瑰簲鐨勬姤璀︿俊鎭�
+ * @param alarmIDs 澶氫釜鎶ヨID
+ * @return 杩斿洖澶氫釜鎶ヨ淇℃伅
*/
std::vector<AlarmInfo> getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const;
@@ -236,7 +237,7 @@
AlarmManager();
~AlarmManager();
- // 禁止拷贝和赋值
+ // 绂佹鎷疯礉鍜岃祴鍊�
AlarmManager(const AlarmManager&) = delete;
AlarmManager& operator=(const AlarmManager&) = delete;
diff --git a/SourceCode/Bond/Servo/AlarmPopupDlg.cpp b/SourceCode/Bond/Servo/AlarmPopupDlg.cpp
new file mode 100644
index 0000000..cc2a48d
--- /dev/null
+++ b/SourceCode/Bond/Servo/AlarmPopupDlg.cpp
@@ -0,0 +1,278 @@
+锘�#include "stdafx.h"
+#include "Servo.h"
+#include "AlarmPopupDlg.h"
+#include "afxdialogex.h"
+#include "Log.h"
+#include "Common.h"
+#include "HorizontalLine.h"
+
+
+IMPLEMENT_DYNAMIC(CAlarmPopupDlg, CDialogEx)
+
+CAlarmPopupDlg::CAlarmPopupDlg(CWnd* pParent /*=NULL*/)
+ : CDialogEx(IDD_DIALOG_POPUP_ALARM, pParent)
+ , m_hasActive(false)
+{
+ memset(&m_activeAlarm, 0, sizeof(m_activeAlarm));
+ m_crBkgnd = RGB(112, 146, 190);
+ m_hbrBkgnd = nullptr;
+}
+
+CAlarmPopupDlg::~CAlarmPopupDlg()
+{
+}
+
+void CAlarmPopupDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAlarmPopupDlg, CDialogEx)
+ ON_BN_CLICKED(IDC_POPUP_BTN_CLOSE, &CAlarmPopupDlg::OnBnClickedClose)
+ ON_BN_CLICKED(IDC_BUTTON_ALARM_OFF, &CAlarmPopupDlg::OnBnClickedAlarmOff)
+ ON_WM_CTLCOLOR()
+ ON_WM_DESTROY()
+END_MESSAGE_MAP()
+
+BOOL CAlarmPopupDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ // 鑳屾櫙鍒�
+ if (m_hbrBkgnd != nullptr) {
+ ::DeleteObject(m_hbrBkgnd);
+ }
+ m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+
+ // 瀛椾綋
+ HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+ LOGFONT lf;
+
+ ::GetObject(hFontDefault, sizeof(LOGFONT), &lf);
+ lf.lfHeight -= 8;
+ lf.lfWeight = 700;
+ m_fontTitle.CreateFontIndirect(&lf);
+
+ ::GetObject(hFontDefault, sizeof(LOGFONT), &lf);
+ lf.lfHeight -= 8;
+ m_fontLevel.CreateFontIndirect(&lf);
+
+ ::GetObject(hFontDefault, sizeof(LOGFONT), &lf);
+ lf.lfHeight -= 16;
+ m_fontName.CreateFontIndirect(&lf);
+
+ ::GetObject(hFontDefault, sizeof(LOGFONT), &lf);
+ lf.lfHeight -= 8;
+ m_fontDescription.CreateFontIndirect(&lf);
+
+ GetDlgItem(IDC_LABEL_TITLE)->SetFont(&m_fontTitle);
+ GetDlgItem(IDC_LABEL_LEVEL)->SetFont(&m_fontLevel);
+ GetDlgItem(IDC_LABEL_NAME)->SetFont(&m_fontName);
+ GetDlgItem(IDC_LABEL_DESCRIPTION)->SetFont(&m_fontDescription);
+ GetDlgItem(IDC_LABEL_NO_ALARM)->SetFont(&m_fontDescription);
+
+
+ // 鍥炬爣
+ CString strIcon1;
+ HICON hIcon;
+ CStatic* pStatic;
+
+ strIcon1.Format(_T("%s\\Res\\Alarm_o_24.ico"), theApp.m_strAppDir);
+ pStatic = (CStatic*)GetDlgItem(IDC_ICON_TITLE);
+ hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),
+ strIcon1, IMAGE_ICON, 24, 24,
+ LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+ pStatic->SetIcon(hIcon);
+
+ strIcon1.Format(_T("%s\\Res\\Alarm_o_64.ico"), theApp.m_strAppDir);
+ pStatic = (CStatic*)GetDlgItem(IDC_ICON_ALARM);
+ hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),
+ strIcon1, IMAGE_ICON, 64, 64,
+ LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+ pStatic->SetIcon(hIcon);
+
+
+ // 鍏抽棴鎸夐挳
+ strIcon1.Format(_T("%s\\Res\\close_blcak_24.ico"), theApp.m_strAppDir);
+ pStatic = (CStatic*)GetDlgItem(IDC_ICON_ALARM);
+ hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),
+ strIcon1, IMAGE_ICON, 128, 128,
+ LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+ m_btnClose.SubclassDlgItem(IDC_POPUP_BTN_CLOSE, this);
+ m_btnClose.SetIcon(hIcon, hIcon, 24);
+ m_btnClose.SetFaceColor(m_crBkgnd);
+ m_btnClose.SetBkgndColor(BS_NORMAL, BTN_ALARM_OFF_BKGND_NORMAL);
+ m_btnClose.SetBkgndColor(BS_HOVER, BTN_ALARM_OFF_BKGND_NORMAL);
+ m_btnClose.SetBkgndColor(BS_PRESS, BTN_ALARM_OFF_BKGND_PRESS);
+ m_btnClose.SetFrameColor(m_crBkgnd);
+
+
+ // 瑙i櫎璀﹀憡鎸夐挳
+ m_btnAlarmOff.SubclassDlgItem(IDC_BUTTON_ALARM_OFF, this);
+ m_btnAlarmOff.SetFrameColor(BS_NORMAL, BTN_ALARM_OFF_FRAME_NORMAL);
+ m_btnAlarmOff.SetFrameColor(BS_HOVER, BTN_ALARM_OFF_FRAME_HOVER);
+ m_btnAlarmOff.SetFrameColor(BS_PRESS, BTN_ALARM_OFF_FRAME_PRESS);
+ m_btnAlarmOff.SetBkgndColor(BS_NORMAL, BTN_ALARM_OFF_BKGND_NORMAL);
+ m_btnAlarmOff.SetBkgndColor(BS_HOVER, BTN_ALARM_OFF_BKGND_HOVER);
+ m_btnAlarmOff.SetBkgndColor(BS_PRESS, BTN_ALARM_OFF_BKGND_PRESS);
+
+
+ // 闈欓煶鎸夐挳
+ bool bMute = false;
+ m_btnSoundOff.SubclassDlgItem(IDC_BUTTON_SOUND_OFF, this);
+ m_btnSoundOff.SetFrameColor(BS_NORMAL, BTN_SOUND_OFF_FRAME_NORMAL);
+ m_btnSoundOff.SetFrameColor(BS_HOVER, BTN_SOUND_OFF_FRAME_HOVER);
+ m_btnSoundOff.SetFrameColor(BS_PRESS, BTN_SOUND_OFF_FRAME_PRESS);
+ SetButtonBackgroundColors(bMute);
+
+ // 妯嚎1
+ CHorizontalLine* pLine = CHorizontalLine::Hook(GetDlgItem(IDC_LINE1)->m_hWnd);
+ pLine->SetBkgndColor(m_crBkgnd);
+ pLine->SetLineColor(RGB(168, 168, 168));
+
+ pLine = CHorizontalLine::Hook(GetDlgItem(IDC_LINE2)->m_hWnd);
+ pLine->SetBkgndColor(m_crBkgnd);
+ pLine->SetLineColor(RGB(168, 168, 168));
+
+ RefreshContent();
+ return TRUE;
+}
+
+void CAlarmPopupDlg::ShowNoAlarmControls(bool bShow)
+{
+ const int ids[] = { IDC_LABEL_NO_ALARM, IDC_POPUP_BTN_CLOSE };
+ for (int id : ids) {
+ if (auto* p = GetDlgItem(id)) {
+ p->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
+ }
+ }
+}
+
+void CAlarmPopupDlg::ShowAlarmControls(bool bShow)
+{
+ const int ids[] = {
+ IDC_BUTTON_PREV, IDC_BUTTON_NEXT,
+ IDC_LABEL_TITLE, IDC_ICON_ALARM, IDC_ICON_TITLE,
+ IDC_LABEL_LEVEL, IDC_LABEL_NAME,
+ IDC_LINE1, IDC_BUTTON_SOUND_OFF, IDC_BUTTON_ALARM_OFF,
+ IDC_LINE2, IDC_LABEL_DESCRIPTION
+ };
+ for (int id : ids) {
+ if (auto* p = GetDlgItem(id)) {
+ p->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
+ }
+ }
+}
+
+void CAlarmPopupDlg::RefreshContent()
+{
+ auto actives = AlarmManager::getInstance().getActiveAlarms();
+ if (!actives.empty()) {
+ m_activeAlarm = actives.front();
+ m_hasActive = true;
+
+ AlarmManager& alarmManager = AlarmManager::getInstance();
+ const AlarmInfo* info = alarmManager.getAlarmInfoByID(m_activeAlarm.nId);
+
+ CString title, level, name, desc;
+ level.Format(_T("绛夌骇: %d"), m_activeAlarm.nSeverityLevel);
+
+ if (info != nullptr && !info->strAlarmText.empty()) {
+ name = CString(info->strAlarmText.c_str());
+ }
+ else {
+ name.Format(_T("ID:%d (%s)"), m_activeAlarm.nId, CString(m_activeAlarm.strDeviceName.c_str()));
+ }
+
+ if (!m_activeAlarm.strDescription.empty()) {
+ desc = CString(m_activeAlarm.strDescription.c_str());
+ }
+ else if (info != nullptr && !info->strDescription.empty()) {
+ desc = CString(info->strDescription.c_str());
+ }
+ else {
+ desc = _T("鏆傛棤鎻忚堪");
+ }
+
+ title.Format(_T("璁惧:%s 鍗曞厓:%s"),
+ CString(m_activeAlarm.strDeviceName.c_str()),
+ CString(m_activeAlarm.strUnitName.c_str()));
+
+ SetDlgItemText(IDC_LABEL_TITLE, title);
+ SetDlgItemText(IDC_LABEL_NAME, name);
+ SetDlgItemText(IDC_LABEL_LEVEL, level);
+ SetDlgItemText(IDC_LABEL_DESCRIPTION, desc);
+ ShowAlarmControls(true);
+ ShowNoAlarmControls(false);
+ ShowWindow(SW_SHOW);
+ }
+ else {
+ m_hasActive = false;
+ SetDlgItemText(IDC_LABEL_NO_ALARM, _T("褰撳墠鏃犳姤璀�"));
+ SetDlgItemText(IDC_LABEL_NAME, _T(""));
+ SetDlgItemText(IDC_LABEL_LEVEL, _T(""));
+ SetDlgItemText(IDC_LABEL_DESCRIPTION, _T(""));
+ ShowAlarmControls(false);
+ ShowNoAlarmControls(true);
+ }
+}
+
+void CAlarmPopupDlg::OnBnClickedClose()
+{
+ ShowWindow(SW_HIDE);
+}
+
+void CAlarmPopupDlg::OnBnClickedAlarmOff()
+{
+ if (!m_hasActive) return;
+
+ AlarmManager& alarmManager = AlarmManager::getInstance();
+ alarmManager.clearAlarmByAttributes(
+ m_activeAlarm.nId,
+ m_activeAlarm.nDeviceId,
+ m_activeAlarm.nUnitId,
+ CToolUnits::getCurrentTimeString());
+ RefreshContent();
+}
+
+HBRUSH CAlarmPopupDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+ HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+ if (nCtlColor == CTLCOLOR_STATIC) {
+ pDC->SetBkColor(m_crBkgnd);
+ pDC->SetTextColor(RGB(30, 30, 30));
+ hbr = m_hbrBkgnd;
+ }
+ else if (nCtlColor == CTLCOLOR_DLG) {
+ hbr = m_hbrBkgnd;
+ }
+
+ return hbr;
+}
+
+void CAlarmPopupDlg::OnDestroy()
+{
+ CDialogEx::OnDestroy();
+
+ if (m_hbrBkgnd != nullptr) {
+ ::DeleteObject(m_hbrBkgnd);
+ m_hbrBkgnd = nullptr;
+ }
+}
+
+void CAlarmPopupDlg::SetButtonBackgroundColors(bool bMute)
+{
+ if (!bMute) {
+ m_btnSoundOff.SetBkgndColor(BS_NORMAL, BTN_SOUND_OFF_BKGND_NORMAL);
+ m_btnSoundOff.SetBkgndColor(BS_HOVER, BTN_SOUND_OFF_BKGND_HOVER);
+ m_btnSoundOff.SetBkgndColor(BS_PRESS, BTN_SOUND_OFF_BKGND_PRESS);
+ m_btnSoundOff.Invalidate();
+ }
+ else {
+ m_btnSoundOff.SetBkgndColor(BS_NORMAL, BTN_SOUND_ON_BKGND_NORMAL);
+ m_btnSoundOff.SetBkgndColor(BS_HOVER, BTN_SOUND_ON_BKGND_HOVER);
+ m_btnSoundOff.SetBkgndColor(BS_PRESS, BTN_SOUND_ON_BKGND_PRESS);
+ m_btnSoundOff.Invalidate();
+ }
+}
diff --git a/SourceCode/Bond/Servo/AlarmPopupDlg.h b/SourceCode/Bond/Servo/AlarmPopupDlg.h
new file mode 100644
index 0000000..5ca49a0
--- /dev/null
+++ b/SourceCode/Bond/Servo/AlarmPopupDlg.h
@@ -0,0 +1,53 @@
+锘�#pragma once
+#include "afxwin.h"
+#include "AlarmManager.h"
+#include "Common.h"
+#include "ToolUnits.h"
+#include "BlButton.h"
+
+// 绠�鍖栫増鎶ヨ寮圭獥锛屽鎺� AlarmManager 鐨勬椿璺冨憡璀�
+class CAlarmPopupDlg : public CDialogEx
+{
+ DECLARE_DYNAMIC(CAlarmPopupDlg)
+
+public:
+ CAlarmPopupDlg(CWnd* pParent = NULL);
+ virtual ~CAlarmPopupDlg();
+
+public:
+ void RefreshContent(); // 鍒锋柊褰撳墠鍛婅鏄剧ず
+
+private:
+ COLORREF m_crBkgnd;
+ HBRUSH m_hbrBkgnd;
+ CFont m_fontTitle;
+ CFont m_fontLevel;
+ CFont m_fontName;
+ CFont m_fontDescription;
+ CBlButton m_btnClose;
+ CBlButton m_btnSoundOff;
+ CBlButton m_btnAlarmOff;
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_DIALOG_POPUP_ALARM };
+#endif
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 鏀寔
+
+ DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnInitDialog();
+ afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+ afx_msg void OnDestroy();
+ afx_msg void OnBnClickedClose();
+ afx_msg void OnBnClickedAlarmOff();
+
+private:
+ bool m_hasActive;
+ AlarmData m_activeAlarm;
+ void SetButtonBackgroundColors(bool bMute);
+ void ShowNoAlarmControls(bool bShow);
+ void ShowAlarmControls(bool bShow);
+};
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 80ce726..df536fb 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -153,132 +153,132 @@
LOGE("杩炴帴CC-Link澶辫触.");
}
else {
- LOGI("杩炴帴CC-Link鎴愬姛.");
- BoardVersion version{};
- int nRet = m_cclink.GetBoardVersion(version);
- if (nRet == 0) {
- LOGD("鐗堟湰淇℃伅锛�%s.", version.toString().c_str());
- }
- else {
- LOGE("鑾峰彇CC-Link鐗堟湰淇℃伅澶辫触.");
- }
-
- BoardStatus status;
- nRet = m_cclink.GetBoardStatus(status);
- if (nRet == 0) {
- LOGD("鐘舵�侊細%s.", status.toString().c_str());
- }
- else {
- LOGE("鑾峰彇CC-Link鐘舵�佸け璐�.");
- }
+ LOGI("杩炴帴CC-Link鎴愬姛.");
+ BoardVersion version{};
+ int nRet = m_cclink.GetBoardVersion(version);
+ if (nRet == 0) {
+ LOGD("鐗堟湰淇℃伅锛�%s.", version.toString().c_str());
+ }
+ else {
+ LOGE("鑾峰彇CC-Link鐗堟湰淇℃伅澶辫触.");
}
-
- // 鍒濆鍖栨坊鍔犲悇瀛愯澶�
- CLoadPort* pPort1, * pPort2, * pPort3, * pPort4;
- CBonder* pBonder1, * pBonder2;
- CEFEM* pEfem;
- CArm* pArm;
- CArmTray* pArmTray1, * pArmTray2;
- CFliper* pFliper;
- CVacuumBake* pVacuumBake;
- CAligner* pAligner;
- CBakeCooling* pBakeCooling;
- CMeasurement* pMeasurement;
-
- pPort1 = addLoadPort(0);
- pPort2 = addLoadPort(1);
- pPort3 = addLoadPort(2);
- pPort4 = addLoadPort(3);
- pEfem = addEFEM();
- pArm = addArm();
- pArmTray1 = addArmTray(0);
- pArmTray2 = addArmTray(1);
- pFliper = addFliper();
- pVacuumBake = addVacuumBake();
- pAligner = addAligner();
- pBonder1 = addBonder(0);
- pBonder2 = addBonder(1);
- pBakeCooling = addBakeCooling();
- pMeasurement = addMeasurement();
-
- ASSERT(pEfem);
- ASSERT(pFliper);
- ASSERT(pVacuumBake);
- ASSERT(pAligner);
- ASSERT(pBonder1);
- ASSERT(pBonder2);
- ASSERT(pBakeCooling);
- ASSERT(pMeasurement);
-
- pEfem->setPort(0, pPort1);
- pEfem->setPort(1, pPort2);
- pEfem->setPort(2, pPort3);
- pEfem->setPort(3, pPort4);
- pEfem->setFliper(pFliper);
- pEfem->setAligner(pAligner);
- pEfem->setArmTray(0, pArmTray1);
- pEfem->setArmTray(1, pArmTray2);
- pPort1->setArm(pArm);
- pPort2->setArm(pArm);
- pPort3->setArm(pArm);
- pPort4->setArm(pArm);
- pArmTray1->setArm(pArm);
- pArmTray2->setArm(pArm);
- pFliper->setArm(pArm);
- pVacuumBake->setArm(pArm);
- pAligner->setArm(pArm);
- pBonder1->setArm(pArm);
- pBonder2->setArm(pArm);
- pBakeCooling->setArm(pArm);
- pMeasurement->setArm(pArm);
-
- connectEquipments();
-
-
-
- // 璇荤紦瀛樻暟鎹�
- const ULONGLONG boot_cache_begin = GetTickCount64();
- const ULONGLONG boot_read_begin = GetTickCount64();
- readCache();
- LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin));
-
- const ULONGLONG boot_state_begin = GetTickCount64();
- loadState();
- LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin));
- if (m_listener.onControlJobChanged) {
- notifyControlJobChanged();
+ BoardStatus status;
+ nRet = m_cclink.GetBoardStatus(status);
+ if (nRet == 0) {
+ LOGD("鐘舵�侊細%s.", status.toString().c_str());
}
-
- LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)",
- (unsigned long long)(GetTickCount64() - boot_cache_begin),
- (unsigned long long)(GetTickCount64() - boot_master_begin));
-
-
- // 瀹氭椂鍣�
- g_pMaster = this;
- SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc);
-
-
- // 璋冨害绾跨▼
- m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this,
- 0, &m_nDispatchThreadAddr);
-
-
- // 鐩戞帶bit绾跨▼
- m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this,
- 0, &m_nReadBitsThreadAddr);
-
-
- // 鏇茬嚎鏈嶅姟
- CreateDAQBridgeServer();
-
-
- LOGI("<Master>鍒濆鍖栧畬鎴�.");
- LOGI("[BOOT][MASTER] init finished, total cost=%llu ms",
- (unsigned long long)(GetTickCount64() - boot_master_begin));
- return 0;
+ else {
+ LOGE("鑾峰彇CC-Link鐘舵�佸け璐�.");
+ }
}
+
+
+ // 鍒濆鍖栨坊鍔犲悇瀛愯澶�
+ CLoadPort* pPort1, * pPort2, * pPort3, * pPort4;
+ CBonder* pBonder1, * pBonder2;
+ CEFEM* pEfem;
+ CArm* pArm;
+ CArmTray* pArmTray1, * pArmTray2;
+ CFliper* pFliper;
+ CVacuumBake* pVacuumBake;
+ CAligner* pAligner;
+ CBakeCooling* pBakeCooling;
+ CMeasurement* pMeasurement;
+
+ pPort1 = addLoadPort(0);
+ pPort2 = addLoadPort(1);
+ pPort3 = addLoadPort(2);
+ pPort4 = addLoadPort(3);
+ pEfem = addEFEM();
+ pArm = addArm();
+ pArmTray1 = addArmTray(0);
+ pArmTray2 = addArmTray(1);
+ pFliper = addFliper();
+ pVacuumBake = addVacuumBake();
+ pAligner = addAligner();
+ pBonder1 = addBonder(0);
+ pBonder2 = addBonder(1);
+ pBakeCooling = addBakeCooling();
+ pMeasurement = addMeasurement();
+
+ ASSERT(pEfem);
+ ASSERT(pFliper);
+ ASSERT(pVacuumBake);
+ ASSERT(pAligner);
+ ASSERT(pBonder1);
+ ASSERT(pBonder2);
+ ASSERT(pBakeCooling);
+ ASSERT(pMeasurement);
+
+ pEfem->setPort(0, pPort1);
+ pEfem->setPort(1, pPort2);
+ pEfem->setPort(2, pPort3);
+ pEfem->setPort(3, pPort4);
+ pEfem->setFliper(pFliper);
+ pEfem->setAligner(pAligner);
+ pEfem->setArmTray(0, pArmTray1);
+ pEfem->setArmTray(1, pArmTray2);
+ pPort1->setArm(pArm);
+ pPort2->setArm(pArm);
+ pPort3->setArm(pArm);
+ pPort4->setArm(pArm);
+ pArmTray1->setArm(pArm);
+ pArmTray2->setArm(pArm);
+ pFliper->setArm(pArm);
+ pVacuumBake->setArm(pArm);
+ pAligner->setArm(pArm);
+ pBonder1->setArm(pArm);
+ pBonder2->setArm(pArm);
+ pBakeCooling->setArm(pArm);
+ pMeasurement->setArm(pArm);
+
+ connectEquipments();
+
+
+
+ // 璇荤紦瀛樻暟鎹�
+ const ULONGLONG boot_cache_begin = GetTickCount64();
+ const ULONGLONG boot_read_begin = GetTickCount64();
+ readCache();
+ LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin));
+
+ const ULONGLONG boot_state_begin = GetTickCount64();
+ loadState();
+ LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin));
+ if (m_listener.onControlJobChanged) {
+ notifyControlJobChanged();
+ }
+
+ LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)",
+ (unsigned long long)(GetTickCount64() - boot_cache_begin),
+ (unsigned long long)(GetTickCount64() - boot_master_begin));
+
+
+ // 瀹氭椂鍣�
+ g_pMaster = this;
+ SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc);
+
+
+ // 璋冨害绾跨▼
+ m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this,
+ 0, &m_nDispatchThreadAddr);
+
+
+ // 鐩戞帶bit绾跨▼
+ m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this,
+ 0, &m_nReadBitsThreadAddr);
+
+
+ // 鏇茬嚎鏈嶅姟
+ CreateDAQBridgeServer();
+
+
+ LOGI("<Master>鍒濆鍖栧畬鎴�.");
+ LOGI("[BOOT][MASTER] init finished, total cost=%llu ms",
+ (unsigned long long)(GetTickCount64() - boot_master_begin));
+ return 0;
+ }
int CMaster::term()
{
@@ -3607,14 +3607,14 @@
auto& dataTypes = CServoUtilsTool::getEqDataTypes();
auto& bonderTypes = dataTypes[MID_Bonder1];
for (size_t i = 0; i < bonderTypes.size(); ++i) {
- m_pCollector->buffersSetChannelName(MID_Bonder1, i + 1, bonderTypes[i].c_str());
- m_pCollector->buffersSetChannelName(MID_Bonder2, i + 1, bonderTypes[i].c_str());
+ m_pCollector->buffersSetChannelName(MID_Bonder1, (UINT)i + 1, bonderTypes[(UINT)i].c_str());
+ m_pCollector->buffersSetChannelName(MID_Bonder2, (UINT)i + 1, bonderTypes[(UINT)i].c_str());
}
auto& vacuumbakeTypes = dataTypes[MID_VacuumBakeA];
for (size_t i = 0; i < vacuumbakeTypes.size(); ++i) {
- m_pCollector->buffersSetChannelName(MID_VacuumBakeA, i + 1, vacuumbakeTypes[i].c_str());
- m_pCollector->buffersSetChannelName(MID_VacuumBakeB, i + 1, vacuumbakeTypes[i].c_str());
+ m_pCollector->buffersSetChannelName(MID_VacuumBakeA, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str());
+ m_pCollector->buffersSetChannelName(MID_VacuumBakeB, (UINT)i + 1, vacuumbakeTypes[(UINT)i].c_str());
}
auto& coolingTypes = dataTypes[MID_BakeCoolingA];
diff --git a/SourceCode/Bond/Servo/Common.h b/SourceCode/Bond/Servo/Common.h
index b207bfd..41b56e7 100644
--- a/SourceCode/Bond/Servo/Common.h
+++ b/SourceCode/Bond/Servo/Common.h
@@ -24,6 +24,7 @@
/* 软件侧 ALID */
#define ALID_SOFTWARE_PAUSE_EVENT 9000
+#define ALID_SOFTWARE_TEST_ALARM 9099
/* Channel Name */
#define MC_CHANNEL1_NAME "McChannel1"
@@ -561,3 +562,23 @@
/* PPID名字最大长度 */
#define PPID_NAME_MAX 80
+
+/* 解除警告 按钮 */
+#define BTN_ALARM_OFF_FRAME_NORMAL RGB(88, 88, 88)
+#define BTN_ALARM_OFF_FRAME_HOVER RGB(88, 88, 88)
+#define BTN_ALARM_OFF_FRAME_PRESS RGB(88, 88, 88)
+#define BTN_ALARM_OFF_BKGND_NORMAL RGB(255, 127, 39)
+#define BTN_ALARM_OFF_BKGND_HOVER RGB(255, 157, 59)
+#define BTN_ALARM_OFF_BKGND_PRESS RGB(255, 100, 29)
+
+/* 静音按钮 */
+#define BTN_SOUND_OFF_FRAME_NORMAL RGB(88, 88, 88)
+#define BTN_SOUND_OFF_FRAME_HOVER RGB(88, 88, 88)
+#define BTN_SOUND_OFF_FRAME_PRESS RGB(88, 88, 88)
+#define BTN_SOUND_OFF_BKGND_NORMAL RGB(255, 127, 39)
+#define BTN_SOUND_OFF_BKGND_HOVER RGB(255, 157, 59)
+#define BTN_SOUND_OFF_BKGND_PRESS RGB(255, 100, 29)
+#define BTN_SOUND_ON_BKGND_NORMAL RGB(100, 200, 100)
+#define BTN_SOUND_ON_BKGND_HOVER RGB(150, 250, 150)
+#define BTN_SOUND_ON_BKGND_PRESS RGB(50, 150, 50)
+
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 1c07a27..98fa6fd 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
@@ -835,6 +835,26 @@
PUSHBUTTON "Online Remote",IDC_BUTTON_ONLINE_REMOTE,138,15,58,27
END
+IDD_DIALOG_POPUP_ALARM DIALOGEX 0, 0, 379, 247
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "<< 上一条",IDC_BUTTON_PREV,8,224,50,14,NOT WS_VISIBLE
+ PUSHBUTTON "下一条 >>",IDC_BUTTON_NEXT,62,224,50,14,NOT WS_VISIBLE
+ LTEXT "警告",IDC_LABEL_TITLE,27,6,67,17,SS_CENTERIMAGE | NOT WS_VISIBLE
+ ICON "",IDC_ICON_ALARM,29,28,20,20
+ ICON "",IDC_ICON_TITLE,7,8,20,20,NOT WS_VISIBLE
+ LTEXT "等级:--",IDC_LABEL_LEVEL,75,26,118,18
+ LTEXT "警告名称",IDC_LABEL_NAME,120,45,251,24
+ PUSHBUTTON "",IDC_POPUP_BTN_CLOSE,354,0,24,22
+ CONTROL "Custom1",IDC_LINE1,"BYHorizontalLine",WS_TABSTOP,7,78,364,8
+ PUSHBUTTON "静音",IDC_BUTTON_SOUND_OFF,228,216,68,22,WS_DISABLED
+ PUSHBUTTON "异常解除",IDC_BUTTON_ALARM_OFF,304,216,68,22,WS_DISABLED
+ CONTROL "Custom1",IDC_LINE2,"BYHorizontalLine",WS_TABSTOP,7,202,364,8
+ LTEXT "警告描述:",IDC_LABEL_DESCRIPTION,18,98,329,89
+ LTEXT "当前没有警告", IDC_LABEL_NO_ALARM, 18, 98, 329, 89, NOT WS_VISIBLE
+END
+
/////////////////////////////////////////////////////////////////////////////
//
@@ -1288,6 +1308,14 @@
TOPMARGIN, 7
BOTTOMMARGIN, 90
END
+
+ IDD_DIALOG_POPUP_ALARM, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 371
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 238
+ END
END
#endif // APSTUDIO_INVOKED
@@ -1552,6 +1580,11 @@
0
END
+IDD_DIALOG_POPUP_ALARM AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index 3f876a1..f1eff4a 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -223,6 +223,7 @@
<ClInclude Include="..\jsoncpp\include\json\writer.h" />
<ClInclude Include="..\jsoncpp\lib_json\json_batchallocator.h" />
<ClInclude Include="AccordionWnd.h" />
+ <ClInclude Include="AlarmPopupDlg.h" />
<ClInclude Include="CBaseDlg.h" />
<ClInclude Include="CCarrierSlotGrid.h" />
<ClInclude Include="CCarrierSlotSelector.h" />
@@ -451,6 +452,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="AccordionWnd.cpp" />
+ <ClCompile Include="AlarmPopupDlg.cpp" />
<ClCompile Include="CBaseDlg.cpp" />
<ClCompile Include="CCarrierSlotGrid.cpp" />
<ClCompile Include="CCarrierSlotSelector.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index dd0ee29..09bb6e1 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -244,6 +244,7 @@
<ClCompile Include="CPageProdOverview.cpp" />
<ClCompile Include="HmLabel.cpp" />
<ClCompile Include="CPageCtrlState.cpp" />
+ <ClCompile Include="AlarmPopupDlg.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AlarmManager.h" />
@@ -530,6 +531,7 @@
<ClInclude Include="CPageProdOverview.h" />
<ClInclude Include="HmLabel.h" />
<ClInclude Include="CPageCtrlState.h" />
+ <ClInclude Include="AlarmPopupDlg.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Servo.rc" />
diff --git a/SourceCode/Bond/Servo/ServoDlg.cpp b/SourceCode/Bond/Servo/ServoDlg.cpp
index 7c6641f..f8a74b8 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/SourceCode/Bond/Servo/ServoDlg.cpp
@@ -31,6 +31,7 @@
#include "InputDialog.h"
#include "ClientListDlg.h"
#include "CControlJobManagerDlg.h"
+#include "AlarmManager.h"
#include "CUserManager2.h"
#include "CUserManager2Dlg.h"
#include "CUserXLogDlg.h"
@@ -110,6 +111,8 @@
m_pTopToolbar = nullptr;
m_pMyStatusbar = nullptr;
m_pRobotTaskDlg = nullptr;
+ m_pTab = nullptr;
+ m_pAlarmPopupDlg = nullptr;
}
void CServoDlg::DoDataExchange(CDataExchange* pDX)
@@ -264,7 +267,7 @@
CString text;
if (cj != nullptr) {
std::string st = cj->getStateText();
- text.Format(_T("ControlJob: %S (%S)"), cj->id().c_str(), st.c_str());
+ text.Format(_T("ControlJob: %s (%s)"), cj->id().c_str(), st.c_str());
if (cj->state() == SERVO::CJState::Paused) {
text += _T(" [Paused]");
}
@@ -326,6 +329,9 @@
//dlg.DoModal();
}
}
+ else if (RX_CODE_ALARM_SET == code || RX_CODE_ALARM_CLEAR == code) {
+ RefreshAlarmBadge();
+ }
if (RX_CODE_PASSIVE_STATUS_CHANGED == code) {
int state = 0;
@@ -357,6 +363,77 @@
theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
->subscribe(m_pObserver);
+ }
+}
+
+void CServoDlg::RefreshAlarmBadge()
+{
+ if (m_pTopToolbar == nullptr) return;
+ auto activeAlarms = AlarmManager::getInstance().getActiveAlarms();
+
+ // 缁存姢鏈鍒楄〃锛氬綋鍓嶆椿璺冧笖鏈湪宸茶闆嗗悎涓殑鎶ヨ
+ std::unordered_set<int> activeIds;
+ m_unreadAlarms.clear();
+ for (const auto& alarm : activeAlarms) {
+ activeIds.insert(alarm.nId);
+ if (m_ackAlarms.find(alarm.nId) == m_ackAlarms.end()) {
+ m_unreadAlarms.push_back(alarm);
+ }
+ }
+ // 绉婚櫎宸茶闆嗗悎涓凡涓嶅啀娲昏穬鐨勫憡璀�
+ for (auto it = m_ackAlarms.begin(); it != m_ackAlarms.end(); ) {
+ if (activeIds.find(*it) == activeIds.end()) {
+ it = m_ackAlarms.erase(it);
+ }
+ else {
+ ++it;
+ }
+ }
+
+ int count = static_cast<int>(m_unreadAlarms.size());
+
+ auto* pBtn = dynamic_cast<CBlButton*>(m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM));
+ if (pBtn != nullptr) {
+ if (count <= 0) {
+ pBtn->SetBadgeNumber(0);
+ pBtn->ShowDotBadge(FALSE, RGB(255, 0, 0));
+ pBtn->StopFlash();
+ }
+ else if (count <= 9) {
+ pBtn->ShowDotBadge(FALSE, RGB(255, 0, 0));
+ pBtn->SetBadgeNumber(count);
+ if (!pBtn->IsFlash()) pBtn->Flash(600);
+ }
+ else {
+ pBtn->SetBadgeNumber(0);
+ pBtn->ShowDotBadge(TRUE, RGB(255, 0, 0));
+ if (!pBtn->IsFlash()) pBtn->Flash(600);
+ }
+ pBtn->EnableWindow(TRUE);
+ }
+}
+
+void CServoDlg::RaiseTestAlarm()
+{
+ theApp.m_model.raiseSoftAlarm(ALID_SOFTWARE_TEST_ALARM, "Test Alarm (Ctrl+Alt+T)");
+}
+
+void CServoDlg::ClearTestAlarm()
+{
+ theApp.m_model.clearSoftAlarm(ALID_SOFTWARE_TEST_ALARM);
+}
+
+void CServoDlg::MarkAlarmsRead()
+{
+ auto* pBtn = dynamic_cast<CBlButton*>(m_pTopToolbar ? m_pTopToolbar->GetBtn(IDC_BUTTON_ALARM) : nullptr);
+ for (const auto& alarm : m_unreadAlarms) {
+ m_ackAlarms.insert(alarm.nId);
+ }
+ m_unreadAlarms.clear();
+ if (pBtn != nullptr) {
+ pBtn->SetBadgeNumber(0);
+ pBtn->ShowDotBadge(FALSE, RGB(255, 0, 0));
+ pBtn->StopFlash();
}
}
@@ -466,7 +543,7 @@
(unsigned long long)(GetTickCount64() - boot_pages_begin),
(unsigned long long)(GetTickCount64() - boot_ui_begin));
- CHmTab* m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd);
+ m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd);
m_pTab->SetPaddingLeft(20);
m_pTab->SetItemMarginLeft(18);
m_pTab->AddItem("鐘舵�佸浘", FALSE);
@@ -531,13 +608,13 @@
}
LOGI("[BOOT][UI] before master.init, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
- // 鐩稿綋浜庡欢鏃惰皟鐢╩aster鐨勫垵濮嬪寲
- const ULONGLONG boot_master_begin = GetTickCount64();
- theApp.m_model.m_master.init();
- LOGI("[BOOT][UI] m_master.init finished, cost=%llu ms (since OnInit start %llu ms)",
- (unsigned long long)(GetTickCount64() - boot_master_begin),
- (unsigned long long)(GetTickCount64() - boot_ui_begin));
- theApp.m_model.loadPortParams();
+ // 鐩稿綋浜庡欢鏃惰皟鐢╩aster鐨勫垵濮嬪寲
+ const ULONGLONG boot_master_begin = GetTickCount64();
+ theApp.m_model.m_master.init();
+ LOGI("[BOOT][UI] m_master.init finished, cost=%llu ms (since OnInit start %llu ms)",
+ (unsigned long long)(GetTickCount64() - boot_master_begin),
+ (unsigned long long)(GetTickCount64() - boot_ui_begin));
+ theApp.m_model.loadPortParams();
}
@@ -547,6 +624,8 @@
// 鏇存柊鐧诲綍鐘舵��
UpdateLoginStatus();
+ // 鍒濆鍖栨姤璀﹁鏍�
+ RefreshAlarmBadge();
//SystemLogManager::getInstance.log(SystemLogManager::LogType::Info, _T("BondEq鍚姩..."));
//SystemLogManager::getInstance.
@@ -848,6 +927,12 @@
m_pMyStatusbar->DestroyWindow();
delete m_pMyStatusbar;
m_pMyStatusbar = nullptr;
+ }
+
+ if (m_pAlarmPopupDlg != nullptr) {
+ m_pAlarmPopupDlg->DestroyWindow();
+ delete m_pAlarmPopupDlg;
+ m_pAlarmPopupDlg = nullptr;
}
if (m_pRobotTaskDlg != nullptr) {
@@ -1256,6 +1341,16 @@
dlg.SetEFEM(pEFEM);
dlg.DoModal();
}
+ else if (id == IDC_BUTTON_ALARM) {
+ if (m_pAlarmPopupDlg == nullptr) {
+ m_pAlarmPopupDlg = new CAlarmPopupDlg();
+ m_pAlarmPopupDlg->Create(IDD_DIALOG_POPUP_ALARM, this);
+ m_pAlarmPopupDlg->CenterWindow();
+ }
+ m_pAlarmPopupDlg->RefreshContent();
+ m_pAlarmPopupDlg->ShowWindow(SW_SHOW);
+ MarkAlarmsRead();
+ }
else if (id == IDC_BUTTON_SETTINGS) {
SERVO::CEquipment* pEq = theApp.m_model.m_master.getEquipment(EQ_ID_EFEM);
((SERVO::CEFEM*)pEq)->printDebugRobotState();
@@ -1367,6 +1462,23 @@
return 0;
}
+BOOL CServoDlg::PreTranslateMessage(MSG* pMsg)
+{
+ if (pMsg->message == WM_KEYDOWN) {
+ const bool ctrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ const bool alt = (GetKeyState(VK_MENU) & 0x8000) != 0;
+ if (ctrl && alt && pMsg->wParam == 'T') {
+ RaiseTestAlarm();
+ return TRUE;
+ }
+ if (ctrl && alt && pMsg->wParam == 'Y') {
+ ClearTestAlarm();
+ return TRUE;
+ }
+ }
+ return CDialogEx::PreTranslateMessage(pMsg);
+}
+
CString& CServoDlg::GetRuntimeFormatText(CString& strText, const char* pszSuffix)
{
ULONGLONG ullRunTime = (ULONGLONG)(theApp.m_model.getMaster().getRunTime() * 0.001);
diff --git a/SourceCode/Bond/Servo/ServoDlg.h b/SourceCode/Bond/Servo/ServoDlg.h
index df4b01d..ec0cba7 100644
--- a/SourceCode/Bond/Servo/ServoDlg.h
+++ b/SourceCode/Bond/Servo/ServoDlg.h
@@ -3,6 +3,8 @@
//
#pragma once
+#include <vector>
+#include <unordered_set>
#include "BlButton.h"
#include "PageLog.h"
#include "PageAlarm.h"
@@ -15,12 +17,15 @@
#include "CPanelProduction.h"
#include "CPageGraph1.h"
#include "CPageGraph2.h"
+#include "HmTab.h"
#include "TopToolbar.h"
#include "CMyStatusbar.h"
#include "CRobotTaskDlg.h"
#include "CPageGlassList.h"
#include "CPageVarialbles.h"
#include "CPageDataVarialbles.h"
+#include "AlarmPopupDlg.h"
+#include "AlarmManager.h"
// CServoDlg 瀵硅瘽妗�
@@ -36,6 +41,10 @@
private:
void InitRxWindows();
+ void RefreshAlarmBadge();
+ void MarkAlarmsRead();
+ void RaiseTestAlarm();
+ void ClearTestAlarm();
void Resize();
void SetLeftPanelType(int type, bool resize = true);
void ShowChildPage(int index);
@@ -53,6 +62,10 @@
CPageAlarm* m_pPageAlarm;
CPageLog* m_pPageLog;
CPageTransferLog* m_pPageTransferLog;
+ CAlarmPopupDlg* m_pAlarmPopupDlg;
+ CHmTab* m_pTab;
+ std::vector<AlarmData> m_unreadAlarms;
+ std::unordered_set<int> m_ackAlarms;
// 瀵硅瘽妗嗘暟鎹�
#ifdef AFX_DESIGN_TIME
@@ -116,4 +129,5 @@
afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result);
LRESULT OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam);
LRESULT OnStatusbarBtnClicked(WPARAM wParam, LPARAM lParam);
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
};
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 52ee640..5eacbaf 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
@@ -49,7 +49,6 @@
#define IDD_DIALOG_RECIPE_DEVICE_BIND 167
#define IDD_PAGE_VARIABLE 168
#define IDD_PAGE_REPORT 169
-#define IDD_PAGE_ 170
#define IDD_PAGE_COLLECTION_EVENT 171
#define IDD_DIALOG_CONTROL_JOB 172
#define IDD_PAGE_GLASS_LIST 173
@@ -68,6 +67,7 @@
#define IDD_DIALOG_EVENT_EDIT 188
#define IDD_PANEL_PRODUCTION 189
#define IDD_PROD_CTRL_STATE 190
+#define IDD_DIALOG_POPUP_ALARM 191
#define IDC_SERVO_GRAPH1 1001
#define IDC_BUTTON_LOG 1002
#define IDC_EDIT_LOG 1003
@@ -332,6 +332,23 @@
#define IDC_BUTTON_OFFLINE 1252
#define IDC_BUTTON_ONLINE_LOCAL 1253
#define IDC_BUTTON_ONLINE_REMOTE 1254
+#define IDC_POPUP_TITLE 1255
+#define IDC_POPUP_ALARM_ID 1256
+#define IDC_POPUP_ALARM_LEVEL 1257
+#define IDC_POPUP_ALARM_DESC 1258
+#define IDC_POPUP_BTN_CLOSE 1259
+#define IDC_POPUP_BTN_CLEAR 1260
+#define IDC_BUTTON_PREV 1261
+#define IDC_BUTTON_NEXT 1262
+#define IDC_ICON_ALARM 1263
+#define IDC_ICON_TITLE 1264
+#define IDC_LABEL_LEVEL 1265
+#define IDC_LABEL_NAME 1267
+#define IDC_BUTTON_SOUND_OFF 1268
+#define IDC_BUTTON_ALARM_OFF 1269
+#define IDC_LINE2 1270
+#define IDC_LABEL_DESCRIPTION 1271
+#define IDC_LABEL_NO_ALARM 1272
#define ID_MENU_HELP_ABOUT 32771
#define ID_MENU_FILE_EXIT 32772
#define ID_MENU_FILE_SECSTEST 32773
@@ -369,9 +386,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 191
+#define _APS_NEXT_RESOURCE_VALUE 192
#define _APS_NEXT_COMMAND_VALUE 32804
-#define _APS_NEXT_CONTROL_VALUE 1255
+#define _APS_NEXT_CONTROL_VALUE 1273
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
--
Gitblit v1.9.3