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($"{Module}.Rf.PresetMode"); //_scMatchMode = SC.GetValue($"{Module}.Rf.MatchMode"); //_scMatchPositionC1 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC1"); //_scMatchPositionC2 = SC.GetConfigItem($"{Module}.Rf.MatchPositionC2"); //_scEnableC1C2Position = SC.GetValue($"{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); } /// /// /// /// 百分比数字 /// 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()); } } }