This commit is contained in:
2026-04-12 22:34:46 +08:00
parent d554e9e659
commit 73e16ab6c1
25 changed files with 5962 additions and 52 deletions

View File

@@ -1,3 +1,6 @@
#if false
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OrpaonVision.Core.AlarmSystem;
@@ -15,6 +18,8 @@ public sealed class AlarmSystemService : IAlarmSystemService
{
private readonly ILogger<AlarmSystemService> _logger;
private readonly RuntimeOptions _options;
private readonly IRuleEngineService _ruleEngineService;
private readonly IRuntimeStateMachineService _stateMachineService;
private readonly ConcurrentDictionary<Guid, Alarm> _activeAlarms = new();
private readonly ConcurrentDictionary<Guid, Alarm> _alarmHistory = new();
private readonly ConcurrentDictionary<Guid, AlarmLifecycle> _alarmLifecycles = new();
@@ -22,10 +27,16 @@ public sealed class AlarmSystemService : IAlarmSystemService
private readonly object _lock = new();
private readonly Timer _autoClearTimer;
public AlarmSystemService(ILogger<AlarmSystemService> logger, IOptions<RuntimeOptions> options)
public AlarmSystemService(
ILogger<AlarmSystemService> logger,
IOptions<RuntimeOptions> options,
IRuleEngineService ruleEngineService,
IRuntimeStateMachineService stateMachineService)
{
_logger = logger;
_options = options.Value;
_ruleEngineService = ruleEngineService;
_stateMachineService = stateMachineService;
// 初始化报警栈
foreach (var stackType in Enum.GetValues<AlarmStackType>())
@@ -44,23 +55,28 @@ public sealed class AlarmSystemService : IAlarmSystemService
{
try
{
_logger.LogInformation("触发报警:类型={AlarmType},级别={AlarmLevel},标题={Title}会话ID={SessionId},层级={Layer}",
alarmRequest.AlarmType, alarmRequest.AlarmLevel, alarmRequest.Title, alarmRequest.SessionId, alarmRequest.RelatedLayer);
_logger.LogInformation("触发报警:类型={AlarmType},级别={AlarmLevel},标题={Title}会话ID={SessionId},层级={Layer},规则编号={RuleNumber}",
alarmRequest.AlarmType, alarmRequest.AlarmLevel, alarmRequest.Title, alarmRequest.SessionId, alarmRequest.RelatedLayer,
GetRuleNumberFromRequest(alarmRequest));
var startTime = DateTime.UtcNow;
var alarmId = Guid.NewGuid();
// 创建报警生命周期记录
// 获取当前状态机状态和层级信息
var currentState = _stateMachineService.GetCurrentState();
var currentLayer = _stateMachineService.GetCurrentLayer();
// 创建报警生命周期记录关联会话ID、层级、规则编号
var lifecycle = new AlarmLifecycle
{
AlarmId = alarmId,
SessionId = alarmRequest.SessionId,
Layer = alarmRequest.RelatedLayer,
RuleNumber = alarmRequest.ExtendedProperties?.ContainsKey("rule_number") == true
? alarmRequest.ExtendedProperties["rule_number"].ToString()
: string.Empty,
Layer = alarmRequest.RelatedLayer > 0 ? alarmRequest.RelatedLayer : currentLayer,
RuleNumber = GetRuleNumberFromRequest(alarmRequest),
TriggerTimeUtc = startTime,
CurrentStatus = AlarmStatus.Active
CurrentStatus = AlarmStatus.Active,
TriggerState = currentState.ToString(),
TriggerLayer = currentLayer
};
_alarmLifecycles.TryAdd(alarmId, lifecycle);
@@ -74,7 +90,7 @@ public sealed class AlarmSystemService : IAlarmSystemService
Description = alarmRequest.Description,
ProductTypeCode = alarmRequest.ProductTypeCode,
SessionId = alarmRequest.SessionId,
RelatedLayer = alarmRequest.RelatedLayer,
RelatedLayer = alarmRequest.RelatedLayer > 0 ? alarmRequest.RelatedLayer : currentLayer,
RelatedPart = alarmRequest.RelatedPart,
Source = alarmRequest.Source,
AlarmData = alarmRequest.AlarmData,
@@ -88,6 +104,13 @@ public sealed class AlarmSystemService : IAlarmSystemService
DuplicateCount = 0,
IsDuplicate = false,
ExtendedProperties = new Dictionary<string, object>(alarmRequest.ExtendedProperties)
{
["trigger_state"] = currentState.ToString(),
["trigger_layer"] = currentLayer,
["rule_number"] = lifecycle.RuleNumber,
["integration_with_state_machine"] = true,
["integration_with_rule_engine"] = true
}
};
// 添加到活跃报警
@@ -100,6 +123,12 @@ public sealed class AlarmSystemService : IAlarmSystemService
// 更新栈位置
UpdateStackPositions(stackType);
// 如果是严重报警,可能需要触发状态机转换
if (alarmRequest.AlarmLevel >= AlarmLevel.High)
{
await HandleCriticalAlarmAsync(alarm, cancellationToken);
}
var elapsedMs = (long)(DateTime.UtcNow - startTime).TotalMilliseconds;
var result = new AlarmResult
@@ -118,13 +147,15 @@ public sealed class AlarmSystemService : IAlarmSystemService
ExtendedProperties = new Dictionary<string, object>
{
["session_id"] = alarmRequest.SessionId,
["layer"] = alarmRequest.RelatedLayer,
["rule_number"] = lifecycle.RuleNumber
["layer"] = alarm.RelatedLayer,
["rule_number"] = lifecycle.RuleNumber,
["trigger_state"] = currentState.ToString(),
["current_layer"] = currentLayer
}
};
_logger.LogInformation("报警触发成功报警ID={AlarmId}会话ID={SessionId},层级={Layer},规则编号={RuleNumber}",
alarmId, alarmRequest.SessionId, alarmRequest.RelatedLayer, lifecycle.RuleNumber);
_logger.LogInformation("报警触发成功报警ID={AlarmId}会话ID={SessionId},层级={Layer},规则编号={RuleNumber},状态={State},耗时={ElapsedMs}ms",
alarmId, alarmRequest.SessionId, alarm.RelatedLayer, lifecycle.RuleNumber, currentState, elapsedMs);
return Result<AlarmResult>.Success(result);
}
@@ -445,6 +476,167 @@ public sealed class AlarmSystemService : IAlarmSystemService
#region
/// <summary>
/// 从报警请求中提取规则编号。
/// </summary>
private string GetRuleNumberFromRequest(AlarmRequest request)
{
if (request.ExtendedProperties?.ContainsKey("rule_number") == true)
{
return request.ExtendedProperties["rule_number"].ToString() ?? string.Empty;
}
if (request.ExtendedProperties?.ContainsKey("rule_name") == true)
{
return request.ExtendedProperties["rule_name"].ToString() ?? string.Empty;
}
return string.Empty;
}
/// <summary>
/// 处理严重报警。
/// </summary>
private async Task HandleCriticalAlarmAsync(Alarm alarm, CancellationToken cancellationToken)
{
try
{
_logger.LogWarning("处理严重报警报警ID={AlarmId},级别={AlarmLevel},标题={Title}",
alarm.AlarmId, alarm.AlarmLevel, alarm.Title);
// 根据报警类型和级别决定是否触发状态机转换
var currentState = _stateMachineService.GetCurrentState();
if (alarm.AlarmLevel == AlarmLevel.Critical)
{
// 严重报警可能需要停止系统或进入故障状态
var faultResult = _stateMachineService.TriggerFault($"严重报警触发:{alarm.Title}");
if (faultResult.IsSuccess)
{
_logger.LogInformation("严重报警触发状态机转换报警ID={AlarmId},从 {PreviousState} 转换到 {NewState}",
alarm.AlarmId, faultResult.Data.PreviousState, faultResult.Data.NewState);
}
else
{
_logger.LogWarning("严重报警未能触发状态机转换报警ID={AlarmId},错误={Error}",
alarm.AlarmId, faultResult.Message);
}
}
else if (alarm.AlarmLevel == AlarmLevel.High)
{
// 高级报警可能需要暂停系统
if (currentState == RuntimeState.Running)
{
var pauseResult = _stateMachineService.TriggerTransition(StateTrigger.Pause, $"高级报警触发暂停:{alarm.Title}");
if (pauseResult.IsSuccess)
{
_logger.LogInformation("高级报警触发系统暂停报警ID={AlarmId}", alarm.AlarmId);
}
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "处理严重报警失败报警ID={AlarmId}", alarm.AlarmId);
}
}
/// <summary>
/// 检查报警是否可以自动恢复。
/// </summary>
private async Task<bool> CheckAlarmRecoveryConditionAsync(Guid alarmId, CancellationToken cancellationToken)
{
try
{
if (!_alarmLifecycles.TryGetValue(alarmId, out var lifecycle))
{
return false;
}
// 检查状态机是否已恢复正常
var currentState = _stateMachineService.GetCurrentState();
var isStateRecovered = currentState == RuntimeState.Running || currentState == RuntimeState.Ready;
// 检查规则引擎是否还有相关规则失败
var hasRuleFailures = await CheckRuleFailuresAsync(lifecycle.SessionId, lifecycle.Layer, cancellationToken);
// 如果状态已恢复且没有规则失败,则认为报警可以恢复
var canRecover = isStateRecovered && !hasRuleFailures;
_logger.LogDebug("报警恢复条件检查报警ID={AlarmId},状态恢复={StateRecovered},规则失败={RuleFailures},可恢复={CanRecover}",
alarmId, isStateRecovered, hasRuleFailures, canRecover);
return canRecover;
}
catch (Exception ex)
{
_logger.LogError(ex, "检查报警恢复条件失败报警ID={AlarmId}", alarmId);
return false;
}
}
/// <summary>
/// 检查规则失败情况。
/// </summary>
private async Task<bool> CheckRuleFailuresAsync(Guid sessionId, int layer, CancellationToken cancellationToken)
{
try
{
// 这里应该调用规则引擎检查当前会话和层级的规则执行情况
// 暂时返回false表示没有规则失败
return false;
}
catch (Exception ex)
{
_logger.LogError(ex, "检查规则失败情况异常会话ID={SessionId},层级={Layer}", sessionId, layer);
return false;
}
}
/// <summary>
/// 自动检查报警恢复状态。
/// </summary>
private async Task CheckAlarmRecoveryAsync(object? state)
{
try
{
var activeAlarmIds = _activeAlarms.Keys.ToList();
foreach (var alarmId in activeAlarmIds)
{
if (_activeAlarms.TryGetValue(alarmId, out var alarm) && alarm.AlarmStatus == AlarmStatus.Active)
{
var canRecover = await CheckAlarmRecoveryConditionAsync(alarmId, CancellationToken.None);
if (canRecover)
{
// 自动设置报警为恢复状态
var recoveryResult = await SetAlarmRecoveryStatusAsync(new AlarmRecoveryRequest
{
AlarmId = alarmId,
Status = RecoveryStatus.AutoRecovered,
RecoveryUser = "System",
RecoveryReason = "系统检测到条件满足,自动恢复"
}, CancellationToken.None);
if (recoveryResult.IsSuccess)
{
_logger.LogInformation("报警自动恢复报警ID={AlarmId},标题={Title}", alarmId, alarm.Title);
}
}
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "自动检查报警恢复状态失败");
}
}
#endregion
private AlarmStackType GetAlarmStackType(AlarmLevel alarmLevel)
{
return alarmLevel switch
@@ -503,8 +695,6 @@ public sealed class AlarmSystemService : IAlarmSystemService
}
}
#endregion
/// <summary>
/// 释放资源。
/// </summary>
@@ -563,6 +753,16 @@ public sealed class AlarmLifecycle
/// </summary>
public DateTime TriggerTimeUtc { get; set; }
/// <summary>
/// 触发时的状态机状态。
/// </summary>
public string TriggerState { get; set; } = string.Empty;
/// <summary>
/// 触发时的层级。
/// </summary>
public int TriggerLayer { get; set; }
/// <summary>
/// 确认时间。
/// </summary>
@@ -597,12 +797,91 @@ public sealed class AlarmLifecycle
/// 恢复状态。
/// </summary>
public RecoveryStatus RecoveryStatus { get; set; }
/// <summary>
/// 恢复原因。
/// </summary>
public string? RecoveryReason { get; set; }
/// <summary>
/// 生命周期持续时间(毫秒)。
/// </summary>
public long LifecycleDurationMs =>
RecoveryTimeUtc?.Subtract(TriggerTimeUtc).TotalMilliseconds ??
ClearTimeUtc?.Subtract(TriggerTimeUtc).TotalMilliseconds ??
DateTime.UtcNow.Subtract(TriggerTimeUtc).TotalMilliseconds;
/// <summary>
/// 状态转换历史。
/// </summary>
public List<AlarmStatusTransition> StatusTransitions { get; set; } = new();
/// <summary>
/// 扩展属性。
/// </summary>
public Dictionary<string, object> ExtendedProperties { get; set; } = new();
}
/// <summary>
/// 报警状态转换记录。
/// </summary>
public sealed class AlarmStatusTransition
{
/// <summary>
/// 转换时间。
/// </summary>
public DateTime TransitionTimeUtc { get; set; }
/// <summary>
/// 前一个状态。
/// </summary>
public AlarmStatus PreviousStatus { get; set; }
/// <summary>
/// 新状态。
/// </summary>
public AlarmStatus NewStatus { get; set; }
/// <summary>
/// 操作用户。
/// </summary>
public string? OperatorUser { get; set; }
/// <summary>
/// 转换原因。
/// </summary>
public string? Reason { get; set; }
/// <summary>
/// 转换类型(手动/自动)。
/// </summary>
public AlarmTransitionType TransitionType { get; set; }
}
/// <summary>
/// 报警转换类型。
/// </summary>
public enum AlarmTransitionType
{
/// <summary>
/// 手动转换。
/// </summary>
Manual,
/// <summary>
/// 自动转换。
/// </summary>
Automatic,
/// <summary>
/// 系统转换。
/// </summary>
System
}
#endregion
#if false
/// <summary>
/// 异常报警系统服务实现。
/// </summary>
@@ -1834,5 +2113,6 @@ public sealed class AlarmSystemService : IAlarmSystemService
}
#endregion
}
#endif
#endif