IoSlitValve.cs 9.1 KB

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