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.

273 lines
11 KiB

  1. using BPA.Helper;
  2. using BPASmartClient.Model;
  3. using System;
  4. using System.Collections.Concurrent;
  5. using System.Collections.Generic;
  6. using System.Collections.ObjectModel;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using System.Windows;
  12. namespace BPASmartClient.CustomResource.Pages.Model
  13. {
  14. public class AlarmHelper<AlarmT> where AlarmT : class, new()
  15. {
  16. private volatile static ConcurrentDictionary<string, AlarmT> _Instance;
  17. private static readonly object Obj_Lock = new object();
  18. public static AlarmT GetInstance(string name = "")
  19. {
  20. lock (Obj_Lock)
  21. {
  22. if (string.IsNullOrEmpty(name)) name = typeof(AlarmT).Name;
  23. if (_Instance == null) _Instance = new ConcurrentDictionary<string, AlarmT>();
  24. if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new AlarmT());
  25. return _Instance[name];
  26. }
  27. }
  28. private AlarmHelper() { }
  29. public static List<Alarm> Alarms { get; set; } = new List<Alarm>();
  30. public static List<Alarm> HistoryAlarms { get; set; } = new List<Alarm>();
  31. static ConcurrentDictionary<string, bool> flagbit = new ConcurrentDictionary<string, bool>();
  32. static ConcurrentDictionary<string, Delay> delays = new ConcurrentDictionary<string, Delay>();
  33. public static Action<string> AddAction { get; set; }
  34. public static Action<string> RemoveAction { get; set; }
  35. public static Action ChangeAction { get; set; }
  36. //public static AlarmT Alarm { get; set; } = new AlarmT();
  37. public static void Init()
  38. {
  39. //AlarmViewModel.AlarmInfos = Alarms;
  40. ThreadManage.GetInstance().StartLong(new Action(() =>
  41. {
  42. if (_Instance != null)
  43. {
  44. foreach (var temp in _Instance)
  45. {
  46. foreach (var item in temp.Value.GetType().GetProperties())
  47. {
  48. if (item.CustomAttributes.Count() > 0)
  49. {
  50. var AlarmModel = item.GetCustomAttribute<AlarmAttribute>();
  51. if (AlarmModel != null)
  52. {
  53. bool value = Convert.ToBoolean(_Instance[temp.Key].GetType().GetProperty(item.Name)?.GetValue(_Instance[temp.Key]));
  54. string text = typeof(AlarmT).Name == temp.Key ? AlarmModel.AlarmInfo : $"{temp.Key}:{AlarmModel.AlarmInfo}";
  55. EdgeAlarm(value, text, 1, AlarmModel.AlarmLevel, AlarmModel.AlarmType);
  56. }
  57. }
  58. }
  59. }
  60. }
  61. Thread.Sleep(100);
  62. }), $"{typeof(AlarmT).Name},报警通用模块监听");
  63. }
  64. /// <summary>
  65. /// 沿报警检测
  66. /// </summary>
  67. /// <param name="Trigger">触发变量</param>
  68. /// <param name="text">报警信息</param>
  69. /// <param name="edgeType">触发类型,上升沿 或 下降沿</param>
  70. private static void EdgeAlarm(bool Trigger, string text, int delay = 2, AlarmLevel alarmLevel = AlarmLevel.一般报警, AlarmTriggerType edgeType = AlarmTriggerType.Rising)
  71. {
  72. if (!flagbit.ContainsKey(text)) flagbit.TryAdd(text, false);
  73. if (!delays.ContainsKey(text)) delays.TryAdd(text, Delay.GetInstance(text));
  74. if (edgeType == AlarmTriggerType.Rising ? delays[text].Start(Trigger, delay) : delays[text].Start(!Trigger, delay))
  75. {
  76. if (edgeType == AlarmTriggerType.Rising ? !flagbit[text] : flagbit[text])
  77. {
  78. AddAlarm(Trigger, text, alarmLevel);
  79. flagbit[text] = edgeType == AlarmTriggerType.Rising ? true : false;
  80. }
  81. }
  82. else RemoveAlarm(text);
  83. if (edgeType == AlarmTriggerType.Rising ? flagbit[text] : !flagbit[text]) flagbit[text] = Trigger;
  84. }
  85. /// <summary>
  86. /// 添加报警信息
  87. /// </summary>
  88. /// <param name="AlarmInfo">报警信息</param>
  89. private static void AddAlarm(object value, string AlarmInfo, AlarmLevel alarmLevel)
  90. {
  91. Alarm tempAlarm = new Alarm()
  92. {
  93. NumId = Alarms.Count + 1,
  94. Date = DateTime.Now.ToString("yyyy/MM/dd"),
  95. Grade = alarmLevel.ToString(),
  96. Info = AlarmInfo,
  97. Value = value.ToString(),
  98. Time = DateTime.Now.ToString("HH:mm:ss"),
  99. };
  100. var res = Sqlite<Alarm>.GetInstance.Base.Add(tempAlarm);
  101. Sqlite<Alarm>.GetInstance.Save();
  102. if (Alarms.FirstOrDefault(p => p.Info == AlarmInfo) == null)
  103. {
  104. Alarms.Insert(0, tempAlarm);
  105. for (int i = 0; i < Alarms.Count; i++) { Alarms.ElementAt(i).NumId = i + 1; }
  106. AddAction?.Invoke(AlarmInfo);//添加报警通知
  107. ChangeAction?.Invoke();//更改报警通知
  108. }
  109. }
  110. /// <summary>
  111. /// 移除报警信息
  112. /// </summary>
  113. /// <param name="AlarmInfo">报警信息</param>
  114. private static void RemoveAlarm(string AlarmInfo)
  115. {
  116. var result = Alarms.FirstOrDefault(p => p.Info == AlarmInfo);
  117. if (result != null)
  118. {
  119. Alarms.Remove(result);
  120. for (int i = 0; i < Alarms.Count; i++) { Alarms.ElementAt(i).NumId = i + 1; }
  121. if (RemoveAction != null) RemoveAction(AlarmInfo);
  122. if (ChangeAction != null) ChangeAction();
  123. }
  124. }
  125. }
  126. //public class AlarmHelper<AlarmT> where AlarmT : class, new()
  127. //{
  128. // //private volatile static ConcurrentDictionary<string, AlarmT> _Instance;
  129. // //public static AlarmT GetInstance(string name)
  130. // //{
  131. // // if (_Instance == null) _Instance = new ConcurrentDictionary<string, AlarmT>();
  132. // // if (!_Instance.ContainsKey(name)) _Instance.TryAdd(name, new AlarmT());
  133. // // return _Instance[name];
  134. // //}
  135. // //private AlarmHelper() { }
  136. // public static ObservableCollection<Alarm> Alarms { get; set; } = new ObservableCollection<Alarm>();
  137. // public static List<Alarm> HistoryAlarms { get; set; } = new List<Alarm>();
  138. // static ConcurrentDictionary<string, bool> flagbit = new ConcurrentDictionary<string, bool>();
  139. // static ConcurrentDictionary<string, Delay> delays = new ConcurrentDictionary<string, Delay>();
  140. // public static Action<string> AddAction { get; set; }
  141. // public static Action<string> RemoveAction { get; set; }
  142. // public static Action ChangeAction { get; set; }
  143. // public static AlarmT Alarm { get; set; } = new AlarmT();
  144. // public static void Init()
  145. // {
  146. // AlarmViewModel.AlarmInfos = Alarms;
  147. // ThreadManage.GetInstance().StartLong(new Action(() =>
  148. // {
  149. // foreach (var item in Alarm.GetType().GetProperties())
  150. // {
  151. // if (item.CustomAttributes.Count() > 0)
  152. // {
  153. // var AlarmModel = item.GetCustomAttribute<AlarmAttribute>();
  154. // if (AlarmModel != null)
  155. // {
  156. // bool value = Convert.ToBoolean(Alarm.GetType().GetProperty(item.Name)?.GetValue(Alarm));
  157. // EdgeAlarm(value, AlarmModel.AlarmInfo, 1, AlarmModel.AlarmLevel, AlarmModel.AlarmType);
  158. // }
  159. // }
  160. // }
  161. // Thread.Sleep(100);
  162. // }), $"{typeof(AlarmT).Name},报警通用模块监听");
  163. // }
  164. // //public static void AnalogAlarm(dynamic Trigger, string info, dynamic HH = null, dynamic H = 0, dynamic L = 0, dynamic LL = 0)
  165. // //{
  166. // //}
  167. // /// <summary>
  168. // /// 沿报警检测
  169. // /// </summary>
  170. // /// <param name="Trigger">触发变量</param>
  171. // /// <param name="text">报警信息</param>
  172. // /// <param name="edgeType">触发类型,上升沿 或 下降沿</param>
  173. // private static void EdgeAlarm(bool Trigger, string text, int delay = 2, AlarmLevel alarmLevel = AlarmLevel.一般报警, AlarmTriggerType edgeType = AlarmTriggerType.Rising)
  174. // {
  175. // if (!flagbit.ContainsKey(text)) flagbit.TryAdd(text, false);
  176. // if (!delays.ContainsKey(text)) delays.TryAdd(text, Delay.GetInstance(text));
  177. // if (edgeType == AlarmTriggerType.Rising ? delays[text].Start(Trigger, delay) : delays[text].Start(!Trigger, delay))
  178. // {
  179. // if (edgeType == AlarmTriggerType.Rising ? !flagbit[text] : flagbit[text])
  180. // {
  181. // AddAlarm(Trigger, text, alarmLevel);
  182. // flagbit[text] = edgeType == AlarmTriggerType.Rising ? true : false;
  183. // }
  184. // }
  185. // else RemoveAlarm(text);
  186. // if (edgeType == AlarmTriggerType.Rising ? flagbit[text] : !flagbit[text]) flagbit[text] = Trigger;
  187. // }
  188. // /// <summary>
  189. // /// 添加报警信息
  190. // /// </summary>
  191. // /// <param name="AlarmInfo">报警信息</param>
  192. // private static void AddAlarm(object value, string AlarmInfo, AlarmLevel alarmLevel)
  193. // {
  194. // Alarm tempAlarm = new Alarm()
  195. // {
  196. // NumId = Alarms.Count + 1,
  197. // Date = DateTime.Now.ToString("yyyy/MM/dd"),
  198. // Grade = alarmLevel.ToString(),
  199. // Info = AlarmInfo,
  200. // Value = value.ToString(),
  201. // Time = DateTime.Now.ToString("HH:mm:ss"),
  202. // };
  203. // var res = Sqlite<Alarm>.GetInstance.Base.Add(tempAlarm);
  204. // Sqlite<Alarm>.GetInstance.Save();
  205. // if (Alarms.FirstOrDefault(p => p.Info == AlarmInfo) == null)
  206. // {
  207. // Application.Current.Dispatcher.Invoke(new Action(() =>
  208. // {
  209. // Alarms.Insert(0, tempAlarm);
  210. // for (int i = 0; i < Alarms.Count; i++) { Alarms.ElementAt(i).NumId = i + 1; }
  211. // }));
  212. // AddAction?.Invoke(AlarmInfo);//添加报警通知
  213. // ChangeAction?.Invoke();//更改报警通知
  214. // }
  215. // }
  216. // /// <summary>
  217. // /// 移除报警信息
  218. // /// </summary>
  219. // /// <param name="AlarmInfo">报警信息</param>
  220. // private static void RemoveAlarm(string AlarmInfo)
  221. // {
  222. // var result = Alarms.FirstOrDefault(p => p.Info == AlarmInfo);
  223. // if (result != null)
  224. // {
  225. // Application.Current.Dispatcher.Invoke(new Action(() =>
  226. // {
  227. // Alarms.Remove(result);
  228. // for (int i = 0; i < Alarms.Count; i++) { Alarms.ElementAt(i).NumId = i + 1; }
  229. // }));
  230. // if (RemoveAction != null) RemoveAction(AlarmInfo);
  231. // if (ChangeAction != null) ChangeAction();
  232. // }
  233. // }
  234. //}
  235. }