| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667 | using System;using System.Collections.Generic;using System.IO.Ports;using System.Linq;using System.Text;using System.Threading;using Aitex.Core.Common;using Aitex.Core.Common.DeviceData;using Aitex.Core.RT.DataCenter;using Aitex.Core.RT.Device;using Aitex.Core.RT.Device.Unit;using Aitex.Core.RT.Event;using Aitex.Core.RT.Log;using Aitex.Core.RT.OperationCenter;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using MECF.Framework.Common.CommonData;using MECF.Framework.Common.Communications;using MECF.Framework.Common.Device.Bases;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.SubstrateTrackings;using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Common;using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.TazmoRobot{    public enum TazmoRobotState    {        Standby = 0,        TPInUse = 1,        InOperation = 2,        Running,        Pause = 7,        Initializing = 9,        StandbyDueToUnInit = 0X10,        RecoverabelErrorWithoutInit = 0X20,        ErrorRequiredInit = 0xA0,        ErrorRequiredPowerCycle = 0xC0,    }    public enum TazmoRobotPositionEnum    {        UnloadLoad,        Mapping,    }    public enum TazmoRobotArmExtensionEnum    {        PositionToPull,        ArmExtension,    }    public enum TazmoRobotWorkPresenceInfoEnum    {        NoWork,        WorkExists,            }    public enum TazmoRobotGripPostionInfoEnum    {        Close,        Oepn,        WorkIsGripped,        PostionUnknow = 0xF,    }    public enum TazmoRobotZPositionInfo    {        Down = 1,        MidDown,        Mid,        MidUp,        Up,        Unknow = 0xF,    }    public class TazmoRobot : RobotBaseDevice, IConnection    {        private bool isSimulatorMode        {            get            {                 return SC.ContainsItem("System.IsSimulatorMode") ? SC.GetValue<bool>("System.IsSimulatorMode") : false;            }        }        private string _scRoot;        public TazmoRobotState DeviceState { get; private set; }        public bool TaExecuteSuccss { get; set; }        private TazmoRobotConnection _connection;        public TazmoRobotConnection Connection => _connection;        private R_TRIG _trigError = new R_TRIG();        private R_TRIG _trigWarningMessage = new R_TRIG();        private R_TRIG _trigCommunicationError = new R_TRIG();        private R_TRIG _trigRetryConnect = new R_TRIG();        private PeriodicJob _thread;        private static Object _locker = new Object();        private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();        private IoSensor _diRobotReady = null;  //Normal ON        private IoSensor _diRobotBlade1WaferOn = null;   //Off when wafer present        private IoSensor _diRobotBlade2WaferOn = null;        private IoSensor _diRobotError = null; //Normal ON        private IoSensor _diTPinUse = null;        private IoSensor _diRobotArmPos = null;        private IoSensor _diRobotMove = null;        private IoSensor _diRobotHome = null;        private IoTrigger _doRobotHold = null; // Normal ON        private IoTrigger _doRobotIn1 = null; // Normal ON        private bool _enableLog = true;        private bool _commErr = false;        private string _address;                public int CurrentStopPositionPoint { get; private set; }        public int CurrentSlotNumber { get; private set; }        public TazmoRobotPositionEnum CurrentPositionCate { get; private set; }        public TazmoRobotArmExtensionEnum CurrentArmExtensionPos { get; private set; }        //public TazmoRobotWorkPresenceInfoEnum CurrentWorkPresnece { get; private set; }        public TazmoRobotWorkPresenceInfoEnum CurrentArm1WorkPresnece { get; private set; }        public TazmoRobotWorkPresenceInfoEnum CurrentArm2WorkPresnece { get; private set; }        public TazmoRobotGripPostionInfoEnum CurrentArm1GripperPosition { get; private set; }        public TazmoRobotGripPostionInfoEnum CurrentArm2GripperPosition { get; private set; }        public TazmoRobotZPositionInfo CurrentZpositionCate { get; private set; }        public int R1AxisPosition { get; private set; }        public int R2AxisPosition { get; private set; }        public int ZAxisPosition { get; private set; }        public int SAxisPosition { get; private set; }        public string RobotSystemVersion { get; private set; }        public string RobotSoftwareVersion { get; private set; }        private string commasymbol = ",";        private DateTime _dtActionStart;        public string PortName { get; private set; }        public TazmoRobot(string module, string name, string scRoot, IoSensor[] dis, IoTrigger[] dos) : base(module, name)        {                        _scRoot = scRoot;            //base.Initialize();            ResetPropertiesAndResponses();            RegisterSpecialData();            RegisterAlarm();            if (dis != null && dis.Length >= 8)            {                _diRobotReady = dis[0];                _diRobotBlade1WaferOn = dis[1];                _diRobotBlade2WaferOn = dis[2];                _diRobotError = dis[3];                _diTPinUse = dis[4];                _diRobotArmPos = dis[5];                _diRobotMove = dis[6];                _diRobotHome = dis[7];                _diRobotError.OnSignalChanged += _diRobotError_OnSignalChanged;                _diRobotMove.OnSignalChanged += _diRobotMove_OnSignalChanged;                //_diTPinUse.OnSignalChanged += _diTPinUse_OnSignalChanged;            }            if (dos != null && dos.Length >= 1)            {                _doRobotIn1 = dos[0];                if (_doRobotIn1 != null)                    _doRobotIn1.SetTrigger(true, out _);            }            int bautRate = SC.GetValue<int>($"{scRoot}.{Name}.BaudRate");            int dataBits = SC.GetValue<int>($"{scRoot}.{Name}.DataBits");            Enum.TryParse(SC.GetStringValue($"{scRoot}.{Name}.Parity"), out Parity parity);            Enum.TryParse(SC.GetStringValue($"{scRoot}.{Name}.StopBits"), out StopBits stopBits);            _enableLog = SC.GetValue<bool>($"{scRoot}.{Name}.EnableLogMessage");            PortName = SC.GetStringValue($"{scRoot}.{Name}.PortName");            Address = PortName;            _connection = new TazmoRobotConnection(this, PortName, bautRate, dataBits, parity, stopBits);            _connection.EnableLog(_enableLog);            if (_connection.Connect())            {                EV.PostInfoLog(Module, $"{Module}.{Name} connected");                IsConnected = true;            }            _thread = new PeriodicJob(100, OnTimer, $"{Module}.{Name} MonitorHandler", true);            //_address = SC.GetStringValue($"{_scRoot}.{Name}.DeviceAddress");            ConnectionManager.Instance.Subscribe($"{Name}", this);              }        public void ParseAxisPosition(string data)        {            try            {                 string[] datas = data.Replace("\r", "").Split(',');                switch (datas[0])                {                    case "001":                        R1AxisPosition = Convert.ToInt32(datas[2]);                        break;                    case "002":                        R2AxisPosition = Convert.ToInt32(datas[2]);                        break;                    case "040":                        ZAxisPosition = Convert.ToInt32(datas[2]);                        break;                    case "080":                        SAxisPosition = Convert.ToInt32(datas[2]);                        break;                }             }            catch(Exception ex)            {                LOG.Write(ex);            }        }        private void _diRobotMove_OnSignalChanged(IoSensor arg1, bool arg2)        {                   }        private void _diRobotError_OnSignalChanged(IoSensor arg1, bool arg2)        {            if (arg2)            {                lock (_locker)                {                    _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "STA", ""));                }                OnError("RobotError");            }        }        public void ParseStatus(string state)        {            int statecode = Convert.ToInt32(state, 16);            if (statecode <= 0x10) DeviceState = (TazmoRobotState)statecode;            else            {                ErrorCode = statecode.ToString("X3");                EV.Notify($"{Name}Error{ErrorCode}");                OnError("RobotError");            }            if (statecode >= 0x20 && statecode <= 0x99) DeviceState = TazmoRobotState.RecoverabelErrorWithoutInit;            if (statecode >= 0xA0 && statecode <= 0xBF) DeviceState = TazmoRobotState.ErrorRequiredInit;            if (statecode > 0xC0 && statecode <= 0xFF) DeviceState = TazmoRobotState.ErrorRequiredPowerCycle;        }        public void ParseStatusAndPostion(string cmd,string statedata)        {            string[] data = statedata.Split(',');            switch(cmd)            {                case "WCH":                case "VCH":                    if(data[0] == "1") CurrentArm1WorkPresnece = (TazmoRobotWorkPresenceInfoEnum)Convert.ToInt32(data[1]);                    if(data[0] == "2") CurrentArm2WorkPresnece = (TazmoRobotWorkPresenceInfoEnum)Convert.ToInt32(data[1]);                    break;                case "STA":                    if (data.Length != 10)                    {                        EV.PostAlarmLog("System", "Received invalid status and postion data:" + statedata);                        return;                    }                    ParseStatus(data[0]);                    CurrentStopPositionPoint = Convert.ToInt32(data[1]);                    CurrentSlotNumber = Convert.ToInt32(data[2]);                    CurrentPositionCate = (TazmoRobotPositionEnum)Convert.ToInt32(data[3]);                    CurrentArmExtensionPos = (TazmoRobotArmExtensionEnum)Convert.ToInt32(data[4]);                                        CurrentArm1WorkPresnece = (TazmoRobotWorkPresenceInfoEnum)Convert.ToInt32(data[5]);                    CurrentArm2WorkPresnece = (TazmoRobotWorkPresenceInfoEnum)Convert.ToInt32(data[6]);                    CurrentArm1GripperPosition = (TazmoRobotGripPostionInfoEnum)Convert.ToInt32(data[7]);                    CurrentArm2GripperPosition = (TazmoRobotGripPostionInfoEnum)Convert.ToInt32(data[8]);                    CurrentZpositionCate = (TazmoRobotZPositionInfo)Convert.ToInt32(data[9],16);                    break;            }                    }        public void ParseAllStageSpeed(string statedata)        {            string[] data = statedata.Split(',');            if (data.Length != 10)            {                // EV.PostAlarmLog("System", "Received Query Speed data:" + statedata);                return;            }            ParseStatus(data[0]);            Speed = Convert.ToInt32(data[3]);        }        private void RegisterAlarm()        {            EV.Subscribe(new EventItem(60011, "Alarm", $"{Name}Error", $"{Name} Occurred Error", EventLevel.Alarm, EventType.EventUI_Notify));            for(int i = 0x20;i<=0x99; i++)            {                string errorcode = i.ToString("X3");                EV.Subscribe(new EventItem(64000 +i,  "Alarm", $"{Name}Error{errorcode}", $"{Name} Occurred recoverable error without initialization,code:{errorcode}.", EventLevel.Alarm, EventType.EventUI_Notify));            }            for (int i = 0xA0; i <= 0xB0; i++)            {                EV.Subscribe(new EventItem(64000 + i, "Alarm", $"{Name}Error{i.ToString("X3")}", $"{Name} Occurred error require initialization,code:{i.ToString("X3")}.", EventLevel.Alarm, EventType.EventUI_Notify));            }            for (int i = 0xC0; i <= 0xFF; i++)            {                EV.Subscribe(new EventItem(64000 + i, "Alarm", $"{Name}Error{i.ToString("X3")}", $"{Name} Occurred error require power again,code:{i.ToString("X3")}.", EventLevel.Alarm, EventType.EventUI_Notify));            }        }        private void RegisterSpecialData()        {            DATA.Subscribe($"{Name}.TazmoStatus", () => DeviceState.ToString());            DATA.Subscribe($"{Name}.CurrentStopPositionPoint", () => CurrentStopPositionPoint.ToString());            DATA.Subscribe($"{Name}.CurrentSlotNumber", () => CurrentSlotNumber.ToString());            DATA.Subscribe($"{Name}.CurrentPositionCate", () => CurrentPositionCate.ToString());            DATA.Subscribe($"{Name}.CurrentArmExtensionPos", () => CurrentArmExtensionPos.ToString());            DATA.Subscribe($"{Name}.CurrentArm1WorkPresnece", () => CurrentArm1WorkPresnece.ToString());            DATA.Subscribe($"{Name}.CurrentArm2WorkPresnece", () => CurrentArm2WorkPresnece.ToString());            DATA.Subscribe($"{Name}.CurrentArm1GripperPosition", () => CurrentArm1GripperPosition.ToString());            DATA.Subscribe($"{Name}.CurrentArm2GripperPosition", () => CurrentArm2GripperPosition.ToString());            DATA.Subscribe($"{Name}.CurrentZpositionCate", () => CurrentZpositionCate.ToString());            DATA.Subscribe($"{Name}.R1AxisPosition", () => R1AxisPosition.ToString());            DATA.Subscribe($"{Name}.R2AxisPosition", () => R2AxisPosition.ToString());            DATA.Subscribe($"{Name}.ZAxisPosition", () => ZAxisPosition.ToString());            DATA.Subscribe($"{Name}.SAxisPosition", () => SAxisPosition.ToString());            OP.Subscribe(String.Format("{0}.{1}", Name, "StartJog"), (out string reason, int time, object[] param) =>            {                string axis = param[0].ToString();                bool direction = (bool)param[1];                                bool ret = ExecuteRobotJog(axis,direction);                if (ret)                {                    reason = string.Format("{0} {1}", Name, "start jog succesfully");                    return true;                }                reason = $"{Name} start jog failed";                return false;            });            OP.Subscribe(String.Format("{0}.{1}", Name, "StopJog"), (out string reason, int time, object[] param) =>            {                               bool ret = ExecuteRobotStopJog();                if (ret)                {                    reason = string.Format("{0} {1}", Name, "Stop jog succesfully");                    return true;                }                reason = $"{Name} Stop jog failed";                return false;            });        }        private bool ExecuteRobotJog(string axis, bool direction)        {            if (RobotState != RobotStateEnum.Idle) return false;            lock (_locker)            {                string parameter = $"{axis},{(direction ? "0" : "1")},0";                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "JOG", parameter));            }            return true;        }        private bool ExecuteRobotStopJog()        {            if (RobotState != RobotStateEnum.Idle) return false;            lock (_locker)            {                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "JSP",null));            }            return true;        }        private void ResetPropertiesAndResponses()        {        }        private bool OnTimer()        {            try            {                _connection.MonitorTimeout();                if (!_connection.IsConnected || _connection.IsCommunicationError)                {                    lock (_locker)                    {                        _lstHandler.Clear();                    }                    _trigRetryConnect.CLK = !_connection.IsConnected;                    if (_trigRetryConnect.Q)                    {                        _connection.SetPortAddress(SC.GetStringValue($"{Name}.Address"));                        if (!_connection.Connect())                        {                            EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");                        }                    }                    return true;                }                HandlerBase handler = null;                if (!_connection.IsBusy)                {                    lock (_locker)                    {                        if (_lstHandler.Count == 0)                        {                        }                        if (_lstHandler.Count > 0)                        {                            handler = _lstHandler.First.Value;                            if (handler != null) _connection.Execute(handler);                            _lstHandler.RemoveFirst();                        }                    }                }            }            catch (Exception ex)            {                LOG.Write(ex);            }            return true;        }        public string Address { get; private set; }        public bool IsConnected { get; private set; }        public bool Connect()        {            return _connection.Connect();        }        public bool Disconnect()        {            return _connection.Disconnect();        }        public bool ParseReadData(string _command, string[] rdata)        {            try            {                if (_command.Equals("RMP"))                {                    ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), rdata[0].ToString());                    CurrentSlotMap = rdata[2].ToString();                                    }                return true;            }            catch (Exception ex)            {                LOG.Write(ex);                return true;            }        }        public string CurrentSlotMap { get; private set; }        public override bool IsReady()        {            if (_diRobotError != null && _diRobotError.Value)                return false;            //if (_diTPinUse != null && !_diTPinUse.Value)            //    return false;            return RobotState == RobotStateEnum.Idle && !IsBusy;        }        public virtual bool ResetCPU(out string reason)        {            lock (_locker)            {                _lstHandler.Clear();                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "CPI", ""));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "STA", ""));            }            reason = "";            return true;        }        protected override bool fStop(object[] param)        {            lock (_locker)            {                _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "PAU", null));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this,"STA", null));            }            return true;        }              protected override bool fError(object[] param)        {            return true;        }        public override bool SetSpeed(object[] param)        {            if (!IsReady()) return false;            Int32 speedvalue;            if (!Int32.TryParse(param[0].ToString(), out speedvalue)) return false;            if (SC.ContainsItem($"Robot.{RobotModuleName}.RobotSpeed"))            {                SC.SetItemValue($"Robot.{RobotModuleName}.RobotSpeed", speedvalue);            }            var p1 = speedvalue;            var p2 = speedvalue;            var p3 = speedvalue;            var p4 = speedvalue;            var p5 = speedvalue;            var p6 = speedvalue;            var p7 = speedvalue;            var p8 = speedvalue;            var p9 = speedvalue;            var p10 = speedvalue;            var p11 = speedvalue;            var p12 = speedvalue;            var p13 = speedvalue;            string para1 = $"0,2,{p1},{p2},{p3},{p4},{p5},{p6},{p7},{p8},{p9},{p10},{p11},{p12},{p13}";            lock (_locker)            {                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "DWL", para1));            }            return true;        }        protected override bool fStartSetParameters(object[] param)        {            _dtActionStart = DateTime.Now;            try            {                string strParameter;                string setcommand = param[0].ToString();                switch (setcommand)                {                    case "RobotSpeed":   // SSPD Set the motion speed                        Int32 speedvalue;                        if (!Int32.TryParse(param[1].ToString(), out speedvalue)) return false;                        if (SC.ContainsItem($"Robot.{RobotModuleName}.RobotSpeed"))                        {                            SC.SetItemValue($"Robot.{RobotModuleName}.RobotSpeed", speedvalue);                        }                        var p1 = speedvalue;                        var p2 = speedvalue;                        var p3 = speedvalue;                        var p4 = speedvalue;                        var p5 = speedvalue;                        var p6 = speedvalue;                        var p7 = speedvalue;                        var p8 = speedvalue;                        var p9 = speedvalue;                        var p10 = speedvalue;                        var p11 = speedvalue;                        var p12 = speedvalue;                        var p13 = speedvalue;                        string para1 = $"0,2,{p1},{p2},{p3},{p4},{p5},{p6},{p7},{p8},{p9},{p10},{p11},{p12},{p13}";                        lock (_locker)                        {                            _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "DWL", para1));                        }                        break;                }            }            catch (Exception)            {                string reason = "";                if (param != null)                {                    foreach (var para in param)                    {                        reason += para.ToString() + ",";                    }                }                EV.PostAlarmLog(Name, "Set command parameter invalid:" + reason);                return false;            }            return true;        }        protected override bool fMonitorSetParamter(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("SetParameterTimeout");                return true;            }            return _lstHandler.Count == 0 && !_connection.IsBusy;        }        public bool IsPause;        protected override bool fReset(object[] param)        {            _lstHandler.Clear();            _connection.ForceClear();                        lock (_locker)            {                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "CER", ""));                if (IsPause)                    _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "CNT", ""));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "001,2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "002,2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "040,2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "080,2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "STA", ""));            }            return true;        }        private bool _isNeedWaferConfirm   ////0=auto detect,1=down move after release        {            get            {                if (SC.ContainsItem($"{_scRoot}.{RobotModuleName}.NeedWaferConfirm"))                    return SC.GetValue<bool>($"{_scRoot}.{RobotModuleName}.NeedWaferConfirm");                return true;            }        }        protected override bool fMonitorReset(object[] param)        {            IsBusy = false;            if( _lstHandler.Count == 0 && !_connection.IsBusy)            {                BladeTarget = ModuleName.System;                Blade1Target = ModuleName.System;                Blade2Target = ModuleName.System;                return true;            }            return false;        }        protected override bool fStartHome(object[] param)        {            lock (_locker)            {                _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "HOM",""));            }            _dtActionStart = DateTime.Now;            return true;        }        protected override bool fMonitorHome(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Init timeout");                return true;            }            if (_lstHandler.Count == 0 && !_connection.IsBusy)            {                EV.PostInfoLog(RobotModuleName.ToString(), "Home complete.");                BladeTarget = ModuleName.System;                Blade1Target = ModuleName.System;                Blade2Target = ModuleName.System;                CmdTarget = ModuleName.System;                MoveInfo = new RobotMoveInfo()                {                    Action = RobotAction.Moving,                    ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                    BladeTarget = BuildBladeTarget(),                };                return true;            }            return false;        }        protected override bool fStartInit(object[] param)        {            lock (_locker)            {                _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "RST", _isNeedWaferConfirm ? "0" : "1"));                                _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "1"));                _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "STA", ""));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "001,2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "002,2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "040,2"));                _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RED", "080,2"));            }            _dtActionStart = DateTime.Now;            return true;        }        protected override bool fMonitorInit(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Init timeout");                return true;            }            if (_lstHandler.Count == 0 && !_connection.IsBusy)            {                EV.PostInfoLog(RobotModuleName.ToString(), "Init complete.");                                var waferinfoOnArm1 = WaferManager.Instance.GetWafer(RobotModuleName, 0);                var waferinfoOnArm2 = WaferManager.Instance.GetWafer(RobotModuleName, 1);                if (CurrentArm1WorkPresnece == TazmoRobotWorkPresenceInfoEnum.NoWork && !waferinfoOnArm1.IsEmpty)                {                    EV.PostAlarmLog(RobotModuleName.ToString(), "Robot didn't detect wafer on blade1,but it has record.");                }                if (CurrentArm1WorkPresnece == TazmoRobotWorkPresenceInfoEnum.WorkExists && waferinfoOnArm1.IsEmpty)                {                    EV.PostAlarmLog(RobotModuleName.ToString(), "Robot detect wafer on blade1, will create wafer.");                    WaferManager.Instance.CreateWafer(RobotModuleName, 0, WaferStatus.Normal, Size);                }                if (CurrentArm2WorkPresnece == TazmoRobotWorkPresenceInfoEnum.NoWork && !waferinfoOnArm2.IsEmpty)                {                    EV.PostAlarmLog(RobotModuleName.ToString(), "Robot didn't detect wafer on blade2,but it has record.");                }                if (CurrentArm2WorkPresnece == TazmoRobotWorkPresenceInfoEnum.WorkExists && waferinfoOnArm2.IsEmpty)                {                    EV.PostAlarmLog(RobotModuleName.ToString(), "Robot detect wafer on blade2, will create wafer.");                    WaferManager.Instance.CreateWafer(RobotModuleName, 1, WaferStatus.Normal, Size);                }                BladeTarget = ModuleName.System;                Blade1Target = ModuleName.System;                Blade2Target = ModuleName.System;                CmdTarget = ModuleName.System;                MoveInfo = new RobotMoveInfo()                {                    Action = RobotAction.Moving,                    ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                    BladeTarget = BuildBladeTarget(),                };                return true;            }            return base.fMonitorInit(param);        }            protected override bool fResetToReady(object[] param)        {            return true;        }        protected override bool fStartExtendForPick(object[] param)        {            return true;        }        protected override bool fStartExtendForPlace(object[] param)        {            return true;        }        protected override bool fStartGoTo(object[] param)        {            try            {                RobotArmEnum arm = (RobotArmEnum)param[0];                ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());                var moduleIndex = Chamber2staion(module);                string para1 = moduleIndex;                int slot = (int)param[2] + 1;                para1 += commasymbol + slot.ToString();                para1 += arm == RobotArmEnum.Lower ? commasymbol + "1" : commasymbol + "2";                lock (_locker)                {                    if (arm == RobotArmEnum.Lower)                    {                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "MTP", para1));                    }                    if (arm == RobotArmEnum.Upper)                    {                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "MTP", para1));                    }                }                _dtActionStart = DateTime.Now;                EV.PostInfoLog("Robot", $"{RobotModuleName} start to goto {module}.");                return true;            }            catch (Exception ex)            {                LOG.Write(ex);                return false;            }        }        protected override bool fMonitorGoTo(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Goto Postion timeout");                return true;            }            if(_lstHandler.Count == 0 && !_connection.IsBusy)            {                RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0];                ModuleName sourcemodule = (ModuleName)Enum.Parse(typeof(ModuleName), CurrentParamter[1].ToString());                int SourceslotIndex = (int)CurrentParamter[2];                BladeTarget = sourcemodule;                Blade1Target = sourcemodule;                Blade2Target = sourcemodule;                EV.PostInfoLog("Robot", $"{RobotModuleName} goto {sourcemodule} completed.");                return true;            }            return base.fMonitorGoTo(param);        }                protected override bool fStartGrip(object[] param)        {            _dtActionStart = DateTime.Now;            RobotArmEnum arm = (RobotArmEnum)param[0];            lock (_locker)            {                if (arm == RobotArmEnum.Both)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVN", "1"));                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVN", "2"));                }                if (arm == RobotArmEnum.Lower)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVN", "1"));                }                if (arm == RobotArmEnum.Upper)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVN", "2"));                }            }            EV.PostInfoLog("Robot", $"{RobotModuleName} start to grip arm {arm}.");            return true;        }        protected override bool fMonitorGrip(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Grip timeout");                return true;            }            if (_lstHandler.Count == 0 && !_connection.IsBusy)            {                RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0];                               EV.PostInfoLog("Robot",$"{RobotModuleName} {arm} grip wafer completed.");                return true;            }            return base.fMonitorGrip(param);        }        protected override bool fStartUnGrip(object[] param)        {            _dtActionStart = DateTime.Now;            RobotArmEnum arm = (RobotArmEnum)param[0];            lock (_locker)            {                if (arm == RobotArmEnum.Both)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVF", "1"));                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVF", "2"));                }                if (arm == RobotArmEnum.Lower)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVF", "1"));                }                if (arm == RobotArmEnum.Upper)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "VVF", "2"));                }            }            EV.PostInfoLog("Robot", $"{RobotModuleName} start to ungrip arm {arm}.");            return true;        }        protected override bool fMonitorUnGrip(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Ungrip timeout");                return true;            }            if (_lstHandler.Count == 0 && !_connection.IsBusy)            {                RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0];                EV.PostInfoLog("Robot", $"{RobotModuleName} {arm} ungrip wafer completed.");                return true;            }            return base.fMonitorGrip(param);        }        protected override bool fStartMapWafer(object[] param)        {                        _dtActionStart = DateTime.Now;            ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[0].ToString());            string moduleIndex = Chamber2staion(module);            string para1 = moduleIndex + commasymbol + "0";            _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "MAP", para1));            _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "RMP", moduleIndex));                        if (ModuleHelper.IsLoadPort(module))            {                var lp = DEVICE.GetDevice<LoadPortBaseDevice>(module.ToString());                if (lp != null)                    lp.NoteTransferStart();            }            BladeTarget = module;            Blade1Target = module;            Blade2Target = module;            CmdTarget = module;            MoveInfo = new RobotMoveInfo()            {                Action = RobotAction.Moving,                ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                BladeTarget = BuildBladeTarget(),            };            EV.PostInfoLog("Robot", $"{RobotModuleName} start to map station {module}.");            return true;        }        protected override bool fMonitorMap(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Map timeout");                return true;            }            if (_lstHandler.Count == 0 && !_connection.IsBusy)            {                ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), CurrentParamter[0].ToString());                if (ModuleHelper.IsLoadPort(module))                {                    var lp = DEVICE.GetDevice<LoadPortBaseDevice>(module.ToString());                    if (lp != null)                        lp.NoteTransferStop();                }                EV.PostInfoLog("Robot",$"{RobotModuleName} map {module} completed.");                BladeTarget =  ModuleName.System;                Blade1Target = ModuleName.System;                 Blade2Target = ModuleName.System;                CmdTarget = ModuleName.System;                MoveInfo = new RobotMoveInfo()                {                    Action = RobotAction.Moving,                    ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                    BladeTarget = BuildBladeTarget(),                };                NotifySlotMapResult(module, CurrentSlotMap);                return true;            }            return base.fMonitorMap(param);        }        protected override bool fStartPickWafer(object[] param)        {            _dtActionStart = DateTime.Now;            try            {                RobotArmEnum arm = (RobotArmEnum)param[0];                ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());                if (ModuleHelper.IsLoadPort(module))                {                    var lp = DEVICE.GetDevice<LoadPortBaseDevice>(module.ToString());                    if (lp != null)                        lp.NoteTransferStart();                }                int slot = (int)param[2] + 1;                                string moduleIndex = Chamber2staion(module);                if(param.Length >=4 && (bool)param[3] == true)                {                    moduleIndex = Chamber2staion(module,true);                }                                               lock (_locker)                {                    if (arm == RobotArmEnum.Lower)                    {                        ////para1 += ",1";                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "GET", $"{moduleIndex},{slot},1"));                        //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "1"));                    }                    if (arm == RobotArmEnum.Upper)                    {                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "GET", $"{moduleIndex},{slot},2"));                        //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "2"));                    }                    if(arm == RobotArmEnum.Both)                    {                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "GET", $"{moduleIndex},{slot},1"));                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "GET", $"{moduleIndex},{slot+1},2"));                        //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "1"));                        //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "2"));                    }                                        //_lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "STA", ""));                                    }                                                BladeTarget = module;                Blade1Target = module;                Blade2Target = module;                CmdTarget = module;                MoveInfo = new RobotMoveInfo()                {                    Action = RobotAction.Moving,                    ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                    BladeTarget = BuildBladeTarget(),                };                EV.PostInfoLog("Robot", $"{RobotModuleName} start to pick wafer from {module} slot{slot} with arm:{arm}.");                return true;            }            catch (Exception ex)            {                LOG.Write(ex);                return false;            }        }        protected override bool fMonitorPick(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Pick timeout");                return true;            }            if (_lstHandler.Count == 0 && !_connection.IsBusy)            {                RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0];                                ModuleName sourcemodule;                if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false;                if (ModuleHelper.IsLoadPort(sourcemodule))                {                    var lp = DEVICE.GetDevice<LoadPortBaseDevice>(sourcemodule.ToString());                    if (lp != null)                        lp.NoteTransferStop();                }                int SourceslotIndex;                if (!int.TryParse(CurrentParamter[2].ToString(), out SourceslotIndex)) return false;                                if (arm == RobotArmEnum.Lower)                {                    //if(GetWaferState(arm) != RobotArmWaferStateEnum.Present)                    //{                    //    OnError("Wafer detect error");                                            //}                    WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0);                }                if (arm == RobotArmEnum.Upper)                {                    //if(GetWaferState(arm) != RobotArmWaferStateEnum.Present)                    //{                    //    OnError("Wafer detect error");                                            //}                    WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 1);                }                if (arm == RobotArmEnum.Both)                {                    //if(GetWaferState(arm) != RobotArmWaferStateEnum.Present)                    //{                    //   OnError("Wafer detect error");                                            //}                    WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex, RobotModuleName, 0);                    WaferManager.Instance.WaferMoved(sourcemodule, SourceslotIndex + 1, RobotModuleName, 1);                }                EV.PostInfoLog("Robot", $"{RobotModuleName} pick wafer from {sourcemodule},slot:{SourceslotIndex+1} completed.");                BladeTarget = ModuleName.System;                Blade1Target = ModuleName.System;                Blade2Target = ModuleName.System;                CmdTarget = ModuleName.System;                MoveInfo = new RobotMoveInfo()                {                    Action = RobotAction.Moving,                    ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                    BladeTarget = BuildBladeTarget(),                };                return true;            }            return base.fMonitorPick(param);        }        protected override bool fStartPlaceWafer(object[] param)        {            _dtActionStart = DateTime.Now;            RobotArmEnum arm = (RobotArmEnum)param[0];            ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());            int slot = (int)param[2] + 1;            if (ModuleHelper.IsLoadPort(module))            {                var lp = DEVICE.GetDevice<LoadPortBaseDevice>(module.ToString());                if (lp != null)                    lp.NoteTransferStart();            }            string moduleIndex = Chamber2staion(module);            if (param.Length == 4 && (bool)param[3])                moduleIndex = Chamber2staion(module,true);                                               lock (_locker)            {                if (arm == RobotArmEnum.Both)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "PUT", $"{moduleIndex},{slot},1"));                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "PUT", $"{moduleIndex},{slot+1},2"));                    //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "1"));                    //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "2"));                }                if (arm == RobotArmEnum.Lower)                {                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "PUT", $"{moduleIndex},{slot},1"));                    //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "1"));                }                if (arm == RobotArmEnum.Upper)                {                    // para1 += ",2";                    _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "PUT", $"{moduleIndex},{slot},2"));                    //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "2"));                }                //_lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "STA", ""));            }            BladeTarget = module;            Blade1Target = module;            Blade2Target = module;            CmdTarget = module;            MoveInfo = new RobotMoveInfo()            {                Action = RobotAction.Moving,                ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                BladeTarget = BuildBladeTarget(),            };            EV.PostInfoLog("Robot", $"{RobotModuleName} start to place wafer to {module} slot{slot} with arm:{arm}.");            return true;        }        protected override bool fMonitorPlace(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Place timeout");                return true;            }            if (_lstHandler.Count != 0 || _connection.IsBusy) return false;            RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0];            ModuleName sourcemodule;            if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false;            if(ModuleHelper.IsLoadPort(sourcemodule))            {                var lp = DEVICE.GetDevice<LoadPortBaseDevice>(sourcemodule.ToString());                lp.NoteTransferStop();            }            int Sourceslotindex;            if (!int.TryParse(CurrentParamter[2].ToString(), out Sourceslotindex)) return false;                      if (arm == RobotArmEnum.Lower)            {                                //if(GetWaferState(arm) != RobotArmWaferStateEnum.Absent)                //{                //    OnError("Wafer detect error");                //}                WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex);            }            if (arm == RobotArmEnum.Upper)            {                                //if (GetWaferState(arm) != RobotArmWaferStateEnum.Absent)                //{                //    OnError("Wafer detect error");                                       //}                WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex);            }            if (arm == RobotArmEnum.Both)            {                //if (GetWaferState(arm) != RobotArmWaferStateEnum.Absent)                //{                                  //    OnError("Wafer detect error");                                      //}                WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex);                WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex + 1);            }            BladeTarget = ModuleName.System;            Blade1Target = ModuleName.System;            Blade2Target = ModuleName.System;            CmdTarget = ModuleName.System;            MoveInfo = new RobotMoveInfo()            {                Action = RobotAction.Moving,                ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                BladeTarget = BuildBladeTarget(),            };            EV.PostInfoLog("System", $"{RobotModuleName} place wafer to {sourcemodule} slot {Sourceslotindex+1} with arm {arm}" +                $" successfully.");            return true;        }        protected override bool fStartReadData(object[] param)        {            if (param.Length < 1) return false;            string readcommand = param[0].ToString();            switch (readcommand)            {                case "CurrentStatus":                    lock (_locker)                    {                        //_lstHandlers.AddLast(new SR100RobotReadHandler(this, "RSTS"));                        //_lstHandlers.AddLast(new SR100RobotReadHandler(this, "RPOS", "F"));                        //_lstHandlers.AddLast(new SR100RobotReadHandler(this, "RPOS", "R"));                    }                    break;                case "MappingData":                    {                        ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());                        string para1 = Chamber2staion(module);                        lock (_locker)                        {                            _lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "MAP", para1));                        }                    }                    break;                default:                    break;            }            return true;        }        protected override bool fMonitorReadData(object[] param)        {            IsBusy = false;            return _lstHandler.Count == 0 && !_connection.IsBusy;        }        protected override bool fStartRetractFromPick(object[] param)        {            throw new NotImplementedException();        }        protected override bool fStartRetractFromPlace(object[] param)        {            throw new NotImplementedException();        }                protected override bool fStartSwapWafer(object[] param)        {            _dtActionStart = DateTime.Now;            try            {                RobotArmEnum arm = (RobotArmEnum)param[0];                ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());                if (ModuleHelper.IsLoadPort(module))                {                    var lp = DEVICE.GetDevice<LoadPortBaseDevice>(module.ToString());                    if (lp != null)                        lp.NoteTransferStart();                }                int slot = (int)param[2] + 1;                string moduleIndex = Chamber2staion(module);                if (param.Length >= 4 && (bool)param[3] == true)                {                    moduleIndex = Chamber2staion(module, true);                }                lock (_locker)                {                    if (arm == RobotArmEnum.Lower)                    {                        ////para1 += ",1";                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "EXG", $"{moduleIndex},{slot},1"));                                        }                    if (arm == RobotArmEnum.Upper)                    {                        _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "EXG", $"{moduleIndex},{slot},2"));                    }                    if (arm == RobotArmEnum.Both)                    {                                           }                    //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "1"));                    //_lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "2"));                    //_lstHandler.AddLast(new TazmoRobotSingleTransactionHandler(this, "STA", ""));                }                BladeTarget = module;                Blade1Target = module;                Blade2Target = module;                CmdTarget = module;                MoveInfo = new RobotMoveInfo()                {                    Action = RobotAction.Moving,                    ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                    BladeTarget = BuildBladeTarget(),                };                EV.PostInfoLog("Robot", $"{RobotModuleName} start to swap wafer from {module} slot{slot} with arm:{arm}.");                return true;            }            catch (Exception ex)            {                LOG.Write(ex);                return false;            }        }        protected override bool fMonitorSwap(object[] param)        {            IsBusy = false;            if (DateTime.Now - _dtActionStart > TimeSpan.FromSeconds(RobotCommandTimeout))            {                OnError("Swap timeout");                return true;            }            if (_lstHandler.Count != 0 || _connection.IsBusy) return false;            RobotArmEnum arm = (RobotArmEnum)CurrentParamter[0];            ModuleName sourcemodule;            if (!Enum.TryParse(CurrentParamter[1].ToString(), out sourcemodule)) return false;            int Sourceslotindex;            if (!int.TryParse(CurrentParamter[2].ToString(), out Sourceslotindex)) return false;            if (ModuleHelper.IsLoadPort(sourcemodule))            {                var lp = DEVICE.GetDevice<LoadPortBaseDevice>(sourcemodule.ToString());                lp.NoteTransferStop();            }            if (arm == RobotArmEnum.Lower)            {                                //if ( !(GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Present                //        && GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Absent))                //{                //    OnError("Wafer detect error");                                     //}                WaferManager.Instance.WaferMoved(sourcemodule, Sourceslotindex, RobotModuleName, 0);                WaferManager.Instance.WaferMoved(RobotModuleName, 1, sourcemodule, Sourceslotindex);            }            if (arm == RobotArmEnum.Upper)            {                //if ( !(GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Present &&                //    GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Absent))                //{                //   OnError("Wafer detect error");                                    //}                WaferManager.Instance.WaferMoved(sourcemodule, Sourceslotindex, RobotModuleName, 1);                WaferManager.Instance.WaferMoved(RobotModuleName, 0, sourcemodule, Sourceslotindex);            }            BladeTarget = ModuleName.System;            Blade1Target = ModuleName.System;            Blade2Target = ModuleName.System;            CmdTarget = ModuleName.System;            MoveInfo = new RobotMoveInfo()            {                Action = RobotAction.Moving,                ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,                BladeTarget = BuildBladeTarget(),            };            EV.PostInfoLog("Robot", $"{RobotModuleName} swap wafer from {sourcemodule} slot{Sourceslotindex+1} with arm:{arm} completed.");            return true;        }        public override void OnError(string errortext)        {            _lstHandler.Clear();            base.OnError(errortext);        }        protected override bool fStartTransferWafer(object[] param)        {            return true;        }        public override void Reset()        {            _trigError.RST = true;            _connection.SetCommunicationError(false, "");            _trigCommunicationError.RST = true;            _enableLog = SC.GetValue<bool>($"{_scRoot}.{Name}.EnableLogMessage");            _connection.EnableLog(_enableLog);            _trigRetryConnect.RST = true;            //base.Reset();        }        public void NoteError(string errortext)        {            OnError(errortext);        }        public void CheckWaferPresentAndGrip()        {            if (GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Present)            {                if (WaferManager.Instance.CheckNoWafer(ModuleName.Robot, 0))                {                    EV.PostWarningLog($"{RobotModuleName}", $"System detec wafer on lower arm, will create wafer automatically.");                    WaferManager.Instance.CreateWafer(ModuleName.Robot, 0, WaferStatus.Normal);                }            }            if (GetWaferState(RobotArmEnum.Lower) == RobotArmWaferStateEnum.Absent)            {                _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "1"));                if (WaferManager.Instance.CheckHasWafer(ModuleName.Robot, 0))                {                    EV.PostWarningLog($"{ModuleName.Robot}", $"System didn't detect wafer on lower arm, but it has record.");                }            }            if (GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Present)            {                if (WaferManager.Instance.CheckNoWafer(ModuleName.Robot, 1))                {                    EV.PostWarningLog($"{ModuleName.Robot}", $"System detect wafer on upper arm, will create wafer automatically.");                    WaferManager.Instance.CreateWafer(ModuleName.Robot, 1, WaferStatus.Normal);                }            }            if (GetWaferState(RobotArmEnum.Upper) == RobotArmWaferStateEnum.Absent)            {                _lstHandler.AddLast(new TazmoRobotTwinTransactionHandler(this, "WCH", "2"));                if (WaferManager.Instance.CheckHasWafer(ModuleName.Robot, 1))                {                    EV.PostWarningLog($"{ModuleName.Robot}", $"System didn't detect wafer on upper arm, but it has record.");                }            }        }        public override RobotArmWaferStateEnum GetWaferState(RobotArmEnum arm)        {            if (arm == RobotArmEnum.Lower)            {                if (_diRobotBlade1WaferOn != null)                {                    if (_diRobotBlade1WaferOn.Value) return RobotArmWaferStateEnum.Present;                    else return RobotArmWaferStateEnum.Absent;                }                return CurrentArm1WorkPresnece== TazmoRobotWorkPresenceInfoEnum.WorkExists  ? RobotArmWaferStateEnum.Present : RobotArmWaferStateEnum.Absent;            }            if (arm == RobotArmEnum.Upper)            {                if (_diRobotBlade2WaferOn != null)                {                    if (_diRobotBlade2WaferOn.Value) return RobotArmWaferStateEnum.Present;                    else return RobotArmWaferStateEnum.Absent;                }                return CurrentArm2WorkPresnece == TazmoRobotWorkPresenceInfoEnum.WorkExists ? RobotArmWaferStateEnum.Present : RobotArmWaferStateEnum.Absent;            }            if (arm == RobotArmEnum.Both)            {                if (_diRobotBlade1WaferOn != null && _diRobotBlade2WaferOn != null)                {                    if (_diRobotBlade2WaferOn.Value && _diRobotBlade1WaferOn.Value)                        return RobotArmWaferStateEnum.Present;                    else if (!_diRobotBlade2WaferOn.Value && !_diRobotBlade1WaferOn.Value)                        return RobotArmWaferStateEnum.Absent;                    else return RobotArmWaferStateEnum.Unknown;                }                if (CurrentArm1WorkPresnece == TazmoRobotWorkPresenceInfoEnum.WorkExists                    && CurrentArm2WorkPresnece == TazmoRobotWorkPresenceInfoEnum.WorkExists)                {                    return RobotArmWaferStateEnum.Present;                }                if (CurrentArm1WorkPresnece == TazmoRobotWorkPresenceInfoEnum.NoWork                     && CurrentArm1WorkPresnece == TazmoRobotWorkPresenceInfoEnum.NoWork)                {                    return RobotArmWaferStateEnum.Absent;                }            }            return RobotArmWaferStateEnum.Unknown;        }        public override bool OnActionDone(object[] param)        {            EV.PostInfoLog("Robot", $"OnActionDone");            IsBusy = false;                      if (_lstHandler.Count == 0)            {                IsBusy = false;                return base.OnActionDone(param);            }            return true;        }        protected override bool fClear(object[] param)        {            return true;        }        private string Chamber2staion(ModuleName chamber, bool flip = false,WaferSize size = WaferSize.WS12)        {            if(ModuleHelper.IsLoadPort(chamber))            {                var lp = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());                int carrierIndex = lp.InfoPadCarrierIndex;                if (flip)                    return SC.GetStringValue($"CarrierInfo.Carrier{carrierIndex}.{chamber}FlipStation");                else                    return SC.GetStringValue($"CarrierInfo.Carrier{carrierIndex}.{chamber}FrontStation");            }            if (flip)                return SC.GetStringValue($"CarrierInfo.Size{size.ToString().Replace("WS","")}.{chamber}FlipStation");            else                return SC.GetStringValue($"CarrierInfo.Size{size.ToString().Replace("WS", "")}.{chamber}FrontStation");        }        private string BuildBladeTarget()        {            return (CmdRobotArm == RobotArmEnum.Upper ? "ArmB" : "ArmA") + "." + CmdTarget;        }    }}
 |