IoThrottleValve.cs 9.6 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.Device;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.IOCore;
  8. using Aitex.Core.RT.Log;
  9. using Aitex.Core.RT.OperationCenter;
  10. using Aitex.Core.RT.SCCore;
  11. using Aitex.Core.Util;
  12. namespace Aitex.Core.RT.Device.Unit
  13. {
  14. public class IoThrottleValve : BaseDevice, IDevice
  15. {
  16. public struct Context
  17. {
  18. public string tvName;
  19. public string aoPressureModeName;
  20. public string aoPressureSetPointName;
  21. public string aoPositionSetPointName;
  22. public string aiPressureFeedbackName;
  23. public string aiPositionFeedbackName;
  24. public string aiStateName;
  25. };
  26. public PressureCtrlMode PressureMode
  27. {
  28. get
  29. {
  30. if (_aoPressureMode == null)
  31. return PressureCtrlMode.TVPositionCtrl;
  32. return Math.Abs(_aoPressureMode.FloatValue - 2) < 0.1 ? PressureCtrlMode.TVPositionCtrl : PressureCtrlMode.TVPressureCtrl;
  33. }
  34. set
  35. {
  36. if (_aoPositionSetPoint == null || _aoPressureSetPoint == null || _aoPressureMode == null)
  37. return;
  38. short setpoint = (short)(value == PressureCtrlMode.TVPositionCtrl ? 2 : 1);
  39. if (Math.Abs(_aoPressureSetPoint.FloatValue - setpoint) > 0.01)
  40. {
  41. if (value == PressureCtrlMode.TVPositionCtrl)
  42. {
  43. _aoPositionSetPoint.FloatValue = PositionFeedback;
  44. }
  45. else
  46. {
  47. _aoPressureSetPoint.FloatValue = PressureFeedback;
  48. }
  49. _aoPressureMode.FloatValue = setpoint;
  50. }
  51. }
  52. }
  53. public int State => _aiState == null ? 1 : (int)_aiState.Value;
  54. [Subscription("ProcessPressureOffset")]
  55. public double ProcessPressureOffset
  56. {
  57. get
  58. {
  59. if (_scProcessPressureOffset != null)
  60. return _scProcessPressureOffset.DoubleValue;
  61. return 0;
  62. }
  63. }
  64. [Subscription(AITThrottleValvePropertyName.TVPositionSetPoint)]
  65. public float PositionSetpoint
  66. {
  67. get
  68. {
  69. if (_aoPositionSetPoint != null)
  70. {
  71. return _aoPositionSetPoint.FloatValue;
  72. }
  73. return 0;
  74. }
  75. set
  76. {
  77. if (_aoPositionSetPoint != null)
  78. {
  79. _aoPositionSetPoint.FloatValue=value;
  80. }
  81. }
  82. }
  83. [Subscription(AITThrottleValvePropertyName.TVPosition)]
  84. public float PositionFeedback //=> _aiPositionFeedback?.Value ?? 0;
  85. {
  86. get
  87. {
  88. if (_aiPositionFeedback != null)
  89. {
  90. return _aiPositionFeedback.FloatValue;
  91. }
  92. return 0;
  93. }
  94. }
  95. [Subscription(AITThrottleValvePropertyName.TVPressureSetPoint)]
  96. public float PressureSetpoint
  97. {
  98. get
  99. {
  100. if (_aoPressureSetPoint != null)
  101. {
  102. return _aoPressureSetPoint.FloatValue;
  103. }
  104. return 0;
  105. }
  106. set
  107. {
  108. if (_aoPressureSetPoint != null)
  109. {
  110. _aoPressureSetPoint.FloatValue = value;
  111. }
  112. }
  113. }
  114. [Subscription(AITThrottleValvePropertyName.TVPressure)]
  115. public float PressureFeedback //=> _aiPressureFeedback?.Value ?? 0;
  116. {
  117. get
  118. {
  119. if (_aiPressureFeedback != null)
  120. {
  121. return _aiPressureFeedback.FloatValue;
  122. }
  123. return 0;
  124. }
  125. }
  126. public bool IsIndependent { get; set; }
  127. public bool IsOffline => _diOffline != null && _diOffline.RawData;
  128. private readonly DIAccessor _diOffline;
  129. private readonly AIAccessor _aiPressureFeedback;
  130. private readonly AIAccessor _aiPositionFeedback;
  131. private readonly AOAccessor _aoPressureSetPoint;
  132. private readonly AOAccessor _aoPositionSetPoint;
  133. private readonly AOAccessor _aoPressureMode;
  134. private readonly AIAccessor _aiState;
  135. private SCConfigItem _scProcessPressureOffset;
  136. private readonly R_TRIG _tvStatusAlmTrig = new R_TRIG();
  137. private readonly R_TRIG _trigOffline = new R_TRIG();
  138. public IoThrottleValve(string module, XmlElement node, string ioModule = "")
  139. {
  140. base.Module = module;
  141. base.Name = node.GetAttribute("id");
  142. base.Display = node.GetAttribute("display");
  143. base.DeviceID = node.GetAttribute("schematicId");
  144. _aiPositionFeedback = ParseAiNode("aiPositionFeedback", node, ioModule);
  145. _aiPressureFeedback = ParseAiNode("aiPressureFeedback", node, ioModule);
  146. _aoPositionSetPoint = ParseAoNode("aoPositionSetPoint", node, ioModule);
  147. _aoPressureSetPoint = ParseAoNode("aoPressureSetPoint", node, ioModule);
  148. _aiState = ParseAiNode("aiState", node, ioModule);
  149. _aoPressureMode = ParseAoNode("aoPressureMode", node, ioModule);
  150. _diOffline = ParseDiNode("diOffline", node, ioModule);
  151. _scProcessPressureOffset = SC.GetConfigItem($"{Module}.ProcessPressureOffset");
  152. }
  153. public bool Initialize()
  154. {
  155. DATA.Subscribe($"{Module}.{Name}", Getter, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  156. PressureMode = PressureCtrlMode.TVPressureCtrl;
  157. DEVICE.Register($"{Module}.{Name}.{AITThrottleValveOperation.SetMode}", _setMode);
  158. DEVICE.Register($"{Module}.{Name}.{AITThrottleValveOperation.SetPosition}", _setPosition);
  159. DEVICE.Register($"{Module}.{Name}.{AITThrottleValveOperation.SetPressure}", _setPressure);
  160. OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetMode}", _setMode2);
  161. OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetPressure}", _setPressure2);
  162. OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetPosition}", _setPosition2);
  163. return true;
  164. }
  165. private bool _setPosition2(string arg1, object[] arg2)
  166. {
  167. return this._setPosition(out string str1, 0, arg2).Value;
  168. }
  169. private bool _setMode2(string arg1, object[] arg2)
  170. {
  171. return this._setMode(out string str, 0, arg2).Value;
  172. }
  173. private bool _setPressure2(string arg1, object[] arg2)
  174. {
  175. return this._setPressure(out string str, 0, arg2).Value;
  176. }
  177. private bool? _setPressure(out string reason, int time, object[] param)
  178. {
  179. PressureMode = PressureCtrlMode.TVPressureCtrl;
  180. double target = Convert.ToDouble(param[0]);
  181. //double target = (double)param[0];
  182. PositionSetpoint = 0.0f;
  183. PressureSetpoint = (float)target - (float)ProcessPressureOffset;
  184. reason = $"pressure set {target} mTorr";
  185. return true;
  186. }
  187. private bool? _setPosition(out string reason, int time, object[] param)
  188. {
  189. double target = Convert.ToDouble(param[0]);
  190. //double target = (double)param[0];
  191. PressureMode = PressureCtrlMode.TVPositionCtrl;
  192. PositionSetpoint = (short) target;
  193. PressureSetpoint = 0.0f;
  194. reason = $"position set to {target:F1}%";
  195. return true;
  196. }
  197. private bool? _setMode(out string reason, int time, object[] param)
  198. {
  199. PressureMode = (PressureCtrlMode) Enum.Parse(typeof(PressureCtrlMode), (string) param[0], true);
  200. reason = $"Throttle valve set to {PressureMode} mode";
  201. return true;
  202. }
  203. private object Getter()
  204. {
  205. AITThrottleValveData data = new AITThrottleValveData()
  206. {
  207. Module = Module,
  208. DeviceName = Name,
  209. DeviceSchematicId = DeviceID,
  210. DisplayName = Display,
  211. Mode = (int) PressureMode,
  212. PositionFeedback = PositionFeedback,
  213. PositionSetPoint = PositionSetpoint,
  214. PressureFeedback = PressureFeedback,
  215. PressureSetPoint = PressureSetpoint,
  216. State = State,
  217. };
  218. return data;
  219. }
  220. public void Terminate()
  221. {
  222. }
  223. public void Monitor()
  224. {
  225. try
  226. {
  227. _tvStatusAlmTrig.CLK = State != 1;
  228. if (_tvStatusAlmTrig.Q)
  229. {
  230. EV.PostAlarmLog(Module, "蝶阀工作状态异常");
  231. }
  232. _trigOffline.CLK = IsOffline;
  233. if (_trigOffline.Q)
  234. {
  235. EV.PostAlarmLog(Module, "蝶阀离线");
  236. }
  237. }
  238. catch (Exception ex)
  239. {
  240. LOG.Write(ex);
  241. throw ex;
  242. }
  243. }
  244. public void Reset()
  245. {
  246. _tvStatusAlmTrig.RST = true;
  247. _trigOffline.RST = true;
  248. }
  249. public void SetPositionMode(int position)
  250. {
  251. PressureMode = PressureCtrlMode.TVPositionCtrl;
  252. PositionSetpoint = (short)position;
  253. }
  254. }
  255. }