IoDoor.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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.SCCore;
  9. using Aitex.Core.Util;
  10. namespace Aitex.Core.RT.Device.Unit
  11. {
  12. public enum DoorStateEnum
  13. {
  14. Unknown,
  15. Up,
  16. Down,
  17. Error,
  18. }
  19. public class IoDoor : BaseDevice, IDevice
  20. {
  21. public DoorStateEnum State
  22. {
  23. get
  24. {
  25. if (_diOpen.Value && _diClose.Value)
  26. return DoorStateEnum.Error;
  27. if (_diOpen.Value && !_diClose.Value)
  28. return DoorStateEnum.Up;
  29. if (!_diOpen.Value && _diClose.Value)
  30. return DoorStateEnum.Down;
  31. return DoorStateEnum.Unknown;
  32. }
  33. }
  34. enum DeviceState
  35. {
  36. Idle,
  37. Opening,
  38. Closing,
  39. Error,
  40. }
  41. private DIAccessor _diOpen;
  42. private DIAccessor _diClose;
  43. private DIAccessor _diOpenEnable;
  44. private DIAccessor _diCloseEnable;
  45. private DOAccessor _doOpen;
  46. private DOAccessor _doClose;
  47. private DeviceState _state = DeviceState.Idle;
  48. private DeviceTimer _timer = new DeviceTimer();
  49. private SCConfigItem _scTimeout;
  50. public bool IsOpen { get { return !_diClose.Value && _diOpen.Value; } }
  51. public bool IsClose { get { return _diClose.Value && !_diOpen.Value; } }
  52. //在开&关完成之后,是否保持输出,默认不保持
  53. private bool _keepSignalOut = false;
  54. public IoDoor(string module, XmlElement node, string ioModule = "")
  55. {
  56. base.Module = string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module");
  57. base.Name = node.GetAttribute("id");
  58. base.Display = node.GetAttribute("display");
  59. base.DeviceID = node.GetAttribute("schematicId");
  60. _diOpen = ParseDiNode("diOpen", node, ioModule);
  61. _diClose = ParseDiNode("diClose", node, ioModule);
  62. _diOpenEnable = ParseDiNode("diOpenEnable", node, ioModule);
  63. _diCloseEnable = ParseDiNode("diCloseEnable", node, ioModule);
  64. _doOpen = ParseDoNode("doOpen", node, ioModule);
  65. _doClose = ParseDoNode("doClose", node, ioModule);
  66. _keepSignalOut = string.IsNullOrEmpty(node.GetAttribute("keepSignalOut")) ? false : Convert.ToBoolean(node.GetAttribute("keepSignalOut"));
  67. _scTimeout = ParseScNode("scTimeout", node);
  68. }
  69. public bool Initialize()
  70. {
  71. _state = DeviceState.Idle;
  72. DATA.Subscribe($"{Module}.{Name}.OpenFeedback", ()=>_diOpen.Value);
  73. DATA.Subscribe($"{Module}.{Name}.OpenEnable", () => _diOpenEnable==null || _diOpenEnable.Value);
  74. DATA.Subscribe($"{Module}.{Name}.OpenSetpoint", () => _doOpen.Value);
  75. DATA.Subscribe($"{Module}.{Name}.CloseFeedback", () => _diClose.Value);
  76. DATA.Subscribe($"{Module}.{Name}.CloseEnable", () => _diCloseEnable==null || _diCloseEnable.Value);
  77. DATA.Subscribe($"{Module}.{Name}.CloseSetpoint", () => _doClose.Value);
  78. DEVICE.Register($"{Module}.{Name}.Open", (out string reason, int time, object[] param) =>
  79. {
  80. reason = "";
  81. return Open(out reason);
  82. });
  83. DEVICE.Register($"{Module}.{Name}.Close", (out string reason, int time, object[] param) =>
  84. {
  85. reason = "";
  86. return Close(out reason);
  87. });
  88. return true;
  89. }
  90. public void Monitor()
  91. {
  92. switch (_state)
  93. {
  94. case DeviceState.Opening:
  95. if (IsOpen)
  96. {
  97. if (!_keepSignalOut)
  98. {
  99. if (!_doOpen.SetValue(false, out string reason))
  100. {
  101. LOG.Error($"{Module} reset DO failed, {reason}");
  102. }
  103. }
  104. _state = DeviceState.Idle;
  105. }
  106. else if (_timer.IsTimeout())
  107. {
  108. if (!_doOpen.SetValue(false, out string reason))
  109. {
  110. LOG.Error($"{Module} reset DO failed, {reason}");
  111. }
  112. if (_keepSignalOut)
  113. {
  114. _doClose.SetValue(true, out _);
  115. }
  116. EV.PostAlarmLog(Module, $"{Module} {Name} Can not open in {_scTimeout.IntValue} seconds");
  117. _state = DeviceState.Error;
  118. }
  119. break;
  120. case DeviceState.Closing:
  121. if (IsClose)
  122. {
  123. if (!_keepSignalOut)
  124. {
  125. if (!_doClose.SetValue(false, out string reason))
  126. {
  127. LOG.Error($"{Module} reset DO failed, {reason}");
  128. }
  129. }
  130. _state = DeviceState.Idle;
  131. }
  132. else if (_timer.IsTimeout())
  133. {
  134. if (!_doClose.SetValue(false, out string reason))
  135. {
  136. LOG.Error($"{Module} reset DO failed, {reason}");
  137. }
  138. if (_keepSignalOut)
  139. {
  140. _doOpen.SetValue(true, out _);
  141. }
  142. EV.PostAlarmLog(Module, $"{Module} {Name} Can not close in {_scTimeout.IntValue} seconds");
  143. _state = DeviceState.Error;
  144. }
  145. break;
  146. default:
  147. break;
  148. }
  149. }
  150. public void Terminate()
  151. {
  152. if (!_keepSignalOut)
  153. {
  154. _doOpen.SetValue(false, out _);
  155. _doClose.SetValue(false, out _);
  156. }
  157. }
  158. public bool SetDoor(bool open, out string reason)
  159. {
  160. if (open)
  161. return Open(out reason);
  162. return Close(out reason);
  163. }
  164. public bool CheckInterlockEnable(bool open)
  165. {
  166. return open ? (_diOpenEnable == null || _diOpenEnable.Value) : (_diCloseEnable==null || _diCloseEnable.Value);
  167. }
  168. public bool Open(out string reason)
  169. {
  170. if (_diOpenEnable!=null && !_diOpenEnable.Value)
  171. {
  172. reason = "interlock blocked open";
  173. return false;
  174. }
  175. if (!_doClose.SetValue(false, out reason) || !_doOpen.SetValue(true, out reason))
  176. {
  177. _doOpen.SetValue(false, out _);
  178. if (_keepSignalOut)
  179. {
  180. _doClose.SetValue(true, out _);
  181. }
  182. else
  183. {
  184. _doClose.SetValue(false, out _);
  185. }
  186. return false;
  187. }
  188. _timer.Start(_scTimeout.IntValue * 1000);
  189. _state = DeviceState.Opening;
  190. return true;
  191. }
  192. public bool Close(out string reason)
  193. {
  194. if (_diCloseEnable!=null && !_diCloseEnable.Value)
  195. {
  196. reason = "interlock blocked close";
  197. return false;
  198. }
  199. if (!_doClose.SetValue(true, out reason) || !_doOpen.SetValue(false, out reason))
  200. {
  201. _doClose.SetValue(false, out _);
  202. if (_keepSignalOut)
  203. {
  204. _doOpen.SetValue(true, out _);
  205. }
  206. else
  207. {
  208. _doOpen.SetValue(false, out _);
  209. }
  210. return false;
  211. }
  212. _timer.Start(_scTimeout.IntValue * 1000);
  213. _state = DeviceState.Closing;
  214. return true;
  215. }
  216. public void Reset()
  217. {
  218. }
  219. }
  220. }