|
@@ -0,0 +1,402 @@
|
|
|
+using System;
|
|
|
+using System.Collections;
|
|
|
+using System.Text.RegularExpressions;
|
|
|
+using Aitex.Core.Common.DeviceData;
|
|
|
+using Aitex.Core.RT.DataCenter;
|
|
|
+using Aitex.Core.RT.Event;
|
|
|
+using Aitex.Core.RT.IOCore;
|
|
|
+using Aitex.Core.RT.Log;
|
|
|
+using Aitex.Core.RT.OperationCenter;
|
|
|
+using Aitex.Core.RT.SCCore;
|
|
|
+using Aitex.Core.RT.Tolerance;
|
|
|
+using Aitex.Core.Util;
|
|
|
+using MECF.Framework.Common.Communications;
|
|
|
+using MECF.Framework.Common.DataCenter;
|
|
|
+using MECF.Framework.Common.Device.Bases;
|
|
|
+using MECF.Framework.Common.Equipment;
|
|
|
+using VirgoCommon;
|
|
|
+using VirgoRT.Modules;
|
|
|
+
|
|
|
+namespace VirgoRT.Devices
|
|
|
+{
|
|
|
+ static class AdTecMatchAMVGMessage
|
|
|
+ {
|
|
|
+ public const string PRESET = "G";
|
|
|
+ public const string AUTO = "L";
|
|
|
+ public const string MANUAL = "M";
|
|
|
+ public const string PRESET_MEM = "P";
|
|
|
+ public const string START_QUERY = "S3";
|
|
|
+ public const string STOP_QUERY = "SP";
|
|
|
+ public const string WRITE_POS = "$APGR";
|
|
|
+ public const string READ_POS = "$APRR";
|
|
|
+
|
|
|
+ public const string Read_VPPMUL = "R48";
|
|
|
+ public const string Read_VPPDIV = "R49";
|
|
|
+
|
|
|
+ public const string Read_LD_MIN = "R00";
|
|
|
+ public const string Read_LD_MAX = "R01";
|
|
|
+
|
|
|
+ public const string Read_PH_MIN = "R02";
|
|
|
+ public const string Read_PH_MAX = "R03";
|
|
|
+ }
|
|
|
+ class AdTecMatchAMVG : RfMatchBase
|
|
|
+ {
|
|
|
+ // ----------------------------Fields--------------------------
|
|
|
+ //
|
|
|
+ private readonly AsyncSerialPort _serial;
|
|
|
+ private const ushort S3_HEAD_LENGTH = 2;
|
|
|
+ private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
|
|
|
+ private int QUERY_INTERVAL = 1000;
|
|
|
+ private float VPP_MUL_R48 = 1;
|
|
|
+ private float VPP_DIV_R49 = 1;
|
|
|
+ private float LD_MIN = 0;
|
|
|
+ private float LD_MAX = 0;
|
|
|
+ private float PH_MIN = 0;
|
|
|
+ private float PH_MAX = 0;
|
|
|
+ //private int _scMatchPresetMode;
|
|
|
+ //private int _scMatchMode;
|
|
|
+ //private readonly SCConfigItem _scMatchPositionC1;
|
|
|
+ //private readonly SCConfigItem _scMatchPositionC2;
|
|
|
+ //private readonly bool _scEnableC1C2Position;
|
|
|
+
|
|
|
+ // --------------------------Properties------------------------
|
|
|
+ //
|
|
|
+ [Subscription("MatchWorkMode")]
|
|
|
+ public EnumRfMatchTuneMode WorkMode { get; set; }
|
|
|
+ public float C1 { get; set; }
|
|
|
+ public float C2 { get; set; }
|
|
|
+
|
|
|
+ [Subscription("VPP")]
|
|
|
+ public ushort VPP { get; set; }
|
|
|
+
|
|
|
+ public override AITRfMatchData DeviceData
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return new AITRfMatchData
|
|
|
+ {
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------------Constructor-----------------------
|
|
|
+ //
|
|
|
+ public AdTecMatchAMVG(ModuleName mod, string name) : base(mod.ToString(), name)
|
|
|
+ {
|
|
|
+ string test = VirgoDevice.Match.ToString();
|
|
|
+
|
|
|
+ var portNum = SC.GetStringValue($"{mod}.{name}.Port");
|
|
|
+
|
|
|
+ //if (name == "Match")
|
|
|
+ //{
|
|
|
+ // portNum = SC.GetStringValue($"{mod}.match.Port");
|
|
|
+ //}
|
|
|
+
|
|
|
+ _serial = new AsyncSerialPort(portNum, 9600, 8);
|
|
|
+
|
|
|
+ EV.PostInfoLog(Module, $"Get AdTec(AMVG) {name},{portNum}");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //_scMatchPresetMode = SC.GetValue<int>($"{Module}.Rf.PresetMode");
|
|
|
+ //_scMatchMode = SC.GetValue<int>($"{Module}.Rf.MatchMode");
|
|
|
+ //_scMatchPositionC1 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC1");
|
|
|
+ //_scMatchPositionC2 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC2");
|
|
|
+ //_scEnableC1C2Position = SC.GetValue<bool>($"{Module}.Rf.EnableC1C2Position");
|
|
|
+ }
|
|
|
+
|
|
|
+ ~AdTecMatchAMVG()
|
|
|
+ {
|
|
|
+ _serial?.Close();
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool Initialize()
|
|
|
+ {
|
|
|
+ base.Initialize();
|
|
|
+
|
|
|
+ if (_serial.Open())
|
|
|
+ {
|
|
|
+ _serial.OnDataChanged += SerialPortDataReceived;
|
|
|
+ _serial.OnErrorHappened += SerialPortErrorOccurred;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ EV.PostAlarmLog(Module, "Match 串口无法打开");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
|
|
|
+ DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
|
|
|
+ DATA.Subscribe($"{Module}.{Name}.MatchProcessMode", () => ((int)WorkMode));
|
|
|
+
|
|
|
+ OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ OP.Subscribe($"{Module}.{Name}.SetC2", (func, args) =>
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC1}", (out string reason, int time, object[] param) =>
|
|
|
+ {
|
|
|
+ SetMatchPositionC1((float)Convert.ToDouble(param[0]), out reason);
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC2}", (out string reason, int time, object[] param) =>
|
|
|
+ {
|
|
|
+ SetMatchPositionC2((float)Convert.ToDouble(param[0]), out reason);
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ OP.Subscribe($"{Module}.{Name}.SetMatchPositionC1AndC2", (out string reason, int time, object[] param) =>
|
|
|
+ {
|
|
|
+ var cValue = param[0].ToString().Split('_');
|
|
|
+ SetMatchPosition((float)Convert.ToDouble(cValue[0]), (float)Convert.ToDouble(cValue[1]), out reason);
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>
|
|
|
+ {
|
|
|
+ SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ EV.PostInfoLog(Module, $"注册 {Name}的SetMatchProcessMode");
|
|
|
+ OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>
|
|
|
+ {
|
|
|
+ var mode = (string)param[0];
|
|
|
+ var modeValue = EnumRfMatchTuneMode.Auto.ToString();
|
|
|
+ if(!string.IsNullOrWhiteSpace(mode))
|
|
|
+ {
|
|
|
+ LOG.Info($"SetMatchProcessMode {Module} {Name} mode={mode}");
|
|
|
+ modeValue = mode == "Hold" ? EnumRfMatchTuneMode.Manual.ToString() : EnumRfMatchTuneMode.Auto.ToString();
|
|
|
+ }
|
|
|
+ SetMatchMode(modeValue, out reason);
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ _timerQueryStatus.Start(QUERY_INTERVAL);
|
|
|
+ SetWorkMode(EnumRfMatchTuneMode.Auto);
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.START_QUERY);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Monitor()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (_timerQueryStatus.IsTimeout())
|
|
|
+ {
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.Read_VPPDIV);
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.Read_VPPMUL);
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.Read_LD_MAX);
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.Read_LD_MIN);
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.Read_PH_MAX);
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.Read_PH_MIN);
|
|
|
+
|
|
|
+ _timerQueryStatus.Start(QUERY_INTERVAL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LOG.Write(ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Terminate()
|
|
|
+ {
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.STOP_QUERY);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Reset()
|
|
|
+ {
|
|
|
+ //SendCmd(AdTecMatchAMVGMessage.STOP_QUERY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ ///
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="c1,c2">百分比数字</param>
|
|
|
+ /// <param name="c2"></param>
|
|
|
+ public override void SetMatchPosition(float c1, float c2, out string reason)
|
|
|
+ {
|
|
|
+ LOG.Info($"SetMatchPosition {Module} {Name} c1={c1} c2={c2}");
|
|
|
+ base.SetMatchPosition(c1, c2, out reason);
|
|
|
+ //this.SetWorkMode(EnumRfMatchTuneMode.Auto);
|
|
|
+ this.SetPosition(c1, c2);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool SetMatchMode(string mode, out string reason)
|
|
|
+ {
|
|
|
+ reason = string.Empty;
|
|
|
+ LOG.Info($"SetMatchMode {Module} {Name} mode={mode}");
|
|
|
+ if (mode == EnumRfMatchTuneMode.Manual.ToString())
|
|
|
+ SetWorkMode(EnumRfMatchTuneMode.Manual);
|
|
|
+ else
|
|
|
+ SetWorkMode(EnumRfMatchTuneMode.Auto);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void SetMatchPositionC1(float c1, out string reason)
|
|
|
+ {
|
|
|
+ LOG.Info($"SetMatchPositionC1 {Module} {Name} c1={c1} ");
|
|
|
+ base.SetMatchPositionC1(c1, out reason);
|
|
|
+ reason = string.Empty;
|
|
|
+ LoadPosition1 = c1;
|
|
|
+ ushort val1 = (ushort)(c1 * 10);
|
|
|
+
|
|
|
+ string cmd = AdTecMatchMessage.WRITE_POS + val1.ToString("X3");
|
|
|
+ this.SendCmd(cmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void SetMatchPositionC2(float c2, out string reason)
|
|
|
+ {
|
|
|
+ LOG.Info($"SetMatchPositionC2 {Module} {Name} c2={c2} ");
|
|
|
+ base.SetMatchPositionC2(c2, out reason);
|
|
|
+ reason = string.Empty;
|
|
|
+ LoadPosition2 = c2;
|
|
|
+ ushort val2 = (ushort)(c2 * 10);
|
|
|
+
|
|
|
+ string cmd = AdTecMatchMessage.WRITE_POS + val2.ToString("X3");
|
|
|
+ this.SendCmd(cmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void SetPresetMode(RfMatchPresetMode mode)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ // -----------------------Private Method-------------------------
|
|
|
+ //
|
|
|
+ private void SerialPortDataReceived(string strOrg)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(strOrg))
|
|
|
+ {
|
|
|
+ EV.PostAlarmLog(Module, "收到 AdTec(AMVG) Match 数据为空");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ string[] sContent = strOrg.Split('\r');
|
|
|
+
|
|
|
+ foreach (var sItem in sContent)
|
|
|
+ {
|
|
|
+ string sItem1 = sItem.TrimStart('\n');
|
|
|
+
|
|
|
+ if (sItem1.Contains(AdTecMatchAMVGMessage.START_QUERY))
|
|
|
+ {
|
|
|
+ // BYTE 3,4; bit 7
|
|
|
+ string s0 = sItem1.Substring(2 + S3_HEAD_LENGTH, 2);
|
|
|
+ ushort status0 = Convert.ToUInt16(s0, 16);
|
|
|
+ byte[] a1 = BitConverter.GetBytes(status0);
|
|
|
+
|
|
|
+ BitArray ba1 = new BitArray(a1);
|
|
|
+
|
|
|
+ this.WorkMode = ba1[7] ? EnumRfMatchTuneMode.Manual : EnumRfMatchTuneMode.Auto;
|
|
|
+
|
|
|
+ TuneMode1 = WorkMode;
|
|
|
+ TuneMode2 = WorkMode;
|
|
|
+
|
|
|
+ string sVpp = sItem1.Substring(42 + S3_HEAD_LENGTH - 1, 3);
|
|
|
+ var tmpVpp = Convert.ToUInt16(sVpp, 16);
|
|
|
+ if (VPP_DIV_R49 != 0)
|
|
|
+ {
|
|
|
+ tmpVpp = Convert.ToUInt16((tmpVpp * VPP_MUL_R48) / VPP_DIV_R49);
|
|
|
+ }
|
|
|
+ this.VPP = tmpVpp;
|
|
|
+
|
|
|
+ string sLoad = sItem1.Substring(27 + S3_HEAD_LENGTH - 1, 3);
|
|
|
+ string sPhase = sItem1.Substring(30 + S3_HEAD_LENGTH - 1, 3);
|
|
|
+
|
|
|
+ var sLoad1 = Convert.ToUInt64(sLoad, 16);
|
|
|
+ var sPhase2 = Convert.ToUInt64(sPhase, 16);
|
|
|
+
|
|
|
+ if (LD_MAX - LD_MIN != 0)
|
|
|
+ {
|
|
|
+ sLoad1 = Convert.ToUInt64((sLoad1 - LD_MIN) * 100 / (LD_MAX - LD_MIN));
|
|
|
+ }
|
|
|
+ if (PH_MAX - PH_MIN != 0)
|
|
|
+ {
|
|
|
+ sPhase2 = Convert.ToUInt64((sPhase2 - PH_MIN) * 100 / (PH_MAX - PH_MIN));
|
|
|
+ }
|
|
|
+ this.TunePosition1 = sLoad1;
|
|
|
+ this.TunePosition2 = sPhase2;
|
|
|
+ }
|
|
|
+ //else if (sItem1.Contains(AdTecMatchAMVGMessage.READ_POS))
|
|
|
+ //{
|
|
|
+ // string s1 = sItem1.Substring(5);
|
|
|
+ // string sLoad = s1.Substring(0, 3);
|
|
|
+ // string sPhase = s1.Substring(3, 3);
|
|
|
+
|
|
|
+
|
|
|
+ // this.TunePosition1 = Convert.ToUInt64(sLoad, 16) * 0.1f;
|
|
|
+ // this.TunePosition2 = Convert.ToUInt64(sPhase, 16) * 0.1f;
|
|
|
+
|
|
|
+ //}
|
|
|
+ else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_VPPMUL))
|
|
|
+ {
|
|
|
+ VPP_MUL_R48 = Convert.ToUInt16(sItem1.Substring(3), 16);
|
|
|
+ }
|
|
|
+ else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_VPPDIV))
|
|
|
+ {
|
|
|
+ VPP_DIV_R49 = Convert.ToUInt16(sItem1.Substring(3), 16);
|
|
|
+ }
|
|
|
+ else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_LD_MIN))
|
|
|
+ {
|
|
|
+ LD_MIN = Convert.ToUInt16(sItem1.Substring(3), 16);
|
|
|
+ }
|
|
|
+ else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_LD_MAX))
|
|
|
+ {
|
|
|
+ LD_MAX = Convert.ToUInt16(sItem1.Substring(3), 16);
|
|
|
+ }
|
|
|
+ else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_PH_MIN))
|
|
|
+ {
|
|
|
+ PH_MIN = Convert.ToUInt16(sItem1.Substring(3), 16);
|
|
|
+ }
|
|
|
+ else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_PH_MAX))
|
|
|
+ {
|
|
|
+ PH_MAX = Convert.ToUInt16(sItem1.Substring(3), 16);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SerialPortErrorOccurred(string str)
|
|
|
+ {
|
|
|
+ EV.PostAlarmLog(Module, $"AdTec(AMVG) Match error [{str}]");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SendCmd(string str)
|
|
|
+ {
|
|
|
+ if (!str.Contains(AdTecMatchAMVGMessage.Read_VPPMUL) &&
|
|
|
+ !str.Contains(AdTecMatchAMVGMessage.Read_VPPDIV) &&
|
|
|
+ !str.Contains(AdTecMatchAMVGMessage.Read_LD_MIN) &&
|
|
|
+ !str.Contains(AdTecMatchAMVGMessage.Read_LD_MAX) &&
|
|
|
+ !str.Contains(AdTecMatchAMVGMessage.Read_PH_MIN) &&
|
|
|
+ !str.Contains(AdTecMatchAMVGMessage.Read_PH_MAX)
|
|
|
+ )
|
|
|
+ {
|
|
|
+ LOG.Info($"{Module} {Name} AdTec(AMVG) match send:{str}");
|
|
|
+ }
|
|
|
+ _serial?.Write(str + "\r");
|
|
|
+ //EV.PostInfoLog(Module.ToString(), $"Match send [{str}]");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetPosition(float c1val, float c2val)
|
|
|
+ {
|
|
|
+ ushort val1 = (ushort)(c1val * 10);
|
|
|
+ ushort val2 = (ushort)(c2val * 10);
|
|
|
+
|
|
|
+ string cmd = AdTecMatchAMVGMessage.WRITE_POS + val1.ToString("X3") + val2.ToString("X3");
|
|
|
+ this.SendCmd(cmd);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetWorkMode(EnumRfMatchTuneMode mode)
|
|
|
+ {
|
|
|
+ this.SendCmd(mode == EnumRfMatchTuneMode.Auto ? AdTecMatchAMVGMessage.AUTO :
|
|
|
+ mode == EnumRfMatchTuneMode.Manual ? AdTecMatchAMVGMessage.MANUAL : "");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetPresetMemory(byte gear)
|
|
|
+ {
|
|
|
+ this.SendCmd(AdTecMatchAMVGMessage.PRESET_MEM + gear.ToString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|