AdTecRF.cs 34 KB

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