AdTecRF.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. using System;
  2. using System.Threading.Tasks;
  3. using System.Collections;
  4. using System.Text.RegularExpressions;
  5. using Aitex.Core.Common.DeviceData;
  6. using Aitex.Core.RT.DataCenter;
  7. using Aitex.Core.RT.Event;
  8. using Aitex.Core.RT.IOCore;
  9. using Aitex.Core.RT.Log;
  10. using Aitex.Core.RT.OperationCenter;
  11. using Aitex.Core.RT.SCCore;
  12. using Aitex.Core.RT.Tolerance;
  13. using Aitex.Core.Util;
  14. using Aitex.Core.RT.Device;
  15. using MECF.Framework.Common.Communications;
  16. using MECF.Framework.Common.DataCenter;
  17. using MECF.Framework.Common.Device.Bases;
  18. using MECF.Framework.Common.Equipment;
  19. using Venus_Core;
  20. using Venus_RT.Modules;
  21. using System.Threading;
  22. namespace Venus_RT.Devices
  23. {
  24. #region RFG
  25. static class AdTecRfMessage
  26. {
  27. public static string ANALOG = "";
  28. public const string EOF = "\r";
  29. public const char DELIMITER = ' ';
  30. public const string MANUAL = "MANUAL";
  31. public const string RS232 = "***";
  32. public const string SET_POWER = " W";
  33. public const string RF_ON = "G";
  34. public const string RF_OFF = "S";
  35. public const string ERR_RES = "N";
  36. public const string QUERY = "Q";
  37. public const string RESET = "RESET";
  38. public const string CHK_COMM = "HS";
  39. }
  40. class AdTecGenerator : RfPowerBase
  41. {
  42. // ----------------------------Fields--------------------------
  43. //
  44. private int QUERY_INTERVAL = 5000;
  45. private const string INFO_PATTERN = @"(\d{7})\s(\d{5})\s(\d{5})\s(\d{5})\s(\d{5})";
  46. private double _total;
  47. private double _fromLast;
  48. private bool _bRFPowerOn = false;
  49. private readonly AsyncSerialPort _serial;
  50. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  51. private readonly DeviceTimer _timerTotal = new DeviceTimer();
  52. private readonly DeviceTimer _timerFromLast = new DeviceTimer();
  53. private readonly DeviceTimer _timerRFTurnOn = new DeviceTimer();
  54. private DateTime _powerOnStartTime;
  55. private TimeSpan _powerOnElapsedTime;
  56. private readonly RD_TRIG _rfOnTrigger = new RD_TRIG();
  57. private readonly R_TRIG _ErrTrigger = new R_TRIG();
  58. private readonly R_TRIG _trigPMNeeded = new R_TRIG();
  59. private readonly RD_TRIG _trigOnOff = new RD_TRIG();
  60. private ToleranceChecker _checkerPower;
  61. private ToleranceChecker _checkerReflectPower;
  62. private readonly double _scPowerAlarmTime;
  63. private readonly double _scPowerAlarmRange;
  64. private readonly double _scPowerWarningTime;
  65. private readonly double _scPowerWarningRange;
  66. private readonly double _scReflectPowerAlarmTime;
  67. private readonly double _scReflectPowerAlarmRange;
  68. private readonly double _scPowerRange;
  69. private readonly DIAccessor _diIntlk;
  70. private StatsDataItemRFAndPump _statRFOnTime;
  71. private readonly VenusDevice _device;
  72. // --------------------------Properties------------------------
  73. //
  74. public bool ConnectedStatus { get; set; }
  75. public override float ScalePower => (float)_scPowerRange;
  76. public GeneratorStatus Status { get; set; }
  77. public string LastPMTime
  78. {
  79. get
  80. {
  81. return _statRFOnTime != null ? _statRFOnTime.LastPMTime.ToString() : "";
  82. }
  83. }
  84. public double DaysFromLastPM
  85. {
  86. get
  87. {
  88. return _statRFOnTime == null ? 0 : _statRFOnTime.fromLastPM;
  89. }
  90. set
  91. {
  92. if (_statRFOnTime != null)
  93. _statRFOnTime.fromLastPM = value;
  94. }
  95. }
  96. public double TotalDays
  97. {
  98. get
  99. {
  100. return _statRFOnTime != null ? _statRFOnTime.Total : 0;
  101. }
  102. set
  103. {
  104. if (_statRFOnTime != null)
  105. _statRFOnTime.Total = value;
  106. }
  107. }
  108. public double PMIntervalDays
  109. {
  110. get
  111. {
  112. return _statRFOnTime != null ? _statRFOnTime.PMInterval : 0;
  113. }
  114. }
  115. public bool IsPMNeeded
  116. {
  117. get
  118. {
  119. return DaysFromLastPM > PMIntervalDays;
  120. }
  121. }
  122. public bool EnableAlarm
  123. {
  124. get
  125. {
  126. return _statRFOnTime == null || _statRFOnTime.AlarmEnable;
  127. }
  128. }
  129. public override bool IsPowerOn
  130. {
  131. get => Status == GeneratorStatus.ON;
  132. set { }
  133. }
  134. public override bool IsError
  135. {
  136. get => Status == GeneratorStatus.ERROR;
  137. set { }
  138. }
  139. [Subscription("PowerOnTime")]
  140. public string PowerOnTime
  141. {
  142. get
  143. {
  144. if (_bRFPowerOn)
  145. _powerOnElapsedTime = DateTime.Now - _powerOnStartTime;
  146. return $"{(int)_powerOnElapsedTime.TotalHours:00}:{_powerOnElapsedTime.Minutes:00}:{(_powerOnElapsedTime.Seconds > 0 ? (_powerOnElapsedTime.Seconds + 1) : 0):00}";
  147. }
  148. }
  149. public bool RFInterlock => _diIntlk == null || _diIntlk.Value;
  150. private float _forwardPower;
  151. public override float ForwardPower
  152. {
  153. get
  154. {
  155. return _forwardPower;
  156. }
  157. set
  158. {
  159. _forwardPower = CalibrationData(value, false);
  160. }
  161. }
  162. public new AITRfData DeviceData =>
  163. new AITRfData
  164. {
  165. Module = Module,
  166. DeviceName = Name,
  167. ScalePower = ScalePower,
  168. ForwardPower = ForwardPower,
  169. ReflectPower = ReflectPower,
  170. IsRfOn = IsPowerOn,
  171. PowerSetPoint = PowerSetPoint,
  172. PowerOnElapsedTime = PowerOnTime,
  173. IsInterlockOk = RFInterlock,
  174. WorkMode = (int)RfMode.ContinuousWaveMode,
  175. DisplayName ="Source RF",
  176. };
  177. // --------------------------Constructor-----------------------
  178. //
  179. public AdTecGenerator(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  180. {
  181. var portNum = SC.GetStringValue(device == VenusDevice.Rf ? $"{mod}.Rf.Port" : $"{mod}.BiasRf.Port");
  182. this.Status = GeneratorStatus.Unknown;
  183. _device = device;
  184. _serial = new AsyncSerialPort(portNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "\r\r");
  185. _scPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmTime");
  186. _scPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmRange");
  187. _scPowerWarningTime = SC.GetValue<double>($"{Module}.{Name}.PowerWarningTime");
  188. _scPowerWarningRange = SC.GetValue<double>($"{Module}.{Name}.PowerWarningRange");
  189. _scReflectPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmTime");
  190. _scReflectPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmRange");
  191. _scPowerRange = SC.GetValue<double>($"{Module}.{Name}.PowerRange");
  192. _scEnableCalibration = SC.GetConfigItem($"{Module}.{Name}.EnableCalibration");
  193. _scCalibrationTable = SC.GetConfigItem($"{Module}.{Name}.CalibrationTable");
  194. _diIntlk = IO.DI[$"{Module}.DI_RF_Generator_Interlock"];
  195. }
  196. ~AdTecGenerator()
  197. {
  198. _serial?.Close();
  199. }
  200. public override bool Initialize()
  201. {
  202. base.Initialize();
  203. DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
  204. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetPowerOnOff}", (out string reason, int time, object[] param) =>
  205. {
  206. SetPowerOnOff(Convert.ToBoolean((string)param[0]), out reason);
  207. return true;
  208. });
  209. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetPower}", (out string reason, int time, object[] param) =>
  210. {
  211. reason = "";
  212. ushort val = Convert.ToUInt16(param[0]);
  213. SetPower(val);
  214. return true;
  215. });
  216. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetContinuousPower}", (out string reason, int time, object[] param) =>
  217. {
  218. reason = "";
  219. ushort val = Convert.ToUInt16(param[0]);
  220. SetPower(val);
  221. return true;
  222. });
  223. if (_serial.Open())
  224. {
  225. this.ConnectedStatus = true;
  226. _serial.OnDataChanged += SerialPortDataReceived;
  227. _serial.OnErrorHappened += SerialPortErrorOccurred;
  228. }
  229. else
  230. {
  231. this.ConnectedStatus = false;
  232. LOG.Write(eEvent.ERR_RF, Module, "AD TEC 射频发生器串口无法打开");
  233. return false;
  234. }
  235. _statRFOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.RfOnTime");
  236. _timerQueryStatus.Start(QUERY_INTERVAL);
  237. _checkerPower = new ToleranceChecker(_scPowerAlarmTime);
  238. _checkerReflectPower = new ToleranceChecker(_scReflectPowerAlarmTime);
  239. SetCommunicationMode(1);
  240. return true;
  241. }
  242. public override void Monitor()
  243. {
  244. // 状态查询
  245. if (_timerQueryStatus.IsTimeout())
  246. {
  247. this.SendCmd(AdTecRfMessage.QUERY);
  248. _timerQueryStatus.Start(QUERY_INTERVAL);
  249. }
  250. // power on triggered
  251. _rfOnTrigger.CLK = IsPowerOn;
  252. if (_rfOnTrigger.R)
  253. {
  254. _total = TotalDays;
  255. _fromLast = DaysFromLastPM;
  256. _timerTotal.Start(0);
  257. _timerFromLast.Start(0);
  258. _powerOnStartTime = DateTime.Now;
  259. _checkerPower.Reset(_scPowerAlarmTime);
  260. _checkerReflectPower.Reset(_scReflectPowerAlarmTime);
  261. _alarmChecker.Reset(_scPowerAlarmTime);
  262. _warningChecker.Reset(_scPowerWarningTime);
  263. }
  264. if (_rfOnTrigger.M)
  265. {
  266. TotalDays = _total + _timerTotal.GetElapseTime() / 1000 / 60 / 60;
  267. DaysFromLastPM = _fromLast + _timerFromLast.GetElapseTime() / 1000 / 60 / 60;
  268. //_checkerPower.Monitor(ForwardPower, PowerSetPoint - _scPowerAlarmRange, PowerSetPoint + _scPowerAlarmRange, _scPowerAlarmTime);
  269. //if (_checkerPower.Trig)
  270. //{
  271. // EV.PostAlarmLog($"{Module}",
  272. // $"{Display} Forward power {ForwardPower:0} out of range[{PowerSetPoint - _scPowerAlarmRange:0},{PowerSetPoint + _scPowerAlarmRange:0}] in {_scPowerAlarmTime:0} seconds");
  273. // SetPowerOnOff(false, out _);
  274. //}
  275. if (_recipeAlarmRange > 0 && _recipeAlarmRange / 100.0 * PowerSetPoint < _scPowerAlarmRange)
  276. {
  277. if (_recipeIgnoreTimer.GetElapseTime() > _recipeIgnoreTimeMS)
  278. {
  279. _recipeAlarmChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_recipeAlarmRange / 100.0 * PowerSetPoint), PowerSetPoint + Math.Abs(_recipeAlarmRange / 100.0 * PowerSetPoint), _scPowerAlarmTime);
  280. if (_recipeAlarmChecker.Trig)
  281. {
  282. LOG.Write(eEvent.ERR_RF, Module, Display + $" out of tolerance in {_scPowerAlarmTime:0} seconds");
  283. SetPowerOnOff(false, out _);
  284. }
  285. }
  286. }
  287. else
  288. {
  289. _alarmChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_scPowerAlarmRange), PowerSetPoint + Math.Abs(_scPowerAlarmRange), _scPowerAlarmTime);
  290. if (_alarmChecker.Trig)
  291. {
  292. LOG.Write(eEvent.ERR_RF, Module, Display + $" out of tolerance in {_scPowerAlarmTime:0} seconds");
  293. }
  294. }
  295. if (_recipeWarningRange > 0 && _recipeWarningRange / 100.0 * PowerSetPoint < _scPowerWarningRange)
  296. {
  297. if (_recipeIgnoreTimer.GetElapseTime() > _recipeIgnoreTimeMS)
  298. {
  299. _recipeWarningChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_recipeWarningRange / 100.0 * PowerSetPoint), PowerSetPoint + Math.Abs(_recipeWarningRange / 100.0 * PowerSetPoint), _scPowerWarningTime);
  300. if (_recipeWarningChecker.Trig)
  301. {
  302. EV.PostWarningLog(Module, Display + $" out of tolerance in {_scPowerWarningTime:0} seconds");
  303. }
  304. }
  305. }
  306. else
  307. {
  308. _warningChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_scPowerWarningRange), PowerSetPoint + Math.Abs(_scPowerWarningRange), _scPowerWarningTime);
  309. if (_warningChecker.Trig)
  310. {
  311. EV.PostWarningLog(Module, Display + $" out of tolerance in {_scPowerWarningTime:0} seconds");
  312. }
  313. }
  314. _checkerReflectPower.Monitor(ReflectPower, double.MinValue, _scReflectPowerAlarmRange, _scReflectPowerAlarmTime);
  315. if (_checkerReflectPower.Trig)
  316. {
  317. LOG.Write(eEvent.ERR_RF, Module,
  318. $"{Display} Reflect power {ReflectPower:0} out of range[0,{_scReflectPowerAlarmRange:0}] in {_scReflectPowerAlarmTime:0} seconds");
  319. SetPowerOnOff(false, out _);
  320. }
  321. }
  322. if (PMIntervalDays > 0)
  323. {
  324. _trigPMNeeded.CLK = IsPMNeeded;
  325. if (_trigPMNeeded.Q)
  326. {
  327. if (EnableAlarm)
  328. {
  329. LOG.Write(eEvent.ERR_RF, Module, "rf on time value larger than setting interval days");
  330. }
  331. }
  332. }
  333. if (_rfOnTrigger.T)
  334. StatsDataManager.Instance.Increase($"{Module}.RfOnTime", $"{Module} RfOnTime", DaysFromLastPM, TotalDays);
  335. if (!_rfOnTrigger.CLK)
  336. {
  337. ForwardPower = 0;
  338. ReflectPower = 0;
  339. }
  340. // 通信 checking, 2 second 一次
  341. //if (_timerComm.IsTimeout() && !_bQueryComm)
  342. //{
  343. // this.SendCmd(AdTecRfMessage.CHK_COMM);
  344. // _bQueryComm = true;
  345. // _timerComm.Start(CHK_COMM_INTERVAL);
  346. //}
  347. // RF Turn On & Off Timeout Check
  348. _trigOnOff.CLK = _bRFPowerOn;
  349. if (_trigOnOff.R) //RF Turn On
  350. {
  351. _timerRFTurnOn.Start(SC.GetValue<int>($"{Module}.Rf.RFTurnOnTimeout") * 1000);
  352. }
  353. if (_trigOnOff.M) //RF Stay On
  354. {
  355. if (_timerRFTurnOn.IsTimeout())
  356. {
  357. if (!IsPowerOn)
  358. {
  359. LOG.Write(eEvent.ERR_RF, Module, "RF Turn On Failed");
  360. _timerRFTurnOn.Stop();
  361. }
  362. }
  363. }
  364. if (_trigOnOff.T)
  365. {
  366. _timerRFTurnOn.Stop();
  367. }
  368. base.Monitor();
  369. }
  370. public override void Terminate()
  371. {
  372. _serial?.Close();
  373. }
  374. public override void Reset()
  375. {
  376. _rfOnTrigger.RST = true;
  377. _ErrTrigger.RST = true;
  378. _trigPMNeeded.RST = true;
  379. this.SendCmd(AdTecRfMessage.RESET);
  380. this.Status = GeneratorStatus.OFF;
  381. _bRFPowerOn = false;
  382. base.Reset();
  383. }
  384. public void SetRfMode(RfMode mode)
  385. {
  386. throw new NotImplementedException();
  387. }
  388. public override void SetCommunicationMode(int mode)
  389. {
  390. CommunicationType t1 = (CommunicationType)mode;
  391. switch (t1)
  392. {
  393. case CommunicationType.Analogue:
  394. this.SendCmd(AdTecRfMessage.ANALOG);
  395. break;
  396. case CommunicationType.RS232:
  397. this.SendCmd(AdTecRfMessage.RS232);
  398. break;
  399. default:
  400. throw new ArgumentOutOfRangeException("Communication mode error");
  401. }
  402. }
  403. public override void SetPower(float val)
  404. {
  405. if (!(this.ControlMode == EnumRfPowerControlMode.RS232Mode)) SetCommunicationMode(1);
  406. ushort a = !_scEnableCalibration.BoolValue ? (ushort)val : (ushort)CalibrationData(val, true);
  407. if (SendCmd($"{a:D4}{AdTecRfMessage.SET_POWER}"))
  408. {
  409. PowerSetPoint = val;
  410. }
  411. }
  412. public override bool SetPowerOnOff(bool on, out string str)
  413. {
  414. if (!(this.ControlMode == EnumRfPowerControlMode.RS232Mode)) SetCommunicationMode(1);
  415. str = "";
  416. var _chamber = DEVICE.GetDevice<JetPM>(Module);
  417. if (on && !_chamber.CheckGeneratorAndHVInterlock(_device))
  418. {
  419. return false;
  420. }
  421. if (on)
  422. {
  423. SendCmd(AdTecRfMessage.RF_ON);
  424. _bRFPowerOn = true;
  425. _powerOnStartTime = DateTime.Now;
  426. QUERY_INTERVAL = 500;
  427. }
  428. else
  429. {
  430. SendCmd(AdTecRfMessage.RF_OFF);
  431. _bRFPowerOn = false;
  432. ForwardPower = 0;
  433. ReflectPower = 0;
  434. QUERY_INTERVAL = 500;
  435. _ErrTrigger.RST = true;
  436. }
  437. _timerQueryStatus.Start(QUERY_INTERVAL);
  438. return true;
  439. }
  440. //----------------------------------Private Method-------------------------------
  441. //
  442. private void SerialPortDataReceived(string str)
  443. {
  444. if (string.IsNullOrEmpty(str))
  445. {
  446. LOG.Write(eEvent.ERR_RF, Module, "AdTec RFG 无数据反馈");
  447. return;
  448. }
  449. string str2 = str.Trim('\r');
  450. if (str2 == AdTecRfMessage.ERR_RES)
  451. {
  452. LOG.Write(eEvent.WARN_RF, Module, $"AdTEC 收到 [{str2}]");
  453. return;
  454. }
  455. try
  456. {
  457. //LOG.Info($"{Module} Generator rec [{str2}]");
  458. Match match1 = Regex.Match(str2, INFO_PATTERN);
  459. if (!match1.Success)
  460. {
  461. //EV.PostWarningLog(Module, "AdTec 数据格式错误");
  462. if (!SC.GetValue<bool>("System.IsSimulatorMode"))
  463. {
  464. LOG.Write( eEvent.WARN_RF, Module,$"{Module}, AdTec 数据格式错误");
  465. }
  466. return;
  467. }
  468. string[] str1 =
  469. {
  470. match1.Groups[1].Value,
  471. match1.Groups[2].Value,
  472. match1.Groups[3].Value,
  473. match1.Groups[4].Value,
  474. match1.Groups[5].Value
  475. };
  476. this.ParseQueryData(str1);
  477. }
  478. catch (Exception ex)
  479. {
  480. LOG.WriteExeption(ex);
  481. }
  482. }
  483. private void ParseQueryData(string[] strInfo)
  484. {
  485. // Control mode
  486. string s2 = strInfo[0].Substring(0, 1);
  487. this.ControlMode = (EnumRfPowerControlMode)Convert.ToUInt16(s2);
  488. // output mode
  489. string s0 = strInfo[0].Substring(1, 1);
  490. this.WorkMode = (EnumRfPowerWorkMode)Convert.ToUInt16(s0);
  491. // ON/OFF
  492. char s1 = strInfo[0][2];
  493. if (s1 == '1')
  494. {
  495. Status = GeneratorStatus.ON;
  496. }
  497. else if (s1 == '0')
  498. {
  499. Status = GeneratorStatus.OFF;
  500. }
  501. // error code
  502. string alarm = strInfo[0].Substring(5, 2);
  503. byte errCode = Convert.ToByte(alarm);
  504. _ErrTrigger.CLK = errCode > 0;
  505. if (_ErrTrigger.Q)
  506. {
  507. string code = errCode == 1 ? "Ref Over" :
  508. errCode == 2 ? "Ref Limit" :
  509. errCode == 3 ? "Cur Over" :
  510. errCode == 4 ? "Cur Limit" :
  511. errCode == 5 ? "Temp Over" :
  512. errCode == 6 ? "Temp Sensor Short" :
  513. errCode == 7 ? "Temp Sensor Open" :
  514. errCode == 8 ? "Sensor Error" :
  515. errCode == 9 ? "Fwd Power Over" :
  516. errCode == 10 ? "RF ON Timer" :
  517. errCode == 11 ? "RS232C error" :
  518. errCode == 12 ? "Amp Unbalance" :
  519. errCode == 14 ? "Fan error" :
  520. errCode == 15 ? "Coolant Error" :
  521. errCode == 16 ? "Voltage Error" :
  522. errCode == 17 ? "Fwd Power Down" :
  523. errCode == 22 ? "PD Over" :
  524. errCode == 23 ? "PD Limit" :
  525. errCode == 26 ? "Dew Condensation" :
  526. errCode == 29 ? "SW Failure" :
  527. errCode == 99 ? "Safety Lock" : string.Empty;
  528. if (!string.IsNullOrEmpty(code))
  529. {
  530. if (errCode == 99)
  531. LOG.Write(eEvent.EV_DEVICE_INFO, Module, "Source Generator " + code);
  532. else
  533. LOG.Write(eEvent.ERR_RF, Module, "Source Generator " + code);
  534. }
  535. }
  536. // forward power
  537. this.ForwardPower = Convert.ToUInt64(strInfo[2]);
  538. // reflect power
  539. this.ReflectPower = Convert.ToUInt64(strInfo[3]);
  540. }
  541. private void SerialPortErrorOccurred(string obj)
  542. {
  543. Status = GeneratorStatus.ERROR;
  544. LOG.Write(eEvent.ERR_RF, Module, $"AdTec RFG 串口出错, [{obj}]");
  545. }
  546. private bool SendCmd(string str)
  547. {
  548. if (str != AdTecRfMessage.QUERY)
  549. {
  550. LOG.Write(eEvent.EV_DEVICE_INFO, Module, $"Generator send [{str}]");
  551. }
  552. return _serial.Write(str + "\r");
  553. }
  554. }
  555. #endregion RFG
  556. #region match
  557. static class AdTecMatchMessage
  558. {
  559. public const string PRESET = "G";
  560. public const string AUTO = "L";
  561. public const string MANUAL = "M";
  562. public const string PRESET_MEM = "P";
  563. public const string START_QUERY = "S3";
  564. public const string STOP_QUERY = "SP";
  565. public const string WRITE_POS = "$APGR";
  566. public const string READ_POS = "$APRR";
  567. }
  568. class AdTecMatch : RfMatchBase
  569. {
  570. // ----------------------------Fields--------------------------
  571. //
  572. private readonly AsyncSerialPort _serial;
  573. private const ushort S3_HEAD_LENGTH = 2;
  574. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  575. private int QUERY_INTERVAL = 1000;
  576. //private int _scMatchPresetMode;
  577. //private int _scMatchMode;
  578. //private readonly SCConfigItem _scMatchPositionC1;
  579. //private readonly SCConfigItem _scMatchPositionC2;
  580. //private readonly bool _scEnableC1C2Position;
  581. // --------------------------Properties------------------------
  582. //
  583. [Subscription("MatchWorkMode")]
  584. public EnumRfMatchTuneMode WorkMode { get; set; }
  585. public float C1 { get; set; }
  586. public float C2 { get; set; }
  587. [Subscription("VPP")]
  588. public ushort VPP { get; set; }
  589. public override AITRfMatchData DeviceData
  590. {
  591. get
  592. {
  593. return new AITRfMatchData
  594. {
  595. };
  596. }
  597. }
  598. // --------------------------Constructor-----------------------
  599. //
  600. public AdTecMatch(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())
  601. {
  602. var portNum = SC.GetStringValue(device == VenusDevice.Match ? $"{mod}.match.Port" : $"{mod}.BiasMatch.Port");
  603. _serial = new AsyncSerialPort(portNum, 9600, 8);
  604. //_scMatchPresetMode = SC.GetValue<int>($"{Module}.Rf.PresetMode");
  605. //_scMatchMode = SC.GetValue<int>($"{Module}.Rf.MatchMode");
  606. //_scMatchPositionC1 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC1");
  607. //_scMatchPositionC2 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC2");
  608. //_scEnableC1C2Position = SC.GetValue<bool>($"{Module}.Rf.EnableC1C2Position");
  609. }
  610. ~AdTecMatch()
  611. {
  612. _serial?.Close();
  613. }
  614. public override bool Initialize()
  615. {
  616. base.Initialize();
  617. if (_serial.Open())
  618. {
  619. _serial.OnDataChanged += SerialPortDataReceived;
  620. _serial.OnErrorHappened += SerialPortErrorOccurred;
  621. }
  622. else
  623. {
  624. LOG.Write(eEvent.ERR_RF, Module, "Match 串口无法打开");
  625. return false;
  626. }
  627. DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
  628. DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
  629. DATA.Subscribe($"{Module}.{Name}.WorkMode", () => (int)WorkMode);
  630. OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
  631. {
  632. return true;
  633. });
  634. OP.Subscribe($"{Module}.{Name}.SetC2", (func, args) =>
  635. {
  636. return true;
  637. });
  638. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC1}", (out string reason, int time, object[] param) =>
  639. {
  640. SetMatchPositionC1((float)Convert.ToDouble(param[0]), out reason);
  641. return true;
  642. });
  643. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC2}", (out string reason, int time, object[] param) =>
  644. {
  645. SetMatchPositionC2((float)Convert.ToDouble(param[0]), out reason);
  646. return true;
  647. });
  648. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>
  649. {
  650. SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);
  651. return true;
  652. });
  653. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>
  654. {
  655. SetMatchMode((string)param[0] == "Auto" ? EnumRfMatchTuneMode.Auto : EnumRfMatchTuneMode.Manual, out reason);
  656. return true;
  657. });
  658. _timerQueryStatus.Start(QUERY_INTERVAL);
  659. this.SendCmd(AdTecMatchMessage.START_QUERY);
  660. //LOG.Write(eEvent.ERR_RF, Module, "Initialize done.");
  661. return true;
  662. }
  663. public override void Monitor()
  664. {
  665. try
  666. {
  667. if (_timerQueryStatus.IsTimeout())
  668. {
  669. this.SendCmd(AdTecMatchMessage.READ_POS);
  670. _timerQueryStatus.Start(QUERY_INTERVAL);
  671. }
  672. }
  673. catch (Exception ex)
  674. {
  675. LOG.WriteExeption(ex);
  676. }
  677. }
  678. public override void Terminate()
  679. {
  680. this.SendCmd(AdTecMatchMessage.STOP_QUERY);
  681. }
  682. public override void Reset()
  683. {
  684. //SendCmd(AdTecMatchMessage.STOP_QUERY);
  685. }
  686. /// <summary>
  687. ///
  688. /// </summary>
  689. /// <param name="c1,c2">百分比数字</param>
  690. /// <param name="c2"></param>
  691. ///
  692. private async void executeMatchPostion(float c1, float c2)
  693. {
  694. SetWorkMode(EnumRfMatchTuneMode.Manual);
  695. await Task.Delay(200);
  696. SetPosition(c1, c2);
  697. await Task.Delay(200);
  698. SetPresetMemory(0);
  699. await Task.Delay(200);
  700. SetWorkMode(EnumRfMatchTuneMode.Auto);
  701. }
  702. public override void SetMatchPosition(float c1, float c2, out string reason)
  703. {
  704. LOG.Write(eEvent.WARN_RF, Module, $"AdTec Match error [{c1}, {c2}]");
  705. base.SetMatchPosition(c1, c2, out reason);
  706. executeMatchPostion(c1, c2);
  707. reason = "";
  708. }
  709. public void SetPresetMode(RfMatchPresetMode mode)
  710. {
  711. }
  712. // -----------------------Private Method-------------------------
  713. //
  714. private void SerialPortDataReceived(string strOrg)
  715. {
  716. if (string.IsNullOrWhiteSpace(strOrg))
  717. {
  718. LOG.Write(eEvent.ERR_RF, Module, "收到 Match 数据为空");
  719. return;
  720. }
  721. string[] sContent = strOrg.Split('\r');
  722. foreach (var sItem in sContent)
  723. {
  724. string sItem1 = sItem.TrimStart('\n');
  725. if (sItem1.Contains(AdTecMatchMessage.START_QUERY))
  726. {
  727. // BYTE 3,4; bit 7
  728. string s0 = sItem1.Substring(2 + S3_HEAD_LENGTH, 2);
  729. ushort status0 = Convert.ToUInt16(s0, 16);
  730. byte[] a1 = BitConverter.GetBytes(status0);
  731. BitArray ba1 = new BitArray(a1);
  732. this.WorkMode = ba1[7] ? EnumRfMatchTuneMode.Manual : EnumRfMatchTuneMode.Auto;
  733. TuneMode1 = WorkMode;
  734. TuneMode2 = WorkMode;
  735. string sVpp = sItem1.Substring(42 + S3_HEAD_LENGTH, 3);
  736. this.VPP = Convert.ToUInt16(sVpp, 16);
  737. }
  738. else if (sItem1.Contains(AdTecMatchMessage.READ_POS))
  739. {
  740. string s1 = sItem1.Substring(5);
  741. string sLoad = s1.Substring(0, 3);
  742. string sPhase = s1.Substring(3, 3);
  743. this.TunePosition1 = Convert.ToUInt64(sLoad, 16) * 0.1f;
  744. this.TunePosition2 = Convert.ToUInt64(sPhase, 16) * 0.1f;
  745. }
  746. }
  747. }
  748. private void SerialPortErrorOccurred(string str)
  749. {
  750. LOG.Write(eEvent.ERR_RF, Module, $"AdTec Match error [{str}]");
  751. }
  752. private void SendCmd(string str)
  753. {
  754. _serial?.Write(str + "\r");
  755. //EV.PostInfoLog(Module.ToString(), $"Match send [{str}]");
  756. }
  757. private void SetPosition(float c1val, float c2val)
  758. {
  759. ushort val1 = (ushort)(c1val * 10);
  760. ushort val2 = (ushort)(c2val * 10);
  761. string cmd = AdTecMatchMessage.WRITE_POS + val1.ToString("X3") + val2.ToString("X3");
  762. this.SendCmd(cmd);
  763. }
  764. public override bool SetMatchMode(EnumRfMatchTuneMode enumRfMatchTuneMode, out string reason)
  765. {
  766. reason = string.Empty;
  767. SetWorkMode(enumRfMatchTuneMode);
  768. return true;
  769. }
  770. private void SetWorkMode(EnumRfMatchTuneMode mode)
  771. {
  772. this.SendCmd(mode == EnumRfMatchTuneMode.Auto ? AdTecMatchMessage.AUTO :
  773. mode == EnumRfMatchTuneMode.Manual ? AdTecMatchMessage.MANUAL : "");
  774. }
  775. private void SetPresetMemory(byte gear)
  776. {
  777. this.SendCmd(AdTecMatchMessage.PRESET_MEM + gear.ToString());
  778. }
  779. }
  780. #endregion match
  781. }