AdTecRF.cs 31 KB

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