IoThrottleValve.cs 12 KB

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