IoLoopPump.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. namespace Aitex.Core.RT.Device.Unit
  12. {
  13. public class IoLoopPump : BaseDevice, IDevice
  14. {
  15. public int SetPoint
  16. {
  17. get
  18. {
  19. //if (_doOpen.Value && _doClose.Value) return (int) CylinderState.Error;
  20. if (_doOpen.Value ) return (int) CylinderState.Open;
  21. if (!_doOpen.Value ) return (int) CylinderState.Close;
  22. //if (!_doOpen.Value && !_doClose.Value) return (int) CylinderState.Unknown;
  23. return (int) CylinderState.Unknown;
  24. }
  25. }
  26. public CylinderState State
  27. {
  28. get
  29. {
  30. if (_diOpened.Value && _diClosed.Value)
  31. return CylinderState.Error;
  32. if (_diOpened.Value && !_diClosed.Value)
  33. return CylinderState.Open;
  34. if (!_diOpened.Value && _diClosed.Value)
  35. return CylinderState.Close;
  36. if (!_diOpened.Value && !_diClosed.Value)
  37. return CylinderState.Unknown;
  38. return CylinderState.Unknown;
  39. }
  40. }
  41. private AITCylinderData DeviceData
  42. {
  43. get
  44. {
  45. AITCylinderData deviceData = new AITCylinderData
  46. {
  47. Module = Module,
  48. DeviceName = Name,
  49. DeviceSchematicId = DeviceID,
  50. DisplayName = Display,
  51. OpenFeedback = _diOpened.Value,
  52. CloseFeedback = _diClosed.Value,
  53. OpenSetPoint = _doOpen.Value,
  54. IsLoop = _cmdLoop,
  55. };
  56. return deviceData;
  57. }
  58. }
  59. //public int Status
  60. //{
  61. // get
  62. // {
  63. // if (_diOpened.Value && _diClosed.Value)
  64. // return (int)CylinderState.Error;
  65. // if (_diOpened.Value && !_diClosed.Value)
  66. // return (int)CylinderState.Open;
  67. // if (!_diOpened.Value && _diClosed.Value)
  68. // return (int)CylinderState.Close;
  69. // if (!_diOpened.Value && !_diClosed.Value)
  70. // return (int)CylinderState.Unknown;
  71. // return (int)CylinderState.Unknown;
  72. // }
  73. //}
  74. //private DIAccessor _diLeak;
  75. private DIAccessor _diOpened;
  76. private DIAccessor _diClosed;
  77. private DOAccessor _doOpen;
  78. private bool _cmdLoop;
  79. private DeviceTimer _loopTimer = new DeviceTimer();
  80. private DeviceTimer _loopTimeout = new DeviceTimer();
  81. private R_TRIG _trigReset = new R_TRIG();
  82. private R_TRIG _trigOpenError = new R_TRIG();
  83. private R_TRIG _trigCloseError = new R_TRIG();
  84. private SCConfigItem _scLoopInterval;
  85. private SCConfigItem _scLoopTimeout;
  86. private R_TRIG _trigSetPointDone = new R_TRIG();
  87. private int _interval;
  88. public IoLoopPump(string module, XmlElement node, string ioModule = "")
  89. {
  90. base.Module = node.GetAttribute("module");
  91. base.Name = node.GetAttribute("id");
  92. base.Display = node.GetAttribute("display");
  93. base.DeviceID = node.GetAttribute("schematicId");
  94. _diOpened = ParseDiNode("diOpen", node, ioModule);
  95. _diClosed = ParseDiNode("diClose", node, ioModule);
  96. _doOpen = ParseDoNode("doOpen", node, ioModule);
  97. _scLoopInterval = SC.GetConfigItem($"Modules.{Module}.{Name}.PumpLoopInterval");
  98. _scLoopTimeout = SC.GetConfigItem($"Modules.{Module}.{Name}.PumpLoopTimeout");
  99. }
  100. public bool Initialize()
  101. {
  102. DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
  103. OP.Subscribe($"{Module}.{Name}.{AITCylinderOperation.Open}", InvokeOpenCylinder);
  104. OP.Subscribe($"{Module}.{Name}.{AITCylinderOperation.Close}", InvokeCloseCylinder);
  105. DEVICE.Register($"{Name}.{AITCylinderOperation.Open}", (out string reason, int time, object[] param) =>
  106. {
  107. bool ret = SetCylinder(true, out reason);
  108. if (ret)
  109. {
  110. reason = string.Format("Open Cylinder {0}", Name);
  111. return true;
  112. }
  113. return false;
  114. });
  115. DEVICE.Register($"{Name}.{AITCylinderOperation.Close}", (out string reason, int time, object[] param) =>
  116. {
  117. bool ret = SetCylinder(false, out reason);
  118. if (ret)
  119. {
  120. reason = string.Format("Close {0}", Name);
  121. return true;
  122. }
  123. return false;
  124. });
  125. return true;
  126. }
  127. private bool InvokeOpenCylinder(string arg1, object[] arg2)
  128. {
  129. string reason;
  130. if (!SetCylinder(true, out reason))
  131. {
  132. EV.PostWarningLog(Module, $"Can not open {Module}.{Name}, {reason}");
  133. return false;
  134. }
  135. EV.PostInfoLog(Module, $"Open {Module}.{Name}");
  136. return true;
  137. }
  138. private bool InvokeCloseCylinder(string arg1, object[] arg2)
  139. {
  140. string reason;
  141. if (!SetCylinder(false, out reason))
  142. {
  143. EV.PostWarningLog(Module, $"Can not close {Module}.{Name}, {reason}");
  144. return false;
  145. }
  146. EV.PostInfoLog(Module, $"Close {Module}.{Name}");
  147. return true;
  148. }
  149. public void Terminate()
  150. {
  151. _doOpen.Value = false;
  152. }
  153. public bool SetCylinder(bool isOpen, out string reason)
  154. {
  155. _cmdLoop = isOpen;
  156. _doOpen.Value = isOpen;
  157. _loopTimer.Start(_scLoopInterval.IntValue);
  158. _loopTimeout.Start(_scLoopTimeout.IntValue * 1000);
  159. _interval = _scLoopInterval.IntValue;
  160. if (_interval < 300)
  161. _interval = 300;
  162. reason = "";
  163. return true;
  164. }
  165. public void Monitor()
  166. {
  167. if (_cmdLoop)
  168. {
  169. if (_loopTimer.IsTimeout() && ((_doOpen.Value && State == CylinderState.Open)
  170. || (!_doOpen.Value && State == CylinderState.Close)))
  171. {
  172. _loopTimer.Start(_interval);
  173. _doOpen.Value = !_doOpen.Value;
  174. _loopTimeout.Start(_scLoopTimeout.IntValue * 1000);
  175. }
  176. _trigOpenError.CLK = _doOpen.Value && State != CylinderState.Open && _loopTimeout.IsTimeout();
  177. if (_trigOpenError.Q)
  178. {
  179. EV.PostWarningLog(Module, $"{Module}.{Name}, can not open in {_scLoopTimeout.IntValue} seconds");
  180. }
  181. _trigCloseError.CLK = !_doOpen.Value && State != CylinderState.Close && _loopTimeout.IsTimeout();
  182. if (_trigCloseError.Q)
  183. {
  184. EV.PostWarningLog(Module, $"{Module}.{Name}, can not close in {_scLoopTimeout.IntValue} seconds");
  185. }
  186. }
  187. else
  188. {
  189. _doOpen.Value = false;
  190. }
  191. }
  192. public void Reset()
  193. {
  194. _trigReset.RST = true;
  195. _trigOpenError.RST = true;
  196. _trigCloseError.RST = true;
  197. }
  198. }
  199. }