Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../HardwareUnits/LoadPorts/NCD/NcdIoLoadPort.cs

2738 lines
108 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
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<VALUE<30000]
private AOAccessor _aoMAPEND;//MAP END(10um) [2000<VALUE<30000]
private AOAccessor _aoSENSOR; //SENSOR (112寸 ; 28寸
private AOAccessor _aoSLOT;
private AOAccessor _aoPITCH;
private AOAccessor _aoPOSITIONRANGE; //POSITION RANGE(10um)
private AOAccessor _aoPOSITIONRANGEUPPER; //POSITION RANGE UPPER()
private AOAccessor _aoPOSITIONRANGELOWER; //POSITION RANGE LOWER()
private AOAccessor _aoTHICK;//THICK(10um)
private AOAccessor _aoTHICKRANGE;//THICK RANGE(10um)
private AOAccessor _aoOFFSET;//OFFSET(10um)
private AOAccessor _aoCarrierType;//料盒种类1-FOUP2-FOSB3-Open Cassette
private AIAccessor _aiSlot1MapResult; // ( 0:No Wafer, 1:Wafer, 2:Crossed )
private AIAccessor _aiSlot2MapResult;
private AIAccessor _aiSlot3MapResult;
private AIAccessor _aiSlot4MapResult;
private AIAccessor _aiSlot5MapResult;
private AIAccessor _aiSlot6MapResult;
private AIAccessor _aiSlot7MapResult;
private AIAccessor _aiSlot8MapResult;
private AIAccessor _aiSlot9MapResult;
private AIAccessor _aiSlot10MapResult;
private AIAccessor _aiSlot11MapResult;
private AIAccessor _aiSlot12MapResult;
private AIAccessor _aiSlot13MapResult;
private AIAccessor _aiSlot14MapResult;
private AIAccessor _aiSlot15MapResult;
private AIAccessor _aiSlot16MapResult;
private AIAccessor _aiSlot17MapResult;
private AIAccessor _aiSlot18MapResult;
private AIAccessor _aiSlot19MapResult;
private AIAccessor _aiSlot20MapResult;
private AIAccessor _aiSlot21MapResult;
private AIAccessor _aiSlot22MapResult;
private AIAccessor _aiSlot23MapResult;
private AIAccessor _aiSlot24MapResult;
private AIAccessor _aiSlot25MapResult;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot1;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot1;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot2;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot2;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot3;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot3;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot4;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot4;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot5;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot5;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot6;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot6;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot7;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot7;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot8;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot8;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot9;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot9;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot10;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot10;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot11;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot11;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot12;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot12;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot13;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot13;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot14;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot14;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot15;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot15;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot16;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot16;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot17;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot17;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot18;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot18;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot19;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot19;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot20;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot20;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot21;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot21;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot22;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot22;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot23;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot23;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot24;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot24;
private AIAccessor _aiWAFERPOSITIONUPPEREDGE_Slot25;
private AIAccessor _aiWAFERPOSITIONLOWEREDGE_Slot25;
private AIAccessor _aiErrorCode;
private AIAccessor _aiLastErrorCode;
private AIAccessor _aiTYPE1_CurrentRecipeNumber;
private AIAccessor _aiTYPE1_MAPSTAR;
private AIAccessor _aiTYPE1_MAPEND;
private AIAccessor _aiTYPE1_SENSOR_WaferSize;
private AIAccessor _aiTYPE1_SLOT;
private AIAccessor _aiTYPE1_PITCH;
private AIAccessor _aiTYPE1_POSITIONRANGE;
private AIAccessor _aiTYPE1_POSITIONRANGEUPPER;
private AIAccessor _aiTYPE1_POSITIONRANGELOWER;
private AIAccessor _aiTYPE1_THICK;
private AIAccessor _aiTYPE1_THICKRANGE;
private AIAccessor _aiTYPE1_OFFSET;
private AIAccessor _aiTYPE2_CurrentRecipeNumber;
private AIAccessor _aiTYPE2_MAPSTAR;
private AIAccessor _aiTYPE2_MAPEND;
private AIAccessor _aiTYPE2_SENSOR_WaferSize;
private AIAccessor _aiTYPE2_SLOT;
private AIAccessor _aiTYPE2_PITCH;
private AIAccessor _aiTYPE2_POSITIONRANGE;
private AIAccessor _aiTYPE2_POSITIONRANGEUPPER;
private AIAccessor _aiTYPE2_POSITIONRANGELOWER;
private AIAccessor _aiTYPE2_THICK;
private AIAccessor _aiTYPE2_THICKRANGE;
private AIAccessor _aiTYPE2_OFFSET;
private AIAccessor _aiTYPE3_CurrentRecipeNumber;
private AIAccessor _aiTYPE3_MAPSTAR;
private AIAccessor _aiTYPE3_MAPEND;
private AIAccessor _aiTYPE3_SENSOR_WaferSize;
private AIAccessor _aiTYPE3_SLOT;
private AIAccessor _aiTYPE3_PITCH;
private AIAccessor _aiTYPE3_POSITIONRANGE;
private AIAccessor _aiTYPE3_POSITIONRANGEUPPER;
private AIAccessor _aiTYPE3_POSITIONRANGELOWER;
private AIAccessor _aiTYPE3_THICK;
private AIAccessor _aiTYPE3_THICKRANGE;
private AIAccessor _aiTYPE3_OFFSET;
private AIAccessor _aiTYPE4_CurrentRecipeNumber;
private AIAccessor _aiTYPE4_MAPSTAR;
private AIAccessor _aiTYPE4_MAPEND;
private AIAccessor _aiTYPE4_SENSOR_WaferSize;
private AIAccessor _aiTYPE4_SLOT;
private AIAccessor _aiTYPE4_PITCH;
private AIAccessor _aiTYPE4_POSITIONRANGE;
private AIAccessor _aiTYPE4_POSITIONRANGEUPPER;
private AIAccessor _aiTYPE4_POSITIONRANGELOWER;
private AIAccessor _aiTYPE4_THICK;
private AIAccessor _aiTYPE4_THICKRANGE;
private AIAccessor _aiTYPE4_OFFSET;
private AIAccessor _aiTYPE5_CurrentRecipeNumber;
private AIAccessor _aiTYPE5_MAPSTAR;
private AIAccessor _aiTYPE5_MAPEND;
private AIAccessor _aiTYPE5_SENSOR_WaferSize;
private AIAccessor _aiTYPE5_SLOT;
private AIAccessor _aiTYPE5_PITCH;
private AIAccessor _aiTYPE5_POSITIONRANGE;
private AIAccessor _aiTYPE5_POSITIONRANGEUPPER;
private AIAccessor _aiTYPE5_POSITIONRANGELOWER;
private AIAccessor _aiTYPE5_THICK;
private AIAccessor _aiTYPE5_THICKRANGE;
private AIAccessor _aiTYPE5_OFFSET;
private AIAccessor _aiTYPE6_CurrentRecipeNumber;
private AIAccessor _aiTYPE6_MAPSTAR;
private AIAccessor _aiTYPE6_MAPEND;
private AIAccessor _aiTYPE6_SENSOR_WaferSize;
private AIAccessor _aiTYPE6_SLOT;
private AIAccessor _aiTYPE6_PITCH;
private AIAccessor _aiTYPE6_POSITIONRANGE;
private AIAccessor _aiTYPE6_POSITIONRANGEUPPER;
private AIAccessor _aiTYPE6_POSITIONRANGELOWER;
private AIAccessor _aiTYPE6_THICK;
private AIAccessor _aiTYPE6_THICKRANGE;
private AIAccessor _aiTYPE6_OFFSET;
private AIAccessor _aiRECIPE_TYPE_FEEDBACK;
private DIAccessor _diAck_RecieSave;
private DIAccessor _diAck_RecipeLoad;
private DIAccessor _diAck_Init;
private DIAccessor _diAck_Reset;
private DIAccessor _diAck_SingleMap;
private DIAccessor _diAck_HomePos;
private DIAccessor _diSensor_Presence;
private DIAccessor _diSensor_Placement;
private DIAccessor _diSensor_Protrude;
private DIAccessor _diSensor_VerticalDown;
private DIAccessor _diAck_Load;
private DIAccessor _diAck_Unload;
private DIAccessor _diAck_MapDisable;
private DIAccessor _diAck_MapEnable;
private DIAccessor _diAck_ClampOn;
private DIAccessor _diAck_ClampOff;
private DIAccessor _diAck_DockFwd;
private DIAccessor _diAck_DockHome;
private DIAccessor _diAck_LatchOn;
private DIAccessor _diAck_LatchOff;
private DIAccessor _diAck_DoorClose;
private DIAccessor _diAck_DoorOpen;
private DIAccessor _diAck_VacOn;
private DIAccessor _diAck_VacOff;
private DIAccessor _diAck_VerticalDown;
private DIAccessor _diAck_VerticalUp;
private DIAccessor _diAck_ZtoMapStart;
private DIAccessor _diAck_ZtoMapEnd;
private DIAccessor _diAck_Mapin;
private DIAccessor _diAck_MapOut;
private DIAccessor _diAck_CmdClear;
private DIAccessor _diAck_E84Disable;
private DIAccessor _diAck_E84Enable;
//原X,Y
private DIAccessor _di12MapSensor;
private DIAccessor _di8MapSensor;
private DIAccessor _diSERVOHOME;
private DIAccessor _diFoupPlacementSensor;
private DIAccessor _diDoorCheckSensor;
private DIAccessor _diCDASensor;
private DIAccessor _diDockHomeSensor;
private DIAccessor _diClampOffSensor;
private DIAccessor _diPodForwardSensor;
private DIAccessor _diClampOnSensor;
private DIAccessor _diVACSensor;
private DIAccessor _diLatchLockSensor;
private DIAccessor _diLatchUnlockSensor;
private DIAccessor _diDoorOpenSensor;
private DIAccessor _diDoorCloseSensor;
private DIAccessor _diVerticalMiddleSensor;
private DIAccessor _diVerticalDownSensor;
private DIAccessor _diOPSwitchButton;
private DIAccessor _diMapin;
private DIAccessor _diMapout;
private DIAccessor _diProtrudesensor;
private DIAccessor _diInfoPadA;
private DIAccessor _diInfoPadB;
private DIAccessor _diInfoPadC;
private DIAccessor _diInfoPadD;
private DIAccessor _diServoOn;
private DIAccessor _diPresence;
private DIAccessor _diStepError;
private DIAccessor _diServoerror;
private DIAccessor _diDoorSafe;
private DIAccessor _diSERVO;
private DIAccessor _diSTEP;
private DIAccessor _diClampOnCylinder;
private DIAccessor _diClampOffCylinder;
private DIAccessor _diLatchOnCylinder;
private DIAccessor _diLatchOffCylinder;
private DIAccessor _diDoorOpenCylinder;
private DIAccessor _diDoorCloseCylinder;
private DIAccessor _diSERVOCLEAR1;
private DIAccessor _diSERVOON1;
private DIAccessor _diD3UBIN;
private DIAccessor _diMapForwardCylinder;
private DIAccessor _diSERVOCLEAR2;
private DIAccessor _diSERVOON2;
private DIAccessor _diSERVOCLCOUNT;
private DIAccessor _diVAC;
private DIAccessor _diSERVOBRAKE;
private DIAccessor _diLoadLight;
private DIAccessor _diUnloadLight;
private DIAccessor _diPOWERLIGHT;
private DIAccessor _diFoupPlacementLight;
private DIAccessor _diFoupPresenceLight;
private DIAccessor _diAlarmOccurLight;
private DIAccessor _diStatu1Light;
private DIAccessor _diStatu2Light;
private IoSensor _diIronCassetteDoorClose;
public IoSensor DiIronCassetteDoorClose
{
get => _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<int>($"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<bool>($"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<bool>($"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<bool>($"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<int>($"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<bool>($"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<int>($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}");
int timelimit = SC.ContainsItem($"LoadPort.{Name}.TimeLimitAction") ?
SC.GetValue<int>($"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<int>($"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<int>($"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<int>($"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<int>($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}");
return true;
}
private string _currentloadCommand = "";
private bool _isNeedLoadRecipe;
protected override bool fMonitorLoad(object[] param)
{
IsBusy = false;
try
{
int intRecipeNo = SC.GetValue<int>($"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<int>($"LoadPort.{Name}.TimeLimitLoadportUnload") : 45;
ResetRoutine();
_isNeedLoadRecipe = _aiRECIPE_TYPE_FEEDBACK.Value !=
(short)SC.GetValue<int>($"CarrierInfo.CarrierRecipeNumber{InfoPadCarrierIndex}");
return true;
}
public override int ValidSlotsNumber
{
get
{
if (SC.ContainsItem($"CarrierInfo.CarrierSlotsNumber{InfoPadCarrierIndex}"))
return SC.GetValue<int>($"CarrierInfo.CarrierSlotsNumber{InfoPadCarrierIndex}");
return 25;
}
}
protected override bool fMonitorUnload(object[] param)
{
IsBusy = false;
try
{
int intRecipeNo = SC.GetValue<int>($"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<bool>($"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<int>($"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<T>(string name, XmlElement node) where T : class, IDevice
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
return DEVICE.GetDevice<T>(node.GetAttribute(name));
LOG.Write(string.Format("{0},未定义{1}", node.InnerXml, name));
return null;
}
public static T ParseDeviceNode<T>(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<T>($"{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<string> 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<string> notify, Action<string> 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<string> notify, Action<string> 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<string> 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
/// <summary>
/// already done steps
/// </summary>
private Stack<int> _steps = new Stack<int>();
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<RoutineState> execution, RoutineResult result)
{
if (!Acitve(id))
return;
result.Result = execution();
}
#region interface
public void StopLoop()
{
loop = loopCount;
}
public Tuple<bool, Result> Loop<T>(T id, Func<bool> 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<bool, Result> EndLoop<T>(T id, Func<bool> 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<bool, Result> ExecuteAndWait<T>(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<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> 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<bool, Result> Check<T>(T id, Func<bool> func) //顺序执行
{
return Check(Check(Convert.ToInt32(id), func));
}
public Tuple<bool, Result> Execute<T>(T id, Func<bool> func) //顺序执行
{
return Check(execute(Convert.ToInt32(id), func));
}
public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition
{
return Check(wait(Convert.ToInt32(id), func, timeout));
}
public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> 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<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, Func<double> 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<bool, Result> Wait<T>(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<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> 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<bool, Result> Delay<T>(T id, Func<bool> 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<bool, Result> DelayCheck<T>(T id, Func<bool> 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<bool, bool> execute(int id, Func<bool> func) //顺序执行
{
bool bActive = Acitve(id);
bool bExecute = false;
if (bActive)
{
bExecute = func();
if (bExecute)
{
next();
}
}
return Tuple.Create(bActive, bExecute);
}
private Tuple<bool, bool> Check(int id, Func<bool> func) //check
{
bool bActive = Acitve(id);
bool bExecute = false;
if (bActive)
{
bExecute = func();
next();
}
return Tuple.Create(bActive, bExecute);
}
/// <summary>
/// </summary>
/// <param name="id"></param>
/// <param name="func"></param>
/// <param name="timeout"></param>
/// <returns>
/// item1 Active
/// item2 execute
/// item3 Timeout
///</returns>
private Tuple<bool, bool, bool> wait(int id, Func<bool> 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<bool, bool?, bool> wait(int id, Func<bool?> 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);
}
/// <summary>
/// </summary>
/// <param name="value"></param>
/// <returns>
/// item1 true, return item2
/// </returns>
private Tuple<bool, Result> Check(Tuple<bool, bool> 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<bool, Result> Check(Tuple<bool, bool, bool> 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<bool, Result> Check(Tuple<bool, bool?, bool> 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<bool, bool, bool> 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<bool, Result> 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);
}
}
}