AdTecRF.cs 33 KB

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