IoSlitValve.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. public IoSlitValve(string module, XmlElement node, string ioModule = "")
  57. {
  58. base.Module = string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module");
  59. base.Name = node.GetAttribute("id");
  60. base.Display = node.GetAttribute("display");
  61. base.DeviceID = node.GetAttribute("schematicId");
  62. _keepSignalOut = string.IsNullOrEmpty(node.GetAttribute("keepSignalOut")) ? false : Convert.ToBoolean(node.GetAttribute("keepSignalOut"));
  63. _diOpen = ParseDiNode("diOpen", node, ioModule);
  64. _diClose = ParseDiNode("diClose", node, ioModule);
  65. _diOpenEnable = ParseDiNode("diOpenEnable", node, ioModule);
  66. _diCloseEnable = ParseDiNode("diCloseEnable", node, ioModule);
  67. _doOpen = ParseDoNode("doOpen", node, ioModule);
  68. _doClose = ParseDoNode("doClose", node, ioModule);
  69. _scTimeout = ParseScNode("scTimeout", node, ioModule);
  70. }
  71. public bool Initialize()
  72. {
  73. _state = DeviceState.Idle;
  74. DATA.Subscribe($"{Module}.{Name}.OpenFeedback", () => _diOpen.Value);
  75. DATA.Subscribe($"{Module}.{Name}.OpenEnable", () => _diOpenEnable.Value);
  76. DATA.Subscribe($"{Module}.{Name}.CloseEnable", () => _diCloseEnable.Value);
  77. DATA.Subscribe($"{Module}.{Name}.CloseFeedback", () => _diClose.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. EV.PostAlarmLog(Module, $"{Module} {Name} Can not open in {_scTimeout.IntValue} seconds");
  113. _state = DeviceState.Error;
  114. }
  115. break;
  116. case DeviceState.Closing:
  117. if (IsClose)
  118. {
  119. if (!_keepSignalOut)
  120. {
  121. if (!_doClose.SetValue(false, out string reason))
  122. {
  123. LOG.Error($"{Module} reset DO failed, {reason}");
  124. }
  125. }
  126. _state = DeviceState.Idle;
  127. }
  128. else if (_timer.IsTimeout())
  129. {
  130. if (!_doClose.SetValue(false, out string reason))
  131. {
  132. LOG.Error($"{Module} reset DO failed, {reason}");
  133. }
  134. EV.PostAlarmLog(Module, $"{Module} {Name} Can not close in {_scTimeout.IntValue} seconds");
  135. _state = DeviceState.Error;
  136. }
  137. break;
  138. default:
  139. break;
  140. }
  141. }
  142. public void Terminate()
  143. {
  144. if (!_keepSignalOut)
  145. {
  146. _doOpen.SetValue(false, out _);
  147. _doClose.SetValue(false, out _);
  148. }
  149. }
  150. public bool SetSlitValve(bool open, out string reason)
  151. {
  152. if (open)
  153. return Open(out reason);
  154. return Close(out reason);
  155. }
  156. public bool Open(out string reason)
  157. {
  158. if (!_diOpenEnable.Value)
  159. {
  160. reason = "interlock blocked open";
  161. return false;
  162. }
  163. if (!_doClose.SetValue(false, out reason) || !_doOpen.SetValue(true, out reason))
  164. {
  165. _doClose.SetValue(false, out _);
  166. _doOpen.SetValue(false, out _);
  167. return false;
  168. }
  169. _timer.Start(_scTimeout.IntValue * 1000);
  170. _state = DeviceState.Opening;
  171. return true;
  172. }
  173. public bool Close(out string reason)
  174. {
  175. if (!_diCloseEnable.Value)
  176. {
  177. reason = "interlock blocked close";
  178. return false;
  179. }
  180. if (!_doClose.SetValue(true, out reason) || !_doOpen.SetValue(false, out reason))
  181. {
  182. _doClose.SetValue(false, out _);
  183. _doOpen.SetValue(false, out _);
  184. return false;
  185. }
  186. _timer.Start(_scTimeout.IntValue * 1000);
  187. _state = DeviceState.Closing;
  188. return true;
  189. }
  190. public void Reset()
  191. {
  192. }
  193. }
  194. }