AdTecMatchAMVG.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  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 VirgoCommon;
  18. using VirgoRT.Modules;
  19. namespace VirgoRT.Devices
  20. {
  21. static class AdTecMatchAMVGMessage
  22. {
  23. public const string PRESET = "G";
  24. public const string AUTO = "L";
  25. public const string MANUAL = "M";
  26. public const string PRESET_MEM = "P";
  27. public const string START_QUERY = "S3";
  28. public const string STOP_QUERY = "SP";
  29. public const string WRITE_POS = "$APGR";
  30. public const string READ_POS = "$APRR";
  31. public const string Read_VPPMUL = "R48";
  32. public const string Read_VPPDIV = "R49";
  33. public const string Read_LD_MIN = "R00";
  34. public const string Read_LD_MAX = "R01";
  35. public const string Read_PH_MIN = "R02";
  36. public const string Read_PH_MAX = "R03";
  37. }
  38. class AdTecMatchAMVG : RfMatchBase
  39. {
  40. // ----------------------------Fields--------------------------
  41. //
  42. private readonly AsyncSerialPort _serial;
  43. private const ushort S3_HEAD_LENGTH = 2;
  44. private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
  45. private int QUERY_INTERVAL = 1000;
  46. private float VPP_MUL_R48 = 1;
  47. private float VPP_DIV_R49 = 1;
  48. private float LD_MIN = 0;
  49. private float LD_MAX = 0;
  50. private float PH_MIN = 0;
  51. private float PH_MAX = 0;
  52. private bool isMatch => Name == "match";
  53. //private int _scMatchPresetMode;
  54. //private int _scMatchMode;
  55. //private readonly SCConfigItem _scMatchPositionC1;
  56. //private readonly SCConfigItem _scMatchPositionC2;
  57. //private readonly bool _scEnableC1C2Position;
  58. // --------------------------Properties------------------------
  59. //
  60. [Subscription("MatchWorkMode")]
  61. public EnumRfMatchTuneMode WorkMode { get; set; }
  62. public float C1 { get; set; }
  63. public float C2 { get; set; }
  64. [Subscription("VPP")]
  65. public ushort VPP { get; set; }
  66. public override AITRfMatchData DeviceData
  67. {
  68. get
  69. {
  70. return new AITRfMatchData
  71. {
  72. };
  73. }
  74. }
  75. // --------------------------Constructor-----------------------
  76. //
  77. public AdTecMatchAMVG(ModuleName mod, string name) : base(mod.ToString(), name)
  78. {
  79. string test = VirgoDevice.Match.ToString();
  80. var portNum = SC.GetStringValue($"{mod}.{name}.Port");
  81. //if (name == "Match")
  82. //{
  83. // portNum = SC.GetStringValue($"{mod}.match.Port");
  84. //}
  85. _serial = new AsyncSerialPort(portNum, 9600, 8);
  86. EV.PostInfoLog(Module, $"Get AdTec(AMVG) {name},{portNum}");
  87. //_scMatchPresetMode = SC.GetValue<int>($"{Module}.Rf.PresetMode");
  88. //_scMatchMode = SC.GetValue<int>($"{Module}.Rf.MatchMode");
  89. //_scMatchPositionC1 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC1");
  90. //_scMatchPositionC2 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC2");
  91. //_scEnableC1C2Position = SC.GetValue<bool>($"{Module}.Rf.EnableC1C2Position");
  92. }
  93. ~AdTecMatchAMVG()
  94. {
  95. _serial?.Close();
  96. }
  97. public override bool Initialize()
  98. {
  99. base.Initialize();
  100. if (_serial.Open())
  101. {
  102. _serial.OnDataChanged += SerialPortDataReceived;
  103. _serial.OnErrorHappened += SerialPortErrorOccurred;
  104. }
  105. else
  106. {
  107. EV.PostAlarmLog(Module, "Match 串口无法打开");
  108. return false;
  109. }
  110. DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
  111. DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
  112. DATA.Subscribe($"{Module}.{Name}.MatchProcessMode", () => ((int)WorkMode));
  113. OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
  114. {
  115. return true;
  116. });
  117. OP.Subscribe($"{Module}.{Name}.SetC2", (func, args) =>
  118. {
  119. return true;
  120. });
  121. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC1}", (out string reason, int time, object[] param) =>
  122. {
  123. SetMatchPositionC1((float)Convert.ToDouble(param[0]), out reason);
  124. return true;
  125. });
  126. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC2}", (out string reason, int time, object[] param) =>
  127. {
  128. SetMatchPositionC2((float)Convert.ToDouble(param[0]), out reason);
  129. return true;
  130. });
  131. OP.Subscribe($"{Module}.{Name}.SetMatchPositionC1AndC2", (out string reason, int time, object[] param) =>
  132. {
  133. var cValue = param[0].ToString().Split('_');
  134. SetMatchPosition((float)Convert.ToDouble(cValue[0]), (float)Convert.ToDouble(cValue[1]), out reason);
  135. return true;
  136. });
  137. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>
  138. {
  139. SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);
  140. return true;
  141. });
  142. EV.PostInfoLog(Module, $"注册 {Name}的SetMatchProcessMode");
  143. OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>
  144. {
  145. var mode = (string)param[0];
  146. var modeValue = EnumRfMatchTuneMode.Auto.ToString();
  147. if(!string.IsNullOrWhiteSpace(mode))
  148. {
  149. LOG.Info($"SetMatchProcessMode {Module} {Name} mode={mode}");
  150. modeValue = mode == "Hold" ? EnumRfMatchTuneMode.Manual.ToString() : EnumRfMatchTuneMode.Auto.ToString();
  151. }
  152. SetMatchMode(modeValue, out reason);
  153. return true;
  154. });
  155. _timerQueryStatus.Start(QUERY_INTERVAL);
  156. SetWorkMode(EnumRfMatchTuneMode.Auto);
  157. this.SendCmd(AdTecMatchAMVGMessage.START_QUERY);
  158. return true;
  159. }
  160. public override void Monitor()
  161. {
  162. try
  163. {
  164. if (_timerQueryStatus.IsTimeout())
  165. {
  166. this.SendCmd(AdTecMatchAMVGMessage.Read_VPPDIV);
  167. this.SendCmd(AdTecMatchAMVGMessage.Read_VPPMUL);
  168. this.SendCmd(AdTecMatchAMVGMessage.Read_LD_MAX);
  169. this.SendCmd(AdTecMatchAMVGMessage.Read_LD_MIN);
  170. this.SendCmd(AdTecMatchAMVGMessage.Read_PH_MAX);
  171. this.SendCmd(AdTecMatchAMVGMessage.Read_PH_MIN);
  172. _timerQueryStatus.Start(QUERY_INTERVAL);
  173. }
  174. }
  175. catch (Exception ex)
  176. {
  177. LOG.Write(ex);
  178. }
  179. }
  180. public override void Terminate()
  181. {
  182. this.SendCmd(AdTecMatchAMVGMessage.STOP_QUERY);
  183. }
  184. public override void Reset()
  185. {
  186. //SendCmd(AdTecMatchAMVGMessage.STOP_QUERY);
  187. }
  188. /// <summary>
  189. ///
  190. /// </summary>
  191. /// <param name="c1,c2">百分比数字</param>
  192. /// <param name="c2"></param>
  193. public override void SetMatchPosition(float c1, float c2, out string reason)
  194. {
  195. reason = string.Empty;
  196. if (isMatch) return;
  197. LOG.Info($"SetMatchPosition {Module} {Name} c1={c1} c2={c2}");
  198. base.SetMatchPosition(c1, c2, out reason);
  199. //this.SetWorkMode(EnumRfMatchTuneMode.Auto);
  200. this.SetPosition(c1, c2);
  201. }
  202. public override bool SetMatchMode(string mode, out string reason)
  203. {
  204. reason = string.Empty;
  205. if (isMatch) return true;
  206. LOG.Info($"SetMatchMode {Module} {Name} mode={mode}");
  207. if (mode == EnumRfMatchTuneMode.Manual.ToString())
  208. SetWorkMode(EnumRfMatchTuneMode.Manual);
  209. else
  210. SetWorkMode(EnumRfMatchTuneMode.Auto);
  211. return true;
  212. }
  213. public override void SetMatchPositionC1(float c1, out string reason)
  214. {
  215. reason = string.Empty;
  216. if (isMatch) return;
  217. LOG.Info($"SetMatchPositionC1 {Module} {Name} c1={c1} ");
  218. base.SetMatchPositionC1(c1, out reason);
  219. LoadPosition1 = c1;
  220. ushort val1 = (ushort)(c1 * 10);
  221. string cmd = AdTecMatchMessage.WRITE_POS + val1.ToString("X3");
  222. this.SendCmd(cmd);
  223. }
  224. public override void SetMatchPositionC2(float c2, out string reason)
  225. {
  226. reason = string.Empty;
  227. if (isMatch) return;
  228. LOG.Info($"SetMatchPositionC2 {Module} {Name} c2={c2} ");
  229. base.SetMatchPositionC2(c2, out reason);
  230. LoadPosition2 = c2;
  231. ushort val2 = (ushort)(c2 * 10);
  232. string cmd = AdTecMatchMessage.WRITE_POS + val2.ToString("X3");
  233. this.SendCmd(cmd);
  234. }
  235. public void SetPresetMode(RfMatchPresetMode mode)
  236. {
  237. }
  238. // -----------------------Private Method-------------------------
  239. //
  240. private void SerialPortDataReceived(string strOrg)
  241. {
  242. if (string.IsNullOrWhiteSpace(strOrg))
  243. {
  244. EV.PostAlarmLog(Module, "收到 AdTec(AMVG) Match 数据为空");
  245. return;
  246. }
  247. string[] sContent = strOrg.Split('\r');
  248. foreach (var sItem in sContent)
  249. {
  250. string sItem1 = sItem.TrimStart('\n');
  251. if (sItem1.Contains(AdTecMatchAMVGMessage.START_QUERY))
  252. {
  253. // BYTE 3,4; bit 7
  254. string s0 = sItem1.Substring(2 + S3_HEAD_LENGTH, 2);
  255. ushort status0 = Convert.ToUInt16(s0, 16);
  256. byte[] a1 = BitConverter.GetBytes(status0);
  257. BitArray ba1 = new BitArray(a1);
  258. this.WorkMode = ba1[7] ? EnumRfMatchTuneMode.Manual : EnumRfMatchTuneMode.Auto;
  259. TuneMode1 = WorkMode;
  260. TuneMode2 = WorkMode;
  261. string sVpp = sItem1.Substring(42 + S3_HEAD_LENGTH - 1, 3);
  262. var tmpVpp = Convert.ToUInt16(sVpp, 16);
  263. if (VPP_DIV_R49 != 0)
  264. {
  265. tmpVpp = Convert.ToUInt16((tmpVpp * VPP_MUL_R48) / VPP_DIV_R49);
  266. }
  267. this.VPP = tmpVpp;
  268. string sLoad = sItem1.Substring(27 + S3_HEAD_LENGTH - 1, 3);
  269. string sPhase = sItem1.Substring(30 + S3_HEAD_LENGTH - 1, 3);
  270. var sLoad1 = Convert.ToUInt64(sLoad, 16);
  271. var sPhase2 = Convert.ToUInt64(sPhase, 16);
  272. if (LD_MAX - LD_MIN != 0)
  273. {
  274. sLoad1 = Convert.ToUInt64((sLoad1 - LD_MIN) * 100 / (LD_MAX - LD_MIN));
  275. }
  276. if (PH_MAX - PH_MIN != 0)
  277. {
  278. sPhase2 = Convert.ToUInt64((sPhase2 - PH_MIN) * 100 / (PH_MAX - PH_MIN));
  279. }
  280. this.TunePosition1 = sLoad1;
  281. this.TunePosition2 = sPhase2;
  282. }
  283. //else if (sItem1.Contains(AdTecMatchAMVGMessage.READ_POS))
  284. //{
  285. // string s1 = sItem1.Substring(5);
  286. // string sLoad = s1.Substring(0, 3);
  287. // string sPhase = s1.Substring(3, 3);
  288. // this.TunePosition1 = Convert.ToUInt64(sLoad, 16) * 0.1f;
  289. // this.TunePosition2 = Convert.ToUInt64(sPhase, 16) * 0.1f;
  290. //}
  291. else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_VPPMUL))
  292. {
  293. VPP_MUL_R48 = Convert.ToUInt16(sItem1.Substring(3), 16);
  294. }
  295. else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_VPPDIV))
  296. {
  297. VPP_DIV_R49 = Convert.ToUInt16(sItem1.Substring(3), 16);
  298. }
  299. else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_LD_MIN))
  300. {
  301. LD_MIN = Convert.ToUInt16(sItem1.Substring(3), 16);
  302. }
  303. else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_LD_MAX))
  304. {
  305. LD_MAX = Convert.ToUInt16(sItem1.Substring(3), 16);
  306. }
  307. else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_PH_MIN))
  308. {
  309. PH_MIN = Convert.ToUInt16(sItem1.Substring(3), 16);
  310. }
  311. else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_PH_MAX))
  312. {
  313. PH_MAX = Convert.ToUInt16(sItem1.Substring(3), 16);
  314. }
  315. }
  316. }
  317. private void SerialPortErrorOccurred(string str)
  318. {
  319. EV.PostAlarmLog(Module, $"AdTec(AMVG) Match error [{str}]");
  320. }
  321. private void SendCmd(string str)
  322. {
  323. if (!str.Contains(AdTecMatchAMVGMessage.Read_VPPMUL) &&
  324. !str.Contains(AdTecMatchAMVGMessage.Read_VPPDIV) &&
  325. !str.Contains(AdTecMatchAMVGMessage.Read_LD_MIN) &&
  326. !str.Contains(AdTecMatchAMVGMessage.Read_LD_MAX) &&
  327. !str.Contains(AdTecMatchAMVGMessage.Read_PH_MIN) &&
  328. !str.Contains(AdTecMatchAMVGMessage.Read_PH_MAX)
  329. )
  330. {
  331. LOG.Info($"{Module} {Name} AdTec(AMVG) match send:{str}");
  332. }
  333. _serial?.Write(str + "\r");
  334. //EV.PostInfoLog(Module.ToString(), $"Match send [{str}]");
  335. }
  336. private void SetPosition(float c1val, float c2val)
  337. {
  338. if (isMatch) return;
  339. ushort val1 = (ushort)(c1val * 10);
  340. ushort val2 = (ushort)(c2val * 10);
  341. string cmd = AdTecMatchAMVGMessage.WRITE_POS + val1.ToString("X3") + val2.ToString("X3");
  342. this.SendCmd(cmd);
  343. }
  344. private void SetWorkMode(EnumRfMatchTuneMode mode)
  345. {
  346. if (isMatch) return;
  347. this.SendCmd(mode == EnumRfMatchTuneMode.Auto ? AdTecMatchAMVGMessage.AUTO :
  348. mode == EnumRfMatchTuneMode.Manual ? AdTecMatchAMVGMessage.MANUAL : "");
  349. }
  350. private void SetPresetMemory(byte gear)
  351. {
  352. if (isMatch) return;
  353. this.SendCmd(AdTecMatchAMVGMessage.PRESET_MEM + gear.ToString());
  354. }
  355. }
  356. }