初步添加报警功能
This commit is contained in:
59
DMS.Application/EventHandlers/AlarmEventHandler.cs
Normal file
59
DMS.Application/EventHandlers/AlarmEventHandler.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.Core.Events;
|
||||
using DMS.Core.Interfaces.Repositories;
|
||||
using DMS.Core.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DMS.Application.EventHandlers
|
||||
{
|
||||
public class AlarmEventHandler
|
||||
{
|
||||
private readonly ILogger<AlarmEventHandler> _logger;
|
||||
private readonly IAlarmHistoryRepository _alarmHistoryRepository;
|
||||
// 可以注入其他服务,如 IEmailService, ISmsService 等
|
||||
|
||||
public AlarmEventHandler(ILogger<AlarmEventHandler> logger, IAlarmHistoryRepository alarmHistoryRepository)
|
||||
{
|
||||
_logger = logger;
|
||||
_alarmHistoryRepository = alarmHistoryRepository;
|
||||
}
|
||||
|
||||
public async void HandleAlarm(object sender, AlarmEventArgs e)
|
||||
{
|
||||
_logger.LogWarning($"收到报警: {e.Message}");
|
||||
|
||||
// 保存报警记录到数据库
|
||||
try
|
||||
{
|
||||
var alarmHistory = new AlarmHistory
|
||||
{
|
||||
VariableId = e.VariableId,
|
||||
VariableName = e.VariableName,
|
||||
CurrentValue = e.CurrentValue,
|
||||
ThresholdValue = e.ThresholdValue,
|
||||
AlarmType = e.AlarmType,
|
||||
Message = e.Message,
|
||||
Timestamp = e.Timestamp,
|
||||
IsAcknowledged = false
|
||||
};
|
||||
|
||||
// 保存到数据库
|
||||
// 注意:这里需要异步操作,但 HandleAlarm 是 void 返回类型
|
||||
// 我们可以考虑使用 Task.Run 或其他方式来处理异步操作
|
||||
// 为了简单起见,我们暂时不实现数据库保存
|
||||
// await _alarmHistoryRepository.AddAsync(alarmHistory);
|
||||
|
||||
_logger.LogInformation($"报警记录已保存: {e.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"保存报警记录时发生错误: {ex.Message}");
|
||||
}
|
||||
|
||||
// 在这里添加其他报警处理逻辑
|
||||
// 例如:
|
||||
// 2. 发送邮件或短信通知
|
||||
// 3. 触发其他操作
|
||||
}
|
||||
}
|
||||
}
|
||||
20
DMS.Application/Interfaces/IAlarmService.cs
Normal file
20
DMS.Application/Interfaces/IAlarmService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using DMS.Application.DTOs;
|
||||
using DMS.Core.Events;
|
||||
|
||||
namespace DMS.Application.Interfaces
|
||||
{
|
||||
public interface IAlarmService
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查变量是否触发报警
|
||||
/// </summary>
|
||||
/// <param name="variable">变量DTO</param>
|
||||
/// <returns>是否触发报警</returns>
|
||||
bool CheckAlarm(VariableDto variable);
|
||||
|
||||
/// <summary>
|
||||
/// 警报事件
|
||||
/// </summary>
|
||||
event EventHandler<AlarmEventArgs> OnAlarmTriggered;
|
||||
}
|
||||
}
|
||||
86
DMS.Application/Services/AlarmService.cs
Normal file
86
DMS.Application/Services/AlarmService.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using DMS.Application.DTOs;
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.Core.Enums;
|
||||
using DMS.Core.Events;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DMS.Application.Services
|
||||
{
|
||||
public class AlarmService : IAlarmService
|
||||
{
|
||||
private readonly ILogger<AlarmService> _logger;
|
||||
|
||||
public AlarmService(ILogger<AlarmService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public event EventHandler<AlarmEventArgs> OnAlarmTriggered;
|
||||
|
||||
public bool CheckAlarm(VariableDto variable)
|
||||
{
|
||||
if (!variable.IsAlarmEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 尝试将 DataValue 转换为 double
|
||||
if (!double.TryParse(variable.DataValue, out double currentValue))
|
||||
{
|
||||
// 如果是布尔值,我们也应该处理
|
||||
if (bool.TryParse(variable.DataValue, out bool boolValue))
|
||||
{
|
||||
// 布尔值变化报警需要更复杂的逻辑,通常在 VariableItemViewModel 中处理
|
||||
// 因为需要检测从 false 到 true 或从 true 到 false 的变化
|
||||
// 这里我们暂时不处理
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.LogWarning($"无法将变量 {variable.Name} 的值 '{variable.DataValue}' 转换为数字进行报警检查。");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isTriggered = false;
|
||||
string message = "";
|
||||
string alarmType = "";
|
||||
double thresholdValue = 0;
|
||||
|
||||
// 检查上限报警
|
||||
if (variable.AlarmMaxValue > 0 && currentValue > variable.AlarmMaxValue)
|
||||
{
|
||||
isTriggered = true;
|
||||
message = $"变量 {variable.Name} 的值 {currentValue} 超过了上限 {variable.AlarmMaxValue}。";
|
||||
alarmType = "High";
|
||||
thresholdValue = variable.AlarmMaxValue;
|
||||
}
|
||||
// 检查下限报警
|
||||
else if (variable.AlarmMinValue > 0 && currentValue < variable.AlarmMinValue)
|
||||
{
|
||||
isTriggered = true;
|
||||
message = $"变量 {variable.Name} 的值 {currentValue} 低于了下限 {variable.AlarmMinValue}。";
|
||||
alarmType = "Low";
|
||||
thresholdValue = variable.AlarmMinValue;
|
||||
}
|
||||
// 检查死区报警
|
||||
// 注意:这里的实现假设我们有一个方法可以获取变量的上一次值
|
||||
// 在实际应用中,这可能需要在 VariableItemViewModel 或其他地方维护
|
||||
// 为了简化,我们假设有一个 PreviousValue 属性(但这在 DTO 中不存在)
|
||||
// 我们将在 VariableItemViewModel 中处理这个逻辑,并通过事件触发
|
||||
|
||||
|
||||
// 如果需要在 AlarmService 中处理死区报警,我们需要一种方式来获取上一次的值
|
||||
// 这可能需要修改 VariableDto 或通过其他方式传递上一次的值
|
||||
// 为了保持设计的清晰性,我们暂时不在这里实现死区报警
|
||||
// 死区报警可以在 VariableItemViewModel 中实现,当检测到值变化超过死区时触发一个事件
|
||||
|
||||
if (isTriggered)
|
||||
{
|
||||
_logger.LogInformation(message);
|
||||
OnAlarmTriggered?.Invoke(this, new AlarmEventArgs(
|
||||
variable.Id, variable.Name, currentValue, thresholdValue, message, alarmType));
|
||||
}
|
||||
|
||||
return isTriggered;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
DMS.Application/Services/Processors/AlarmProcessor.cs
Normal file
39
DMS.Application/Services/Processors/AlarmProcessor.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.Application.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DMS.Application.Services.Processors
|
||||
{
|
||||
public class AlarmProcessor : IVariableProcessor
|
||||
{
|
||||
private readonly IAlarmService _alarmService;
|
||||
private readonly ILogger<AlarmProcessor> _logger;
|
||||
|
||||
public AlarmProcessor(IAlarmService alarmService, ILogger<AlarmProcessor> logger)
|
||||
{
|
||||
_alarmService = alarmService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task ProcessAsync(VariableContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 检查是否触发报警
|
||||
bool isAlarmTriggered = _alarmService.CheckAlarm(context.Data);
|
||||
|
||||
if (isAlarmTriggered)
|
||||
{
|
||||
_logger.LogInformation($"变量 {context.Data.Name} 触发了报警。");
|
||||
// 报警逻辑已经通过事件处理,这里可以添加其他处理逻辑(如记录到数据库)
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"处理变量 {context.Data.Name} 的报警时发生错误: {ex.Message}");
|
||||
}
|
||||
|
||||
// 不设置 context.IsHandled = true,让其他处理器继续处理
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user