| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000 | using System;using System.Threading.Tasks;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 Aitex.Core.RT.Device;using MECF.Framework.Common.Communications;using MECF.Framework.Common.DataCenter;using MECF.Framework.Common.Device.Bases;using MECF.Framework.Common.Equipment;using Venus_Core;using System.Collections.Generic;using System.Diagnostics;using System.Net.Sockets;using Venus_RT.Modules;using System.Windows.Interop;using Venus_RT.Modules.PMs;namespace Venus_RT.Devices{    #region RFG    static class AdTecRfMessage    {        public static string ANALOG = "";        public const string EOF = "\r";        public const char DELIMITER = ' ';        public const string MANUAL = "MANUAL";        public const string RS232 = "***";        public const string SET_POWER = " W";        public const string RF_ON = "G";        public const string RF_OFF = "S";        public const string ERR_RES = "N";        public const string QUERY = "Q";        public const string RESET = "RESET";        public const string CHK_COMM = "HS";    }    class AdTecGenerator : RfPowerBase    {        // ----------------------------Fields--------------------------        //        private int QUERY_INTERVAL = 5000;        private const string INFO_PATTERN = @"(\d{7})\s(\d{5})\s(\d{5})\s(\d{5})\s(\d{5})";        private double _total;        private double _fromLast;        private bool _bRFPowerOn = false;        private readonly AsyncSerialPort _serial;        private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();        private readonly DeviceTimer _timerTotal = new DeviceTimer();        private readonly DeviceTimer _timerFromLast = new DeviceTimer();        private readonly DeviceTimer _timerRFTurnOn = new DeviceTimer();        private DateTime _powerOnStartTime;        private TimeSpan _powerOnElapsedTime;        private readonly RD_TRIG _rfOnTrigger = new RD_TRIG();        private readonly R_TRIG _ErrTrigger = new R_TRIG();        private readonly R_TRIG _trigPMNeeded = new R_TRIG();        private readonly RD_TRIG _trigOnOff = new RD_TRIG();        private ToleranceChecker _checkerPower;        private ToleranceChecker _checkerReflectPower;        private readonly double _scPowerAlarmTime;        private readonly double _scPowerAlarmRange;        private readonly double _scPowerWarningTime;        private readonly double _scPowerWarningRange;        private readonly double _scReflectPowerAlarmTime;        private readonly double _scReflectPowerAlarmRange;        private readonly double _scPowerRange;        private readonly DIAccessor _diIntlk;        private StatsDataItemRFAndPump _statRFOnTime;        private readonly VenusDevice _device;        private Stopwatch monitorStopwatch = new Stopwatch();        private JetPMBase _chamber;        //private bool _intrtlockFlag = false;        public bool ConnectedStatus { get; set; }        public override float ScalePower => (float)_scPowerRange;        public GeneratorStatus Status { get; set; }        public string LastPMTime        {            get            {                return _statRFOnTime != null ? _statRFOnTime.LastPMTime.ToString() : "";            }        }        public double DaysFromLastPM        {            get            {                return _statRFOnTime == null ? 0 : _statRFOnTime.fromLastPM;            }            set            {                if (_statRFOnTime != null)                    _statRFOnTime.fromLastPM = value;            }        }        public double TotalDays        {            get            {                return _statRFOnTime != null ? _statRFOnTime.Total : 0;            }            set            {                if (_statRFOnTime != null)                    _statRFOnTime.Total = value;            }        }        public double PMIntervalDays        {            get            {                return _statRFOnTime != null ? _statRFOnTime.PMInterval : 0;            }        }        public bool IsPMNeeded        {            get            {                return DaysFromLastPM > PMIntervalDays;            }        }        public bool EnableAlarm        {            get            {                return _statRFOnTime == null || _statRFOnTime.AlarmEnable;            }        }        public override bool IsPowerOn        {            get => Status == GeneratorStatus.ON;            set { }        }        public override bool IsError        {            get => Status == GeneratorStatus.ERROR;            set { }        }        [Subscription("PowerOnTime")]        public string PowerOnTime        {            get            {                if (_bRFPowerOn)                    _powerOnElapsedTime = DateTime.Now - _powerOnStartTime;                return $"{(int)_powerOnElapsedTime.TotalHours:00}:{_powerOnElapsedTime.Minutes:00}:{(_powerOnElapsedTime.Seconds > 0 ? (_powerOnElapsedTime.Seconds + 1) : 0):00}";            }        }        public bool RFInterlock => _diIntlk == null || _diIntlk.Value;        private float _forwardPower;        public override float ForwardPower        {            get            {                return _forwardPower;            }            set            {                _forwardPower = CalibrationData(value, false);            }        }        public new AITRfData DeviceData =>            new AITRfData            {                Module = Module,                DeviceName = Name,                ScalePower = ScalePower,                ForwardPower = ForwardPower,                ReflectPower = ReflectPower,                IsRfOn = IsPowerOn,                PowerSetPoint = PowerSetPoint,                PowerOnElapsedTime = PowerOnTime,                IsInterlockOk = RFInterlock,                WorkMode = (int)RfMode.ContinuousWaveMode,                DisplayName = "Source RF",            };        // --------------------------Constructor-----------------------        //        public AdTecGenerator(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())        {            var portNum = SC.GetStringValue(device == VenusDevice.Rf ? $"{mod}.Rf.Port" : $"{mod}.BiasRf.Port");            this.Status = GeneratorStatus.Unknown;            _device = device;            _serial = new AsyncSerialPort(portNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "\r\r");            _scPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmTime");            _scPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.PowerAlarmRange");            _scPowerWarningTime = SC.GetValue<double>($"{Module}.{Name}.PowerWarningTime");            _scPowerWarningRange = SC.GetValue<double>($"{Module}.{Name}.PowerWarningRange");            _scReflectPowerAlarmTime = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmTime");            _scReflectPowerAlarmRange = SC.GetValue<double>($"{Module}.{Name}.ReflectPowerAlarmRange");            _scPowerRange = SC.GetValue<double>($"{Module}.{Name}.PowerRange");            _scEnableCalibration = SC.GetConfigItem($"{Module}.{Name}.EnableCalibration");            _scCalibrationTable = SC.GetConfigItem($"{Module}.{Name}.CalibrationTable");            _diIntlk = IO.DI[$"{Module}.DI_RF_Generator_Interlock"];            SerachCommandList = new List<string>()            {            AdTecRfMessage.QUERY            };            intervalTime = 300;            sendDataChangedEvent += SkyPump_sendDataChangedEvent;            baseStopwatch.Start();            baseTimer.Enabled = true;            monitorStopwatch.Start();        }        private void SkyPump_sendDataChangedEvent(string obj)        {            var newstr = obj + "\r";            _serial?.Write(newstr);        }        ~AdTecGenerator()        {            _serial?.Close();        }        public override bool Initialize()        {            base.Initialize();            DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetPowerOnOff}", (out string reason, int time, object[] param) =>            {                SetPowerOnOff(Convert.ToBoolean((string)param[0]), out reason);                return true;            });            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetPower}", (out string reason, int time, object[] param) =>            {                reason = "";                ushort val = Convert.ToUInt16(param[0]);                SetPower(val);                return true;            });            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetContinuousPower}", (out string reason, int time, object[] param) =>            {                reason = "";                ushort val = Convert.ToUInt16(param[0]);                SetPower(val);                return true;            });            if (_serial.Open())            {                this.ConnectedStatus = true;                _serial.OnDataChanged += SerialPortDataReceived;                _serial.OnErrorHappened += SerialPortErrorOccurred;            }            else            {                this.ConnectedStatus = false;                LOG.Write(eEvent.ERR_RF, Module, "AD TEC 射频发生器串口无法打开");                return false;            }            _statRFOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.RfOnTime");            _timerQueryStatus.Start(QUERY_INTERVAL);            _checkerPower = new ToleranceChecker(_scPowerAlarmTime);            _checkerReflectPower = new ToleranceChecker(_scReflectPowerAlarmTime);            SetCommunicationMode(1);            return true;        }        public override void Monitor()        {            // 状态查询            //if (_timerQueryStatus.IsTimeout())            //{            //    this.SendCmd(AdTecRfMessage.QUERY);            //    _timerQueryStatus.Start(QUERY_INTERVAL);            //}            // power on triggered            _rfOnTrigger.CLK = IsPowerOn;            if (_rfOnTrigger.R)            {                _total = TotalDays;                _fromLast = DaysFromLastPM;                _timerTotal.Start(0);                _timerFromLast.Start(0);                _powerOnStartTime = DateTime.Now;                _checkerPower.Reset(_scPowerAlarmTime);                _checkerReflectPower.Reset(_scReflectPowerAlarmTime);                _alarmChecker.Reset(_scPowerAlarmTime);                _warningChecker.Reset(_scPowerWarningTime);            }            if (_rfOnTrigger.M)            {                TotalDays = _total + _timerTotal.GetElapseTime() / 1000 / 60 / 60;                DaysFromLastPM = _fromLast + _timerFromLast.GetElapseTime() / 1000 / 60 / 60;                //_checkerPower.Monitor(ForwardPower, PowerSetPoint - _scPowerAlarmRange, PowerSetPoint + _scPowerAlarmRange, _scPowerAlarmTime);                //if (_checkerPower.Trig)                //{                //    EV.PostAlarmLog($"{Module}",                //        $"{Display} Forward power {ForwardPower:0} out of range[{PowerSetPoint - _scPowerAlarmRange:0},{PowerSetPoint + _scPowerAlarmRange:0}] in {_scPowerAlarmTime:0} seconds");                //    SetPowerOnOff(false, out _);                //}                //if (_recipeAlarmRange > 0 && _recipeAlarmRange / 100.0 * PowerSetPoint < _scPowerAlarmRange)                //{                //    if (_recipeIgnoreTimer.GetElapseTime() > _recipeIgnoreTimeMS)                //    {                //        _recipeAlarmChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_recipeAlarmRange / 100.0 * PowerSetPoint), PowerSetPoint + Math.Abs(_recipeAlarmRange / 100.0 * PowerSetPoint), _scPowerAlarmTime);                //        if (_recipeAlarmChecker.Trig)                //        {                //            LOG.Write(eEvent.ERR_RF, Module, Display + $" out of tolerance in {_scPowerAlarmTime:0} seconds");                //            SetPowerOnOff(false, out _);                //        }                //    }                //}                //else                //{                //    _alarmChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_scPowerAlarmRange), PowerSetPoint + Math.Abs(_scPowerAlarmRange), _scPowerAlarmTime);                //    if (_alarmChecker.Trig)                //    {                //        LOG.Write(eEvent.ERR_RF, Module, Display + $" out of tolerance in {_scPowerAlarmTime:0} seconds");                //    }                //}                //if (_recipeWarningRange > 0 && _recipeWarningRange / 100.0 * PowerSetPoint < _scPowerWarningRange)                //{                //    if (_recipeIgnoreTimer.GetElapseTime() > _recipeIgnoreTimeMS)                //    {                //        _recipeWarningChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_recipeWarningRange / 100.0 * PowerSetPoint), PowerSetPoint + Math.Abs(_recipeWarningRange / 100.0 * PowerSetPoint), _scPowerWarningTime);                //        if (_recipeWarningChecker.Trig)                //        {                //            EV.PostWarningLog(Module, Display + $" out of tolerance in {_scPowerWarningTime:0} seconds");                //        }                //    }                //}                //else                //{                //    _warningChecker.Monitor(ForwardPower, PowerSetPoint - Math.Abs(_scPowerWarningRange), PowerSetPoint + Math.Abs(_scPowerWarningRange), _scPowerWarningTime);                //    if (_warningChecker.Trig)                //    {                //        EV.PostWarningLog(Module, Display + $" out of tolerance in {_scPowerWarningTime:0} seconds");                //    }                //}                //_checkerReflectPower.Monitor(ReflectPower, double.MinValue, _scReflectPowerAlarmRange, _scReflectPowerAlarmTime);                //if (_checkerReflectPower.Trig)                //{                //    LOG.Write(eEvent.ERR_RF, Module,                //        $"{Display} Reflect power {ReflectPower:0} out of range[0,{_scReflectPowerAlarmRange:0}] in {_scReflectPowerAlarmTime:0} seconds");                //    SetPowerOnOff(false, out _);                //}            }            if (PMIntervalDays > 0)            {                _trigPMNeeded.CLK = IsPMNeeded;                if (_trigPMNeeded.Q)                {                    if (EnableAlarm)                    {                        LOG.Write(eEvent.ERR_RF, Module, "rf on time value larger than setting interval days");                    }                }            }            if (_rfOnTrigger.T)                //StatsDataManager.Instance.Increase($"{Module}.RfOnTime", $"{Module} RfOnTime", DaysFromLastPM, TotalDays);            if (!_rfOnTrigger.CLK)            {                ForwardPower = 0;                ReflectPower = 0;            }            // 通信 checking, 2 second 一次            //if (_timerComm.IsTimeout() && !_bQueryComm)            //{            //    this.SendCmd(AdTecRfMessage.CHK_COMM);            //    _bQueryComm = true;            //    _timerComm.Start(CHK_COMM_INTERVAL);            //}            // RF Turn On & Off Timeout Check            _trigOnOff.CLK = _bRFPowerOn;            if (_trigOnOff.R)   //RF Turn On            {                _timerRFTurnOn.Start(SC.GetValue<int>($"{Module}.{Name}.RFTurnOnTimeout") * 1000);            }            if (_trigOnOff.M)   //RF Stay On            {                if (_timerRFTurnOn.IsTimeout())                {                    if (!IsPowerOn)                    {                        LOG.Write(eEvent.ERR_RF, Module, $"{Name} Turn On Failed");                        _timerRFTurnOn.Stop();                    }                }            }            if (_trigOnOff.T)            {                _timerRFTurnOn.Stop();            }            if (monitorStopwatch.ElapsedMilliseconds > 1000)            {                if (IsPowerOn == true && _chamber != null && _chamber.RFInterlock(_device) == false)                {                    SetPowerOnOff(false, out _);                }                monitorStopwatch.Restart();            }            base.Monitor();        }        public override void Terminate()        {            if (IsPowerOn)            {                SetPowerOnOff(false, out _);            }            _serial?.Close();        }        public override void Reset()        {            _rfOnTrigger.RST = true;            _ErrTrigger.RST = true;            _trigPMNeeded.RST = true;            this.SendCmd(AdTecRfMessage.RESET);            this.Status = GeneratorStatus.OFF;            _bRFPowerOn = false;            base.Reset();        }        public void SetRfMode(RfMode mode)        {            throw new NotImplementedException();        }        public override void SetCommunicationMode(int mode)        {            CommunicationType t1 = (CommunicationType)mode;            switch (t1)            {                case CommunicationType.Analogue:                    this.SendCmd(AdTecRfMessage.ANALOG);                    break;                case CommunicationType.RS232:                    this.SendCmd(AdTecRfMessage.RS232);                    break;                default:                    throw new ArgumentOutOfRangeException("Communication mode error");            }        }        public override void SetPower(float val)        {            if (!(this.ControlMode == EnumRfPowerControlMode.RS232Mode)) SetCommunicationMode(1);            ushort a = !_scEnableCalibration.BoolValue ? (ushort)val : (ushort)CalibrationData(val, true);            if (SendCmd($"{a:D4}{AdTecRfMessage.SET_POWER}"))            {                PowerSetPoint = val;            }        }        public override bool SetPowerOnOff(bool on, out string str)        {            if (!(this.ControlMode == EnumRfPowerControlMode.RS232Mode)) SetCommunicationMode(1);            str = "";            _chamber = DEVICE.GetDevice<JetPMBase>(Module);            //if (on && !_chamber.CheckGeneratorAndHVInterlock(_device))            //{            //    return false;            //}            if (on)            {                SendCmd(AdTecRfMessage.RF_ON);                _bRFPowerOn = true;                _powerOnStartTime = DateTime.Now;                QUERY_INTERVAL = 500;            }            else            {                SendCmd(AdTecRfMessage.RF_OFF);                _bRFPowerOn = false;                ForwardPower = 0;                ReflectPower = 0;                QUERY_INTERVAL = 500;                _ErrTrigger.RST = true;            }            _timerQueryStatus.Start(QUERY_INTERVAL);            return true;        }        //----------------------------------Private Method-------------------------------        //        private void SerialPortDataReceived(string str)        {            if (string.IsNullOrEmpty(str))            {                LOG.Write(eEvent.ERR_RF, Module, "AdTec RFG 无数据反馈");                return;            }            string str2 = str.Trim('\r');            if (str2 == AdTecRfMessage.ERR_RES)            {                LOG.Write(eEvent.WARN_RF, Module, $"AdTEC 收到 [{str2}]");                return;            }            try            {                //LOG.Info($"{Module} Generator rec [{str2}]");                Match match1 = Regex.Match(str2, INFO_PATTERN);                if (!match1.Success)                {                    //EV.PostWarningLog(Module, "AdTec 数据格式错误");                    if (!SC.GetValue<bool>("System.IsSimulatorMode"))                    {                        LOG.Write(eEvent.WARN_RF, Module, $"{Module}, AdTec 数据格式错误");                    }                    return;                }                string[] str1 =                {                    match1.Groups[1].Value,                    match1.Groups[2].Value,                    match1.Groups[3].Value,                    match1.Groups[4].Value,                    match1.Groups[5].Value                };                this.ParseQueryData(str1);            }            catch (Exception ex)            {                LOG.WriteExeption(ex);            }        }        private void ParseQueryData(string[] strInfo)        {            // Control mode            string s2 = strInfo[0].Substring(0, 1);            this.ControlMode = (EnumRfPowerControlMode)Convert.ToUInt16(s2);            // output mode            string s0 = strInfo[0].Substring(1, 1);            this.WorkMode = (EnumRfPowerWorkMode)Convert.ToUInt16(s0);            // ON/OFF            char s1 = strInfo[0][2];            if (s1 == '1')            {                Status = GeneratorStatus.ON;            }            else if (s1 == '0')            {                Status = GeneratorStatus.OFF;            }            // error code            string alarm = strInfo[0].Substring(5, 2);            byte errCode = Convert.ToByte(alarm);            _ErrTrigger.CLK = errCode > 0;            if (_ErrTrigger.Q)            {                string code = errCode == 1 ? "Ref Over" :                    errCode == 2 ? "Ref Limit" :                    errCode == 3 ? "Cur Over" :                    errCode == 4 ? "Cur Limit" :                    errCode == 5 ? "Temp Over" :                    errCode == 6 ? "Temp Sensor Short" :                    errCode == 7 ? "Temp Sensor Open" :                    errCode == 8 ? "Sensor Error" :                    errCode == 9 ? "Fwd Power Over" :                    errCode == 10 ? "RF ON Timer" :                    errCode == 11 ? "RS232C error" :                    errCode == 12 ? "Amp Unbalance" :                    errCode == 14 ? "Fan error" :                    errCode == 15 ? "Coolant Error" :                    errCode == 16 ? "Voltage Error" :                    errCode == 17 ? "Fwd Power Down" :                    errCode == 22 ? "PD Over" :                    errCode == 23 ? "PD Limit" :                    errCode == 26 ? "Dew Condensation" :                    errCode == 29 ? "SW Failure" :                    errCode == 99 ? "Safety Lock" : string.Empty;                if (!string.IsNullOrEmpty(code))                {                    if (errCode == 99)                        LOG.Write(eEvent.EV_DEVICE_INFO, Module, "Source Generator " + code);                    else                    {                        LOG.Write(eEvent.ERR_RF, Module, "Source Generator " + code);                        Singleton<RouteManager>.Instance.GetPM(ModuleHelper.Converter(Module)).PostMsg(PMEntity.MSG.Error);                    }                }            }            // forward power            this.ForwardPower = Convert.ToUInt64(strInfo[2]);            // reflect power            this.ReflectPower = Convert.ToUInt64(strInfo[3]);        }        private void SerialPortErrorOccurred(string obj)        {            Status = GeneratorStatus.ERROR;            LOG.Write(eEvent.ERR_RF, Module, $"AdTec RFG 串口出错, [{obj}]");        }        private bool SendCmd(string str)        {            if (str != AdTecRfMessage.QUERY)            {                LOG.Write(eEvent.EV_DEVICE_INFO, Module, $"Generator send [{str}]");            }            SetPointCommandQueue.Add(str);            return true;            //return _serial.Write(str + "\r");        }        public override bool ReConnect()        {            return _serial.ReConnect();        }    }    #endregion RFG    #region match    static class AdTecMatchMessage    {        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";    }    class AdTecMatch : RfMatchBase    {        private readonly AsyncSerialPort _serial;        private const ushort S3_HEAD_LENGTH = 2;        private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();        private int QUERY_INTERVAL = 1000;        //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 float VDC { get; set; }        public new AITMatchData DeviceData        {            get            {                return new AITMatchData                {                    Module = Module,                    DeviceName = Name,                    WorkMode = WorkMode.ToString(),                    C1 = TunePosition1,                    C2 = TunePosition2,                    VPP = "",                    DCBias = DCBias.ToString()                };            }        }        //public override AITRfMatchData DeviceData        //{        //    get        //    {        //        return new AITRfMatchData        //        {        //        };        //    }        //}        // --------------------------Constructor-----------------------        //        public AdTecMatch(ModuleName mod, VenusDevice device) : base(mod.ToString(), device.ToString())        {            var portNum = SC.GetStringValue($"{mod}.{device}.Port");            _serial = new AsyncSerialPort(portNum, 9600, 8);            //_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");            SerachCommandList = new List<string>()            {            AdTecMatchMessage.READ_POS,            AdTecMatchMessage.START_QUERY            };            intervalTime = 100;            sendDataChangedEvent += AdTecMatch_sendDataChangedEvent;            baseStopwatch.Start();            baseTimer.Enabled = true;        }        private void AdTecMatch_sendDataChangedEvent(string obj)        {            this.SendCmd(obj);        }        ~AdTecMatch()        {            _serial?.Close();        }        public override bool Initialize()        {            base.Initialize();            if (_serial.Open())            {                _serial.OnDataChanged += SerialPortDataReceived;                _serial.OnErrorHappened += SerialPortErrorOccurred;            }            else            {                LOG.Write(eEvent.ERR_RF, Module, "Match 串口无法打开");                return false;            }            DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);            DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);            DATA.Subscribe($"{Module}.{Name}.VDC", () => VDC);            DATA.Subscribe($"{Module}.{Name}.WorkMode", () => WorkMode.ToString());            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}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>            {                SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);                return true;            });            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>            {                SetMatchMode((string)param[0] == "Auto" ? EnumRfMatchTuneMode.Auto : EnumRfMatchTuneMode.Manual, out reason);                return true;            });            _timerQueryStatus.Start(QUERY_INTERVAL);            this.SendCmd(AdTecMatchMessage.START_QUERY);            //LOG.Write(eEvent.ERR_RF, Module, "Initialize done.");            return true;        }        public override void Monitor()        {            //try            //{            //    if (_timerQueryStatus.IsTimeout())            //    {            //        this.SendCmd(AdTecMatchMessage.READ_POS);            //        _timerQueryStatus.Start(QUERY_INTERVAL);            //    }            //}            //catch (Exception ex)            //{            //    LOG.WriteExeption(ex);            //}        }        public override void Terminate()        {            this.SendCmd(AdTecMatchMessage.STOP_QUERY);        }        public override void Reset()        {            //SendCmd(AdTecMatchMessage.STOP_QUERY);        }        /// <summary>        ///        /// </summary>        /// <param name="c1,c2">百分比数字</param>        /// <param name="c2"></param>        ///         private void executeMatchPostion(float c1, float c2)        {            SetWorkMode(EnumRfMatchTuneMode.Manual);            //await Task.Delay(200);            SetPosition(c1, c2);            //await Task.Delay(200);            SetPresetMemory(0);            //await Task.Delay(200);            // SetWorkMode(EnumRfMatchTuneMode.Auto);        }        public override void SetMatchPosition(float c1, float c2, out string reason)        {            //LOG.Write(eEvent.WARN_RF, Module, $"AdTec Match error [{c1}, {c2}]");            base.SetMatchPosition(c1, c2, out reason);            executeMatchPostion(c1, c2);            reason = "";        }        public void SetPresetMode(RfMatchPresetMode mode)        {        }        // -----------------------Private Method-------------------------        //        private void SerialPortDataReceived(string strOrg)        {            if (string.IsNullOrWhiteSpace(strOrg))            {                LOG.Write(eEvent.ERR_RF, Module, "收到 Match 数据为空");                return;            }            string[] sContent = strOrg.Split('\r');            foreach (var sItem in sContent)            {                string sItem1 = sItem.TrimStart('\n');                if (sItem1.Contains(AdTecMatchMessage.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, 3);                    this.VPP = Convert.ToUInt16(sVpp, 16);                    string sVDC = sItem1.Substring(39 + S3_HEAD_LENGTH, 3);                    this.VDC = Convert.ToUInt16(sVDC, 16);                }                else if (sItem1.Contains(AdTecMatchMessage.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;                }            }        }        private void SerialPortErrorOccurred(string str)        {            LOG.Write(eEvent.ERR_RF, Module, $"AdTec Match error [{str}]");        }        private void SendCmd(string 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 = AdTecMatchMessage.WRITE_POS + val1.ToString("X3") + val2.ToString("X3");            SetPointCommandQueue.Add(cmd);            //this.SendCmd(cmd);        }        public override bool SetMatchMode(EnumRfMatchTuneMode enumRfMatchTuneMode, out string reason)        {            reason = string.Empty;            SetWorkMode(enumRfMatchTuneMode);            return true;        }        private void SetWorkMode(EnumRfMatchTuneMode mode)        {            string data = mode == EnumRfMatchTuneMode.Auto ? AdTecMatchMessage.AUTO :                mode == EnumRfMatchTuneMode.Manual ? AdTecMatchMessage.MANUAL : "";            //this.SendCmd(mode == EnumRfMatchTuneMode.Auto ? AdTecMatchMessage.AUTO :            //    mode == EnumRfMatchTuneMode.Manual ? AdTecMatchMessage.MANUAL : "");            SetPointCommandQueue.Add(data);        }        private void SetPresetMemory(byte gear)        {            //this.SendCmd(AdTecMatchMessage.PRESET_MEM + gear.ToString());            SetPointCommandQueue.Add(AdTecMatchMessage.PRESET_MEM + gear.ToString());        }    }    #endregion match}
 |