This repository has been archived on 2024-01-02. You can view files and clone it, but cannot push or open issues or pull requests.
Sic06/FrameworkLocal/RTEquipmentLibrary/HardwareUnits/LoadPorts/NCD/NcdIoLoadPort.cs

2738 lines
108 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}