internal static void InitLocate(AoEquipment aeqp, IHandlingBatch hb) { var eqp = aeqp.ToFabAoEquipment(); FabLot lot = hb.ToFabLot(); if (IsUseJig(lot) == false) { return; } var loableList = GetLoadableJigArrangeList(aeqp, lot); if (loableList == null || loableList.Count == 0) { return; } foreach (var item in loableList[0].Jigs) { if (item.IsBusy) { continue; } lot.CurrentJig.Add(item); if (lot.CurrentJig.Count == eqp.UseJigCount) { break; } } }
private void AddTargetWaitWip(WipProfile profile, List <JobState> jobList, FabStep step, string prodVer, int exCludeStepCnt, AoEquipment inputEqp, decimal allowRunDonwTime ) { FabAoEquipment eqp = inputEqp.ToFabAoEquipment(); decimal tact = GetAverageTactTime(step, prodVer); if (exCludeStepCnt > 0) //자신의 Wait 제외시 { WipStep ws = new WipStep(step, tact, 0); profile.AddWipStep(ws); } else { decimal stepWaitQty = GetCurrenStepWaitWipQty(eqp, step, prodVer, allowRunDonwTime); WipStep ws = new WipStep(step, tact, stepWaitQty); profile.AddWipStep(ws); } }
public static bool TryGetMaxRequiredEqp(AoEquipment aeqp, List <JobFilterInfo> joblist, out double maxRequireEqp) { maxRequireEqp = 0; FabAoEquipment eqp = aeqp.ToFabAoEquipment(); //if (eqp.EqpID == "THATS400")// && eqp.NowDT >= LcdHelper.StringToDateTime("20190923181719")) // Console.WriteLine("B"); WeightFactor wf; if (TryGetEqpWeightFactor(eqp, Constants.WF_REQUIRED_EQP_PRIORITY, out wf) == false) { return(false); } double inflowHour = (double)wf.Criteria[0]; foreach (JobFilterInfo info in joblist) { double workCnt = info.WorkingEqpCnt; double needCnt = info.GetNewAssignNeedCnt(eqp, inflowHour, workCnt); maxRequireEqp = Math.Max(maxRequireEqp, needCnt); info.NewAssignNeedCount = needCnt; } return(true); }
public static float GetSetupTime(AoEquipment aeqp, string shopID, string stepID, string productID, string prodVer, string ownerType, string ownerID, bool markingAcid = false) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); //if(eqp.EqpID == "THATS300") // Console.WriteLine("B"); //if (CheckLastPlan(eqp, shopID, stepID, productID, prodVer, ownerType, ownerID)) // return 0; SetupInfo info = CreateHelper.CreateSetupInfo(eqp, shopID, stepID, productID, prodVer, ownerType, ownerID); string eqpGroup = eqp.TargetEqp.EqpGroup; float setupTime = GetSetupTime(eqpGroup, info); float acidChangeTime = AcidMaster.GetAcidChangeTime(eqp, stepID, productID); float totalSetupTime = setupTime + acidChangeTime; //용액교체 Setup 발생시 EqpPlan 기록을 위해 표시 if (markingAcid && acidChangeTime > 0) { AcidMaster.SetSetupMark(eqp, true); } return(totalSetupTime); }
private static List <MaskArrange> GetLoadableJigArrangeList(AoEquipment aeqp, FabLot lot) { List <MaskArrange> list = new List <MaskArrange>(); var eqp = aeqp.ToFabAoEquipment(); var malist = MaskMaster.GetMatchedMaskArrangeList(aeqp, lot, ToolType.JIG); if (malist == null) { return(list); } foreach (var item in malist) { int ableQty = 0; foreach (var mask in item.Jigs) { if (mask.IsBusy) { continue; } ableQty++; } if (ableQty >= eqp.UseJigCount) { list.Add(item); } } return(list); }
//Chamber생성 internal static void InitializeParallelChamber(AoEquipment aeqp) { var eqp = aeqp.ToFabAoEquipment(); if (eqp.IsParallelChamber == false) { return; } FabEqp taretEqp = aeqp.Target as FabEqp; AoChamberProc2 proc = eqp.FirstProcess <AoChamberProc2>(); var chambers = proc.Chambers; if (chambers != null) { int count = chambers.Length; eqp.SubEqps = new FabSubEqp[count]; for (int i = 0; i < count; i++) { var chamberInfo = chambers[i]; string subEqpID = chamberInfo.Label; var subEqp = taretEqp.GetSubEqp(subEqpID) as FabSubEqp; subEqp.ChamberInfo = chamberInfo; eqp.SubEqps[i] = subEqp; subEqp.LastPlan = SimHelper.CreateInitLastPlan(subEqp.StatusInfo); subEqp.LastIdleRunStartTime = aeqp.NowDT; subEqp.LastIdleStartTime = aeqp.NowDT; } } }
public ISet <string> GET_NEED_SETUP_CHAMBERS0(AoEquipment aeqp, ChamberInfo[] loadableChambers, IHandlingBatch hb, ref bool handled, ISet <string> prevReturnValue) { var eqp = aeqp.ToFabAoEquipment(); var lot = hb.ToFabLot(); //if (eqp.EqpID == "THCVD300" && lot != null && lot.LotID == "TH011661N0H") // Console.WriteLine("B"); HashSet <string> list = new HashSet <string>(); foreach (var c in loadableChambers) { var subEqp = eqp.FindSubEqp(c); if (subEqp == null) { continue; } var setupTime = Time.FromMinutes(subEqp.GetSetupTime(lot)); if (setupTime <= Time.Zero) { continue; } c.SetSetupTime(setupTime); list.Add(subEqp.SubEqpID); } return(list); }
private static bool IsLoadableEqpArrange(AoEquipment aeqp, FabLot lot) { var eqp = aeqp.ToFabAoEquipment(); bool checkQty = true; if (InputMart.Instance.GlobalParameters.ApplyArrangeMType == false) { checkQty = false; } bool isLoadable = EqpArrangeMaster.IsLoadable(eqp, lot, checkQty); if (isLoadable == false) { return(false); } //1차 선택 (1차 : Mask 미고려 선택, 2차 : Mask 고려 후 선택) if (lot.CurrentEqpArrange != null) { string productVersion = lot.CurrentProductVersion; lot.CurrentEqpArrange.SetUsedArrange(productVersion); } return(true); }
internal static void SetLayerBalance(AoEquipment aeqp, LayerStats sts) { var eqp = aeqp.ToFabAoEquipment(); string dspEqpGroupID = eqp.DspEqpGroupID; _layerBalanceState[dspEqpGroupID] = sts; }
public static FabMask SelectBestMask(AoEquipment aeqp, FabLot lot) { var eqp = aeqp.ToFabAoEquipment(); string productVersion = lot.CurrentProductVersion; FabMask selectMask = null; //연속진행 중인 경우 if (eqp.IsLastPlan(lot)) { var currMask = eqp.GetCurrentMask(); if (currMask != null && currMask.IsLoadable_Limit(lot)) { var currEA = lot.CurrentEqpArrange; if (currEA != null) { var last = eqp.GetLastPlan(); //eqp.LastPlan as FabPlanInfo; if (currEA.IsLoableByProductVersion(last.ProductVersion)) { selectMask = currMask; productVersion = last.ProductVersion; } } } } if (selectMask == null) { var loadableList = GetLoadableMaskArrangeList(aeqp, lot, ToolType.MASK); if (loadableList == null || loadableList.Count == 0) { return(null); } if (loadableList.Count > 1) { loadableList.Sort(new CompareHelper.MaskArrangeComparer(eqp.EqpID)); } var best = loadableList[0]; selectMask = best.Mask; productVersion = best.ProductVersion; } //2차 선택 (1차 : Mask 미고려 선택, 2차 : Mask 고려 후 선택) lot.CurrentEqpArrange.SetUsedArrange(productVersion); //if (eqp.NowDT >= LcdHelper.StringToDateTime("20190820153409")) //{ // if (lot.LotID == "LARRAYI0075" && lot.CurrentStepID == "1300") // Console.WriteLine("B"); //} return(selectMask); }
internal static float GetAcidChangeTime(AoEquipment aeqp, FabLot lot) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); string productID = lot.CurrentProductID; string stepID = lot.CurrentStepID; return(GetAcidChangeTime(eqp, productID, stepID)); }
internal static LayerStats CalcLayerBalance(AoEquipment aeqp) { var eqp = aeqp.ToFabAoEquipment(); LayerStats sts = new LayerStats(eqp); SetLayerBalance(aeqp, sts); return(sts); }
internal static void EndDispatch_ParallelChamber(this AoEquipment aeqp) { var eqp = aeqp.ToFabAoEquipment(); if (eqp.IsParallelChamber == false) { return; } eqp.TriggerInfo = null; }
internal static void StartDispatch_ParallelChamber(this AoEquipment aeqp) { var eqp = aeqp.ToFabAoEquipment(); if (eqp.IsParallelChamber == false) { return; } eqp.SetTriggerSubEqpInfo(); }
public static void SetSetupTime(this JobFilterInfo info, AoEquipment aeqp) { FabLot lot = info.Sample; if (lot == null) { return; } info.SetupTime = SetupMaster.GetSetupTime(aeqp, lot); var eqp = aeqp.ToFabAoEquipment(); }
private static void EvaluateJobFilter(AoEquipment aeqp, List <JobFilterInfo> list) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); string runMode = eqp.GetCurrentRunMode(); Dictionary <string, List <FabAoEquipment> > workingEqps = ResHelper.GetWorkingEqpInfos(aeqp, true); foreach (JobFilterInfo info in list) { List <FabAoEquipment> eqpList = info.InitJobFilterInfo(eqp, workingEqps); //RunMode if (info.IsFilterRunMode(eqp, list)) { info.FilterType = DispatchFilter.RunMode; info.FilterReason = runMode; continue; } //Dummy Wait 필터 if (info.IsFilterDummyWaitEqp(eqp, eqpList)) { info.FilterType = DispatchFilter.DummyWaitEqp; continue; } //Setup 필터 if (info.IsFilterSetup(eqp)) { info.FilterType = DispatchFilter.Setup; continue; } //New Eqp Assign 필터 if (info.IsFilterNewEqpAssign(eqp, eqpList)) { info.FilterType = DispatchFilter.NewEqpAssign; continue; } //TODO : 로직 검증 필요 (bong - 2019.11.11) ////M Type Arrnage 잔여반영 필터 //if (info.IsFilterInflowMoreThenRemainArrMtype(eqp)) //{ // info.FilterType = DispatchFilter.InflowArrTypeM; // continue; //} } }
private static bool IsWaitSmallSizeLot(AoEquipment aeqp, JobFilterInfo info, FabLot lot, double waitQty, double setupTime, double ratio, StepTime st) { var step = lot.CurrentFabStep; if (step == null) { return(false); } var stdStep = step.StdStep; if (stdStep == null || stdStep.IsInputStep) { return(false); } FabAoEquipment eqp = aeqp.ToFabAoEquipment(); TimeSpan firstInflowTime = TimeSpan.FromMinutes(setupTime); decimal allowTime = 3m; WeightFactor wf; WeightHelper.TryGetEqpWeightFactor(eqp, Constants.WF_ALLOW_RUN_DOWN_TIME, out wf); if (wf != null) { allowTime = (decimal)wf.Criteria[0]; } double inflowQty1 = Convert.ToDouble(InFlowAgent.GetInflowQty(info, aeqp, (decimal)firstInflowTime.TotalHours, 0)); double inflowQty2 = Convert.ToDouble(InFlowAgent.GetInflowQty(info, aeqp, allowTime, 0)); double waitQty1 = waitQty + inflowQty1; double waitQty2 = waitQty + inflowQty2; //Setup 시간 이내에 유입이 있나? if (LcdHelper.IsIncludeInRange(waitQty, waitQty1 * 0.95d, waitQty1 * 1.05d)) { //지정된 시간내에 유입재공이 있나? if (LcdHelper.IsIncludeInRange(waitQty, waitQty2 * 0.95d, waitQty2 * 1.05d)) { double requiredSec = st.TactTime * waitQty2; bool isSmall = requiredSec < setupTime * 60 * ratio; return(isSmall); } } return(false); }
////TODO : Temp-POC 모델용 //public static bool EqualsStep(this FabStep current, FabStep next) //{ // bool rvalue = true; // if (current.StepID != next.StepID) // { // rvalue = false; // if (current.StepID.EndsWith("R") || next.StepID.EndsWith("R")) // { // var orignStepID = "-"; //current.GetStepPatternKey();// current.StepID.Split('-')[0]; // var newStepID = "-"; //next.GetStepPatternKey();// next.StepID.Split('-')[0]; // if (orignStepID.Equals(newStepID)) // rvalue = true; // } // } // return rvalue; //} public static void CheckContinueousQty(AoEquipment aeqp, IHandlingBatch hb) { var eqp = aeqp.ToFabAoEquipment(); FabLot lot = hb.ToFabLot(); bool isLast = ResHelper.IsLastPlan(eqp, lot, true); if (isLast == false) { ResetContinueousQty(aeqp); } UpdateContinueousQty(aeqp, lot.UnitQty); }
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 Dictionary <string, List <FabAoEquipment> > GetWorkingEqpInfos(AoEquipment aeqp, bool with) { var eqp = aeqp.ToFabAoEquipment(); Dictionary <string, List <FabAoEquipment> > result = new Dictionary <string, List <FabAoEquipment> >(); string dspEqpGroupID = eqp.DspEqpGroupID; List <FabAoEquipment> eqpGroups = GetEqpsByDspEqpGroup(dspEqpGroupID); if (eqpGroups != null) { foreach (FabAoEquipment it in eqpGroups) { if ((aeqp.Target as FabEqp).ShopID != (it.Target as FabEqp).ShopID) { continue; } if (with == false && it == aeqp) { continue; } var last = it.LastPlan as FabPlanInfo; if (last == null || it.Loader.IsBlocked()) { continue; } string shopID = last.ShopID; string stepID = last.StepID; string productID = last.ProductID; string prodVer = last.ProductVersion; string ownerType = last.OwnerType; string key = CreateKeyForJobFilter(shopID, stepID, productID, prodVer, ownerType); List <FabAoEquipment> list; if (result.TryGetValue(key, out list) == false) { result.Add(key, list = new List <FabAoEquipment>()); } list.Add(it); } } return(result); }
public static void StartTask(FabLot lot, AoEquipment aeqp) { //if (IsUseTool(lot) == false) // return; FabAoEquipment eqp = aeqp.ToFabAoEquipment(); FabMask mask = lot.CurrentMask; eqp.SeizeMaskTool(mask, lot); if (mask != null) { mask.AddLoadInfo(eqp.EqpID, lot); mask.MoveQty(eqp, lot); } }
internal int GetCurrenStepWaitWipQty(AoEquipment aeqp, FabStep currentStep, string productVersion, decimal allowRunDownTime) { if (allowRunDownTime <= 0) { return(0); } FabAoEquipment eqp = aeqp.ToFabAoEquipment(); List <FabLot> wips = GetStepWipList(currentStep, WipType.Wait, productVersion); int qty = 0; foreach (var lot in wips) { //해당 설비에서 로딩가능한 대기재공인지 Lot if (eqp != null && EqpArrangeMaster.IsLoadable_CheckOnly(eqp, lot) == false) { continue; } //잔여 AllowTime 안에 Hold가 풀리는지 if (lot.IsHold) { Time remainHold = lot.HoldTime - (eqp.NowDT - lot.HoldStartTime); if ((decimal)remainHold.TotalHours > allowRunDownTime) { continue; } } //Min Qtime (최소대기시간) 내에 풀리는지? if (lot.CurrentFabPlan.LotFilterInfo.FilterType == DispatchFilter.MinQtime) { if ((decimal)lot.CurrentFabPlan.LotFilterInfo.RemainMinStayTime.TotalHours > allowRunDownTime) { continue; } } qty += lot.UnitQty; } return(qty); }
public static void DoGroupFilter(AoEquipment aeqp, IList <IHandlingBatch> wips, IDispatchContext ctx, List <IHandlingBatch> revaluation) { var eqp = aeqp.ToFabAoEquipment(); FilterHelper.BuildJobFilterInfo(eqp, wips, ctx); List <JobFilterInfo> list = ctx.Get <List <JobFilterInfo> >(Constants.JobGroup, null); if (list == null) { return; } EvaluateJobFilter(eqp, list); for (int i = wips.Count - 1; i >= 0; i--) { var hb = wips[i]; bool isRemove = false; if (hb.HasContents) { for (int j = hb.Contents.Count - 1; j >= 0; j--) { var lot = hb.Contents[j] as FabLot; if (DoGroupFilterMore(aeqp, lot, revaluation)) { hb.Contents.RemoveAt(j); continue; } } isRemove = hb.Contents.Count == 0; } else { isRemove = DoGroupFilterMore(eqp, hb.ToFabLot(), revaluation); } if (isRemove) { wips.RemoveAt(i); continue; } } }
/// <summary> /// </summary> /// <param name="aeqp"/> /// <param name="handled"/> public void ON_EQP_START0(AoEquipment aeqp, ref bool handled) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); var eqpState = eqp.Target.State; if (eqpState == ResourceState.Up) { if (eqp.IsProcessing == false) { eqp.OnStateChanged(LoadingStates.IDLE); } } else if (eqpState == ResourceState.Down) { eqp.OnStateChanged(LoadingStates.DOWN); } }
internal static bool IsLoadable_ParallelChamber(AoEquipment aeqp, FabLot lot) { var eqp = aeqp.ToFabAoEquipment(); if (eqp.IsParallelChamber == false) { return(true); } var subEqpList = GetLoadableSubEqps(eqp, lot); if (subEqpList != null && subEqpList.Count > 0) { return(true); } return(false); }
public static bool IsFilterPreventLayerChange(AoEquipment aeqp, FabLot lot) { var eqp = aeqp.ToFabAoEquipment(); //if (eqp.EqpID == "THCVDC00" && eqp.NowDT >= LcdHelper.StringToDateTime("20200108 090229")) // Console.WriteLine("B"); WeightFactor wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_PREVENT_LAYER_CHANGE_FILTER); if (wf == null || wf.Factor == 0) { return(false); } var step = lot.CurrentFabStep; if (IsLastRunStep(eqp, step)) { return(false); } var stepList = SimHelper.GetDspEqpSteps(eqp.DspEqpGroupID); if (stepList == null || stepList.Count <= 1) { return(false); } var last = eqp.GetLastPlan(); if (last == null) { return(false); } bool isFilter = ExistRunEqpByDspEqpGroup(eqp, last.FabStep) == false; //if (isFilter) // info.FilterReason = string.Format(""); return(isFilter); }
internal static List <FabMask> SelectJigMask(AoEquipment aeqp, FabLot lot) { List <FabMask> result = new List <FabMask>(); var eqp = aeqp.ToFabAoEquipment(); if (eqp.IsLastPlan(lot)) { var currentJig = eqp.GetCurrentJig(); if (currentJig != null) { result.AddRange(currentJig.Masks); } } if (result.Count < eqp.UseJigCount) { var loadableList = GetLoadableJigArrangeList(aeqp, lot); if (loadableList == null || loadableList.Count == 0) { return(null); } foreach (var item in loadableList[0].Jigs) { if (item.IsBusy) { continue; } result.Add(item); if (result.Count == eqp.UseJigCount) { break; } } } return(result); }
private static bool DoGroupFilterMore(AoEquipment aeqp, FabLot lot, List <IHandlingBatch> revaluation) { var eqp = aeqp.ToFabAoEquipment(); if (HasFilterInfo(aeqp, lot)) { //재평가 필요한 경우(구현필요) if (HasWeakFilterInfo(aeqp, lot)) { revaluation.Add(lot); } else { WriteFilterInfo(lot, eqp); } return(true); } return(false); }
private static bool IsArrive(AoEquipment aeqp, FabLot lot, ref string reason) { var eqp = aeqp.ToFabAoEquipment(); DateTime now = aeqp.NowDT; //초기 Wait재공 if (lot.PreviousPlan == null && lot.Wip.InitialStep.StepID == lot.CurrentFabStep.StepID) { return(true); } Time tranferTime = TransferMaster.GetTransferTime(lot, eqp); if (now < lot.DispatchInTime + tranferTime) { Time remain = lot.DispatchInTime.AddMinutes(tranferTime.TotalMinutes) - now; reason = string.Format("Remain {0}Min", remain.TotalMinutes.ToRound(2)); return(false); } return(true); }
internal static bool IsLoadableToolArrange(AoEquipment aeqp, FabLot lot, bool isReal = true) { var eqp = aeqp.ToFabAoEquipment(); if (MaskMaster.IsUseTool(lot) == false) { return(true); } var mask = MaskMaster.SelectBestMask(aeqp, lot); if (mask == null) { return(false); } if (isReal) { lot.CurrentMask = mask; } return(true); }