/// <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)); }
private static bool IsLastRunStep(FabAoEquipment eqp, FabStep step) { if (eqp == null || step == null) { return(false); } if (eqp.IsParallelChamber) { foreach (var subEqp in eqp.SubEqps) { var last = subEqp.LastPlan; if (last != null && last.StepID == step.StepID) { return(true); } } } else { var last = eqp.GetLastPlan(); if (last != null && last.StepID == step.StepID) { return(true); } } return(false); }
/// <summary> /// </summary> /// <param name="entity"/> /// <param name="now"/> /// <param name="target"/> /// <param name="factor"/> /// <param name="ctx"/> /// <returns/> public WeightValue ASSIGN_STEP_PRIORITY(Mozart.Simulation.Engine.ISimEntity entity, DateTime now, Mozart.Simulation.Engine.ActiveObject target, Mozart.SeePlan.DataModel.WeightFactor factor, Mozart.SeePlan.Simulation.IDispatchContext ctx) { if (factor.Factor == 0) { return(new WeightValue(0)); } FabAoEquipment eqp = target as FabAoEquipment; FabEqp targetEqp = eqp.TargetEqp; FabLot lot = entity as FabLot; float score = 0f; bool isLastStep = false; var last = eqp.GetLastPlan(); if (last != null) { if (last.StepID == lot.CurrentStepID) { isLastStep = true; } } if (isLastStep || targetEqp.MainRunSteps.Contains(lot.CurrentFabStep.StdStep)) { score = 1f; } string lastStepID = last == null ? "-" : last.StepID; string desc = string.Format("[Last : {0}, MainSteps:{1}]", lastStepID, targetEqp.EqpMainRunsSteps); return(new WeightValue(score * factor.Factor, desc)); }
private static bool IsLoadableDummy(FabAoEquipment eqp, FabLot dummy, decimal inflowHours) { var now = eqp.NowDT; var last = eqp.GetLastPlan(); //eqp.LastPlan as FabPlanInfo; if (last == null) { return(false); } //M제약에 의해 진행 중인 last의 Arrange가 없어진 경우 if (EqpArrangeMaster.IsLoadable(eqp, dummy) == false) { return(false); } var currEA = dummy.CurrentEqpArrange; if (currEA == null || currEA.IsLoableByProductVersion(last.ProductVersion) == false) { return(false); } string reason = string.Empty; if (FilterMaster.IsEqpRecipeTime(eqp, dummy, now.AddHours((double)inflowHours), ref reason) == false) { return(false); } //Dummy Mask 확인 if (FilterMaster.IsLoadableToolArrange(eqp, dummy, false) == false) { return(false); } //MixRun(ParallelChamber) if (eqp.IsParallelChamber) { var subEqp = eqp.TriggerSubEqp; if (subEqp != null) { if (subEqp.IsLoadable(last.FabStep, now) == false) { return(false); } } } return(true); }
public static FabLot NeedAllowRunDown_Dummy(AoEquipment aeqp, IList <IHandlingBatch> wips) { //TODO : Current Wait + PreviousStep Run + Inflow Arrivedin FabAoEquipment eqp = aeqp.ToFabAoEquipment(); //if (eqp.EqpID == "THCVD400" && eqp.NowDT >= LcdHelper.StringToDateTime("20200211 091146")) // Console.WriteLine("B"); decimal inflowHours; if (CanMakeDummy(eqp, wips, out inflowHours) == false) { return(null); } var last = eqp.GetLastPlan(); //eqp.LastPlan as FabPlanInfo; FabStep lastStep = last.Step as FabStep; FabLot dummy = CreateHelper.CreateDispatchDummyLot(lastStep, last); if (IsLoadableDummy(eqp, dummy, inflowHours) == false) { return(null); } var idleTime = eqp.GetIdleRunTime(); decimal adjustHour = inflowHours - Convert.ToDecimal(idleTime.TotalHours); //직전 Step에 Run Wip이 존재하는 경우는 대기함 bool isExistPrevStepRunWip = InFlowMaster.ExistPrevStepRunWip(eqp, last.ProductID, last.ProductVersion, last.OwnerType, lastStep, adjustHour); if (isExistPrevStepRunWip == false) { //AllowRunDown Factor decimal inflowQty = InFlowMaster.GetAllowRunDownWip(eqp, last.ProductID, last.ProductVersion, last.OwnerType, lastStep, adjustHour); if (inflowQty <= 0) { inflowQty += eqp.GetFilteredWipQty(last); } if (inflowQty <= 0) { return(null); } } dummy.DispatchInTime = eqp.NowDT; return(dummy); }
internal static bool IsLastPlan(this FabAoEquipment eqp, string shopID, string stepID, string productID, string productVersion, string ownerType, string ownerID, bool checkProductVersion = true) { var last = eqp.GetLastPlan(); if (last == null) { return(false); } if (last.IsMatched(shopID, stepID, productID, productVersion, ownerType, ownerID, checkProductVersion)) { return(true); } return(false); }
private static bool IsLastPlan(FabAoEquipment eqp, string productID, string stepID) { var last = eqp.GetLastPlan(); //eqp.LastPlan as FabPlanInfo; if (last == null) { return(false); } if (last.ProductID != productID) { return(false); } if (last.StepID != stepID) { return(false); } return(true); }
/// <summary> /// </summary> /// <param name="entity"/> /// <param name="now"/> /// <param name="target"/> /// <param name="factor"/> /// <param name="ctx"/> /// <returns/> public WeightValue MIN_MOVEQTY_PRIORITY(Mozart.Simulation.Engine.ISimEntity entity, DateTime now, Mozart.Simulation.Engine.ActiveObject target, Mozart.SeePlan.DataModel.WeightFactor factor, Mozart.SeePlan.Simulation.IDispatchContext ctx) { if (factor.Factor == 0) { return(new WeightValue(0)); } FabAoEquipment eqp = target as FabAoEquipment; var last = eqp.GetLastPlan(); //eqp.LastPlan; float score = 0f; if (last == null) { return(new WeightValue(0, string.Format("[LastPlan NULL, CONT:{0}]", eqp.ContinuousQty))); } int minMoveQty = (int)factor.Criteria[0]; if (minMoveQty == 0) { return(new WeightValue(0, string.Format("[MinMove Not Setting, CONT:{0}]", eqp.ContinuousQty))); } FabLot lot = entity as FabLot; bool isLastPlan = eqp.IsLastPlan(lot); if (isLastPlan && eqp.ContinuousQty < minMoveQty) { score = 1f; } string desc = string.Format("[MIN:{0}, CONT:{1}, IsLast:{2}]", minMoveQty, eqp.ContinuousQty, isLastPlan); return(new WeightValue(score * factor.Factor, desc)); }
private bool IsSupportRun(FabAoEquipment eqp, DcnTarget target) { if (eqp == null || target == null) { return(false); } var targetEqp = eqp.Target as FabEqp; if (target.ShopID != target.ShopID) { return(false); } var last = eqp.GetLastPlan(); //eqp.LastPlan as FabPlanInfo; if (last == null) { return(false); } //SupportStep 진행 중 여부 체크 var find = this.SupportSteps.Find(t => t.StepID == last.StepID); if (find == null) { return(false); } if (last.ProductID == target.ProductID) { return(true); } return(false); }
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); }
private static bool CanMakeDummy(FabAoEquipment eqp, IList <IHandlingBatch> wips, out decimal inflowHours) { inflowHours = 0; var last = eqp.GetLastPlan(); // eqp.LastPlan as FabPlanInfo; if (last == null) { return(false); } if (IsSomeOneDummyWait(eqp, last)) { return(false); } WeightFactor wf; if (TryGetEqpWeightFactor(eqp, Constants.WF_ALLOW_RUN_DOWN_TIME, out wf) == false) { return(false); } inflowHours = (decimal)wf.Criteria[0]; if (inflowHours <= 0) { return(false); } var idleTime = eqp.GetIdleRunTime(); //AllowRunDown 지나면 기다릴 필요 없음. //(IdleRun이 발생시작부터 (jung-임시), Idle 시작부터면 설정된 Inflow 시간 + ProcessTime이됨. if (idleTime.TotalHours > Convert.ToDouble(inflowHours)) { return(false); } //EqpRecipe X Type인 경우는 DummyLot을 만들지 않는다. if (eqp.IsEqpRecipeRun) { return(false); } //var stdStep = last.FabStep.StdStep; //int count = stdStep.GetWorkingEqpCount(last); //if (count > 1) // return null; //동일한 Spec Lot이 존재하는 경우 대기 X if (wips != null && wips.Count > 0) { var find = wips.FirstOrDefault(t => eqp.IsLastPlan(t.Sample as FabLot)); if (find != null) { return(false); } } //Setup이 필요없는 제품 존재하는 경우 대기 X(2019.12.16 - by.liujian(유건)) if (wips != null && wips.Count > 0) { var find = wips.FirstOrDefault(t => ResHelper.IsNeedSetup(eqp, t.Sample as FabLot) == false); if (find != null) { return(false); } } //CF PHOTO (MAIN/SUB) - remain target return(true); }
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()); }