AdTecRF.cs 30 KB

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