EdwardsPump--.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. using System;
  2. using System.Collections;
  3. using System.Text;
  4. using System.Xml;
  5. using Aitex.Core.Common.DeviceData;
  6. using Aitex.Core.RT.DataCenter;
  7. using Aitex.Core.RT.Device;
  8. using Aitex.Core.RT.Event;
  9. using Aitex.Core.RT.IOCore;
  10. using Aitex.Core.RT.Log;
  11. using Aitex.Core.RT.OperationCenter;
  12. using Aitex.Core.RT.SCCore;
  13. using Aitex.Core.RT.Tolerance;
  14. using Aitex.Core.Util;
  15. using MECF.Framework.Common.Communications;
  16. using MECF.Framework.Common.Device.Bases;
  17. using MECF.Framework.Common.Equipment;
  18. using VirgoCommon;
  19. namespace VirgoRT.Devices
  20. {
  21. public enum EdwardsPumpState { ON = 0, OFF, Connected, Disconnected, Unknown, ERROR }
  22. public enum EdwardsPumpControlState { ReleaseCcontrol = 0, TtakeControl, Unknown }
  23. static class EdwardsPumpControlSystemParameters
  24. {
  25. public const int System_Node = 1;
  26. public const int Dry_Pump_Current = 3;
  27. public const int Dry_Pump_Power = 4;
  28. public const int Booster_Current = 7;
  29. public const int Booster_Power = 8;
  30. public const int Dry_Pump_Control = 11;
  31. public const int Dry_Pump_Run_hours = 14;
  32. public const int Number_of_pump_starts = 20;
  33. }
  34. static class EdwardsPumpMessage
  35. {
  36. public const string EOF = "\r\n";
  37. public const string RESET = "/";
  38. public const string QUERY_Alarm_Status = "?A";
  39. public const string QUERY_Bitfield_Status = "?B";
  40. public const string QUERY_Control_Status = "?C";
  41. public const string QUERY_Gas_ballast_Status = "?D";
  42. public const string QUERY_Gate_valve_Status = "?G";
  43. public const string QUERY_Nitrogen_supply_Status = "?N";
  44. public const string QUERY_On_process_Status = "?O";
  45. public const string QUERY_Pump_Status = "?P";
  46. public const string QUERY_Run_til_crash_Status = "?R";
  47. public const string QUERY_Inlet_purge_Status = "?U";
  48. public const string QUERY_Pump_node_type = "?T";
  49. public const string QUERY_Value = "?V";
  50. public const string QUERY_Serial_Number = "?S";
  51. public const string QUERY_Information = "?I";
  52. public const string QUERY_Format_mode = "?F";
  53. public const string COMMAND_Release_Control = "!C0";
  54. public const string COMMAND_Take_Control = "!C1";
  55. public const string COMMAND_Gas_ballast = "!D";
  56. public const string COMMAND_Equipment = "!E";
  57. public const string COMMAND_Format_mode = "!F";
  58. public const string COMMAND_Gate_valve = "!G";
  59. public const string COMMAND_Reserved = "!L";
  60. public const string COMMAND_Simulation_mode = "!M";
  61. public const string COMMAND_Nitrogen_supply = "!N";
  62. public const string COMMAND_On_process = "!O";
  63. public const string COMMAND_Switch_on_Pump = "!P1";
  64. public const string COMMAND_Switch_off_Pump_Auto_shut_down = "!P0";
  65. public const string COMMAND_Switch_off_Pump_Fast_shut_down = "!P2";
  66. public const string COMMAND_Run_til_crash = "!R";
  67. public const string COMMAND_Reserved_do_not_use = "!T";
  68. public const string COMMAND_Inlet_purge = "!U";
  69. public const string COMMAND_Terminate_protocol = "!XO";
  70. public const string SET_SHORT_REPLY = "!F0";
  71. public const string SET_LONG_REPLY = "!F1";
  72. }
  73. class EdwardsPump : PumpBase
  74. {
  75. // ----------------------------Fields--------------------------
  76. //
  77. private const ushort CHK_ST_INTERVAL = 1000;
  78. private const ushort CHK_CONTROL_INTERVAL = 3 * 1000;
  79. private const ushort CHK_REC_INTERVAL = 20 * 1000;
  80. private const ushort CHK_PUMP_REC_INTERVAL = 10 * 1000;
  81. private const string EOF = "\r";
  82. private const char MSG_DELIMITER = ' ';
  83. private readonly string _PortNum = "COM91";
  84. private const int _counterMax = 30;
  85. private int _counter = 0;
  86. private static string SendData;
  87. private readonly AsyncSerialPort _serial;
  88. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  89. private readonly DeviceTimer _timerControlStatus = new DeviceTimer();
  90. private readonly DeviceTimer _timerReceiveStatus = new DeviceTimer();
  91. private readonly DeviceTimer _timerPumpOn = new DeviceTimer();
  92. private readonly DeviceTimer _timerPumpOff = new DeviceTimer();
  93. private readonly R_TRIG _trigPumpOn = new R_TRIG();
  94. private readonly R_TRIG _trigPumpOff = new R_TRIG();
  95. private readonly R_TRIG _trigReceiveStatus = new R_TRIG();
  96. // --------------------------Properties------------------------
  97. //
  98. public EdwardsPumpState StatusDry { get; set; }
  99. public EdwardsPumpControlState ControlStatusDry { get; set; }
  100. [Subscription(AITPumpProperty.IsRunning)]
  101. public override bool IsRunning
  102. {
  103. get
  104. {
  105. return StatusDry == EdwardsPumpState.ON;
  106. }
  107. }
  108. [Subscription(AITPumpProperty.IsControl)]
  109. public override bool IsControl
  110. {
  111. get
  112. {
  113. return ControlStatusDry == EdwardsPumpControlState.TtakeControl;
  114. }
  115. }
  116. [Subscription(AITPumpProperty.IsError)]
  117. public override bool IsError
  118. {
  119. get
  120. {
  121. return StatusDry == EdwardsPumpState.ERROR || StatusDry == EdwardsPumpState.Disconnected;
  122. }
  123. }
  124. public override AITPumpData DeviceData
  125. {
  126. get
  127. {
  128. AITPumpData deviceData = new AITPumpData
  129. {
  130. DeviceName = Name,
  131. DeviceModule = Module,
  132. DeviceSchematicId = DeviceID,
  133. DisplayName = Display,
  134. IsError = false,
  135. IsWarning = false,
  136. IsOn = IsRunning,
  137. //WaterFlow = WaterFlowValue,
  138. IsDryPumpEnable = true,
  139. IsN2PressureEnable = false,
  140. IsWaterFlowEnable = false,
  141. //WaterFlowWarning = WaterFlowWarning,
  142. //WaterFlowAlarm = WaterFlowAlarm,
  143. //N2PressureAlarm = N2PressureAlarm,
  144. //N2PressureWarning = N2PressureWarning,
  145. };
  146. return deviceData;
  147. }
  148. }
  149. // --------------------------Constructor-----------------------
  150. //
  151. public EdwardsPump(ModuleName mod) : base(mod.ToString(), VirgoDevice.MainPump.ToString(), "Edwards Pump", "")
  152. {
  153. _PortNum = SC.GetStringValue($"{mod}.DryPump.Port");
  154. StatusDry = EdwardsPumpState.Unknown;
  155. ControlStatusDry = EdwardsPumpControlState.Unknown;
  156. _serial = new AsyncSerialPort(_PortNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "\r\n", true);
  157. }
  158. public override bool Initialize()
  159. {
  160. base.Initialize();
  161. if (!_serial.Open())
  162. {
  163. StatusDry = EdwardsPumpState.Disconnected;
  164. EV.PostAlarmLog(this.Module, "Edwards Pump串口无法打开");
  165. return false;
  166. }
  167. StatusDry = EdwardsPumpState.Connected;
  168. ControlStatusDry = EdwardsPumpControlState.Unknown;
  169. _trigPumpOn.RST = true;
  170. _trigPumpOff.RST = true;
  171. _trigReceiveStatus.RST = true;
  172. _serial.OnDataChanged += OnPortDataChanged;
  173. _serial.OnErrorHappened += OnErrorOccurred;
  174. SendCmd(EdwardsPumpMessage.RESET);
  175. SendCmd(EdwardsPumpMessage.SET_SHORT_REPLY);
  176. SendCmd(EdwardsPumpMessage.COMMAND_Take_Control);
  177. _timerQueryStatus.Start(CHK_ST_INTERVAL);
  178. _timerControlStatus.Start(CHK_CONTROL_INTERVAL);
  179. _timerReceiveStatus.Start(CHK_REC_INTERVAL);
  180. return true;
  181. }
  182. private void OnErrorOccurred(string obj)
  183. {
  184. StatusDry = EdwardsPumpState.ERROR;
  185. ControlStatusDry = EdwardsPumpControlState.Unknown;
  186. LOG.Error($"[{Module}] edwards pump error: [{obj}]");
  187. }
  188. private void OnPortDataChanged(string obj)
  189. {
  190. if (string.IsNullOrEmpty(obj))
  191. LOG.Error($"[{Module}] edwards pump message IsNullOrEmpty");
  192. try
  193. {
  194. _timerReceiveStatus.Stop();
  195. _timerReceiveStatus.Start(CHK_REC_INTERVAL);
  196. string cmd = obj.ToString().Split('\n')[0].Split('\r')[0];
  197. switch (SendData)
  198. {
  199. case EdwardsPumpMessage.RESET:
  200. break;
  201. case EdwardsPumpMessage.COMMAND_Take_Control:
  202. EV.PostInfoLog(this.Module, $"Take Control Edwards Pump {QueryCmdReply(cmd)}");
  203. break;
  204. case EdwardsPumpMessage.COMMAND_Release_Control:
  205. EV.PostInfoLog(this.Module, $"Release Control Edwards Pump {QueryCmdReply(cmd)}");
  206. break;
  207. case EdwardsPumpMessage.COMMAND_Switch_on_Pump:
  208. EV.PostInfoLog(this.Module, $"Switch on Edwards Pump {QueryCmdReply(cmd)}");
  209. break;
  210. case EdwardsPumpMessage.COMMAND_Switch_off_Pump_Fast_shut_down:
  211. EV.PostInfoLog(this.Module, $"Switch off Edwards Pump {QueryCmdReply(cmd)}");
  212. break;
  213. case EdwardsPumpMessage.QUERY_Pump_Status:
  214. if (cmd == "0")
  215. {
  216. StatusDry = EdwardsPumpState.OFF;
  217. if (_trigPumpOn.Q && _timerPumpOn.IsTimeout())
  218. {
  219. _trigPumpOn.RST = true;
  220. EV.PostMessage(Module, EventEnum.DefaultWarning, "Edwards Pump 无法打开");
  221. }
  222. if (_trigPumpOff.Q)
  223. {
  224. EV.PostInfoLog(this.Module, $"Edwards Pump关闭");
  225. }
  226. _trigPumpOff.RST = true;
  227. }
  228. else if (cmd == "4")
  229. {
  230. StatusDry = EdwardsPumpState.ON;
  231. if (_trigPumpOff.Q && _timerPumpOff.IsTimeout())
  232. {
  233. _trigPumpOff.RST = true;
  234. EV.PostMessage(Module, EventEnum.DefaultWarning, "Edwards Pump 无法关闭");
  235. }
  236. if (_trigPumpOn.Q)
  237. {
  238. EV.PostInfoLog(this.Module, $"Edwards Pump打开");
  239. }
  240. _trigPumpOn.RST = true;
  241. }
  242. break;
  243. case EdwardsPumpMessage.QUERY_Control_Status:
  244. if (cmd == "0")
  245. {
  246. ControlStatusDry = EdwardsPumpControlState.ReleaseCcontrol;
  247. }
  248. else if (cmd == "1")
  249. {
  250. ControlStatusDry = EdwardsPumpControlState.TtakeControl;
  251. }
  252. break;
  253. default:
  254. //EV.PostInfoLog(this.Module, $"Edwards Pump {SendData} {QueryCmdReply(cmd)}");
  255. break;
  256. }
  257. }
  258. catch (Exception ex)
  259. {
  260. LOG.Error($"[{Module}] edwards pump error: [{ex.Message}]");
  261. }
  262. }
  263. public string QueryCmdReply(string cmd)
  264. {
  265. if (cmd == "ERR 0")
  266. {
  267. return "No error";
  268. }
  269. else if (cmd == "ERR 1")
  270. {
  271. return "Invalid message";
  272. }
  273. else if (cmd == "ERR 2")
  274. {
  275. return "Number not found";
  276. }
  277. else if (cmd == "ERR 3")
  278. {
  279. return "Number Invalid";
  280. }
  281. else if (cmd == "ERR 4")
  282. {
  283. return "Parameter’s value not received";
  284. }
  285. else if (cmd == "ERR 5")
  286. {
  287. return "Command not possible";
  288. }
  289. else
  290. {
  291. return cmd;
  292. }
  293. }
  294. public override void Monitor()
  295. {
  296. try
  297. {
  298. // 状态查询
  299. if (_timerQueryStatus.IsTimeout() && this.StatusDry != EdwardsPumpState.ERROR)
  300. {
  301. this.SendCmd(EdwardsPumpMessage.QUERY_Pump_Status);
  302. _timerQueryStatus.Start(CHK_ST_INTERVAL);
  303. }
  304. // Control查询
  305. if (_timerControlStatus.IsTimeout())
  306. {
  307. this.SendCmd(EdwardsPumpMessage.QUERY_Control_Status);
  308. _timerControlStatus.Start(CHK_ST_INTERVAL);
  309. }
  310. if (_timerReceiveStatus.IsTimeout() && this.StatusDry != EdwardsPumpState.ERROR)
  311. {
  312. _trigReceiveStatus.CLK = true;
  313. if (_trigReceiveStatus.Q)
  314. {
  315. EV.PostMessage("System", EventEnum.DefaultWarning, $"[{Module}] Edwards Pump 没有回复");
  316. }
  317. }
  318. }
  319. catch (Exception ex)
  320. {
  321. throw ex;
  322. }
  323. }
  324. private bool SendCmd(string str)
  325. {
  326. SendData = str;
  327. if (SendData == "!P1")
  328. {
  329. _trigPumpOn.CLK = true;
  330. _timerPumpOn.Start(CHK_PUMP_REC_INTERVAL);
  331. LOG.Info($"[{Module}] Switch on Edwards Pump");
  332. }
  333. else if (SendData == "!P2")
  334. {
  335. _trigPumpOff.CLK = true;
  336. _timerPumpOff.Start(CHK_PUMP_REC_INTERVAL);
  337. LOG.Info($"[{Module}] Switch off Edwards Pump");
  338. }
  339. return _serial.Write(str + "\r");
  340. }
  341. public override void Reset()
  342. {
  343. _trigPumpOn.RST = true;
  344. _trigPumpOff.RST = true;
  345. _trigReceiveStatus.RST = true;
  346. SendCmd(EdwardsPumpMessage.RESET);
  347. }
  348. public override void Terminate()
  349. {
  350. //if (StatusDry == EdwardsPumpState.ON)
  351. // SetPumpOnOff(false);
  352. _serial?.Close();
  353. }
  354. public override void SetPumpOnOff(bool on)
  355. {
  356. if (!IsControl)
  357. SendCmd(EdwardsPumpMessage.COMMAND_Take_Control);
  358. SendCmd(on ? EdwardsPumpMessage.COMMAND_Switch_on_Pump : EdwardsPumpMessage.COMMAND_Switch_off_Pump_Fast_shut_down);
  359. }
  360. }
  361. }