AdTecRF.cs 34 KB

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