IoGasValve.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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.Util;
  10. using DocumentFormat.OpenXml.Wordprocessing;
  11. namespace Aitex.Core.RT.Device.Unit
  12. {
  13. public class IoValve : BaseDevice, IDevice
  14. {
  15. public string GVName { get { return Name; } }
  16. public string GVDeviceID { get { return DeviceID; } }
  17. public bool GVIsDefaultOpen { get { return _isDefaultOpen; } }
  18. [Subscription(AITValveDataPropertyName.SetPoint)]
  19. public bool SetPoint //True:open| False:close
  20. {
  21. get
  22. {
  23. return _isNc ? _doOpen.Value : !_doOpen.Value;
  24. }
  25. set
  26. {
  27. if (_doOpen != null)
  28. {
  29. _doOpen.Value = _isNc ? value : !value;
  30. }
  31. if (_doClose != null)
  32. {
  33. _doClose.Value = _isNc ? !value : value;
  34. }
  35. }
  36. }
  37. [Subscription(AITValveDataPropertyName.Status)]
  38. public bool Status //True:open | False:close
  39. {
  40. get
  41. {
  42. if (_diOpen != null)
  43. return _isNc ? _diOpen.Value : !_diOpen.Value;
  44. if (_doOpen != null)
  45. return _isNc ? _doOpen.Value : !_doOpen.Value;
  46. if (_doClose != null)
  47. return _isNc ? !_doClose.Value : _doClose.Value;
  48. return false;
  49. }
  50. }
  51. private AITValveData DeviceData
  52. {
  53. get
  54. {
  55. AITValveData data = new AITValveData()
  56. {
  57. UniqueName = _uniqueName,
  58. DeviceName = GVName,
  59. DefaultValue = GVIsDefaultOpen,
  60. DeviceSchematicId = DeviceID,
  61. DisplayName = Display,
  62. Feedback = Status,
  63. SetPoint = SetPoint,
  64. };
  65. return data;
  66. }
  67. }
  68. /// <summary>
  69. /// normal closed, 0 关闭,1打开
  70. /// </summary>
  71. public bool _isNc;
  72. /// <summary>
  73. /// default open
  74. /// </summary>
  75. public bool _isDefaultOpen;
  76. private DIAccessor _diOpenSensor;
  77. private DIAccessor _diCloseSensor;
  78. private DIAccessor _diOpen;
  79. private DOAccessor _doOpen;
  80. private DOAccessor _doClose;
  81. private bool _operation;
  82. private R_TRIG eventTrigger = new R_TRIG();
  83. private DeviceTimer _timer = new DeviceTimer();
  84. private string _uniqueName;
  85. private object _lockerOperation = new object();
  86. public IoValve(string module, XmlElement node, string ioModule = "")
  87. {
  88. var attrModule = node.GetAttribute("module");
  89. base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
  90. base.Name = node.GetAttribute("id");
  91. base.Display = node.GetAttribute("display");
  92. base.DeviceID = node.GetAttribute("schematicId");
  93. _isNc = Convert.ToBoolean(node.GetAttribute("isNc"));
  94. _isDefaultOpen = Convert.ToBoolean(node.GetAttribute("isDefaultOpen"));
  95. _diOpenSensor = ParseDiNode("diOpenSensor", node, ioModule);
  96. _diCloseSensor = ParseDiNode("diCloseSensor", node, ioModule);
  97. _doOpen = ParseDoNode("doOpen", node, ioModule);
  98. _diOpen = ParseDiNode("diOpen", node, ioModule);
  99. _doClose = ParseDoNode("doClose", node, ioModule);
  100. _uniqueName = $"{Module}.{Name}";
  101. }
  102. public bool Initialize()
  103. {
  104. DATA.Subscribe($"{Module}.{GVName}", () => DeviceData);
  105. DATA.Subscribe($"{Module}.{GVName}.IsOpen", () => Status);
  106. //DATA.Subscribe($"{_uniqueName}.DeviceData", () => DeviceData);
  107. OP.Subscribe($"{_uniqueName}.{AITValveOperation.GVTurnValve}", InvokeOpenCloseValve);
  108. DEVICE.Register($"{Module}.{Name}.{AITValveOperation.GVTurnValve}", (out string reason, int time, object[] param) =>
  109. {
  110. bool bOn = Convert.ToBoolean((string)param[0]);
  111. bool ret = TurnValve(bOn, out reason);
  112. if (ret)
  113. {
  114. reason = string.Format("Valve {0}{1}", Name, bOn ? "Open" : "Close");
  115. return true;
  116. }
  117. return false;
  118. });
  119. //for recipe
  120. DEVICE.Register($"{Module}.{Name}", (out string reason, int time, object[] param) =>
  121. {
  122. bool bOn = Convert.ToBoolean((string)param[0]);
  123. bool ret = TurnValve(bOn, out reason);
  124. if (ret)
  125. {
  126. reason = string.Format("Valve {0}{1}", Name, bOn ? "Open" : "Close");
  127. return true;
  128. }
  129. return false;
  130. });
  131. return true;
  132. }
  133. public void Terminate()
  134. {
  135. TurnValve(_isDefaultOpen, out string reason);
  136. }
  137. private bool InvokeOpenCloseValve(string method, object[] args)
  138. {
  139. bool op = (bool)args[0];
  140. string name = op ? "Open" : "Close";
  141. if (!TurnValve(op, out string reason))
  142. {
  143. LOG.Write(eEvent.WARN_IO_VALVE, Module, $"Can not {name} valve {Module}.{Name}, {reason}");
  144. return false;
  145. }
  146. LOG.Write(eEvent.INFO_IO_VALVE, Module, $"{name} valve {Module}.{Name}");
  147. return true;
  148. }
  149. public void Monitor()
  150. {
  151. try
  152. {
  153. lock (_lockerOperation)
  154. {
  155. if (_timer.IsTimeout())
  156. {
  157. _timer.Stop();
  158. if (Status != _operation)
  159. {
  160. if (_operation)
  161. {
  162. LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
  163. $"{Display} open: valve keep closed" :
  164. $"{Display} Fail to open due to interlock {reason}");
  165. }
  166. else
  167. {
  168. LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
  169. $"{Display} Close : Valve keep open" :
  170. $"{Display} Close : Failed for interlock {reason}");
  171. }
  172. }
  173. _operation = SetPoint;
  174. }
  175. else if (_timer.IsIdle())
  176. {
  177. eventTrigger.CLK = SetPoint != _operation; // fire event only check at first, SetPoint set by interlock
  178. if (eventTrigger.Q)
  179. {
  180. if (_operation)
  181. {
  182. LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
  183. $"Valve {Display} was Close,Reason PLC kept" :
  184. $"Valve {Display} was Close,Reason {reason}");
  185. }
  186. else
  187. {
  188. LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
  189. $"Valve {Display} was Open,Reason PLC Kept" :
  190. $"Valve {Display} was Open,Reason:{reason}");
  191. }
  192. _operation = SetPoint;
  193. }
  194. }
  195. }
  196. }
  197. catch (Exception ex)
  198. {
  199. LOG.WriteExeption(ex);
  200. }
  201. }
  202. public bool TurnValve(bool bOperation, out string reason)
  203. {
  204. lock (_lockerOperation)
  205. {
  206. bool bValue = _isNc ? bOperation : !bOperation;
  207. reason = "";
  208. SetPoint = bValue;
  209. if (Name == "ValveN2")
  210. {
  211. reason = Name;
  212. }
  213. _operation = bOperation;
  214. _timer.Start(2000); //2 seconds to monitor
  215. }
  216. return true;
  217. }
  218. public void Reset()
  219. {
  220. eventTrigger.RST = true;
  221. }
  222. }
  223. }