internal static FabPlanInfo CreateInitLastPlan(EqpStatusInfo info) { string shopID = info.LastShopID; FabProduct prod = BopHelper.FindProduct(shopID, info.LastProduct); if (prod == null || prod.Process == null) { return(null); } FabStep step = prod.Process.FindStep(info.LastStep) as FabStep; if (step == null) { return(null); } FabPlanInfo plan = new FabPlanInfo(step); plan.ShopID = shopID; plan.Product = prod; plan.ProductID = prod.ProductID; plan.ProductVersion = info.LastProductVer; plan.OwnerType = info.LastOwnerType; //TODO : last OwnerID //plan.OwnerID = null; return(plan); }
/// <summary> /// </summary> /// <param name="hb"/> /// <param name="handled"/> public void ON_TRANSFERED0(Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled) { FabLot lot = hb.ToFabLot(); FabPlanInfo plan = lot.CurrentFabPlan; plan.TransferEndTime = AoFactory.Current.NowDT; }
/// <summary> /// </summary> /// <param name="entity"/> /// <param name="now"/> /// <param name="target"/> /// <param name="factor"/> /// <param name="ctx"/> /// <returns/> public WeightValue LAST_RUN(Mozart.Simulation.Engine.ISimEntity entity, DateTime now, Mozart.Simulation.Engine.ActiveObject target, Mozart.SeePlan.DataModel.WeightFactor factor, Mozart.SeePlan.Simulation.IDispatchContext ctx) { FabAoEquipment eqp = target as FabAoEquipment; var last = eqp.GetLastPlan(); //eqp.LastPlan; if (last == null) { return(new WeightValue(0)); } FabPlanInfo plan = last as FabPlanInfo; FabLot lot = entity as FabLot; bool isNeedSetup = eqp.IsNeedSetup(lot); float markValue = 0; if (isNeedSetup == false) { markValue = 1; if (lot.CurrentFabPlan.OwnerType != plan.OwnerType) { markValue = 0.5f; } } return(new WeightValue(markValue * factor.Factor)); }
/// <summary> /// </summary> /// <param name="hb"/> /// <param name="handled"/> public void ON_TRANSFER0(IHandlingBatch hb, ref bool handled) { FabLot lot = hb.ToFabLot(); FabPlanInfo plan = lot.CurrentFabPlan; plan.TransferStartTime = AoFactory.Current.NowDT; }
public static void OnEndTask(FabLot lot) { FabPlanInfo plan = lot.CurrentFabPlan; DateTime nowDT = AoFactory.Current.NowDT; plan.OutQty = lot.UnitQty; plan.TrackOutTime = nowDT; }
/// <summary> /// </summary> /// <param name="lot"/> /// <param name="loadInfo"/> /// <param name="step"/> /// <param name="now"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public Step GET_NEXT_STEP1(Mozart.SeePlan.Simulation.ILot lot, Mozart.SeePlan.DataModel.LoadInfo loadInfo, Mozart.SeePlan.DataModel.Step step, DateTime now, ref bool handled, Mozart.SeePlan.DataModel.Step prevReturnValue) { FabLot flot = lot as FabLot; var fstep = step as FabStep; FabPlanInfo plan = loadInfo as FabPlanInfo; FabProduct prod = flot.FabProduct; FabProduct nextProd = prod; var nextStep = GetNextStep(fstep, prod, plan, ref nextProd); flot.Product = nextProd; return(nextStep); }
internal static bool IsMatched(this FabPlanInfo info, string shopID, string stepID, string productID, string productVersion, string ownerType, string ownerID, bool checkProductVersion) { if (info == null) { return(false); } if (info.ShopID != shopID) { return(false); } if (info.StepID != stepID) { return(false); } if (info.ProductID != productID) { return(false); } if (checkProductVersion) { var stdStep = info.FabStep.StdStep; if (EqpArrangeMaster.IsFixedProductVer(stdStep, productVersion)) { if (info.ProductVersion != productVersion) { return(false); } } } if (info.OwnerType != ownerType) { return(false); } //TODO : OwnerID 추가 필요 //if (info.OwnerID != ownerID) // return false; return(true); }
internal static bool IsMatched(this FabPlanInfo info, FabLot lot, bool checkProductVersion) { if (lot == null) { return(false); } string shopID = lot.CurrentShopID; string stepID = lot.CurrentStepID; string productID = lot.CurrentProductID; string productVersion = lot.CurrentProductVersion; string ownerType = lot.OwnerType; string ownerID = lot.OwnerID; return(info.IsMatched(shopID, stepID, productID, productVersion, ownerType, ownerID, checkProductVersion)); }
/// <summary> /// </summary> /// <param name="lot"/> /// <param name="task"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public LoadInfo CREATE_LOAD_INFO0(Mozart.SeePlan.Simulation.ILot lot, Mozart.SeePlan.DataModel.Step task, ref bool handled, Mozart.SeePlan.DataModel.LoadInfo prevReturnValue) { FabLot flot = lot as FabLot; FabStep step = task as FabStep; FabPlanInfo info = new FabPlanInfo(step); info.ShopID = step.ShopID; info.LotID = flot.LotID; info.Product = flot.FabProduct; info.UnitQty = flot.UnitQty; info.ProductID = info.Product.ProductID; info.ProcessID = info.Product.ProcessID; info.OwnerType = flot.OwnerType; info.OwnerID = flot.OwnerID; //Change ProductVersion flot.CurrentProductVersion = step.IsArrayShop ? flot.OrigProductVersion : "00001"; info.ProductVersion = flot.CurrentProductVersion; if (flot.CurrentProcessID != info.ProcessID) { flot.Route = step.Process; } info.WipInfo = flot.Wip; info.Lot = flot; info.LotFilterInfo = new LotFilterInfo(); info.LotFilterInfo.FilterType = DispatchFilter.None; info.LotFilterInfo.Reason = Constants.NULL_ID; info.LotFilterInfo.RecipeTimes = new Dictionary <string, EqpRecipeInfo>(); if (flot.PlanSteps == null) { flot.PlanSteps = new List <string>(); } flot.PlanSteps.Add(step.StepKey); return(info); }
public static void OnStartTask(FabLot lot) { //if (lot != null && lot.LotID == "TH980305N00") // Console.WriteLine("B"); FabPlanInfo plan = lot.CurrentFabPlan; DateTime nowDT = AoFactory.Current.NowDT; //TODO : ParallelChamber는 Busy 시점에 TrackInTime 기록처리 //plan.TrackInTime = nowDT; plan.UnitQty = lot.UnitQty; var targetEqp = plan.LoadedResource as FabEqp; if (targetEqp == null || targetEqp.IsParallelChamber == false) { plan.TrackInTime = nowDT; plan.InQty = lot.UnitQty; } if (lot.IsRunWipFirstPlan()) { plan.TrackInTime = lot.Wip.LastTrackInTime; plan.StartTime = lot.Wip.LastTrackInTime; plan.InQty = lot.UnitQty; plan.IsInitRunWip = true; } //사용한 EqpArrangeInfo 정보 기록 var currEA = lot.CurrentEqpArrange; if (currEA != null) { plan.UsedEqpArrangeInfo = currEA.UsedEqpArrange; } //초기화 lot.CurrentEqpArrange = null; //LoadGraphMgr.AddWip(lot, nowDT); }
/// <summary> /// 나의 직전 Step(Sub포함) Target시간+Move시간(잔여시간) 이내에 TrackOut 될 수 있는 Lot수량 /// </summary> internal int GetPrevStepRunWipQty(AoEquipment aeqp, FabStep currentStep, string productVersion, DateTime targetTime) { List <FabLot> runWips = GetPrevStepWipList(currentStep, WipType.Run, productVersion); int qty = 0; foreach (var lot in runWips) { if (EqpArrangeMaster.IsLoadable_CheckOnly(aeqp as FabAoEquipment, lot)) { continue; } FabPlanInfo plan = lot.CurrentFabPlan; if (plan.IsLoaded) { AoEquipment prevEqp = AoFactory.Current.GetEquipment(plan.LoadedResource.Key); AoProcess proc = prevEqp.Processes[0]; Time tkOutTime = proc.GetUnloadingTime(lot); tkOutTime += TransferMaster.GetTransferTime(prevEqp, aeqp); if (targetTime < tkOutTime) { continue; } } else { Time tkOutTime = plan.TrackInTime + plan.AoBucketTime; if (targetTime < tkOutTime) { continue; } } qty += lot.UnitQty; } return(qty); }
private static bool IsSomeOneDummyWait(FabAoEquipment eqp, FabPlanInfo last) { //var list = last.FabStep.StdStep.GetWorkingEqpList(last.ProductID, last.ProductVersion, last.OwnerType, last.OwnerID); var list = ResHelper.GetEqpsByDspEqpGroup(eqp.DspEqpGroupID); if (list == null) { return(false); } //var waitEqps = list.FindAll(x => x.IsDummyWait && x.EqpID != eqp.EqpID); var waitEqps = new List <FabAoEquipment>(); foreach (FabAoEquipment item in list) { if (item.EqpID == eqp.EqpID) { continue; } if (item.IsDummyWait == false) { continue; } float setupTime = SetupMaster.GetSetupTime(item, last.ShopID, last.StepID, last.ProductID, last.ProductVersion, last.OwnerType, last.OwnerID); if (setupTime > 0) { continue; } waitEqps.Add(item); } if (waitEqps.Count > 0) { return(true); } return(false); }
//CHECK : jung : IsLastPlan 통합필요 public static int GetFilteredWipQty(this FabAoEquipment eqp, FabPlanInfo plan) { if (plan == null) { return(0); } int qty = 0; foreach (var item in eqp.EqpDispatchInfo.FilterInfos.Values) { foreach (FabLot lot in item.FilterWips) { //TODO : OwnerType 관련 리팩토링 필요 if (plan.FabStep != lot.CurrentFabStep) { continue; } if (plan.ProductID != lot.CurrentProductID) { continue; } if (plan.ProductVersion != lot.CurrentProductID) { continue; } if (plan.OwnerType != lot.OwnerType) { continue; } qty += lot.UnitQty; } } return(qty); }
/// <summary> /// </summary> /// <param name="hb"/> /// <param name="now"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public IHandlingBatch[] STEP_CHANGE0(Mozart.SeePlan.Simulation.IHandlingBatch hb, DateTime now, ref bool handled, Mozart.SeePlan.Simulation.IHandlingBatch[] prevReturnValue) { FabLot lot = hb.ToFabLot(); FabPlanInfo plan = lot.CurrentFabPlan; /* * StepChange */ ILot[] lots = hb.StepChange(now); //설비의 OutPort에서 Lot을 모으는 InterceptMove를 사용할 경우 해당 위치에서 별도 집계 필요함. InFlowMaster.ChangeWipLocation(hb, EventType.TrackOut); //FabPlanInfo prev = lot.PreviousFabPlan; ////InLineMap 다음StepSkip //if (prev.IsLoaded && prev.FabStep.StdStep.IsBaseEqp(prev.ResID)) //{ // plan = lot.CurrentFabPlan; // plan.TransferStartTime = now; // plan.TransferEndTime = now; // plan.EqpInEndTime = now; // plan.EqpInStartTime = now; // plan.Start(now, null); // plan.End(now, null); // lots = hb.StepChange(now); //} QTimeMaster.StepChange(lots, now); return(lots); }
private FabStep GetNextStep(FabStep step, FabProduct product, FabPlanInfo plan, ref FabProduct nextProduct) { string eqpID = plan.ResID; var targEqp = ResHelper.FindEqp(eqpID); string eqpGroup = targEqp == null ? null : targEqp.EqpGroup; string runMode = plan.EqpLoadInfo == null ? null : plan.EqpLoadInfo.RunMode; string productID = plan.ProductID; var branchStep = BranchStepMaster.GetBranchStep(eqpGroup, runMode, productID); if (branchStep != null) { var currProd = product; var currStep = step.GetNextStep(currProd, ref currProd); bool existStep = false; while (currStep != null) { if (currStep.StepID == branchStep.NextStepID) { existStep = true; break; } currStep = currStep.GetNextStep(currProd, ref currProd); } if (existStep) { nextProduct = currProd; return(currStep); } } return(step.GetNextStep(product, ref nextProduct)); }
internal static List <FabLot> WaitForPrevStepWip_Dummy(IDispatchContext ctx, FabAoEquipment eqp) { List <JobFilterInfo> jobList = ctx.Get <List <JobFilterInfo> >(Constants.JobGroup, null); if (jobList == null) { return(null); } FabPlanInfo last = eqp.GetLastPlan(); //eqp.LastPlan as FabPlanInfo; if (last == null) { return(null); } //if (eqp.EqpID == "THWEM200" && LcdHelper.StringToDateTime("20191021235617") <= eqp.NowDT) // Console.WriteLine(); JobState state = InFlowMaster.GetJobState(last.ProductID, last.OwnerType); if (state == null) { return(null); } var holdWips = state.GetHoldWipList(last.FabStep, last.ProductVersion); var prvRunWips = state.GetPrevStepRunWipList(last.FabStep, last.ProductVersion); JobFilterInfo minSetupJobFilter = null; List <JobFilterInfo> filteredList = new List <JobFilterInfo>(); Dictionary <string, JobFilterInfo> current = new Dictionary <string, JobFilterInfo>(); foreach (var info in jobList) { if (info.IsEmpty) { continue; } string key = FilterHelper.GetJobFilterKey(info); current.Add(key, info); if (FilterHelper.CheckIsRunning(eqp, info)) { filteredList.Add(info); continue; } if (info.FilterType != DispatchFilter.None) { filteredList.Add(info); continue; } if (info.SetupTime == 0) { continue; } if (minSetupJobFilter == null) { minSetupJobFilter = info; } if (minSetupJobFilter.SetupTime > info.SetupTime) { minSetupJobFilter = info; } } if (minSetupJobFilter == null) { return(null); } Dictionary <string, FabLot> avableLots = new Dictionary <string, FabLot>(); foreach (var lot in holdWips) { if (eqp.IsLastPlan(lot.CurrentShopID, last.StepID, lot.CurrentProductID, lot.CurrentProductVersion, lot.OwnerType, lot.OwnerID)) { continue; } string key = FilterHelper.GetJobFilterKey(lot.CurrentShopID, last.StepID, lot.CurrentProductID, lot.CurrentProductVersion, lot.OwnerType); if (current.ContainsKey(key)) { continue; } Time remainHold = lot.HoldTime - (eqp.NowDT - lot.HoldStartTime); float setupTime = SetupMaster.GetSetupTime(eqp, lot); if (remainHold.TotalMinutes + setupTime < minSetupJobFilter.SetupTime) { if (avableLots.ContainsKey(key) == false) { avableLots.Add(key, lot); } } } foreach (var lot in prvRunWips) { string lastShopID = last.ShopID; string lastStepID = last.StepID; string currProductID = lot.CurrentProductID; string origProductVersion = lot.OrigProductVersion; string ownerType = lot.OwnerType; string ownerID = lot.OwnerID; //TODO : bong - product version ?? if (eqp.IsLastPlan(lastShopID, lastStepID, currProductID, origProductVersion, ownerType, ownerID)) { continue; } string key = FilterHelper.GetJobFilterKey(lastShopID, lastStepID, currProductID, origProductVersion, ownerType); if (current.ContainsKey(key)) { continue; } Time tranferTime = TransferMaster.GetTransferTime(lot, eqp); Time setupTime = SetupMaster.GetSetupTime(eqp, lastShopID, lastStepID, currProductID, origProductVersion, ownerType, ownerID); if (tranferTime + setupTime < minSetupJobFilter.SetupTime) { if (avableLots.ContainsKey(key) == false) { avableLots.Add(key, lot); } } } Dictionary <string, List <FabAoEquipment> > workingEqps = ResHelper.GetWorkingEqpInfos(eqp, true); List <FabLot> list = new List <FabLot>(); foreach (var lot in avableLots.Values) { FabPlanInfo plan = EntityControl.Instance.CreateLoadInfo(lot, last.Step) as FabPlanInfo; FabLot dummy = CreateHelper.CreateDispatchDummyLot(last.FabStep, plan); dummy.LotID = "DUMMY_PREVSTEP"; JobFilterInfo jobfilter = CreateHelper.CreateDispatchFilterInfo(last.Step as FabStep, lot.CurrentProductID, lot.OrigProductVersion, lot.OwnerType, lot.OwnerID); jobfilter.InitJobFilterInfo(eqp, workingEqps); jobfilter.LotList.Add(dummy); dummy.DispatchFilterInfo = jobfilter; list.Add(dummy); } return(list); }
public static List <JobFilterInfo> CreateJobList(AoEquipment aeqp, IList <IHandlingBatch> list) { Dictionary <string, JobFilterInfo> joblist = new Dictionary <string, JobFilterInfo>(); FabAoEquipment eqp = aeqp as FabAoEquipment; var last = eqp.GetLastPlan(); if (last != null) { FabPlanInfo plan = last; string shopID = plan.Step.StepID; string stepID = plan.StepID; string productID = plan.ProductID; string prodVer = plan.ProductVersion; string ownerType = plan.OwnerType; string ownerID = plan.OwnerID; string key = GetJobFilterKey(shopID, stepID, productID, prodVer, ownerType); JobFilterInfo info = CreateHelper.CreateDispatchFilterInfo(plan.FabStep, productID, prodVer, ownerType, ownerID); info.IsEmpty = true; joblist.Add(key, info); eqp.LastPlanFilterInfo = info; } foreach (IHandlingBatch hb in list) { FabLot lot = hb.ToFabLot(); lot.DispatchFilterInfo = null; string productID = lot.CurrentProductID; string prodVer = lot.CurrentProductVersion; string ownerType = lot.CurrentFabPlan.OwnerType; string ownerID = lot.OwnerID; FabStep step = lot.CurrentFabStep; string key = GetJobFilterKey(step.ShopID, step.StepID, productID, prodVer, ownerType); JobFilterInfo info; if (joblist.TryGetValue(key, out info) == false) { joblist.Add(key, info = CreateHelper.CreateDispatchFilterInfo(step, productID, prodVer, ownerType, ownerID)); } if (hb.HasContents) { foreach (FabLot item in hb.Contents) { info.LotList.Add(item); info.WaitSum += item.UnitQty; item.DispatchFilterInfo = info; item.CurrentFabPlan.LotFilterInfo.Clear(); } } else { info.LotList.Add(lot); info.WaitSum += lot.UnitQty; lot.DispatchFilterInfo = info; lot.CurrentFabPlan.LotFilterInfo.Clear(); } info.IsEmpty = false; } foreach (var info in joblist.Values) { info.WorkingEqpCnt = info.Step.StdStep.GetWorkingEqpCount(info, true, false); info.ExistInflowWip = info.WaitSum > 0; if (info.ExistInflowWip == false) { if (ExistInflowWip(eqp, info)) { info.ExistInflowWip = true; } } } return(joblist.Values.ToList()); }
public static void OnStateChanged(this FabAoEquipment eqp, LoadingStates state, FabLot lot = null, bool isDone = false) { //if (eqp.EqpID == "FHUPH100" && lot != null && lot.LotID == "TH011010N0F") // Console.WriteLine("B"); DateTime now = eqp.NowDT; bool isAheadSetup = false; if (IsAhead(eqp, state, now)) { if (state == LoadingStates.SETUP) { now = eqp.AvailableSetupTime; } if (state == LoadingStates.PM) { now = eqp.AvailablePMTime; } isAheadSetup = true; } eqp.UpdateLastLoadInfo(now, state); eqp.SetLastFabLoadInfo(state, now, lot, isDone, isAheadSetup); UpdateAheadSetupInfo(eqp, state, now); if (eqp.IsParallelChamber) { if (state == LoadingStates.BUSY && lot != null) { FabPlanInfo plan = lot.CurrentFabPlan; if (plan.IsInitRunWip == false) { plan.TrackInTime = now; plan.InQty = lot.UnitQty; } } } else { if (state == LoadingStates.BUSY && lot != null) { lot.CurrentFabPlan.TrackInTime = now; } } OnChamberStateChanged(eqp, lot, state, now, isDone); if (state == LoadingStates.IDLERUN || state == LoadingStates.IDLE) { if (state == LoadingStates.IDLERUN) { if (eqp.LastIdleRunStartTime == DateTime.MinValue) { eqp.LastIdleRunStartTime = now; } } if (eqp.LastIdleStartTime == DateTime.MinValue) { eqp.LastIdleStartTime = now; } } else { //reset (not idle state) eqp.LastIdleRunStartTime = DateTime.MinValue; eqp.LastIdleStartTime = DateTime.MinValue; } }
private static FabLoadInfo SetLastFabLoadInfo(List <FabLoadInfo> infos, LoadingStates state, DateTime now, FabLot lot = null, bool isDone = false, bool isAheadSetup = false) { FabLoadInfo newInfo = new FabLoadInfo(); newInfo.State = state; newInfo.StartTime = now; if (lot != null && state == LoadingStates.BUSY) { lot.CurrentFabPlan.EqpLoadInfo = newInfo; } //PlanEndTime 마감처리 if (isDone) { newInfo.EndTime = now; } FabPlanInfo target = null; if (lot != null && IsRunState(state)) //true = BUSY or SETUP { target = lot.CurrentFabPlan; newInfo.Target = target; if (state == LoadingStates.BUSY) { newInfo.UnitQty = target.UnitQty; } if (state == LoadingStates.SETUP) { if (isAheadSetup) { newInfo.StateInfo = "AHEAD"; } if (target.IsIdleSetup) { newInfo.StateInfo = "IDLE_SETUP"; } if (isAheadSetup && target.IsIdleSetup) { newInfo.StateInfo = "AHEAD_IDLE_SETUP"; } var eqp = ResHelper.GetFabAoEquipment(lot.CurrentPlan.LoadedResource.ResID); if (eqp != null && eqp.IsAcidConst && eqp.AcidDensity.IsSetupMark) { if (isAheadSetup) { newInfo.StateInfo = "AHEAD_ACID"; } else { newInfo.StateInfo = "ACID"; } //용액교체 마크 해제 AcidMaster.SetSetupMark(eqp, false); } } } if (state == LoadingStates.PM) { if (isAheadSetup) { newInfo.StateInfo = "AHEAD"; } } infos.Add(newInfo); return(newInfo); }
internal static void AddLotFilteredInfo(this FabPlanInfo info, string reason, DispatchFilter type) { info.LotFilterInfo.Reason = reason; info.LotFilterInfo.FilterType = type; }