IoDoor2.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. using System;
  2. using System.Xml;
  3. using Aitex.Core.Common.DeviceData;
  4. using Aitex.Core.RT.DataCenter;
  5. using Aitex.Core.RT.Event;
  6. using Aitex.Core.RT.IOCore;
  7. using Aitex.Core.RT.Log;
  8. using Aitex.Core.RT.OperationCenter;
  9. using Aitex.Core.RT.SCCore;
  10. using Aitex.Core.Util;
  11. using MECF.Framework.Common.Event;
  12. namespace Aitex.Core.RT.Device.Unit
  13. {
  14. /// <summary>
  15. /// 支持Alarm机制
  16. ///
  17. /// DI open
  18. /// DI close
  19. ///
  20. /// DO open
  21. /// DO close
  22. ///
  23. /// </summary>
  24. public class IoDoor2 : BaseDevice, IDevice
  25. {
  26. public LidState State
  27. {
  28. get
  29. {
  30. if (_diOpen.Value && _diClose.Value)
  31. return LidState.Error;
  32. if (_diOpen.Value && !_diClose.Value)
  33. return LidState.Open;
  34. if (!_diOpen.Value && _diClose.Value)
  35. return LidState.Close;
  36. return LidState.Unknown;
  37. }
  38. }
  39. enum DeviceState
  40. {
  41. Idle,
  42. Opening,
  43. Closing,
  44. Error,
  45. }
  46. private DIAccessor _diOpen;
  47. private DIAccessor _diClose;
  48. private DOAccessor _doClose;
  49. private DOAccessor _doOpen;
  50. private DeviceState _state = DeviceState.Idle;
  51. private DeviceTimer _timer = new DeviceTimer();
  52. private object _lockerState = new object();
  53. private SCConfigItem _scTimeout;
  54. public bool IsOpen { get { return !_diClose.Value && _diOpen.Value; } }
  55. public bool IsClose { get { return _diClose.Value && !_diOpen.Value; } }
  56. public bool OpenFeedback
  57. {
  58. get { return _diOpen.Value; }
  59. }
  60. public bool CloseFeedback
  61. {
  62. get { return _diClose.Value; }
  63. }
  64. public AlarmEventItem AlarmMoveTimeout { get; set; }
  65. public AlarmEventItem AlarmSignalAbnormal { get; set; }
  66. public IoDoor2(string module, XmlElement node, string ioModule = "")
  67. {
  68. var attrModule = node.GetAttribute("module");
  69. base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
  70. base.Name = node.GetAttribute("id");
  71. base.Display = node.GetAttribute("display");
  72. base.DeviceID = node.GetAttribute("schematicId");
  73. string scBasePath = node.GetAttribute("scBasePath");
  74. if (string.IsNullOrEmpty(scBasePath))
  75. scBasePath = $"{Module}.{Name}";
  76. else
  77. {
  78. scBasePath = scBasePath.Replace("{module}", Module);
  79. }
  80. _diOpen = ParseDiNode("diOpen", node, ioModule);
  81. _diClose = ParseDiNode("diClose", node, ioModule);
  82. _doClose = ParseDoNode("doClose", node, ioModule);
  83. _doOpen = ParseDoNode("doOpen", node, ioModule);
  84. _scTimeout = ParseScNode("scTimeout", node, ioModule, $"{scBasePath}.{Name}.MoveTimeout");
  85. }
  86. public bool Initialize()
  87. {
  88. _state = DeviceState.Idle;
  89. AlarmMoveTimeout = SubscribeAlarm($"{Module}.{Name}.MoveTimeout", "", null);
  90. AlarmSignalAbnormal = SubscribeAlarm($"{Module}.{Name}.SignalAbnormal", $"{Name} Open&Close signal trigger at same time", ResetCheckSignalAbnormal);
  91. DATA.Subscribe($"{Module}.{Name}.State", () => State.ToString());
  92. DATA.Subscribe($"{Module}.{Name}.OpenFeedback", ()=>_diOpen.Value);
  93. DATA.Subscribe($"{Module}.{Name}.CloseFeedback", () => _diClose.Value);
  94. OP.Subscribe($"{Module}.{Name}.Open", (out string reason, int time, object[] param) =>
  95. {
  96. reason = "";
  97. return Open(out reason);
  98. });
  99. OP.Subscribe($"{Module}.{Name}.Close", (out string reason, int time, object[] param) =>
  100. {
  101. reason = "";
  102. return Close(out reason);
  103. });
  104. return true;
  105. }
  106. public void Monitor()
  107. {
  108. lock (_lockerState)
  109. {
  110. switch (_state)
  111. {
  112. case DeviceState.Opening:
  113. if (IsOpen)
  114. {
  115. _state = DeviceState.Idle;
  116. }
  117. else if (_timer.IsTimeout())
  118. {
  119. if (!_doClose.SetValue(true, out string reason))
  120. {
  121. LOG.Error($"{Module} reset DO failed, {reason}");
  122. }
  123. AlarmMoveTimeout.Description = $"Can not open {Name} in {_scTimeout.IntValue} seconds";
  124. AlarmMoveTimeout.Set();
  125. _state = DeviceState.Error;
  126. }
  127. break;
  128. case DeviceState.Closing:
  129. if (IsClose)
  130. {
  131. _state = DeviceState.Idle;
  132. }
  133. else if (_timer.IsTimeout())
  134. {
  135. if (!_doClose.SetValue(false, out string reason))
  136. {
  137. LOG.Error($"{Module} reset DO failed, {reason}");
  138. }
  139. AlarmMoveTimeout.Description = $"Can not close {Name} in {_scTimeout.IntValue} seconds";
  140. AlarmMoveTimeout.Set();
  141. _state = DeviceState.Error;
  142. }
  143. break;
  144. default:
  145. break;
  146. }
  147. }
  148. if (_diOpen.Value && _diClose.Value)
  149. {
  150. AlarmSignalAbnormal.Set();
  151. }
  152. }
  153. public void Terminate()
  154. {
  155. }
  156. public bool SetDoor(bool open, out string reason)
  157. {
  158. if (open)
  159. return Open(out reason);
  160. return Close(out reason);
  161. }
  162. public bool Open(out string reason)
  163. {
  164. lock (_lockerState)
  165. {
  166. if (!_doClose.SetValue(false, out reason))
  167. {
  168. return false;
  169. }
  170. if (!_doOpen.SetValue(true, out reason))
  171. {
  172. return false;
  173. }
  174. _timer.Start(_scTimeout.IntValue * 1000);
  175. _state = DeviceState.Opening;
  176. }
  177. return true;
  178. }
  179. public bool Close(out string reason)
  180. {
  181. lock (_lockerState)
  182. {
  183. if (!_doClose.SetValue(true, out reason))
  184. {
  185. _doClose.SetValue(false, out _);
  186. return false;
  187. }
  188. if (!_doOpen.SetValue(false, out reason))
  189. {
  190. _doClose.SetValue(false, out _);
  191. _doOpen.SetValue(false, out _);
  192. return false;
  193. }
  194. _timer.Start(_scTimeout.IntValue * 1000);
  195. _state = DeviceState.Closing;
  196. }
  197. return true;
  198. }
  199. public bool ResetCheckSignalAbnormal()
  200. {
  201. return !(_diOpen.Value && _diClose.Value);
  202. }
  203. public void Reset()
  204. {
  205. AlarmMoveTimeout.Reset();
  206. AlarmSignalAbnormal.Reset();
  207. }
  208. }
  209. }