using Aitex.Core.Common; 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.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Communications; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDKB; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.VCE.BrooksVCE; using Aitex.Core.RT.Device.Devices; //namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.NCD namespace Aitex.Core.RT.Device.Unit { public class NcdIoLoadPort:LoadPortBaseDevice { public NcdIoLoadPort(string module, XmlElement node, string ioModule = ""): base(node.GetAttribute("module"), node.GetAttribute("id")) { base.Module = node.GetAttribute("module");//string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module"); base.Name = node.GetAttribute("id"); ioModule = node.GetAttribute("ioModule"); _doRecipeSaveCommand = ParseDoNode("DO_RecipeSaveCommand", node, ioModule); _doRecipeLoadCommand = ParseDoNode("DO_RecipeLoadCommand", node, ioModule); _doIntialCommand = ParseDoNode("DO_IntialCommand", node, ioModule); _doResetCommand = ParseDoNode("DO_ResetCommand", node, ioModule); _doSingleMappingCommand = ParseDoNode("DO_SingleMappingCommand", node, ioModule); _doLoadLight = ParseDoNode("DO_LoadLight", node, ioModule); _doUnloadLight = ParseDoNode("DO_UnloadLight", node, ioModule); _doStatu1Light = ParseDoNode("DO_Statu1Light", node, ioModule); _doStatu2Light = ParseDoNode("DO_Statu2Light", node, ioModule); _doLoadCommand = ParseDoNode("DO_LoadCommand", node, ioModule); _doUnloadCommand = ParseDoNode("DO_UnloadCommand", node, ioModule); _doMapDisableCommand = ParseDoNode("DO_MapDisableCommand", node, ioModule); _doMapEnableCommand = ParseDoNode("DO_MapEnableCommand", node, ioModule); _doClampOnCommand = ParseDoNode("DO_ClampOnCommand", node, ioModule); _doClampOffCommand = ParseDoNode("DO_ClampOffCommand", node, ioModule); _doDOCKForwardCommand = ParseDoNode("DO_DOCKForwardCommand", node, ioModule); _doDOCKHomeCommand = ParseDoNode("DO_DOCKHomeCommand", node, ioModule); _doLatchOnCommand = ParseDoNode("DO_LatchOnCommand", node, ioModule); _doLatchOffCommand = ParseDoNode("DO_LatchOffCommand", node, ioModule); _doDoorCloseCommand = ParseDoNode("DO_DoorCloseCommand", node, ioModule); _doDoorOpenCommand = ParseDoNode("DO_DoorOpenCommand", node, ioModule); _doVACOnCommand = ParseDoNode("DO_VACOnCommand", node, ioModule); _doVACOffCommand = ParseDoNode("DO_VACOffCommand", node, ioModule); _doVertiaclDownCommand = ParseDoNode("DO_VertiaclDownCommand", node, ioModule); _doVertiaclUpCommand = ParseDoNode("DO_VertiaclUpCommand", node, ioModule); _doZtoMAPPINGSTARTPOSI = ParseDoNode("DO_ZtoMAPPINGSTARTPOSI", node, ioModule); _doZtoMAPPINGENDPOSI = ParseDoNode("DO_ZtoMAPPINGENDPOSI", node, ioModule); _doMAPIN = ParseDoNode("DO_MAPIN", node, ioModule); _doMAPOUT = ParseDoNode("DO_MAPOUT", node, ioModule); _aoSAVECurrentRecipeNumber = ParseAoNode("AO_SAVECurrentRecipeNumber", node, ioModule); _aoMAPSTAR = ParseAoNode("AO_MAPSTAR", node, ioModule); _aoMAPEND = ParseAoNode("AO_MAPEND", node, ioModule); _aoSENSOR = ParseAoNode("AO_SENSOR", node, ioModule); _aoSLOT = ParseAoNode("AO_SLOT", node, ioModule); _aoPITCH = ParseAoNode("AO_PITCH", node, ioModule); _aoPOSITIONRANGE = ParseAoNode("AO_POSITIONRANGE", node, ioModule); _aoPOSITIONRANGEUPPER = ParseAoNode("AO_POSITIONRANGEUPPER", node, ioModule); _aoPOSITIONRANGELOWER = ParseAoNode("AO_POSITIONRANGELOWER", node, ioModule); _aoTHICK = ParseAoNode("AO_THICK", node, ioModule); _aoTHICKRANGE = ParseAoNode("AO_THICKRANGE", node, ioModule); _aoOFFSET = ParseAoNode("AO_OFFSET", node, ioModule); _aoCarrierType = ParseAoNode("AO_CarrierType", node, ioModule); _aiSlot1MapResult = ParseAiNode("AI_Slot1MapResult", node, ioModule); _aiSlot2MapResult = ParseAiNode("AI_Slot2MapResult", node, ioModule); _aiSlot3MapResult = ParseAiNode("AI_Slot3MapResult", node, ioModule); _aiSlot4MapResult = ParseAiNode("AI_Slot4MapResult", node, ioModule); _aiSlot5MapResult = ParseAiNode("AI_Slot5MapResult", node, ioModule); _aiSlot6MapResult = ParseAiNode("AI_Slot6MapResult", node, ioModule); _aiSlot7MapResult = ParseAiNode("AI_Slot7MapResult", node, ioModule); _aiSlot8MapResult = ParseAiNode("AI_Slot8MapResult", node, ioModule); _aiSlot9MapResult = ParseAiNode("AI_Slot9MapResult", node, ioModule); _aiSlot10MapResult = ParseAiNode("AI_Slot10MapResult", node, ioModule); _aiSlot11MapResult = ParseAiNode("AI_Slot11MapResult", node, ioModule); _aiSlot12MapResult = ParseAiNode("AI_Slot12MapResult", node, ioModule); _aiSlot13MapResult = ParseAiNode("AI_Slot13MapResult", node, ioModule); _aiSlot14MapResult = ParseAiNode("AI_Slot14MapResult", node, ioModule); _aiSlot15MapResult = ParseAiNode("AI_Slot15MapResult", node, ioModule); _aiSlot16MapResult = ParseAiNode("AI_Slot16MapResult", node, ioModule); _aiSlot17MapResult = ParseAiNode("AI_Slot17MapResult", node, ioModule); _aiSlot18MapResult = ParseAiNode("AI_Slot18MapResult", node, ioModule); _aiSlot19MapResult = ParseAiNode("AI_Slot19MapResult", node, ioModule); _aiSlot20MapResult = ParseAiNode("AI_Slot20MapResult", node, ioModule); _aiSlot21MapResult = ParseAiNode("AI_Slot21MapResult", node, ioModule); _aiSlot22MapResult = ParseAiNode("AI_Slot22MapResult", node, ioModule); _aiSlot23MapResult = ParseAiNode("AI_Slot23MapResult", node, ioModule); _aiSlot24MapResult = ParseAiNode("AI_Slot24MapResult", node, ioModule); _aiSlot25MapResult = ParseAiNode("AI_Slot25MapResult", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot1 = ParseAiNode("AI__WAFERPOSITIONUPPEREDGE_Slot1", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot1 = ParseAiNode("AI__WAFERPOSITIONLOWEREDGE_Slot1", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot2 = ParseAiNode("AI__WAFERPOSITIONUPPEREDGE_Slot2", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot2 = ParseAiNode("AI__WAFERPOSITIONLOWEREDGE_Slot2", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot3 = ParseAiNode("AI__WAFERPOSITIONUPPEREDGE_Slot3", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot3 = ParseAiNode("AI__WAFERPOSITIONLOWEREDGE_Slot3", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot4 = ParseAiNode("AI__WAFERPOSITIONUPPEREDGE_Slot4", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot4 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot4", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot5 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot5", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot5 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot5", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot6 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot6", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot6 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot6", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot7 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot7", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot7 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot7", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot8 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot8", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot8 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot8", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot9 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot9", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot9 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot9", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot10 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot10", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot10 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot10", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot11 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot11", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot11 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot11", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot12 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot12", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot12 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot12", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot13 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot13", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot13 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot13", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot14 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot14", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot14 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot14", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot15 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot15", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot15 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot15", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot16 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot16", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot16 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot16", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot17 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot17", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot17 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot17", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot18 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot18", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot18 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot18", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot19 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot19", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot19 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot19", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot20 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot20", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot20 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot20", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot21 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot21", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot21 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot21", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot22 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot22", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot22 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot22", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot23 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot23", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot23 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot23", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot24 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot24", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot24 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot24", node, ioModule); _aiWAFERPOSITIONUPPEREDGE_Slot25 = ParseAiNode("AI_WAFERPOSITIONUPPEREDGE_Slot25", node, ioModule); _aiWAFERPOSITIONLOWEREDGE_Slot25 = ParseAiNode("AI_WAFERPOSITIONLOWEREDGE_Slot25", node, ioModule); _aiErrorCode = ParseAiNode("AI_ErrorCode", node, ioModule); _aiLastErrorCode = ParseAiNode("AI_LastErrorCode", node, ioModule); _aiRECIPE_TYPE_FEEDBACK = ParseAiNode("AI_RECIPE_TYPE_FEEDBACK", node, ioModule); _diAck_RecieSave = ParseDiNode("DI_Ack_RecieSave", node, ioModule); _diAck_RecipeLoad = ParseDiNode("DI_Ack_RecipeLoad", node, ioModule); _diAck_Init = ParseDiNode("DI_Ack_Init", node, ioModule); _diAck_Reset = ParseDiNode("DI_Ack_Reset", node, ioModule); _diAck_SingleMap = ParseDiNode("DI_Ack_SingleMap", node, ioModule); _diAck_HomePos = ParseDiNode("DI_Ack_HomePos", node, ioModule); _diSensor_Presence = ParseDiNode("DI_Sensor_Presence", node, ioModule); _diSensor_Placement = ParseDiNode("DI_Sensor_Placement", node, ioModule); _diSensor_Protrude = ParseDiNode("DI_Sensor_Protrude", node, ioModule); _diSensor_VerticalDown = ParseDiNode("DI_Sensor_VerticalDown", node, ioModule); _diAck_Load = ParseDiNode("DI_Ack_Load", node, ioModule); _diAck_Unload = ParseDiNode("DI_Ack_Unload", node, ioModule); _diAck_MapDisable = ParseDiNode("DI_Ack_MapDisable", node, ioModule); _diAck_MapEnable = ParseDiNode("DI_Ack_MapEnable", node, ioModule); _diAck_ClampOn = ParseDiNode("DI_Ack_ClampOn", node, ioModule); _diAck_ClampOff = ParseDiNode("DI_Ack_ClampOff", node, ioModule); _diAck_DockFwd = ParseDiNode("DI_Ack_DockFwd", node, ioModule); _diAck_DockHome = ParseDiNode("DI_Ack_DockHome", node, ioModule); _diAck_LatchOn = ParseDiNode("DI_Ack_LatchOn", node, ioModule); _diAck_LatchOff = ParseDiNode("DI_Ack_LatchOff", node, ioModule); _diAck_DoorClose = ParseDiNode("DI_Ack_DoorClose", node, ioModule); _diAck_DoorOpen = ParseDiNode("DI_Ack_DoorOpen", node, ioModule); _diAck_VacOn = ParseDiNode("DI_Ack_VacOn", node, ioModule); _diAck_VacOff = ParseDiNode("DI_Ack_VacOff", node, ioModule); _diAck_VerticalDown = ParseDiNode("DI_Ack_VerticalDown", node, ioModule); _diAck_VerticalUp = ParseDiNode("DI_Ack_VerticalUp", node, ioModule); _diAck_ZtoMapStart = ParseDiNode("DI_Ack_ZtoMapStart", node, ioModule); _diAck_ZtoMapEnd = ParseDiNode("DI_Ack_ZtoMapEnd", node, ioModule); _diAck_Mapin = ParseDiNode("DI_Ack_Mapin", node, ioModule); _diAck_MapOut = ParseDiNode("DI_Ack_MapOut", node, ioModule); _diAck_CmdClear = ParseDiNode("DI_Ack_CmdClear", node, ioModule); _diAck_E84Disable = ParseDiNode("DI_Ack_E84Disable", node, ioModule); _diAck_E84Enable = ParseDiNode("DI_Ack_E84Enable", node, ioModule); _di12MapSensor = ParseDiNode("DI_12MapSensor", node, ioModule); _di8MapSensor = ParseDiNode("DI_8MapSensor", node, ioModule); _diSERVOHOME = ParseDiNode("DI_SERVOHOME", node, ioModule); _diFoupPlacementSensor = ParseDiNode("DI_FoupPlacementSensor", node, ioModule); _diDoorCheckSensor = ParseDiNode("DI_DoorCheckSensor", node, ioModule); _diCDASensor = ParseDiNode("DI_CDASensor", node, ioModule); _diDockHomeSensor = ParseDiNode("DI_DockHomeSensor", node, ioModule); _diClampOffSensor = ParseDiNode("DI_ClampOffSensor", node, ioModule); _diPodForwardSensor = ParseDiNode("DI_PodForwardSensor", node, ioModule); _diClampOnSensor = ParseDiNode("DI_ClampOnSensor", node, ioModule); _diVACSensor = ParseDiNode("DI_VACSensor", node, ioModule); _diLatchLockSensor = ParseDiNode("DI_LatchLockSensor", node, ioModule); _diLatchUnlockSensor = ParseDiNode("DI_LatchUnlockSensor", node, ioModule); _diDoorOpenSensor = ParseDiNode("DI_DoorOpenSensor", node, ioModule); _diDoorCloseSensor = ParseDiNode("DI_DoorCloseSensor", node, ioModule); _diVerticalMiddleSensor = ParseDiNode("DI_VerticalMiddleSensor", node, ioModule); _diVerticalDownSensor = ParseDiNode("DI_VerticalDownSensor", node, ioModule); _diOPSwitchButton = ParseDiNode("DI_OPSwitchButton", node, ioModule); _diMapin = ParseDiNode("DI_Mapin", node, ioModule); _diMapout = ParseDiNode("DI_Mapout", node, ioModule); _diProtrudesensor = ParseDiNode("DI_Protrudesensor", node, ioModule); _diInfoPadA = ParseDiNode("DI_InfoPadA", node, ioModule); _diInfoPadB = ParseDiNode("DI_InfoPadB", node, ioModule); _diInfoPadC = ParseDiNode("DI_InfoPadC", node, ioModule); _diInfoPadD = ParseDiNode("DI_InfoPadD", node, ioModule); _diServoOn = ParseDiNode("DI_ServoOn", node, ioModule); _diPresence = ParseDiNode("DI_Presence", node, ioModule); _diStepError = ParseDiNode("DI_StepError", node, ioModule); _diServoerror = ParseDiNode("DI_Servoerror", node, ioModule); _diDoorSafe = ParseDiNode("DI_DoorSafe", node, ioModule); _diSERVO = ParseDiNode("DI_SERVO", node, ioModule); _diSTEP = ParseDiNode("DI_STEP", node, ioModule); _diClampOnCylinder = ParseDiNode("DI_ClampOnCylinder", node, ioModule); _diClampOffCylinder = ParseDiNode("DI_ClampOffCylinder", node, ioModule); _diLatchOnCylinder = ParseDiNode("DI_LatchOnCylinder", node, ioModule); _diLatchOffCylinder = ParseDiNode("DI_LatchOffCylinder", node, ioModule); _diDoorOpenCylinder = ParseDiNode("DI_DoorOpenCylinder", node, ioModule); _diDoorCloseCylinder = ParseDiNode("DI_DoorCloseCylinder", node, ioModule); _diSERVOCLEAR1 = ParseDiNode("DI_SERVOCLEAR1", node, ioModule); _diSERVOON1 = ParseDiNode("DI_SERVOON1", node, ioModule); _diD3UBIN = ParseDiNode("DI_D3UBIN", node, ioModule); _diMapForwardCylinder = ParseDiNode("DI_MapForwardCylinder", node, ioModule); _diSERVOCLEAR2 = ParseDiNode("DI_SERVOCLEAR2", node, ioModule); _diSERVOON2 = ParseDiNode("DI_SERVOON2", node, ioModule); _diSERVOCLCOUNT = ParseDiNode("DI_SERVOCLCOUNT", node, ioModule); _diVAC = ParseDiNode("DI_VAC", node, ioModule); _diSERVOBRAKE = ParseDiNode("DI_SERVOBRAKE", node, ioModule); _diLoadLight = ParseDiNode("DI_LoadLight", node, ioModule); _diUnloadLight = ParseDiNode("DI_UnloadLight", node, ioModule); _diPOWERLIGHT = ParseDiNode("DI_POWERLIGHT", node, ioModule); _diFoupPlacementLight = ParseDiNode("DI_FoupPlacementLight", node, ioModule); _diFoupPresenceLight = ParseDiNode("DI_FoupPresenceLight", node, ioModule); _diAlarmOccurLight = ParseDiNode("DI_AlarmOccurLight", node, ioModule); _diStatu1Light = ParseDiNode("DI_Statu1Light", node, ioModule); _diStatu2Light = ParseDiNode("DI_Statu2Light", node, ioModule); SubscribeData(); SubscribeEventAndAlarm(); IsMapWaferByLoadPort = true; _carrierArrived = new R_TRIG(); _errorOccurredTrig = new R_TRIG(); _lastErrorOccurredTrig = new R_TRIG(); _alarmWaferProtrudeTrig = new R_TRIG(); _thread = new PeriodicJob(10, OnTimer, $"{Module}.{Name} MonitorHandler", true); } public string[] AlarmNcdLoadPortErrors; public string[] AlarmNcdLoadPortLastErrors; private void SubscribeEventAndAlarm() { AlarmNcdLoadPortErrors = new string[73]; for(int i=0;i<73;i++) { AlarmNcdLoadPortErrors[i] = "Ncd " + LPModuleName.ToString() + "Error" + (i + 1).ToString(); EV.Subscribe(new EventItem("Alarm", AlarmNcdLoadPortErrors[i], $"Load Port {Name} occurred error, D2801 error code is {i+1}.", EventLevel.Alarm, EventType.EventUI_Notify)); } AlarmNcdLoadPortLastErrors = new string[29]; for (int i = 0; i < 29; i++) { AlarmNcdLoadPortLastErrors[i] = "Ncd " + LPModuleName.ToString() + "LastError" + (i + 1).ToString(); EV.Subscribe(new EventItem("Alarm", AlarmNcdLoadPortLastErrors[i], $"Load Port {Name} occurred error, D2802 error code is {i + 1}.", EventLevel.Alarm, EventType.EventUI_Notify)); } EV.Subscribe(new EventItem("Alarm", AlarmLoadPortLoadRecipeFailed, $"Load Port {Name} load recipe Timeout.", EventLevel.Alarm, EventType.EventUI_Notify)); } private string AlarmLoadPortLoadRecipeFailed { get => LPModuleName.ToString() + "LoadRecipeFailed"; } private void SubscribeData() { DATA.Subscribe($"{Module}.{Name}.SystemStatus", () => CurrentState.ToString()); DATA.Subscribe($"{Module}.{Name}.Mode", () => Mode.ToString()); DATA.Subscribe($"{Module}.{Name}.InitPosMovement", () => InitPosMovement.ToString()); DATA.Subscribe($"{Module}.{Name}.OperationStatus", () => OperationStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.ErrorCode", () => ErrorCode.ToString()); DATA.Subscribe($"{Module}.{Name}.ContainerStatus", () => ContainerStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.ClampPosition", () => ClampPosition.ToString()); DATA.Subscribe($"{Module}.{Name}.LPDoorLatchPosition", () => LPDoorLatchPosition.ToString()); DATA.Subscribe($"{Module}.{Name}.VacuumStatus", () => VacuumStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.LPDoorState", () => LPDoorState.ToString()); DATA.Subscribe($"{Module}.{Name}.WaferProtrusion", () => WaferProtrusion.ToString()); DATA.Subscribe($"{Module}.{Name}.ElevatorAxisPosition", () => ElevatorAxisPosition.ToString()); DATA.Subscribe($"{Module}.{Name}.MapperPostion", () => MapperPostion.ToString()); DATA.Subscribe($"{Module}.{Name}.MappingStatus", () => MappingStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.Model", () => Model.ToString()); DATA.Subscribe($"{Module}.{Name}.IsFosbModeActual", () => IsFosbModeActual.ToString()); DATA.Subscribe($"{Module}.{Name}.DockPosition", () => DockPosition.ToString()); DATA.Subscribe($"{Name}.SystemStatus", () => CurrentState.ToString()); DATA.Subscribe($"{Name}.Mode", () => Mode.ToString()); DATA.Subscribe($"{Name}.InitPosMovement", () => InitPosMovement.ToString()); DATA.Subscribe($"{Name}.OperationStatus", () => OperationStatus.ToString()); DATA.Subscribe($"{Name}.ErrorCode", () => ErrorCode.ToString()); DATA.Subscribe($"{Name}.ContainerStatus", () => ContainerStatus.ToString()); DATA.Subscribe($"{Name}.ClampPosition", () => ClampPosition.ToString()); DATA.Subscribe($"{Name}.LPDoorLatchPosition", () => LPDoorLatchPosition.ToString()); DATA.Subscribe($"{Name}.VacuumStatus", () => VacuumStatus.ToString()); DATA.Subscribe($"{Name}.LPDoorState", () => LPDoorState.ToString()); DATA.Subscribe($"{Name}.WaferProtrusion", () => WaferProtrusion.ToString()); DATA.Subscribe($"{Name}.ElevatorAxisPosition", () => ElevatorAxisPosition.ToString()); DATA.Subscribe($"{Name}.MapperPostion", () => MapperPostion.ToString()); DATA.Subscribe($"{Name}.MappingStatus", () => MappingStatus.ToString()); DATA.Subscribe($"{Name}.Model", () => Model.ToString()); DATA.Subscribe($"{Name}.IsFosbModeActual", () => IsFosbModeActual.ToString()); DATA.Subscribe($"{Name}.DockPosition", () => DockPosition.ToString()); } private PeriodicJob _thread; private DOAccessor _doRecipeSaveCommand; private DOAccessor _doRecipeLoadCommand; private DOAccessor _doIntialCommand; private DOAccessor _doResetCommand; private DOAccessor _doSingleMappingCommand; private DOAccessor _doLoadLight; private DOAccessor _doUnloadLight; private DOAccessor _doStatu1Light; private DOAccessor _doStatu2Light; private DOAccessor _doLoadCommand; private DOAccessor _doUnloadCommand; private DOAccessor _doMapDisableCommand; private DOAccessor _doMapEnableCommand; private DOAccessor _doClampOnCommand; private DOAccessor _doClampOffCommand; private DOAccessor _doDOCKForwardCommand; private DOAccessor _doDOCKHomeCommand; private DOAccessor _doLatchOnCommand; private DOAccessor _doLatchOffCommand; private DOAccessor _doDoorCloseCommand; private DOAccessor _doDoorOpenCommand; private DOAccessor _doVACOnCommand; private DOAccessor _doVACOffCommand; private DOAccessor _doVertiaclDownCommand; private DOAccessor _doVertiaclUpCommand; private DOAccessor _doZtoMAPPINGSTARTPOSI; private DOAccessor _doZtoMAPPINGENDPOSI; private DOAccessor _doMAPIN; private DOAccessor _doMAPOUT; private AOAccessor _aoSAVECurrentRecipeNumber; private AOAccessor _aoMAPSTAR; //MAP STAR(10um) [ 2000 _diIronCassetteDoorClose; set { _diIronCassetteDoorClose = value; _diIronCassetteDoorClose.OnSignalChanged += _diIronCassetteDoorClose_OnSignalChanged; } } private void _diIronCassetteDoorClose_OnSignalChanged(IoSensor arg1, bool arg2) { if (!IsPlacement || !IsMapped) return; if (arg2) return; if (_diIronCassetteDoorClose.Value) return; if (!_diDockHomeSensor.Value) return; if (!IsReady()) return; Unclamp(out _); } private DateTime _actionStartTime; private int _actionTimeLimit; protected R_TRIG _carrierArrived; protected R_TRIG _errorOccurredTrig; protected R_TRIG _lastErrorOccurredTrig; protected R_TRIG _alarmWaferProtrudeTrig; private int _errorCode = 0; private int _lastErrorCode = 0; public override string ErrorCode { get => _aiErrorCode.Value.ToString(); } public TDKMode Mode { get; set; } = TDKMode.Online; public TDKInitPosMovement InitPosMovement { get; set; } public TDKOperationStatus OperationStatus { get; set; } public TDKContainerStatus ContainerStatus { get { if (_isPlaced && _isPresent) return TDKContainerStatus.NormalMount; if (!_isPlaced && !_isPresent) return TDKContainerStatus.Absence; return TDKContainerStatus.MountError; } } public TDKPosition ClampPosition { get { if (_diClampOffSensor.Value && !_diClampOnCylinder.Value) return TDKPosition.Open; if (!_diClampOffSensor.Value && _diClampOnCylinder.Value) return TDKPosition.Close; return TDKPosition.TBD; } } public TDKPosition LPDoorLatchPosition { get { if (_diLatchLockSensor.Value && !_diLatchUnlockSensor.Value) return TDKPosition.Close; if (!_diLatchLockSensor.Value && _diLatchUnlockSensor.Value) return TDKPosition.Open; return TDKPosition.TBD; } } public TDKVacummStatus VacuumStatus { get { if (_diVACSensor.Value) return TDKVacummStatus.ON; return TDKVacummStatus.OFF; } } public TDKPosition LPDoorState { get { if (_diDoorOpenSensor.Value && !_diDoorCloseSensor.Value) return TDKPosition.Open; if(!_diDoorOpenSensor.Value && _diDoorCloseSensor.Value) return TDKPosition.Close; return TDKPosition.TBD; } } public TDKWaferProtrusion WaferProtrusion { get { if (!_diProtrudesensor.Value) return TDKWaferProtrusion.ShadingStatus; return TDKWaferProtrusion.LightIncidentStatus; } } public TDKElevatorAxisPosition ElevatorAxisPosition { get { if (_diVerticalDownSensor.Value) return TDKElevatorAxisPosition.Down; if (_diAck_ZtoMapEnd.Value) return TDKElevatorAxisPosition.MappingStartPos; if (_diAck_ZtoMapStart.Value) return TDKElevatorAxisPosition.MappingEndPos; return TDKElevatorAxisPosition.TBD; } } public TDKDockPosition DockPosition { get { if (_diDockHomeSensor.Value && !_diPodForwardSensor.Value) return TDKDockPosition.Undock; if (!_diDockHomeSensor.Value && _diPodForwardSensor.Value) return TDKDockPosition.Dock; return TDKDockPosition.TBD; } } public TDKMapPosition MapperPostion { get => TDKMapPosition.TBD; } public TDKMappingStatus MappingStatus { get; set; } = TDKMappingStatus.NormalEnd; public TDKModel Model { get; set; } public CarrierMode LPCarrierMode { get { if(SC.ContainsItem($"CarrierInfo.CarrierFosbMode{InfoPadCarrierIndex}")) { int intvalue = SC.GetValue($"CarrierInfo.CarrierFosbMode{InfoPadCarrierIndex}"); if (intvalue == 0) return CarrierMode.Foup; if (intvalue == 1) return CarrierMode.Fosb; if (intvalue == 2) return CarrierMode.OpenCassette; } return CarrierMode.Foup; } } public override bool IsWaferProtrude { get { //_alarmWaferProtrudeTrig.CLK = !_diProtrudesensor.Value; //if(_alarmWaferProtrudeTrig.Q) //{ // EV.Notify(AlarmLoadPortWaferProtrusion); //} return (!_diProtrudesensor.Value); } } public override bool IsEnableLoad(out string reason) { //if(IsWaferProtrude) //{ // reason = "Wafer Protrusion"; // return false; //} if(SC.ContainsItem($"CarrierInfo.NeedCheckIronDoorCarrier{InfoPadCarrierIndex}") && (SC.GetValue($"CarrierInfo.NeedCheckIronDoorCarrier{InfoPadCarrierIndex}"))) { if(DiIronCassetteDoorClose!=null && !DiIronCassetteDoorClose.Value) { reason = "Iron Door Closed"; return false; } } return base.IsEnableLoad(out reason); } public override bool IsEnableMapWafer(out string reason) { if (IsWaferProtrude) { reason = "Wafer Protrusion"; return false; } if (SC.ContainsItem($"CarrierInfo.NeedCheckIronDoorCarrier{InfoPadCarrierIndex}") && (SC.GetValue($"CarrierInfo.NeedCheckIronDoorCarrier{InfoPadCarrierIndex}"))) { if (DiIronCassetteDoorClose != null && !DiIronCassetteDoorClose.Value) { reason = "Iron Door Closed"; return false; } } return base.IsEnableMapWafer(out reason); } public override bool IsEnableTransferWafer(out string reason) { if(!IsLoaded) { reason = "Carrier Is not loaded"; return false; } if(!IsMapped) { reason = "Not Mapped"; return false; } if(!IsReady()) { reason = "Not Ready"; return false; } if (IsWaferProtrude) { EV.Notify(AlarmLoadPortWaferProtrusion); OnError("Wafer Protrusion"); reason = "Wafer Protrusion"; return false; } if (SC.ContainsItem($"CarrierInfo.NeedCheckIronDoorCarrier{InfoPadCarrierIndex}") && (SC.GetValue($"CarrierInfo.NeedCheckIronDoorCarrier{InfoPadCarrierIndex}"))) { if (DiIronCassetteDoorClose != null && !DiIronCassetteDoorClose.Value) { reason = "Iron Door Closed"; return false; } } if(ErrorCode !="0") { reason = "ErrorCode is " + ErrorCode; return false; } if (IsVerifyPreDefineWaferCount && WaferCount != PreDefineWaferCount) { reason = "Mapping Error:WaferCount not matched"; return false; } return base.IsEnableTransferWafer(out reason); } public override FoupClampState ClampState { get { if (_diClampOffSensor.Value && !_diClampOnCylinder.Value) return FoupClampState.Open; if (!_diClampOffSensor.Value && _diClampOnCylinder.Value) return FoupClampState.Close; return FoupClampState.Unknown; } } public override FoupDockState DockState { get { if(_diDockHomeSensor.Value && !_diPodForwardSensor.Value) return FoupDockState.Undocked; if(!_diDockHomeSensor.Value && _diPodForwardSensor.Value) return FoupDockState.Docked; return FoupDockState.Unknown; } } public override LoadportCassetteState CassetteState { get { if (_isPlaced && _isPresent) return LoadportCassetteState.Normal; if (!_isPlaced) return LoadportCassetteState.Absent; return LoadportCassetteState.Unknown; } } public override FoupDoorState DoorState { get { if (LPDoorState == TDKPosition.Close) return FoupDoorState.Close; if (LPDoorState == TDKPosition.Open) return FoupDoorState.Open; return FoupDoorState.Unknown; } } public override FoupDoorPostionEnum DoorPosition { get { if (_diVerticalDownSensor.Value && !_diVerticalMiddleSensor.Value) return FoupDoorPostionEnum.Down; if (!_diAck_ZtoMapEnd.Value && !_diVerticalMiddleSensor.Value) return FoupDoorPostionEnum.Unknown; return FoupDoorPostionEnum.Unknown; } } public override bool IsVacuumON { get { return _diVACSensor.Value; } } public override WaferSize GetCurrentWaferSize() { int intvalue = SC.GetValue($"CarrierInfo.CarrierWaferSize{InfoPadCarrierIndex}"); if (intvalue == 8) return WaferSize.WS8; if (intvalue == 12) return WaferSize.WS12; return WaferSize.WS0; } public override int InfoPadCarrierIndex { get { if (IsAutoDetectCarrierType) { return (_diInfoPadA.Value ? 8 : 0) + (_diInfoPadB.Value ? 4 : 0) + (_diInfoPadC.Value ? 2 : 0) + (_diInfoPadD.Value ? 1 : 0); } return base.InfoPadCarrierIndex; } set { base.InfoPadCarrierIndex = value; } } public override bool IsVerifyPreDefineWaferCount { get { if (SC.ContainsItem($"LoadPort.{LPModuleName}.IsVerifyPreDefineWaferCount")) return SC.GetValue($"LoadPort.{LPModuleName}.IsVerifyPreDefineWaferCount"); return false; } } private bool OnTimer() { try { _errorOccurredTrig.CLK = (int)_aiErrorCode.Value != _errorCode; _errorCode = (int)_aiErrorCode.Value; _lastErrorOccurredTrig.CLK = (int)_aiLastErrorCode.Value != _lastErrorCode; _lastErrorCode = (int)_aiLastErrorCode.Value; if(_errorOccurredTrig.Q && _errorCode >0) { if (AlarmNcdLoadPortErrors.Length >= _errorCode - 1000) { EV.Notify(AlarmNcdLoadPortErrors[_errorCode - 1001]); OnError(AlarmNcdLoadPortErrors[_errorCode - 1001]); } } if(_lastErrorOccurredTrig.Q && _lastErrorCode>0) { if (AlarmNcdLoadPortLastErrors.Length > _lastErrorCode - 1000) { EV.Notify(AlarmNcdLoadPortLastErrors[_lastErrorCode - 1001]); OnError(AlarmNcdLoadPortLastErrors[_errorCode - 1001]); } } _isPresent = _diSensor_Presence.Value; _isPlaced = _diSensor_Placement.Value; SetPresent(_isPresent); SetPlaced(_diSensor_Placement.Value); _carrierArrived.CLK = _diSensor_Placement.Value; if (_isPlaced) { if (SC.ContainsItem($"CarrierInfo.CarrierName{InfoPadCarrierIndex}")) SpecCarrierType = SC.GetStringValue($"CarrierInfo.CarrierName{InfoPadCarrierIndex}"); } else SpecCarrierType = ""; if (_carrierArrived.Q) { CheckAndLoadRecipe(); } } catch(Exception ex) { LOG.Write(ex); } return true; } private bool CheckAndLoadRecipe() { int intRecipeNo = SC.GetValue($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}"); int timelimit = SC.ContainsItem($"LoadPort.{Name}.TimeLimitAction") ? SC.GetValue($"LoadPort.{Name}.TimeLimitAction") : 45; if (_aiRECIPE_TYPE_FEEDBACK.Value == intRecipeNo) return true; if (_doRecipeLoadCommand.Value) { _doRecipeLoadCommand.SetValue(false, out _); Thread.Sleep(1000); } _aoSAVECurrentRecipeNumber.Value = (short)intRecipeNo; Thread.Sleep(200); _doRecipeLoadCommand.SetValue(true, out _); DateTime _stTime = DateTime.Now; while(!_diAck_RecipeLoad.Value || _aiRECIPE_TYPE_FEEDBACK.Value != intRecipeNo) { if (DateTime.Now - _stTime > TimeSpan.FromSeconds(timelimit)) { _doRecipeLoadCommand.SetValue(false, out _); EV.Notify($"{LPModuleName}LoadRecipeFailed"); OnError($"{LPModuleName}LoadRecipeFailed"); return false; } } _doRecipeLoadCommand.SetValue(false, out _); _stTime = DateTime.Now; while (_diAck_RecipeLoad.Value) { if (DateTime.Now - _stTime > TimeSpan.FromSeconds(timelimit)) { _doRecipeLoadCommand.SetValue(false, out _); EV.Notify($"{LPModuleName}LoadRecipeFailed"); OnError($"{LPModuleName}LoadRecipeFailed"); return false; } } return true; } protected override bool fStartInit(object[] param) { ResetRoutine(); _actionTimeLimit = SC.ContainsItem($"LoadPort.{Name}.TimeLimitLoadportHome") ? SC.GetValue($"LoadPort.{Name}.TimeLimitLoadportHome") : 45; //if(!_diProtrudesensor.Value) //{ // EV.Notify(AlarmLoadPortWaferProtrusion); // return false; //} return true; //_actionStartTime = DateTime.Now; //if (!CheckAndLoadRecipe()) // return false; //return _doIntialCommand.SetValue(true, out _); } protected override bool fMonitorInit(object[] param) { IsBusy = false; int intRecipeNo = SC.GetValue($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}"); try { SetAoValue((int)LoadPortStepEnum.LoadRecipe1, _aoSAVECurrentRecipeNumber, (short)intRecipeNo, Notify); SetDoState((int)LoadPortStepEnum.LoadRecipe2, _doRecipeLoadCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.LoadRecipe3, _actionTimeLimit, _diAck_RecipeLoad, true, Notify, Stop); WaitAiValue((int)LoadPortStepEnum.LoadRecipe4, _actionTimeLimit, _aiRECIPE_TYPE_FEEDBACK, (short)intRecipeNo, Notify, Stop); SetDoState((int)LoadPortStepEnum.LoadRecipe5, _doRecipeLoadCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.LoadRecipe6, _actionTimeLimit, _diAck_RecipeLoad, false, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep1, _doIntialCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep2, _actionTimeLimit, _diAck_Init, true, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep3, _doIntialCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep4, _actionTimeLimit, _diAck_Init, false, Notify, Stop); } catch (RoutineBreakException) { return false; } catch (RoutineFaildException) { EV.Notify(AlarmLoadPortHomeTimeout); OnError("Home failed"); return true; } OnHomed(); return true; } protected override bool fStartLoad(object[] param) { _actionTimeLimit = SC.ContainsItem($"LoadPort.{Name}.TimeLimitLoadportLoad") ? SC.GetValue($"LoadPort.{Name}.TimeLimitLoadportLoad") : 45; ResetRoutine(); if (param == null || param.Length == 0) { _doMapEnableCommand.SetValue(true, out _); _doMapDisableCommand.SetValue(false, out _); _currentloadCommand = "LoadWithMap"; } if (param.Length >= 1 && param[0].ToString() == "LoadWithMap") { _doMapEnableCommand.SetValue(true, out _); _doMapDisableCommand.SetValue(false, out _); _currentloadCommand = "LoadWithMap"; } if (param.Length >= 1 && param[0].ToString() == "LoadWithoutMap") { _doMapEnableCommand.SetValue(false, out _); _doMapDisableCommand.SetValue(true, out _); _currentloadCommand = "LoadWithoutMap"; } if (param.Length >= 1 && param[0].ToString() == "LoadWithCloseDoor") { _doMapEnableCommand.SetValue(true, out _); _doMapDisableCommand.SetValue(false, out _); _currentloadCommand = "LoadWithCloseDoor"; } if (param.Length >= 1 && param[0].ToString() == "LoadWithoutMapWithCloseDoor") { _doMapEnableCommand.SetValue(false, out _); _doMapDisableCommand.SetValue(true, out _); _currentloadCommand = "LoadWithoutMapWithCloseDoor"; } _isNeedLoadRecipe = _aiRECIPE_TYPE_FEEDBACK.Value != (short)SC.GetValue($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}"); return true; } private string _currentloadCommand = ""; private bool _isNeedLoadRecipe; protected override bool fMonitorLoad(object[] param) { IsBusy = false; try { int intRecipeNo = SC.GetValue($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}"); if (_isNeedLoadRecipe) { SetAoValue((int)LoadPortStepEnum.LoadRecipe1, _aoSAVECurrentRecipeNumber, (short)intRecipeNo, Notify); SetDoState((int)LoadPortStepEnum.LoadRecipe2, _doRecipeLoadCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.LoadRecipe3, _actionTimeLimit, _diAck_RecipeLoad, true, Notify, Stop); WaitAiValue((int)LoadPortStepEnum.LoadRecipe4, _actionTimeLimit, _aiRECIPE_TYPE_FEEDBACK, (short)intRecipeNo, Notify, Stop); SetDoState((int)LoadPortStepEnum.LoadRecipe5, _doRecipeLoadCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.LoadRecipe6, _actionTimeLimit, _diAck_RecipeLoad, false, Notify, Stop); } SetDoState((int)LoadPortStepEnum.ActionStep1, _doLoadCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep2, _actionTimeLimit, _diAck_Load, true, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep3, _doLoadCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep4, _actionTimeLimit, _diAck_Load, false, Notify, Stop); if(_currentloadCommand == "LoadWithCloseDoor") { SetDoState((int)LoadPortStepEnum.ActionStep5, _doVertiaclUpCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep6, _actionTimeLimit, _diAck_VerticalUp, true, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep7, _doVertiaclUpCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep8, _actionTimeLimit, _diAck_VerticalUp, false, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep9, _doVertiaclUpCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep10, _actionTimeLimit, _diAck_VerticalUp, true, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep11, _doVertiaclUpCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep12, _actionTimeLimit, _diAck_VerticalUp, false, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep13, _doDoorCloseCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep14, _actionTimeLimit, _diAck_DoorClose, true, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep15, _doDoorCloseCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep16, _actionTimeLimit, _diAck_DoorClose, false, Notify, Stop); } } catch (RoutineBreakException) { return false; } catch (RoutineFaildException) { EV.Notify(AlarmLoadPortLoadTimeOut); OnError("LoadFailed"); return true; } OnLoaded(); if(_currentloadCommand == "LoadWithMap" || _currentloadCommand == "LoadWithCloseDoor") { ReadSlotMap(); } return true; //if (DateTime.Now - _actionStartTime > TimeSpan.FromSeconds(timelimit)) //{ // _doLoadCommand.SetValue(false, out _); // OnError("Load timeout"); // return false; //} //if (_diAck_Load.Value && _diPodForwardSensor.Value && _diDoorOpenSensor.Value && _diVerticalDownSensor.Value) //{ // _doLoadCommand.SetValue(false, out _); // switch (_currentloadCommand) // { // case "LoadWithMap": // //if (!IsMapped) // ReadSlotMap(); // return true; // case "LoadWithCloseDoor": // if (!_diAck_VerticalUp.Value || _diVerticalDownSensor.Value) // { // _doVertiaclUpCommand.SetValue(true, out _); // _doVertiaclDownCommand.SetValue(false, out _); // } // if(_diAck_VerticalUp.Value && !_diVerticalDownSensor.Value) // { // _doVertiaclUpCommand.SetValue(false, out _); // _doVertiaclDownCommand.SetValue(false, out _); // _doDoorOpenCommand.SetValue(false, out _); // _doDoorCloseCommand.SetValue(true, out _); // } // if(!_diVerticalDownSensor.Value && _diAck_DoorClose.Value && _diDoorCloseSensor.Value) // { // _doDoorOpenCommand.SetValue(false, out _); // _doDoorCloseCommand.SetValue(false, out _); // ReadSlotMap(); // return true; // } // break; // default: // break; // } // _doLoadCommand.SetValue(false, out _); // return true; //} //return base.fMonitorLoad(param); } protected override bool fMonitorTransferBlock(object[] param) { if (!_isPlaced) { OnError("Placement Error"); return false; } return base.fMonitorTransferBlock(param); } private void ReadSlotMap() { string strslotmap = ""; AIAccessor[] ais = new AIAccessor[] { _aiSlot25MapResult,_aiSlot24MapResult,_aiSlot23MapResult,_aiSlot22MapResult ,_aiSlot21MapResult, _aiSlot20MapResult,_aiSlot19MapResult, _aiSlot18MapResult, _aiSlot17MapResult ,_aiSlot16MapResult, _aiSlot15MapResult,_aiSlot14MapResult,_aiSlot13MapResult,_aiSlot12MapResult ,_aiSlot11MapResult, _aiSlot10MapResult,_aiSlot9MapResult,_aiSlot8MapResult,_aiSlot7MapResult ,_aiSlot6MapResult, _aiSlot5MapResult,_aiSlot4MapResult,_aiSlot3MapResult,_aiSlot2MapResult,_aiSlot1MapResult, }; WaferCount = 0; for(int i=25-ValidSlotsNumber; i<25;i++) { strslotmap = strslotmap + ais[i].Value.ToString("D1"); if (ais[i].Value != 0) WaferCount++; } if(IsVerifyPreDefineWaferCount) { if(WaferCount != PreDefineWaferCount) { EV.PostAlarmLog("LoadPort", $"{LPModuleName} mapping error,predefine count is {PreDefineWaferCount}, " + $"Mapping result is {WaferCount}."); OnError("Mapping Error"); } } OnSlotMapRead(strslotmap); } protected override bool fStartRead(object[] param) { return true; } protected override bool fStartReset(object[] param) { if(!_doResetCommand.Value) { _doResetCommand.SetValue(true, out _); } else { _doResetCommand.SetValue(false, out _); Thread.Sleep(1000); _doResetCommand.SetValue(true, out _); } _doLoadCommand.SetValue(false, out _); _doUnloadCommand.SetValue(false, out _); _actionStartTime = DateTime.Now; return true; } protected override bool fMonitorReset(object[] param) { IsBusy = false; if(DateTime.Now - _actionStartTime>TimeSpan.FromSeconds(10)) { OnError("Reset Timeout"); _doResetCommand.SetValue(false, out _); return false; } if(_diAck_Reset.Value) { _doResetCommand.SetValue(false, out _); _errorCode = 0; _lastErrorCode = 0; return true; } return false; } protected override bool fStartUnload(object[] param) { _actionTimeLimit = SC.ContainsItem($"LoadPort.{Name}.TimeLimitLoadportUnload") ? SC.GetValue($"LoadPort.{Name}.TimeLimitLoadportUnload") : 45; ResetRoutine(); _isNeedLoadRecipe = _aiRECIPE_TYPE_FEEDBACK.Value != (short)SC.GetValue($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}"); return true; } public override int ValidSlotsNumber { get { if (SC.ContainsItem($"CarrierInfo.CarrierSlotsNumber{InfoPadCarrierIndex}")) return SC.GetValue($"CarrierInfo.CarrierSlotsNumber{InfoPadCarrierIndex}"); return 25; } } protected override bool fMonitorUnload(object[] param) { IsBusy = false; try { int intRecipeNo = SC.GetValue($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}"); if (_isNeedLoadRecipe) { SetAoValue((int)LoadPortStepEnum.LoadRecipe1, _aoSAVECurrentRecipeNumber, (short)intRecipeNo, Notify); SetDoState((int)LoadPortStepEnum.LoadRecipe2, _doRecipeLoadCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.LoadRecipe3, _actionTimeLimit, _diAck_RecipeLoad, true, Notify, Stop); WaitAiValue((int)LoadPortStepEnum.LoadRecipe4, _actionTimeLimit, _aiRECIPE_TYPE_FEEDBACK, (short)intRecipeNo, Notify, Stop); SetDoState((int)LoadPortStepEnum.LoadRecipe5, _doRecipeLoadCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.LoadRecipe6, _actionTimeLimit, _diAck_RecipeLoad, false, Notify, Stop); } SetDoState((int)LoadPortStepEnum.ActionStep1, _doUnloadCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep2, _actionTimeLimit, _diAck_Unload, true, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep3, _doUnloadCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep4, _actionTimeLimit, _diAck_Unload, false, Notify, Stop); if(SC.ContainsItem($"CarrierInfo.KeepClampedAfterUnloadCarrier{InfoPadCarrierIndex}") && SC.GetValue($"CarrierInfo.KeepClampedAfterUnloadCarrier{InfoPadCarrierIndex}")) { SetDoState((int)LoadPortStepEnum.ActionStep5, _doClampOnCommand, true, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep6, _actionTimeLimit, _diAck_ClampOn, true, Notify, Stop); SetDoState((int)LoadPortStepEnum.ActionStep7, _doClampOnCommand, false, Notify); WaitDiState((int)LoadPortStepEnum.ActionStep8, _actionTimeLimit, _diAck_ClampOn, false, Notify, Stop); } else { base.OnUnloaded(); } } catch (RoutineBreakException) { return false; } catch (RoutineFaildException) { EV.Notify(AlarmLoadPortUnloadTimeOut); OnError("UnloadFailed"); return true; } return true; } protected override bool fStartWrite(object[] param) { return true; } protected override bool fStartExecute(object[] param) { if (!CheckAndLoadRecipe()) return false; _actionStartTime = DateTime.Now; try { switch (param[0].ToString()) { case "SetIndicator": _currentExecuteCommand = "SetIndicator"; Indicator light = (Indicator)param[1]; IndicatorState state = (IndicatorState)param[2]; switch(light) { case Indicator.LOAD: if (state == IndicatorState.BLINK || state == IndicatorState.ON) _doLoadLight.SetValue(true, out _); if (state == IndicatorState.OFF) _doLoadLight.SetValue(false, out _); break; case Indicator.UNLOAD: if (state == IndicatorState.BLINK || state == IndicatorState.ON) _doUnloadLight.SetValue(true, out _); if (state == IndicatorState.OFF) _doUnloadLight.SetValue(false, out _); break; case Indicator.ACCESSAUTO: if (state == IndicatorState.BLINK || state == IndicatorState.ON) _doStatu1Light.SetValue(true, out _); if (state == IndicatorState.OFF) _doStatu1Light.SetValue(false, out _); break; case Indicator.ACCESSMANUL: if (state == IndicatorState.BLINK || state == IndicatorState.ON) _doStatu2Light.SetValue(true, out _); if (state == IndicatorState.OFF) _doStatu2Light.SetValue(false, out _); break; } break; case "QueryIndicator": break; case "QueryState": _currentExecuteCommand = "QueryState"; break; case "Undock": _currentExecuteCommand = "Undock"; _doDOCKHomeCommand.SetValue(true, out _); _doDOCKForwardCommand.SetValue(false, out _); break; case "Dock": _currentExecuteCommand = "Dock"; _doDOCKHomeCommand.SetValue(false, out _); _doDOCKForwardCommand.SetValue(true, out _); break; case "CloseDoor": _currentExecuteCommand = "CloseDoor"; _doDoorOpenCommand.SetValue(false, out _); _doDoorCloseCommand.SetValue(true, out _); break; case "OpenDoor": _currentExecuteCommand = "CloseDoor"; _doDoorOpenCommand.SetValue(true, out _); _doDoorCloseCommand.SetValue(false, out _); break; case "Unclamp": _currentExecuteCommand = "Unclamp"; _doClampOffCommand.SetValue(true, out _); _doClampOnCommand.SetValue(false, out _); break; case "Clamp": _currentExecuteCommand = "Clamp"; _doClampOffCommand.SetValue(false, out _); _doClampOnCommand.SetValue(true, out _); break; case "DoorUp": _currentExecuteCommand = "DoorUp"; _doVertiaclDownCommand.SetValue(false, out _); _doVertiaclUpCommand.SetValue(true, out _); break; case "DoorDown": _currentExecuteCommand = "DoorDown"; _doVertiaclDownCommand.SetValue(true, out _); _doVertiaclUpCommand.SetValue(false, out _); break; case "MapWafer": //_currentExecuteCommand = "MapWafer"; //_doZtoMAPPINGSTARTPOSI.SetValue(true, out _); break; case "DoorUpAndClose": _currentExecuteCommand = "DoorUpAndClose"; _doVertiaclUpCommand.SetValue(true, out _); break; case "OpenDoorAndDown": _currentExecuteCommand = "DoorUpAndClose"; _doDoorOpenCommand.SetValue(true, out _); break; case "Move": HandlerMoveCommand(param[1].ToString()); break; case "Set": break; case "Get": break; } return true; } catch (Exception ex) { LOG.Write(ex); EV.PostAlarmLog(Name, $"Parameter invalid"); return false; } } private void HandlerMoveCommand(string movecommand) { switch(movecommand) { case "PODCL": _currentExecuteCommand = "Clamp"; _doClampOffCommand.SetValue(false, out _); _doClampOnCommand.SetValue(true, out _); break; case "YDOOR": _currentExecuteCommand = "Dock"; _doDOCKHomeCommand.SetValue(false, out _); _doDOCKForwardCommand.SetValue(true, out _); break; case "VACON": _currentExecuteCommand = "VacuumOn"; _doVACOnCommand.SetValue(true, out _); _doVACOffCommand.SetValue(false, out _); break; case "DOROP": _currentExecuteCommand = "UnlatchDoor"; _doLatchOffCommand.SetValue(true, out _); _doLatchOnCommand.SetValue(false, out _); break; case "ZMPST": _currentExecuteCommand = "MoveToMapStart"; _doZtoMAPPINGSTARTPOSI.SetValue(true, out _); _doZtoMAPPINGENDPOSI.SetValue(false, out _); break; case "MAPOP": _currentExecuteCommand = "MoveToMapMeasurement"; break; case "ZDRMP": _currentExecuteCommand = "MoveToMapEnd"; _doZtoMAPPINGSTARTPOSI.SetValue(false, out _); _doZtoMAPPINGENDPOSI.SetValue(true, out _); break; case "MAPCL": _currentExecuteCommand = "MoveToMapWait"; break; case "ZDRDW": _currentExecuteCommand = "MoveToLoadPosition"; break; case "ZDRUP": _currentExecuteCommand = "MoveToDoorOpenClosePostion"; _doVertiaclUpCommand.SetValue(true, out _); _doVertiaclDownCommand.SetValue(false, out _); break; case "DORFW": _currentExecuteCommand = "CloseDoor"; _doDoorCloseCommand.SetValue(true, out _); _doDoorOpenCommand.SetValue(false, out _); break; case "DORCL": _currentExecuteCommand = "LatchDoor"; _doLatchOnCommand.SetValue(true, out _); _doLatchOffCommand.SetValue(false, out _); break; case "VACOF": _currentExecuteCommand = "VacuumOff"; _doVACOffCommand.SetValue(true, out _); _doVACOnCommand.SetValue(false, out _); break; case "YWAIT": _currentExecuteCommand = "Undock"; _doDOCKHomeCommand.SetValue(true, out _); _doDOCKForwardCommand.SetValue(false, out _); break; case "PODOP": _currentExecuteCommand = "Unclamp"; _doClampOffCommand.SetValue(true, out _); _doClampOnCommand.SetValue(false, out _); break; case "ORGSH": _currentExecuteCommand = "ORGSH"; _doIntialCommand.SetValue(true, out _); break; default: break; } } private string _currentExecuteCommand; protected override bool fMonitorExecuting(object[] param) { IsBusy = false; int timelimit = SC.ContainsItem($"LoadPort.{Name}.TimeLimitAction") ? SC.GetValue($"LoadPort.{Name}.TimeLimitAction") : 45; if (DateTime.Now - _actionStartTime > TimeSpan.FromSeconds(timelimit)) { OnError("Execute command timeout"); return true; } switch(_currentExecuteCommand) { case "SetIndicator": return true; case "Clamp": if (_diAck_ClampOn.Value) { _doClampOnCommand.SetValue(false, out _); return true; } break; case "Unclamp": if (_diAck_ClampOff.Value) { _doClampOffCommand.SetValue(false, out _); if (_diDockHomeSensor.Value) base.OnUnloaded(); return true; } break; case "Dock": if (_diAck_DockFwd.Value) { _doDOCKForwardCommand.SetValue(false, out _); return true; } break; case "Undock": if (_diAck_DockFwd.Value) { _doDOCKHomeCommand.SetValue(false, out _); return true; } break; case "VacuumOn": if(_diAck_VacOn.Value) { _doVACOnCommand.SetValue(false, out _); return true; } break; case "VacuumOff": if(_diAck_VacOff.Value) { _doVACOffCommand.SetValue(false, out _); return true; } break; case "LatchDoor": if(_diAck_LatchOn.Value) { _doLatchOnCommand.SetValue(false, out _); return true; } break; case "UnlatchDoor": if(_diAck_LatchOff.Value) { _doLatchOffCommand.SetValue(false, out _); return true; } break; case "OpenDoor": if(_diAck_DoorOpen.Value) { _doDoorOpenCommand.SetValue(false, out _); return true; } break; case "CloseDoor": if(_diAck_DoorClose.Value) { _doDoorCloseCommand.SetValue(false, out _); return true; } break; case "MoveToDoorOpenClosePostion": case "DoorUp": if (_diAck_VerticalUp.Value) { _doVertiaclUpCommand.SetValue(false, out _); return true; } break; case "MoveToMapStart": if(_diAck_ZtoMapStart.Value) { _doZtoMAPPINGSTARTPOSI.SetValue(false, out _); return true; } break; case "MoveToMapEnd": if(_diAck_ZtoMapEnd.Value) { _doZtoMAPPINGENDPOSI.SetValue(false, out _); return true; } break; case "DoorDown": if(_diAck_VerticalDown.Value) { _doVertiaclDownCommand.SetValue(false, out _); return true; } break; case "ORGSH": if(_diAck_Init.Value) { _doIntialCommand.SetValue(false, out _); return true; } break; case "MapWafer": //if(_diAck_Mapin) default: return true; } return base.fMonitorExecuting(param); } public override bool SetIndicator(Indicator light, IndicatorState state, out string reason) { reason = ""; return fStartExecute(new object[] { "SetIndicator", light, state }); } public DOAccessor ParseDoNode(string name, XmlElement node, string ioModule = "") { if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim())) return IO.DO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"]; return null; } public DIAccessor ParseDiNode(string name, XmlElement node, string ioModule = "") { if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim())) return IO.DI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"]; return null; } public AOAccessor ParseAoNode(string name, XmlElement node, string ioModule = "") { if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim())) return IO.AO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"]; return null; } public AIAccessor ParseAiNode(string name, XmlElement node, string ioModule = "") { if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim())) return IO.AI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : $"{ioModule}.{node.GetAttribute(name).Trim()}"]; return null; } public SCConfigItem ParseScNode(string name, XmlElement node, string ioModule = "", string defaultScPath = "") { SCConfigItem result = null; if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim())) result = SC.GetConfigItem(node.GetAttribute(name)); if (result == null && !string.IsNullOrEmpty(defaultScPath) && SC.ContainsItem(defaultScPath)) result = SC.GetConfigItem(defaultScPath); return result; } public static T ParseDeviceNode(string name, XmlElement node) where T : class, IDevice { if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim())) return DEVICE.GetDevice(node.GetAttribute(name)); LOG.Write(string.Format("{0},未定义{1}", node.InnerXml, name)); return null; } public static T ParseDeviceNode(string module, string name, XmlElement node) where T : class, IDevice { string device_id = node.GetAttribute(name); if (!string.IsNullOrEmpty(device_id) && !string.IsNullOrEmpty(device_id.Trim())) { return DEVICE.GetDevice($"{module}.{device_id}"); } LOG.Write(string.Format("{0},undefined {1}", node.InnerXml, name)); return null; } public enum CarrierMode { Foup, Fosb, OpenCassette, } private void SetAoValue(int id, AOAccessor ao, short value,Action notify) { var ret = Execute(id, () => { notify($"{LPModuleName} set {ao.Name} to {value}."); ao.Value = value; return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } } } private void WaitAiValue(int id, int time, AIAccessor ai, short value, Action notify, Action error) { var ret = ExecuteAndWait(id, () => { notify($"Wait {LPModuleName} {ai.Name} to be {value}"); return true; }, () => { if (ai.Value == value) return true; return false; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } else if (ret.Item2 == Result.TIMEOUT) //timeout { EV.Notify(AlarmLoadPortError); error($"Wait {LPModuleName} {ai.Name} to be {value} timeout after {time} seconds"); throw new RoutineFaildException(); } else { throw new RoutineBreakException(); } } } private void WaitDiState(int id, int time, DIAccessor di,bool state, Action notify, Action error) { var ret = ExecuteAndWait(id, () => { notify($"Wait {LPModuleName} {di.Name} to be {state}"); return true; }, () => { if (di.Value == state) return true; return false; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } else if (ret.Item2 == Result.TIMEOUT) //timeout { EV.Notify(AlarmLoadPortError); error($"Wait {LPModuleName} {di.Name} to be {state} timeout after {time} seconds"); throw new RoutineFaildException(); } else { throw new RoutineBreakException(); } } } private void SetDoState(int id, DOAccessor _do, bool state, Action notify) { var ret = Execute(id, () => { notify($"{LPModuleName} start set {_do.Name} to {state}."); if (_do.Value == state) { _do.Value = !state; Thread.Sleep(500); } return _do.SetValue(state, out _); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } } } protected void Notify(string message) { EV.PostMessage(Name, EventEnum.GeneralInfo, string.Format("{0}:{1}", Name, message)); } protected void Stop(string failReason) { OnError(string.Format("Failed {0}, {1} ", Name, failReason)); } private enum LoadPortStepEnum { LoadRecipe1, LoadRecipe2, LoadRecipe3, LoadRecipe4, LoadRecipe5, LoadRecipe6, ActionStep1, ActionStep2, ActionStep3, ActionStep4, ActionStep5, ActionStep6, ActionStep7, ActionStep8, ActionStep9, ActionStep10, ActionStep11, ActionStep12, ActionStep13, ActionStep14, ActionStep15, ActionStep16, } //timer, 计算routine时间 protected DeviceTimer counter = new DeviceTimer(); protected DeviceTimer delayTimer = new DeviceTimer(); private enum STATE { IDLE, WAIT, } public int TokenId { get { return _id; } } private int _id; //step index /// /// already done steps /// private Stack _steps = new Stack(); private STATE state; //step state //idel,wait, //loop control private int loop = 0; private int loopCount = 0; private int loopID = 0; private DeviceTimer timer = new DeviceTimer(); public int LoopCounter { get { return loop; } } public int LoopTotalTime { get { return loopCount; } } // public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } } //状态持续时间,单位为秒 public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } } protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running }; public void ResetRoutine() { _id = 0; _steps.Clear(); loop = 0; loopCount = 0; state = STATE.IDLE; counter.Start(60 * 60 * 100); //默认1小时 RoutineToken.Result = RoutineState.Running; } protected void PerformRoutineStep(int id, Func execution, RoutineResult result) { if (!Acitve(id)) return; result.Result = execution(); } #region interface public void StopLoop() { loop = loopCount; } public Tuple Loop(T id, Func func, int count) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); if (bActive) { if (!func()) { return Tuple.Create(bActive, Result.FAIL); //执行错误 } loopID = idx; loopCount = count; next(); return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } public Tuple EndLoop(T id, Func func) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); if (bActive) { if (++loop >= loopCount) //Loop 结束 { if (!func()) { return Tuple.Create(bActive, Result.FAIL); //执行错误 } loop = 0; loopCount = 0; // Loop 结束时,当前loop和loop总数都清零 next(); return Tuple.Create(true, Result.RUN); } //继续下一LOOP next(loopID); return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } public Tuple ExecuteAndWait(T id, IRoutine routine) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); if (bActive) { if (state == STATE.IDLE) { Result startRet = routine.Start(); if (startRet == Result.FAIL) { return Tuple.Create(true, Result.FAIL); //执行错误 } else if (startRet == Result.DONE) { next(); return Tuple.Create(true, Result.DONE); } state = STATE.WAIT; } Result ret = routine.Monitor(); if (ret == Result.DONE) { next(); return Tuple.Create(true, Result.DONE); } else if (ret == Result.FAIL || ret == Result.TIMEOUT) { return Tuple.Create(true, Result.FAIL); } else { return Tuple.Create(true, Result.RUN); } } return Tuple.Create(false, Result.RUN); } public Tuple ExecuteAndWait(T id, List routines) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); if (bActive) { if (state == STATE.IDLE) { foreach (var item in routines) { if (item.Start() == Result.FAIL) return Tuple.Create(true, Result.FAIL); } state = STATE.WAIT; } //wait all sub failed or completedboo bool bFail = false; bool bDone = true; foreach (var item in routines) { Result ret = item.Monitor(); bDone &= (ret == Result.FAIL || ret == Result.DONE); bFail |= ret == Result.FAIL; } if (bDone) { next(); if (bFail) return Tuple.Create(true, Result.FAIL); return Tuple.Create(true, Result.DONE); } return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } public Tuple Check(T id, Func func) //顺序执行 { return Check(Check(Convert.ToInt32(id), func)); } public Tuple Execute(T id, Func func) //顺序执行 { return Check(execute(Convert.ToInt32(id), func)); } public Tuple Wait(T id, Func func, double timeout = int.MaxValue) //Wait condition { return Check(wait(Convert.ToInt32(id), func, timeout)); } public Tuple Wait(T id, Func func, double timeout = int.MaxValue) //Wait condition { return Check(wait(Convert.ToInt32(id), func, timeout)); } public Tuple ExecuteAndWait(T id, Func execute, Func check, double timeout = int.MaxValue) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); bool? bExecute = false; if (bActive) { if (state == STATE.IDLE) { if (!execute()) { return Tuple.Create(bActive, Result.FAIL); //执行错误 } timer.Start(timeout); state = STATE.WAIT; } bExecute = check(); if (bExecute == null) { return Tuple.Create(bActive, Result.FAIL); //Termianate } else { if (bExecute.Value) //检查Success, next { next(); return Tuple.Create(true, Result.RUN); } } if (timer.IsTimeout()) return Tuple.Create(true, Result.TIMEOUT); return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } public Tuple ExecuteAndWait(T id, Func execute, Func check, Func time) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); bool? bExecute = false; double timeout = 0; if (bActive) { if (state == STATE.IDLE) { timeout = time(); if (!execute()) { return Tuple.Create(true, Result.FAIL); //执行错误 } timer.Start(timeout); state = STATE.WAIT; } bExecute = check(); if (bExecute == null) { return Tuple.Create(true, Result.FAIL); //Termianate } if (bExecute.Value) //检查Success, next { next(); return Tuple.Create(true, Result.RUN); } if (timer.IsTimeout()) return Tuple.Create(true, Result.TIMEOUT); return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } public Tuple Wait(T id, IRoutine rt) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); if (bActive) { if (state == STATE.IDLE) { rt.Start(); state = STATE.WAIT; } Result ret = rt.Monitor(); return Tuple.Create(true, ret); } return Tuple.Create(false, Result.RUN); } //Monitor public Tuple Monitor(T id, Func func, Func check, double time) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); bool bCheck = false; if (bActive) { if (state == STATE.IDLE) { if ((func != null) && !func()) { return Tuple.Create(true, Result.FAIL); } timer.Start(time); state = STATE.WAIT; } bCheck = check(); if (!bCheck) { return Tuple.Create(true, Result.FAIL); //Termianate } if (timer.IsTimeout()) { next(); } return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } //Delay public Tuple Delay(T id, Func func, double time) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); if (bActive) { if (state == STATE.IDLE) { if ((func != null) && !func()) { return Tuple.Create(true, Result.FAIL); } timer.Start(time); state = STATE.WAIT; } if (timer.IsTimeout()) { next(); } return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } //先delay 再运行 public Tuple DelayCheck(T id, Func func, double time) { int idx = Convert.ToInt32(id); bool bActive = Acitve(idx); if (bActive) { if (state == STATE.IDLE) { timer.Start(time); state = STATE.WAIT; } if (timer.IsTimeout()) { if (func != null && !func()) { return Tuple.Create(true, Result.FAIL); } next(); } return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } #endregion private Tuple execute(int id, Func func) //顺序执行 { bool bActive = Acitve(id); bool bExecute = false; if (bActive) { bExecute = func(); if (bExecute) { next(); } } return Tuple.Create(bActive, bExecute); } private Tuple Check(int id, Func func) //check { bool bActive = Acitve(id); bool bExecute = false; if (bActive) { bExecute = func(); next(); } return Tuple.Create(bActive, bExecute); } /// /// /// /// /// /// /// item1 Active /// item2 execute /// item3 Timeout /// private Tuple wait(int id, Func func, double timeout = int.MaxValue) //Wait condition { bool bActive = Acitve(id); bool bExecute = false; bool bTimeout = false; if (bActive) { if (state == STATE.IDLE) { timer.Start(timeout); state = STATE.WAIT; } bExecute = func(); if (bExecute) { next(); } bTimeout = timer.IsTimeout(); } return Tuple.Create(bActive, bExecute, bTimeout); } private Tuple wait(int id, Func func, double timeout = int.MaxValue) //Wait condition && Check error { bool bActive = Acitve(id); bool? bExecute = false; bool bTimeout = false; if (bActive) { if (state == STATE.IDLE) { timer.Start(timeout); state = STATE.WAIT; } bExecute = func(); if (bExecute.HasValue && bExecute.Value) { next(); } bTimeout = timer.IsTimeout(); } return Tuple.Create(bActive, bExecute, bTimeout); } /// /// /// /// /// item1 true, return item2 /// private Tuple Check(Tuple value) { if (value.Item1) { if (!value.Item2) { return Tuple.Create(true, Result.FAIL); } return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } private Tuple Check(Tuple value) { if (value.Item1) // 当前执行 { if (CheckTimeout(value)) //timeout { return Tuple.Create(true, Result.TIMEOUT); } return Tuple.Create(true, Result.RUN); } return Tuple.Create(false, Result.RUN); } private Tuple Check(Tuple value) { if (value.Item1) // 当前执行 { if (value.Item2 == null) { return Tuple.Create(true, Result.FAIL); } else { if (value.Item2 == false && value.Item3 == true) //timeout { return Tuple.Create(true, Result.TIMEOUT); } return Tuple.Create(true, Result.RUN); } } return Tuple.Create(false, Result.RUN); } private bool CheckTimeout(Tuple value) { return value.Item1 == true && value.Item2 == false && value.Item3 == true; } private bool Acitve(int id) // { if (_steps.Contains(id)) return false; this._id = id; return true; } private void next() { _steps.Push(this._id); state = STATE.IDLE; } private void next(int step) //loop { while (_steps.Pop() != step) ; state = STATE.IDLE; } public void Delay(int id, double delaySeconds) { Tuple ret = Delay(id, () => { return true; }, delaySeconds * 1000); if (ret.Item1) { if (ret.Item2 == Result.RUN) { throw (new RoutineBreakException()); } } } public bool IsActived(int id) { return _steps.Contains(id); } } }