AdTecMatchAMVG.cs 15 KB

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