终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

157 lines
6.4 KiB

  1. using BPA.Helper;
  2. using BPA.Helper.Interface;
  3. using BPASmartClient.CustomResource.Pages.ViewModel;
  4. using BPASmartClient.Model;
  5. using System;
  6. using System.Collections.Concurrent;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Linq;
  10. using System.Reflection;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using System.Windows;
  14. namespace BPASmartClient.CustomResource.Pages.Model
  15. {
  16. public class AlarmHelper<AlarmT> where AlarmT : class, new()
  17. {
  18. private volatile static ConcurrentDictionary<string, AlarmT> _Instance;
  19. private static readonly object Obj_Lock = new object();
  20. public static AlarmT GetInstance(string name = "")
  21. {
  22. lock (Obj_Lock)
  23. {
  24. if (string.IsNullOrEmpty(name)) name = typeof(AlarmT).Name;
  25. if (_Instance == null) _Instance = new ConcurrentDictionary<string, AlarmT>();
  26. if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new AlarmT());
  27. return _Instance[name];
  28. }
  29. }
  30. private AlarmHelper() { }
  31. public static ObservableCollection<BPASmartClient.Model.Alarm> Alarms { get; set; } = new ObservableCollection<BPASmartClient.Model.Alarm>();
  32. public static List<BPASmartClient.Model.Alarm> HistoryAlarms { get; set; } = new List<BPASmartClient.Model.Alarm>();
  33. static ConcurrentDictionary<string, bool> flagbit = new ConcurrentDictionary<string, bool>();
  34. static ConcurrentDictionary<string, IDelay> delays = new ConcurrentDictionary<string, IDelay>();
  35. public static Action<string> AddAction { get; set; }
  36. public static Action<string> RemoveAction { get; set; }
  37. public static Action ChangeAction { get; set; }
  38. //public static AlarmT Alarm { get; set; } = new AlarmT();
  39. public static void Init()
  40. {
  41. AlarmViewModel.AlarmInfos = Alarms;
  42. TaskManage.GetInstance.StartLong(new Action(() =>
  43. {
  44. if (_Instance != null)
  45. {
  46. foreach (var temp in _Instance)
  47. {
  48. foreach (var item in temp.Value.GetType().GetProperties())
  49. {
  50. if (item.CustomAttributes.Count() > 0)
  51. {
  52. var AlarmModel = item.GetCustomAttribute<AlarmAttribute>();
  53. if (AlarmModel != null)
  54. {
  55. bool value = Convert.ToBoolean(_Instance[temp.Key].GetType().GetProperty(item.Name)?.GetValue(_Instance[temp.Key]));
  56. string text = typeof(AlarmT).Name == temp.Key ? AlarmModel.AlarmInfo : $"{temp.Key}:{AlarmModel.AlarmInfo}";
  57. EdgeAlarm(value, text, 1, AlarmModel.AlarmLevel, AlarmModel.AlarmType);
  58. }
  59. }
  60. }
  61. }
  62. }
  63. Thread.Sleep(100);
  64. }), $"{typeof(AlarmT).Name},报警通用模块监听");
  65. }
  66. /// <summary>
  67. /// 沿报警检测
  68. /// </summary>
  69. /// <param name="Trigger">触发变量</param>
  70. /// <param name="text">报警信息</param>
  71. /// <param name="edgeType">触发类型,上升沿 或 下降沿</param>
  72. private static void EdgeAlarm(bool Trigger, string text, int delay = 2, AlarmLevel alarmLevel = AlarmLevel.一般报警, AlarmTriggerType edgeType = AlarmTriggerType.Rising)
  73. {
  74. if (!flagbit.ContainsKey(text)) flagbit.TryAdd(text, false);
  75. if (!delays.ContainsKey(text)) delays.TryAdd(text, Delay.GetInstance(text));
  76. if (edgeType == AlarmTriggerType.Rising ? delays[text].Start(Trigger, delay) : delays[text].Start(!Trigger, delay))
  77. {
  78. if (edgeType == AlarmTriggerType.Rising ? !flagbit[text] : flagbit[text])
  79. {
  80. AddAlarm(Trigger, text, alarmLevel);
  81. flagbit[text] = edgeType == AlarmTriggerType.Rising ? true : false;
  82. }
  83. }
  84. else RemoveAlarm(text);
  85. if (edgeType == AlarmTriggerType.Rising ? flagbit[text] : !flagbit[text]) flagbit[text] = Trigger;
  86. }
  87. /// <summary>
  88. /// 添加报警信息
  89. /// </summary>
  90. /// <param name="AlarmInfo">报警信息</param>
  91. private static void AddAlarm(object value, string AlarmInfo, AlarmLevel alarmLevel)
  92. {
  93. BPASmartClient.Model.Alarm tempAlarm = new BPASmartClient.Model.Alarm()
  94. {
  95. NumId = Alarms.Count + 1,
  96. Date = DateTime.Now.ToString("yyyy/MM/dd"),
  97. Grade = alarmLevel.ToString(),
  98. Info = AlarmInfo,
  99. Value = value.ToString(),
  100. Time = DateTime.Now.ToString("HH:mm:ss"),
  101. };
  102. try
  103. {
  104. var res = Sqlite<BPASmartClient.Model.Alarm>.GetInstance.Base.Add(tempAlarm);
  105. Sqlite<BPASmartClient.Model.Alarm>.GetInstance.Save();
  106. }
  107. catch (Exception)
  108. {
  109. }
  110. if (Alarms.FirstOrDefault(p => p.Info == AlarmInfo) == null)
  111. {
  112. Application.Current.Dispatcher.Invoke(new Action(() =>
  113. {
  114. Alarms.Insert(0, tempAlarm);
  115. for (int i = 0; i < Alarms.Count; i++) { Alarms.ElementAt(i).NumId = i + 1; }
  116. }));
  117. AddAction?.Invoke(AlarmInfo);//添加报警通知
  118. ChangeAction?.Invoke();//更改报警通知
  119. }
  120. }
  121. /// <summary>
  122. /// 移除报警信息
  123. /// </summary>
  124. /// <param name="AlarmInfo">报警信息</param>
  125. private static void RemoveAlarm(string AlarmInfo)
  126. {
  127. var result = Alarms.FirstOrDefault(p => p.Info == AlarmInfo);
  128. if (result != null)
  129. {
  130. Application.Current.Dispatcher.Invoke(new Action(() =>
  131. {
  132. Alarms.Remove(result);
  133. for (int i = 0; i < Alarms.Count; i++) { Alarms.ElementAt(i).NumId = i + 1; }
  134. }));
  135. if (RemoveAction != null) RemoveAction(AlarmInfo);
  136. if (ChangeAction != null) ChangeAction();
  137. }
  138. }
  139. }
  140. }