AdTecRF.cs 34 KB

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