AdixenTurboPump.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. using System;
  2. using System.Diagnostics;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. using System.Threading.Tasks;
  7. using MECF.Framework.Common.Communications;
  8. using MECF.Framework.Common.Equipment;
  9. using Aitex.Core.RT.SCCore;
  10. using Aitex.Core.RT.Event;
  11. using Aitex.Core.RT.Device;
  12. using MECF.Framework.Common.Device.Bases;
  13. namespace Venus_RT.Devices
  14. {
  15. class AdixenTurboPump : TurboPump
  16. {
  17. public enum Operation
  18. {
  19. SetAddress,
  20. GetChecksum,
  21. GetFaultList,
  22. SetDatalogInterval,
  23. EnableDatalog,
  24. EnableEcho,
  25. DisableEcho,
  26. IdentifyDevice,
  27. IdentifyProduct,
  28. GetCurrentValues,
  29. SwitchSpeedToNormal,
  30. SwitchSpeedToStandbyValue,
  31. SetStandbySpeed,
  32. GetParametersState,
  33. GetIntervalParametersState,
  34. SetPumpWorkingTime,
  35. SetElectronicWorkingTime,
  36. SetStartDelay,
  37. SetTimeToVent,
  38. SetVentingTime,
  39. SetSpeedThreshold,
  40. SetControlTemperatrue,
  41. StopPumpThermostage,
  42. SetBearingThreshold,
  43. GetCurrentSpeed,
  44. StartPumpRotation,
  45. StopPump,
  46. SetVersions,
  47. SetAnalogOutput,
  48. SetTemperatureUnit,
  49. SetBuzzerOpt,
  50. SetCommandMode,
  51. SetBraking,
  52. Invalid,
  53. }
  54. private readonly Dictionary<Operation, string> _noneParaCommandOp = new Dictionary<Operation, string>
  55. {
  56. {Operation.EnableDatalog, "#{0:D3}DLR\r" },
  57. {Operation.EnableEcho, "#{0:D3}ECHON\r" },
  58. {Operation.DisableEcho, "#{0:D3}ECHOFF\r" },
  59. {Operation.SwitchSpeedToNormal, "#{0:D3}NSP\r" },
  60. {Operation.SwitchSpeedToStandbyValue, "#{0:D3}SBY\r" },
  61. {Operation.StopPumpThermostage, "#{0:D3}SET31,30\r" },
  62. {Operation.StartPumpRotation, "#{0:D3}TMPON\r" },
  63. {Operation.StopPump, "#{0:D3}TMPOFF\r" },
  64. };
  65. private readonly Dictionary<Operation, string> _readDataCommandOp = new Dictionary<Operation, string>
  66. {
  67. {Operation.GetChecksum, "#{0:D3}CHKVS\r" },
  68. {Operation.GetFaultList, "#{0:D3}DEF\r" },
  69. {Operation.IdentifyDevice, "#{0:D3}IDN\r" },
  70. {Operation.IdentifyProduct, "#{0:D3}IDP\r" },
  71. {Operation.GetCurrentValues, "#{0:D3}LEV10\r" },
  72. {Operation.GetParametersState, "#{0:D3}SEL10\r" },
  73. {Operation.GetCurrentSpeed, "#{0:D3}SPD\r" },
  74. {Operation.GetIntervalParametersState, "#{0:D3}STA\r" },
  75. };
  76. private readonly Dictionary<Operation, string> _setDataCommandOp = new Dictionary<Operation, string>
  77. {
  78. {Operation.SetAddress, "#{0:D3}ADR {1:D3}\r" },
  79. {Operation.SetDatalogInterval, "#{0:D3}DLI {1:D3}\r" },
  80. {Operation.SetStandbySpeed, "#{0:D3}RPM,{1:D4}\r" },
  81. {Operation.SetPumpWorkingTime, "#{0:D3}SET10,{1:D5}\r" },
  82. {Operation.SetElectronicWorkingTime, "#{0:D3}SET11,{1:D5}\r" },
  83. {Operation.SetStartDelay, "#{0:D3}SET13,{1:D5}\r" },
  84. {Operation.SetTimeToVent, "#{0:D3}SET14,{1:D5}\r" },
  85. {Operation.SetVentingTime, "#{0:D3}SET15,{1:D4}\r" },
  86. {Operation.SetSpeedThreshold, "#{0:D3}SET30,{1:D2}\r" },
  87. {Operation.SetControlTemperatrue, "#{0:D3}SET31,{1:D2}\r" },
  88. {Operation.SetBearingThreshold, "#{0:D3}SET32,{1:D3}\r" },
  89. {Operation.SetAnalogOutput, "#{0:D3}OPT01,{1:D1}\r" },
  90. {Operation.SetTemperatureUnit, "#{0:D3}OPT02,{1:D1}\r" },
  91. {Operation.SetBuzzerOpt, "#{0:D3}OPT11,{1:D1}\r" },
  92. {Operation.SetCommandMode, "#{0:D3}OPT14,{1:D1}\r" },
  93. {Operation.SetBraking, "#{0:D3}OPT25,{1:D1}\r" },
  94. };
  95. private readonly Dictionary<string, string> _comError = new Dictionary<string, string>
  96. {
  97. {"Err0", "adjustment error(out of bounds)" },
  98. {"Err1", "command error (syntax) " },
  99. {"Err2", "parameter error (e.g. non hexadecimal character)" },
  100. {"Err3", "context error" },
  101. {"Err4", "checksum error" },
  102. };
  103. private readonly int _readInterval = 500;
  104. private readonly int _readTimeout = 2000;
  105. private readonly int _address = 0;
  106. private readonly AsyncSerialPort _serial;
  107. private Stopwatch _queryWatch = new Stopwatch();
  108. private Operation _lastReadCommand = Operation.Invalid;
  109. private string _lastAlarmString = string.Empty;
  110. private Regex _rex_ok = new Regex(@"#\d{1,3},OK");
  111. private Regex _rex_err = new Regex(@"#\d{1,3},Err");
  112. public AdixenTurboPump(ModuleName mod)
  113. {
  114. Module = mod.ToString();
  115. var _PortNum = SC.GetStringValue($"{mod}.TurboPump.Port");
  116. _serial = new AsyncSerialPort(_PortNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One);
  117. }
  118. public override bool Initialize()
  119. {
  120. if (!_serial.Open())
  121. {
  122. EV.PostAlarmLog(this.Module, "Adixen Turbo Pump 串口无法打开");
  123. return false;
  124. }
  125. _serial.OnDataChanged += OnPortDataChanged;
  126. _serial.OnErrorHappened += OnErrorOccurred;
  127. return true;
  128. }
  129. public override void Monitor()
  130. {
  131. if ((_queryWatch.ElapsedMilliseconds > _readInterval && _lastReadCommand == Operation.Invalid) || _queryWatch.ElapsedMilliseconds > _readTimeout)
  132. {
  133. SendCommand(Operation.GetCurrentValues);
  134. _queryWatch.Restart();
  135. }
  136. }
  137. public override void Reset()
  138. {
  139. }
  140. public override void Terminate()
  141. {
  142. _serial?.Close();
  143. }
  144. private void OnErrorOccurred(string obj)
  145. {
  146. _noRepeatAlarm($"[{Module}] Adixen Turbo Pump serial port error: [{obj}]");
  147. }
  148. private void OnPortDataChanged(string obj)
  149. {
  150. if (string.IsNullOrEmpty(obj))
  151. {
  152. _noRepeatAlarm("Adixen Turbo Pump receive empty message");
  153. return;
  154. }
  155. try
  156. {
  157. if (_rex_ok.Match(obj).Success)
  158. return;
  159. if(_rex_err.Match(obj).Success)
  160. {
  161. var errs = obj.Trim().Split(',');
  162. if(_comError.ContainsKey(errs[1]))
  163. {
  164. _noRepeatAlarm($"Adixen Turbo Pump communication error: {_comError[errs[1]]}");
  165. }
  166. else
  167. {
  168. _noRepeatAlarm($"Adixen Turbo Pump unknown communication error: {obj}");
  169. }
  170. _lastReadCommand = Operation.Invalid;
  171. return;
  172. }
  173. if(_lastReadCommand == Operation.Invalid)
  174. {
  175. EV.PostWarningLog(Module, $"Adixen Turbo Pump unexpected communication data: {obj}");
  176. return;
  177. }
  178. var result_data = obj.Trim().Split(',');
  179. switch(_lastReadCommand)
  180. {
  181. case Operation.GetCurrentSpeed:
  182. var str_speed = result_data[1].Split();
  183. Speed = int.Parse(str_speed[0]);
  184. break;
  185. }
  186. _lastReadCommand = Operation.Invalid;
  187. }
  188. catch (Exception ex)
  189. {
  190. _noRepeatAlarm($"[{Module}] Adixen Turbo Pump error: [{ex.Message}], Data: {obj}");
  191. }
  192. }
  193. public bool SendCommand(Operation op)
  194. {
  195. if (_noneParaCommandOp.ContainsKey(op))
  196. {
  197. var cmd = string.Format(_noneParaCommandOp[op], _address);
  198. return _serial.Write(cmd);
  199. }
  200. else if (_readDataCommandOp.ContainsKey(op))
  201. {
  202. var cmd = string.Format(_readDataCommandOp[op], _address);
  203. if(_serial.Write(cmd))
  204. {
  205. _lastReadCommand = op;
  206. return true;
  207. }
  208. }
  209. _noRepeatAlarm($"Adixen Turbo Pump: The {op} command need parameters");
  210. return false;
  211. }
  212. public bool SendCommand(Operation op, int data)
  213. {
  214. if (_setDataCommandOp.ContainsKey(op))
  215. {
  216. var cmd = string.Format(_setDataCommandOp[op], _address, data);
  217. return _sendCmd(cmd);
  218. }
  219. _noRepeatAlarm($"Adixen Turbo Pump: The command {op} does not need one parameter");
  220. return false;
  221. }
  222. private bool _sendCmd(string cmd)
  223. {
  224. return _serial.Write(cmd);
  225. }
  226. private void _noRepeatAlarm(string alarm)
  227. {
  228. if(_lastAlarmString != alarm)
  229. {
  230. _lastAlarmString = alarm;
  231. EV.PostAlarmLog(Module, alarm);
  232. }
  233. }
  234. }
  235. }