2026-04-17 09:17:56 +00:00
|
|
|
|
#include "alert_manager.hpp"
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
#include <ctime>
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
|
|
AlertManager::AlertManager()
|
|
|
|
|
|
: upper_threshold_(100.0f), lower_threshold_(-50.0f) {
|
|
|
|
|
|
// 初始化预警映射
|
|
|
|
|
|
alerts_.clear();
|
|
|
|
|
|
alert_history_.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AlertManager::~AlertManager() {
|
|
|
|
|
|
// 自动清理
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::initialize() {
|
|
|
|
|
|
std::cout << "预警管理器初始化完成。" << std::endl;
|
|
|
|
|
|
std::cout << "默认预警阈值:上限=" << upper_threshold_
|
|
|
|
|
|
<< "米,下限=" << lower_threshold_ << "米" << std::endl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::checkAltitudeAlert(float altitude, uint32_t timestamp) {
|
|
|
|
|
|
// 检查上限预警
|
|
|
|
|
|
if (altitude > upper_threshold_) {
|
|
|
|
|
|
auto it = alerts_.find(AlertType::ALTITUDE_UPPER);
|
|
|
|
|
|
if (it == alerts_.end() || it->second.status != AlertStatus::ACTIVE) {
|
|
|
|
|
|
std::ostringstream desc;
|
|
|
|
|
|
desc << "高度超过上限阈值:当前" << altitude
|
|
|
|
|
|
<< "米 > 阈值" << upper_threshold_ << "米";
|
|
|
|
|
|
triggerAlert(AlertType::ALTITUDE_UPPER, timestamp, desc.str());
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 高度恢复正常,更新预警状态
|
|
|
|
|
|
auto it = alerts_.find(AlertType::ALTITUDE_UPPER);
|
|
|
|
|
|
if (it != alerts_.end() && it->second.isActive()) {
|
|
|
|
|
|
updateAlertStatus(AlertType::ALTITUDE_UPPER, AlertStatus::RESOLVED, timestamp);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查下限预警
|
|
|
|
|
|
if (altitude < lower_threshold_) {
|
|
|
|
|
|
auto it = alerts_.find(AlertType::ALTITUDE_LOWER);
|
|
|
|
|
|
if (it == alerts_.end() || it->second.status != AlertStatus::ACTIVE) {
|
|
|
|
|
|
std::ostringstream desc;
|
|
|
|
|
|
desc << "高度低于下限阈值:当前" << altitude
|
|
|
|
|
|
<< "米 < 阈值" << lower_threshold_ << "米";
|
|
|
|
|
|
triggerAlert(AlertType::ALTITUDE_LOWER, timestamp, desc.str());
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 高度恢复正常,更新预警状态
|
|
|
|
|
|
auto it = alerts_.find(AlertType::ALTITUDE_LOWER);
|
|
|
|
|
|
if (it != alerts_.end() && it->second.isActive()) {
|
|
|
|
|
|
updateAlertStatus(AlertType::ALTITUDE_LOWER, AlertStatus::RESOLVED, timestamp);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::setAltitudeThresholds(float upper, float lower) {
|
|
|
|
|
|
if (upper <= lower) {
|
|
|
|
|
|
std::cerr << "错误:上限阈值必须大于下限阈值。" << std::endl;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
upper_threshold_ = upper;
|
|
|
|
|
|
lower_threshold_ = lower;
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "预警阈值已更新:上限=" << upper
|
|
|
|
|
|
<< "米,下限=" << lower << "米" << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// 如果阈值改变,重置相关预警
|
|
|
|
|
|
resetAlert(AlertType::ALTITUDE_UPPER);
|
|
|
|
|
|
resetAlert(AlertType::ALTITUDE_LOWER);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::triggerSensorFailure(uint32_t timestamp) {
|
|
|
|
|
|
triggerAlert(AlertType::SENSOR_FAILURE, timestamp, "传感器故障");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::triggerLowBattery(uint32_t timestamp, float battery_level) {
|
|
|
|
|
|
std::ostringstream desc;
|
|
|
|
|
|
desc << "低电量警告:当前电量" << battery_level << "%";
|
|
|
|
|
|
triggerAlert(AlertType::LOW_BATTERY, timestamp, desc.str());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::triggerCommunicationError(uint32_t timestamp) {
|
|
|
|
|
|
triggerAlert(AlertType::COMMUNICATION_ERROR, timestamp, "通信错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::acknowledgeAllAlerts(uint32_t timestamp) {
|
|
|
|
|
|
for (auto& pair : alerts_) {
|
|
|
|
|
|
if (pair.second.status == AlertStatus::ACTIVE) {
|
|
|
|
|
|
updateAlertStatus(pair.first, AlertStatus::ACKNOWLEDGED, timestamp);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::acknowledgeAlert(AlertType type, uint32_t timestamp) {
|
|
|
|
|
|
auto it = alerts_.find(type);
|
|
|
|
|
|
if (it != alerts_.end() && it->second.status == AlertStatus::ACTIVE) {
|
|
|
|
|
|
updateAlertStatus(type, AlertStatus::ACKNOWLEDGED, timestamp);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::resetAlert(AlertType type) {
|
|
|
|
|
|
auto it = alerts_.find(type);
|
|
|
|
|
|
if (it != alerts_.end()) {
|
|
|
|
|
|
// 如果预警是活动的,先标记为已解决
|
|
|
|
|
|
if (it->second.isActive()) {
|
|
|
|
|
|
updateAlertStatus(type, AlertStatus::RESOLVED,
|
|
|
|
|
|
static_cast<uint32_t>(std::time(nullptr)));
|
|
|
|
|
|
}
|
|
|
|
|
|
alerts_.erase(it);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::resetAllAlerts() {
|
|
|
|
|
|
// 将所有活动预警标记为已解决
|
|
|
|
|
|
auto timestamp = static_cast<uint32_t>(std::time(nullptr));
|
|
|
|
|
|
for (auto& pair : alerts_) {
|
|
|
|
|
|
if (pair.second.isActive()) {
|
|
|
|
|
|
updateAlertStatus(pair.first, AlertStatus::RESOLVED, timestamp);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清空当前预警
|
|
|
|
|
|
alerts_.clear();
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "所有预警已重置。" << std::endl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AlertManager::hasActiveAlerts() const {
|
|
|
|
|
|
for (const auto& pair : alerts_) {
|
|
|
|
|
|
if (pair.second.isActive()) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AlertManager::hasUnacknowledgedAlerts() const {
|
|
|
|
|
|
for (const auto& pair : alerts_) {
|
|
|
|
|
|
if (pair.second.status == AlertStatus::ACTIVE) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<AlertInfo> AlertManager::getActiveAlerts() const {
|
|
|
|
|
|
std::vector<AlertInfo> active_alerts;
|
|
|
|
|
|
|
|
|
|
|
|
for (const auto& pair : alerts_) {
|
|
|
|
|
|
if (pair.second.isActive()) {
|
|
|
|
|
|
active_alerts.push_back(pair.second);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return active_alerts;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<AlertInfo> AlertManager::getAlertHistory(size_t max_count) const {
|
|
|
|
|
|
size_t count = std::min(max_count, alert_history_.size());
|
|
|
|
|
|
std::vector<AlertInfo> history;
|
|
|
|
|
|
|
|
|
|
|
|
// 从最新记录开始获取
|
|
|
|
|
|
size_t start_index = alert_history_.size() - count;
|
|
|
|
|
|
for (size_t i = start_index; i < alert_history_.size(); ++i) {
|
|
|
|
|
|
history.push_back(alert_history_[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return history;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string AlertManager::getStatusDescription() const {
|
|
|
|
|
|
std::ostringstream oss;
|
|
|
|
|
|
|
|
|
|
|
|
auto active_alerts = getActiveAlerts();
|
|
|
|
|
|
if (active_alerts.empty()) {
|
|
|
|
|
|
oss << "系统状态:正常";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
oss << "系统状态:有" << active_alerts.size() << "个活动预警\n";
|
|
|
|
|
|
|
|
|
|
|
|
for (const auto& alert : active_alerts) {
|
|
|
|
|
|
// 转换时间戳
|
|
|
|
|
|
std::time_t trigger_time = alert.trigger_time;
|
|
|
|
|
|
std::tm* tm_info = std::localtime(&trigger_time);
|
|
|
|
|
|
char time_buf[20];
|
|
|
|
|
|
std::strftime(time_buf, sizeof(time_buf), "%H:%M:%S", tm_info);
|
|
|
|
|
|
|
|
|
|
|
|
oss << " - " << getAlertTypeName(alert.type)
|
|
|
|
|
|
<< " [" << getAlertStatusName(alert.status) << "]"
|
|
|
|
|
|
<< " (" << time_buf << "): "
|
|
|
|
|
|
<< alert.description << "\n";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return oss.str();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::clearHistory() {
|
|
|
|
|
|
alert_history_.clear();
|
|
|
|
|
|
std::cout << "预警历史记录已清空。" << std::endl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::addToHistory(const AlertInfo& alert) {
|
|
|
|
|
|
alert_history_.push_back(alert);
|
|
|
|
|
|
|
|
|
|
|
|
// 限制历史记录数量
|
|
|
|
|
|
if (alert_history_.size() > MAX_HISTORY) {
|
|
|
|
|
|
alert_history_.erase(alert_history_.begin());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::triggerAlert(AlertType type, uint32_t timestamp, const std::string& description) {
|
|
|
|
|
|
AlertInfo alert;
|
|
|
|
|
|
alert.type = type;
|
|
|
|
|
|
alert.status = AlertStatus::ACTIVE;
|
|
|
|
|
|
alert.trigger_time = timestamp;
|
|
|
|
|
|
alert.description = description;
|
|
|
|
|
|
|
|
|
|
|
|
alerts_[type] = alert;
|
|
|
|
|
|
addToHistory(alert);
|
|
|
|
|
|
|
|
|
|
|
|
// 输出预警信息
|
|
|
|
|
|
std::cout << "\n[预警] " << getAlertTypeName(type) << ": "
|
|
|
|
|
|
<< description << std::endl;
|
|
|
|
|
|
std::cout << "时间: " << timestamp << " (UTC)" << std::endl;
|
|
|
|
|
|
std::cout << "声光报警:蜂鸣器持续响,红色LED闪烁" << std::endl;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AlertManager::updateAlertStatus(AlertType type, AlertStatus new_status, uint32_t timestamp) {
|
|
|
|
|
|
auto it = alerts_.find(type);
|
|
|
|
|
|
if (it == alerts_.end()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AlertInfo& alert = it->second;
|
|
|
|
|
|
AlertStatus old_status = alert.status;
|
|
|
|
|
|
|
|
|
|
|
|
// 更新状态和时间戳
|
|
|
|
|
|
alert.status = new_status;
|
|
|
|
|
|
|
|
|
|
|
|
switch (new_status) {
|
|
|
|
|
|
case AlertStatus::ACKNOWLEDGED:
|
|
|
|
|
|
alert.acknowledge_time = timestamp;
|
|
|
|
|
|
std::cout << "预警已确认: " << getAlertTypeName(type) << std::endl;
|
|
|
|
|
|
std::cout << "声光反馈:蜂鸣器停止,黄色LED常亮" << std::endl;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case AlertStatus::RESOLVED:
|
|
|
|
|
|
alert.resolve_time = timestamp;
|
|
|
|
|
|
std::cout << "预警已解决: " << getAlertTypeName(type) << std::endl;
|
|
|
|
|
|
std::cout << "声光反馈:蜂鸣器停止,绿色LED闪烁3次" << std::endl;
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新历史记录中的对应条目
|
|
|
|
|
|
for (auto& hist_alert : alert_history_) {
|
|
|
|
|
|
if (hist_alert.type == type &&
|
|
|
|
|
|
hist_alert.trigger_time == alert.trigger_time) {
|
|
|
|
|
|
hist_alert = alert;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string AlertManager::getAlertTypeName(AlertType type) {
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
case AlertType::NONE: return "无";
|
|
|
|
|
|
case AlertType::ALTITUDE_UPPER: return "高度上限预警";
|
|
|
|
|
|
case AlertType::ALTITUDE_LOWER: return "高度下限预警";
|
|
|
|
|
|
case AlertType::SENSOR_FAILURE: return "传感器故障";
|
|
|
|
|
|
case AlertType::LOW_BATTERY: return "低电量预警";
|
|
|
|
|
|
case AlertType::COMMUNICATION_ERROR: return "通信错误";
|
|
|
|
|
|
case AlertType::CALIBRATION_ERROR: return "校准错误";
|
|
|
|
|
|
default: return "未知预警";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string AlertManager::getAlertStatusName(AlertStatus status) {
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
|
case AlertStatus::INACTIVE: return "未激活";
|
|
|
|
|
|
case AlertStatus::ACTIVE: return "预警中";
|
|
|
|
|
|
case AlertStatus::ACKNOWLEDGED: return "已确认";
|
2026-04-22 06:15:49 +00:00
|
|
|
|
case AlertStatus::RESOLVED: return "已解决";
|
2026-04-17 09:17:56 +00:00
|
|
|
|
default: return "未知状态";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|