using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Xml.Linq; using Aitex.Common.Util; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.RecipeCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using FabConnect.SecsGemInterface.Application.Objects.ProcessManagement; using FabConnect.SecsGemInterface.Common; using FabConnect.SecsGemInterface.Common.ToolModel; using FabConnect.SecsGemInterface.GemModel; using FabConnect.SecsGemInterface.HostCommon; using FACore.E87FA; using FurnaceRT.Equipments.LPs; using FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.Schedulers; using FurnaceRT.Equipments.Stockers; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.FAServices.E40s; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.FA.Core.CommonTypes; using MECF.Framework.FA.Core.ConcurrentCollections; using MECF.Framework.FA.Core.E40FA; using MECF.Framework.FA.Core.E87FA; using MECF.Framework.FA.Core.E94FA; using MECF.Framework.FA.Core.FAControl; using MtrlOutSpecPair = MECF.Framework.FA.Core.E94FA.MtrlOutSpecPair; namespace FurnaceRT.Equipments.Systems { public partial class EquipmentManager { private SchedulerDBCallback _dbCallback; public SECsDataItem _SideDummyStateDetail = new SECsDataItem(SECsFormat.List); public SECsDataItem SideDummyStateDetail { get { _SideDummyStateDetail = new SECsDataItem(SECsFormat.List); foreach (var _carrier in CarrierManager.Instance.GetCarrierbytype(CarrierType.SD)) { SECsDataItem _carrierCountsecsdat = new SECsDataItem(SECsFormat.List); SECsDataItem _carrierTimesecsdat = new SECsDataItem(SECsFormat.List); SECsDataItem _carrierThicksecsdat = new SECsDataItem(SECsFormat.List); SECsDataItem _carriersecsdat = new SECsDataItem(SECsFormat.List); float maxUseCount = 0; float maxUseTime = 0; float maxUseThick = 0; foreach (var key in Singleton.Instance.Modules.Keys) { var wafers = WaferManager.Instance.GetWafers(key); if (wafers == null) continue; foreach (var wafer in wafers) { if (wafer != null && !wafer.IsEmpty && wafer.WaferType == WaferType.SD && wafer.OriginStation == (int)_carrier.InternalModuleName) { if (wafer.UseCount > maxUseCount) maxUseCount = wafer.UseCount; if (wafer.UseTime > maxUseTime) maxUseTime = wafer.UseTime; if (wafer.UseThick > maxUseThick) maxUseThick = wafer.UseThick; } } } string useCountState = "UNDIFINE"; string useTimeState = "UNDIFINE"; string useThickState = "UNDIFINE"; if (maxUseCount >= SC.GetValue($"PM1.WaferCycleTime.SDCountAlarm") && maxUseCount > 0) useCountState = "EXCHANGE"; else if (maxUseCount >= SC.GetValue($"PM1.WaferCycleTime.SDCountWarning") && maxUseCount > 0) useCountState = "OVER"; else useCountState = "NORMAL"; if (maxUseTime >= SC.GetValue($"PM1.WaferCycleTime.SDTimeAlarm") && maxUseTime > 0) useTimeState = "EXCHANGE"; else if (maxUseTime >= SC.GetValue($"PM1.WaferCycleTime.SDTimeWarning") && maxUseTime > 0) useTimeState = "OVER"; else useTimeState = "NORMAL"; if (maxUseThick >= SC.GetValue($"PM1.WaferCycleTime.SDThicknessAlarm") && maxUseThick > 0) useThickState = "EXCHANGE"; else if (maxUseThick >= SC.GetValue($"PM1.WaferCycleTime.SDThicknessWarning") && maxUseThick > 0) useThickState = "OVER"; else useThickState = "NORMAL"; int dummystate = 1; if (useCountState == "OVER" || useTimeState == "OVER" || useThickState == "OVER") { dummystate = 3; } if (useCountState == "EXCHANGE" || useTimeState == "EXCHANGE" || useThickState == "EXCHANGE") { dummystate = 2; } _carrierCountsecsdat.Add("UsedCountCaution", SC.GetValue($"PM1.WaferCycleTime.SDCountWarning"), SECsFormat.U2); _carrierCountsecsdat.Add("UsedCountAlarm", SC.GetValue($"PM1.WaferCycleTime.SDCountAlarm"), SECsFormat.U2); _carrierCountsecsdat.Add("UsedCount", (int)maxUseCount, SECsFormat.U2); //_carrierCountsecsdat.Add("UsedCountState", useCountState, SECsFormat.Ascii); _carrierTimesecsdat.Add("UsedTimeCaution", (int)SC.GetValue($"PM1.WaferCycleTime.SDTimeWarning"), SECsFormat.U2); _carrierTimesecsdat.Add("UsedTimeAlarm", (int)SC.GetValue($"PM1.WaferCycleTime.SDTimeAlarm"), SECsFormat.U2); _carrierTimesecsdat.Add("UsedTime", (int)maxUseTime, SECsFormat.U2); //_carrierTimesecsdat.Add("UsedTimeState", useTimeState, SECsFormat.Ascii); _carrierThicksecsdat.Add("UsedThicknessCaution", (int)SC.GetValue($"PM1.WaferCycleTime.SDThicknessWarning"), SECsFormat.U4); _carrierThicksecsdat.Add("UsedThicknessAlarm", (int)SC.GetValue($"PM1.WaferCycleTime.SDThicknessAlarm"), SECsFormat.U4); _carrierThicksecsdat.Add("UsedThickness", (int)maxUseThick, SECsFormat.U4); //_carrierThicksecsdat.Add("UsedThicknessState", useThickState, SECsFormat.Ascii); _carriersecsdat.Add("CarrierID", _carrier.CarrierId, SECsFormat.Ascii); _carriersecsdat.Add("State", dummystate, SECsFormat.U1); _carriersecsdat.Add(_carrierCountsecsdat); _carriersecsdat.Add(_carrierTimesecsdat); _carriersecsdat.Add(_carrierThicksecsdat); _SideDummyStateDetail.Add(_carriersecsdat); } return _SideDummyStateDetail; } } public SECsDataItem _ExtraDummyStateDetail = new SECsDataItem(SECsFormat.List); public SECsDataItem ExtraDummyStateDetail { get { _ExtraDummyStateDetail = new SECsDataItem(SECsFormat.List); foreach (var _carrier in CarrierManager.Instance.GetCarrierbytype(CarrierType.ED)) { SECsDataItem _carrierCountsecsdat = new SECsDataItem(SECsFormat.List); SECsDataItem _carrierTimesecsdat = new SECsDataItem(SECsFormat.List); SECsDataItem _carrierThicksecsdat = new SECsDataItem(SECsFormat.List); SECsDataItem _carriersecsdat = new SECsDataItem(SECsFormat.List); float maxUseCount = 0; float maxUseTime = 0; float maxUseThick = 0; foreach (var key in Singleton.Instance.Modules.Keys) { var wafers = WaferManager.Instance.GetWafers(key); if (wafers == null) continue; foreach (var wafer in wafers) { if (wafer != null && !wafer.IsEmpty && wafer.WaferType == WaferType.ED && wafer.OriginStation == (int)_carrier.InternalModuleName) { if (wafer.UseCount > maxUseCount) maxUseCount = wafer.UseCount; if (wafer.UseTime > maxUseTime) maxUseTime = wafer.UseTime; if (wafer.UseThick > maxUseThick) maxUseThick = wafer.UseThick; } } } string useCountState = "UNDIFINE"; string useTimeState = "UNDIFINE"; string useThickState = "UNDIFINE"; if (maxUseCount >= SC.GetValue($"PM1.WaferCycleTime.EDCountAlarm") && maxUseCount > 0) useCountState = "EXCHANGE"; else if (maxUseCount >= SC.GetValue($"PM1.WaferCycleTime.EDCountWarning") && maxUseCount > 0) useCountState = "OVER"; else useCountState = "NORMAL"; if (maxUseTime >= SC.GetValue($"PM1.WaferCycleTime.EDTimeAlarm") && maxUseTime > 0) useTimeState = "EXCHANGE"; else if (maxUseTime >= SC.GetValue($"PM1.WaferCycleTime.EDTimeWarning") && maxUseTime > 0) useTimeState = "OVER"; else useTimeState = "NORMAL"; if (maxUseThick >= SC.GetValue($"PM1.WaferCycleTime.EDThicknessAlarm") && maxUseThick > 0) useThickState = "EXCHANGE"; else if (maxUseThick >= SC.GetValue($"PM1.WaferCycleTime.EDThicknessWarning") && maxUseThick > 0) useThickState = "OVER"; else useThickState = "NORMAL"; int dummystate = 1; if (useCountState == "OVER" || useTimeState == "OVER" || useThickState == "OVER") { dummystate = 3; } if (useCountState == "EXCHANGE" || useTimeState == "EXCHANGE" || useThickState == "EXCHANGE") { dummystate = 2; } _carrierCountsecsdat.Add("UsedCountCaution", SC.GetValue($"PM1.WaferCycleTime.EDCountWarning"), SECsFormat.U2); _carrierCountsecsdat.Add("UsedCountAlarm", SC.GetValue($"PM1.WaferCycleTime.EDCountAlarm"), SECsFormat.U2); _carrierCountsecsdat.Add("UsedCount", (int)maxUseCount, SECsFormat.U2); //_carrierCountsecsdat.Add("UsedCountState", useCountState, SECsFormat.Ascii); _carrierTimesecsdat.Add("UsedTimeCaution", (int)SC.GetValue($"PM1.WaferCycleTime.EDTimeWarning"), SECsFormat.U2); _carrierTimesecsdat.Add("UsedTimeAlarm", (int)SC.GetValue($"PM1.WaferCycleTime.EDTimeAlarm"), SECsFormat.U2); _carrierTimesecsdat.Add("UsedTime", (int)maxUseTime, SECsFormat.U2); //_carrierTimesecsdat.Add("UsedTimeState", useTimeState, SECsFormat.Ascii); _carrierThicksecsdat.Add("UsedThicknessCaution", (int)SC.GetValue($"PM1.WaferCycleTime.EDThicknessWarning"), SECsFormat.U4); _carrierThicksecsdat.Add("UsedThicknessAlarm", (int)SC.GetValue($"PM1.WaferCycleTime.EDThicknessAlarm"), SECsFormat.U4); _carrierThicksecsdat.Add("UsedThickness", (int)maxUseThick, SECsFormat.U4); //_carrierThicksecsdat.Add("UsedThicknessState", useThickState, SECsFormat.Ascii); _carriersecsdat.Add("CarrierID", _carrier.CarrierId, SECsFormat.Ascii); _carriersecsdat.Add("State", dummystate, SECsFormat.U1); _carriersecsdat.Add(_carrierCountsecsdat); _carriersecsdat.Add(_carrierTimesecsdat); _carriersecsdat.Add(_carrierThicksecsdat); _ExtraDummyStateDetail.Add(_carriersecsdat); } return _ExtraDummyStateDetail; } } public void CreatePj(string processName) { _auto.CreatePj(processName); } public void StartPj() { _auto.StartPj(); } public void EndPj(string endStatus = "Normal") { _auto?.EndPj(endStatus); //_auto.UpdataPJAlarmStatus(endStatus); } public string GetFirstPJId() { return _auto.GetFirstPJId(); } } public partial class EquipmentManager : IEquipmentCallBack { public void InitializeFA(string file) { Singleton.Instance.Initialize("Furnace", file, new int[] { 1, 2, 3, 4 }, Singleton.Instance, null); SubscribeFAState(); } private void SubscribeFAState() { //foreach (var portId in new int[] { 1, 2, 3, 4 }) //{ // var lp = Singleton.Instance.GetLoadPort(portId); // DATA.Subscribe($"LP{portId}.AccessMode", lp.CurrentAccessMode.ToString()); // DATA.Subscribe($"LP{portId}.TransferState", lp.CurrentTransferState.ToString()); // DATA.Subscribe($"LP{portId}.ReserveState", lp.CurrentReserveState.ToString()); // DATA.Subscribe($"LP{portId}.ReserveState", lp.CurrentReserveState.ToString()); //} //DATA.Subscribe($"System.CommunicationStatus", () => Singleton.Instance.FaCommunicationState.ToString()); //DATA.Subscribe($"System.ControlStatus", () => Singleton.Instance.FaControlState.ToString()); //DATA.Subscribe($"System.SpoolingState", () => Singleton.Instance.SpoolingState.ToString()); //OP.Subscribe("FACommand", InvokeFaCommand); } private bool InvokeFaCommand(string method, object[] arg2) { Singleton.Instance.Invoke(arg2[0].ToString(), arg2); return true; } public bool SetContentMap(int portId, ContentMap[] cmaps) { return true; } public bool SetCarrierID(int portId, string carrierId) { return true; } public bool SetCarrierUsage(int portId, string usage) { return true; } public bool VerifySlotMap(int portId, SlotSubstrateStatus[] slotmap) { return true; } public bool VerifySubstrateCount(int portId, int count) { return true; } public bool ReleaseCarrier(int portId) { var _lp = Modules[ModuleName.LP1] as LoadPortModule; if (portId == 1) { _lp = Modules[ModuleName.LP1] as LoadPortModule; } else if (portId == 2) { _lp = Modules[ModuleName.LP2] as LoadPortModule; } else { return false; } //return _lp.LPDevice.SetCatchRelease(false); return true; } public bool ProceedToGetSlotMap(int portId, string carrierId) { return true; } public bool ReadCarrierID(int portId, out string carrierId, out string reason, int startPage = 0, int length = 16) { carrierId = ""; reason = ""; return true; } public bool WriteCarrierID(int portId, string carrierId, out string reason, int startPage = 0, int length = 16) { reason = ""; return true; } public bool InformAccessModeChanged(int portId, bool isauto) { return true; } public bool InformTransferStateChanged(int portId, LPTransferState state) { return true; } public bool IsTransferReady(int portId, out bool isCarrierOn) { isCarrierOn = true; return true; } private bool fMonitorFAJob() { //Singleton.Instance.MonitorJob(); E40ProcessJob[] pjs = Singleton.Instance.FAProcessJobs.Values.ToArray(); E94ControlJob[] cjs = Singleton.Instance.FAControlJobs.Values.ToArray(); if (Singleton.Instance.FAProcessJobs.Count == 0) return true; if (Singleton.Instance.FAControlJobs.Count == 0) return true; foreach (var pj in pjs) { if ((pj.PRJobState == PRJobState.NO_STATE || pj.PRJobState == PRJobState.PROCESS_COMPLETE) && Singleton.Instance.FAProcessJobs.ContainsKey(pj.objID)) Singleton.Instance.FAProcessJobs.Remove(pj.objID); if (pj.PRJobState == PRJobState.ABORTING) Singleton.Instance.FAProcessJobs[pj.objID].RequestStop(); if (pj.PRJobState == PRJobState.ABORTED) Singleton.Instance.FAProcessJobs.Remove(pj.objID); } foreach (var cj in cjs) { if ((cj.State == CtrlJobState.Nostate || cj.State == CtrlJobState.Completed) && Singleton.Instance.FAControlJobs.ContainsKey(cj.objID)) Singleton.Instance.FAControlJobs.Remove(cj.objID); } foreach (var pj in pjs) { if (pj.PRJobState == PRJobState.QUEUED && pj.ControlJobID != null) { bool checkMapOk = true; foreach (var mtrlname in pj.PRMtlNameList) { var test = Singleton.Instance.GetCarrier(mtrlname.CarrierID).CarrierIdStatus; var test1 = Singleton.Instance.GetCarrier(mtrlname.CarrierID).SlotMapStatus; if (test == CarrierIDStatus.ID_VERIFICATION_OK && test1 == SlotMapStatus.SLOT_MAP_VERIFICATION_OK) { } else { checkMapOk = false; } } if (checkMapOk) { pj.ProcessResourceAllocated(); AssignProcessJob(pj); } } } foreach (var cj in cjs) { if (cj.State == CtrlJobState.Queued) { bool allPjSetUp = true; foreach (var pj in cj.ProcessingCtrlSpec) { if (!Singleton.Instance.FAProcessJobs.ContainsKey(pj.PRJobID)) { allPjSetUp = false; break; } if (Singleton.Instance.FAProcessJobs[pj.PRJobID].PRJobState != PRJobState.SETTING_UP) { allPjSetUp = false; break; } } if (allPjSetUp) { cj.CJSelected(); } } //string sourceModule = ""; //检查source ready if (cj.State == CtrlJobState.Selected) { if (!_auto.IsCJExisted(cj.objID)) { AssignControlJob(cj); } if (_auto.IsCJExcuting(cj.objID)) { Task.Delay(1500).ContinueWith(x => { if (_auto.IsCJExisted(cj.objID)) { cj.MaterialArrived(); Task.Delay(500).ContinueWith(y => { foreach (var pj in cj.ProcessingCtrlSpec) { Singleton.Instance.FAProcessJobs[pj.PRJobID].MaterialPresentAndResouceReady(); } }); } else { foreach (var pj in cj.ProcessingCtrlSpec) { Singleton.Instance.FAProcessJobs[pj.PRJobID].RequestAbort(); } Task.Delay(500).ContinueWith(y => { var Status = new MECF.Framework.FA.Core.E94FA.Status(); cj.CJAbort(out Status); }); } }); } cj.MtrlOutSpec.Clear(); } } return true; } public bool AssignProcessJob(E40ProcessJob pj) { //return true; string M1CarrierPara = ""; string M2CarrierPara = ""; string PCarrierPara = ""; List _processcridlst = new List(); foreach (var item in pj.PRMtlNameList) { foreach (var _modulename in Modules.Keys) { var stockermodule = Modules[_modulename] as StockerModule; if (_modulename.ToString().Contains("Stocker") && stockermodule.CurrentCarrier.CarrierId == item.CarrierID) { if (stockermodule.CurrentCarrier.CarrierType == CarrierType.P) { PCarrierPara += _modulename + "," + (item.CarrierID) + ";"; _processcridlst.Add(item.CarrierID); } if (stockermodule.CurrentCarrier.CarrierType == CarrierType.M1) { M1CarrierPara += _modulename + "," + (item.CarrierID) + ";"; _processcridlst.Add(item.CarrierID); } if (stockermodule.CurrentCarrier.CarrierType == CarrierType.M2) { M2CarrierPara += _modulename + "," + (item.CarrierID) + ";"; _processcridlst.Add(item.CarrierID); } } } } string pCarrierPara = string.IsNullOrEmpty(PCarrierPara) ? "" : PCarrierPara.TrimEnd(';'); string m1CarrierPara = string.IsNullOrEmpty(M1CarrierPara) ? "" : M1CarrierPara.TrimEnd(';'); string m2CarrierPara = string.IsNullOrEmpty(M2CarrierPara) ? "" : M2CarrierPara.TrimEnd(';'); int cooltime = !SC.ContainsItem("System.Scheduler.DefaultCoolTime") ? 10 : (int)(SC.GetValue("System.Scheduler.DefaultCoolTime") * 60); Dictionary para = new Dictionary(); para.Add("PJID", pj.objID); para.Add("CarrierPara", PCarrierPara); para.Add("m1CarrierPara", m1CarrierPara); para.Add("m2CarrierPara", m2CarrierPara); para.Add("JobRecipe", pj.RecID.Replace("Furnace\\Job\\", "")); para.Add("ProcessRecipe", pj.RecID.Replace("Furnace\\Process\\", "")); para.Add("LayoutRecipe", ((pj.RecVariableList != null) && (pj.RecVariableList.Count() > 0)) ? pj.RecVariableList[0].RecipeVarValue.ToString() : ""); para.Add("ControlJobName", pj.ControlJobID); para.Add("CoolTime", cooltime); para.Add("ProcessCarrierID", _processcridlst); CheckToPostMessage((int)MSG.FAJobCommand, new object[] { "CreateProcessJob", para }); return true; } public bool AssignControlJob(E94ControlJob cj) { //return false; CheckToPostMessage((int)MSG.FAJobCommand, new object[] { "CreateControlJob", cj.objID, cj.CurrentPRJob }); return true; } public bool RegisterEvent(bool isAlarm, string eventname, string eventcontext) { return true; } public int MaxPRJobSpace { get; } = 100; public int MaxCtrJobSpace { get; } = 100; public bool PostEvent(string eventName, string eventText) { EV.PostInfoLog("FA", $"{eventName}:{eventText}"); return true; } public bool PostLog(string module, string logText) { LOG.Write($"{module}:{logText}"); return true; } public bool ExcuteCommand(string command, ThreadSafeList properties, out RcmdStatus status) { status = new RcmdStatus(); status.ack = RcmdAcknowledge.Ok_All_Normal; Dictionary para = new Dictionary(); EV.PostInfoLog(Module, "进入ExcuteCommand"); PMModule pm1 = Modules[ModuleName.PM1] as PMModule; switch (command.ToUpper()) { case "HOLD ON": //if (pm1.Hold()) //{ // return true; //} //else //{ // status.ack = RcmdAcknowledge.Cannot_perform_now; // return false; //} case "HOLD OFF": //if (pm1.RecipeContinue()) //{ // return true; //} //else //{ // status.ack = RcmdAcknowledge.Cannot_perform_now; // return false; //} default: status.ack = RcmdAcknowledge.Invalid_command; return false; } return true; } public string[] GetRecipeList() { List namelist = new List(); var processType = SC.GetStringValue("System.Recipe.SupportedProcessType"); if (processType == null) { processType = "WaferFlow,COT,DEV,ADH,Oven,Pump,WEE,System,Dummy,Wash"; //processType = "Process"; } string[] recipeProcessType = ((string)processType).Split(','); for (int i = 0; i < recipeProcessType.Length; i++) { var prefix = $"Furnace\\{recipeProcessType[i]}"; var recipes = RecipeFileManager.Instance.GetXmlRecipeNmaeList(prefix, false); namelist.AddRange(recipes); } return namelist.ToArray(); } public string GetRecipeBody(string recipename) { var test = RecipeFileManager.Instance.LoadRecipeByFullPathForFA(recipename); return RecipeFileManager.Instance.LoadRecipeByFullPathForFA(recipename); } public bool DeleteRecipes(string[] recipenames) { return true; } public bool IsAllowedToChangeRemote() { return true; } public PRJobCreatState InformPRJobCreate(IE40ProcessJob job, ref APCTunRetCode[] tuningResult) { return PRJobCreatState.SUCCESS; } public int InformPRJobDelete(IE40ProcessJob job) { return 0; } public void InformTargetCarrierArrived(IE40ProcessJob job) { } public virtual void InformCommunicationStateChange(CommunicationState state) { } public virtual void InformControlStateChange(ControlState state) { } public virtual object GetECValue(string ecname) { SCConfigItem sc; if (!SC.ContainsItem(ecname)) return null; sc = SC.GetConfigItem(ecname); return sc.Value; } public virtual bool SetECValue(string ecName, object ecValue) { if (SC.ContainsItem(ecName)) SC.SetItemValueFromString(ecName, ecValue.ToString()); return true; } public virtual object GetSVValue(string svname) { object data = DATA.Poll(svname); if (data != null) { return data; } return ""; } public virtual void OnReceivedTerminalMessage(List msg) { foreach (var message in msg) { EV.PostPopDialogMessage(EventLevel.Warning, "TerminalMessage", message); } } public virtual void InformCtrlJobHOQ(IE94ControlJob job) { return; } public virtual void InformCtrlJobInQueued(LinkedList jobs) { } public virtual bool PerformPreConditioning(IE40ProcessJob pjob) { return true; } public virtual bool InformProcessStart(IE40ProcessJob pjob) { return true; } public virtual bool PerformPostConditioning(IE40ProcessJob pjob) { return true; } public virtual bool PerformTerminate(IE40ProcessJob pjob) { return true; } public bool InformCarrierAccessStateChange(int portId, string carrierId, AccessStatus state) { return true; } public bool InformCarrierIDStateChange(int portId, string carrierId, string carrierType, CarrierIDStatus state) { if ((carrierId != null && carrierId != "") && state == CarrierIDStatus.ID_VERIFICATION_OK) { StockerNameForFATJob.Clear(); foreach (var moduleName in Modules.Keys) { var stockerModule = Modules[moduleName] as StockerModule; if (stockerModule == null || !stockerModule.CurrentCarrier.IsEmpty) continue; var occupyStockers = _transferJob.GetOccupyStockers(); if (occupyStockers != null && occupyStockers.Any(x => x == moduleName.ToString())) continue; if (stockerModule.WaferType.Contains(carrierType.Replace("_", "")) || stockerModule.WaferType.Contains("None")) { StockerNameForFATJob.Add(moduleName); break; } } if (StockerNameForFATJob.Count == 0) { return false; } var _lp = Modules[ModuleName.LP1] as LoadPortModule; if (portId == 1) { _lp = Modules[ModuleName.LP1] as LoadPortModule; } else if (portId == 2) { _lp = Modules[ModuleName.LP2] as LoadPortModule; } if (portId == 3) { _lp = Modules[ModuleName.LP3] as LoadPortModule; } else if (portId == 4) { _lp = Modules[ModuleName.LP4] as LoadPortModule; } else { return false; } _lp.UpdateCarrierID(carrierId); Dictionary para = new Dictionary(); para.Add("WaferType", carrierType.Replace("_", "")); para.Add("CarrierPara", $"{StockerNameForFATJob.FirstOrDefault().ToString()},{carrierId},0,,,{_lp.Name.ToString()}"); para.Add("TransferType", "Loading"); return CheckToPostJobMessage((int)MSG.CreateTransferJob, para); //_transferJob.CreateJob(para); } return true; } public bool InformCarrierSlotMapStateChange(int portId, string carrierId, SlotMapStatus state) { return true; } public int InformPRJobStateChange(IE40ProcessJob job, PRJobState state) { return 0; } public void InformCtrlJobStateChange(IE94ControlJob job, CtrlJobState state) { } public virtual int InformCtrlJobCreate(IE94ControlJob job) { return 0; } public bool CarrierOutByID(string id, int portid) { StockerModule currrentStocker = null; foreach (var _modulename in Modules.Keys) { var stockermodule = Modules[_modulename] as StockerModule; if (_modulename.ToString().Contains("Stocker") && stockermodule.CurrentCarrier.CarrierId == id) { currrentStocker = stockermodule; } } var _lp = Modules[ModuleName.LP1] as LoadPortModule; if (portid == 1) { _lp = Modules[ModuleName.LP1] as LoadPortModule; } else if (portid == 2) { _lp = Modules[ModuleName.LP2] as LoadPortModule; } else if (portid == 3) { _lp = Modules[ModuleName.LP3] as LoadPortModule; } else if (portid == 4) { _lp = Modules[ModuleName.LP4] as LoadPortModule; } else { return false; } if (currrentStocker != null) { Dictionary para = new Dictionary(); para.Add("WaferType", currrentStocker.CurrentCarrier.CarrierType.ToString()); para.Add("CarrierPara", $"{currrentStocker.Name},{_lp.Name.ToString()}"); para.Add("TransferType", "Unloading"); return CheckToPostJobMessage((int)MSG.CreateTransferJob, para); } else { return false; } } } }