//internal static LoadingStates GetLoadingState(LoadStates loadState) //{ // LoadingStates states = LoadingStates.IDLE; // switch (loadState) // { // case LoadStates.SETUP: // states = LoadingStates.SETUP; // break; // case LoadStates.BUSY: // states = LoadingStates.BUSY; // break; // case LoadStates.IDLERUN: // states = LoadingStates.IDLERUN; // break; // case LoadStates.IDLE: // states = LoadingStates.IDLE; // break; // case LoadStates.PM: // states = LoadingStates.PM; // break; // case LoadStates.DOWN: // states = LoadingStates.DOWN; // break; // case LoadStates.WAIT_SETUP: // states = LoadingStates.WAIT_SETUP; // break; // case LoadStates.RENT: // states = LoadingStates.PM; // break; // } // return states; //} //internal static LoadStates GetLoadState(LoadingStates states) //{ // LoadStates loadState = LoadStates.IDLE; // switch (states) // { // case LoadingStates.BUSY: // loadState = LoadStates.BUSY; // break; // case LoadingStates.DOWN: // loadState = LoadStates.DOWN; // break; // case LoadingStates.IDLE: // loadState = LoadStates.IDLE; // break; // case LoadingStates.IDLERUN: // loadState = LoadStates.IDLERUN; // break; // case LoadingStates.PM: // loadState = LoadStates.PM; // break; // case LoadingStates.SETUP: // loadState = LoadStates.SETUP; // break; // case LoadingStates.WAIT_SETUP: // loadState = LoadStates.WAIT_SETUP; // break; // } // return loadState; //} public static List <string> GetNowAvailableChambers(AoEquipment aeqp, FabLot lot, DateTime now) { if (aeqp.IsParallelChamber == false) { return(null); } //AoChamberProc2 가 Parallel Chamber임 AoChamberProc2 proc = aeqp.FirstProcess <AoChamberProc2>(); List <string> result = new List <string>(); foreach (ChamberInfo chamber in proc.Chambers) { //chamber 진행여부(chamber.Current 는 현재 진행인 상태(currently in process)를 나타냄) if (chamber.Current != null) { continue; } //chamber.GetrAvailableTime 이 미래이면 현재 가동중, 현재(now) 이면 idle인 상태 if (chamber.GetAvailableTime() <= now) { result.Add(chamber.Label); } } return(result); }
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); }
public static Time GetTransferTime(AoEquipment fromEqp, AoEquipment toEqp) { FabEqp from = fromEqp.Target as FabEqp; FabEqp to = toEqp.Target as FabEqp; return(GetTransferTime(from.OutStocker, to.InStocker)); }
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 decimal GetAllowRunDownWip(AoEquipment aeqp, string productID, string productVersion, string ownerType, FabStep step, decimal remainRundown) { var job = InFlowMaster.GetJobState(productID, ownerType); if (job == null) { return(0m); } //Wip Profile WipProfile iflow = job.CreateWipProfile(step, productVersion, 0, aeqp.Target.Preset as FabWeightPreset, aeqp, remainRundown, false); iflow.CalcProfile(); var qty = job.GetInflowWip(iflow, remainRundown); ////자신 + 직전 ////자신의 대기재공중 Load가능한 수량 //qty += job.GetCurrenStepWaitWipQty(aeqp, step, productVersion, remainRundown); ////자신의 직전의 Run중 Load가능한 수량 //DateTime targetTime = aeqp.NowDT.AddHours((double)-remainRundown); //qty += job.GetPrevStepRunWipQty(aeqp, step, productVersion, targetTime); return(qty); }
public static Time GetTransferTime(FabLot lot, AoEquipment eqp) { string from = null; string to = null; if (lot != null && lot.PreviousFabPlan != null) { if (lot.PreviousFabPlan.IsLoaded) { FabEqp prevEqp = lot.PreviousPlan.LoadedResource as FabEqp; from = prevEqp.OutStocker; } else { //init wip step --> next step if (lot.Plans.Count == 2) { string wipEqpID = lot.Wip.WipEqpID; var prevEqp = ResHelper.FindEqp(wipEqpID); from = prevEqp != null ? prevEqp.OutStocker : wipEqpID; } } } if (eqp != null) { to = (eqp.Target as FabEqp).InStocker; } return(GetTransferTime(from, to)); }
/// <summary> /// </summary> /// <param name="hb"/> /// <param name="ao"/> /// <param name="now"/> /// <param name="handled"/> public void ON_END_TASK0(IHandlingBatch hb, ActiveObject ao, DateTime now, ref bool handled) { try { AoEquipment equip = ao as AoEquipment; MicronBEAssyBELot lot = hb as MicronBEAssyBELot; if (equip == null) { SimulationHelper.CollectEqpPlan(hb, equip, LoadState.BUSY.ToString()); } MicronBEAssyBEStep step = lot.CurrentStep as MicronBEAssyBEStep; //if (step.StepAction != null && step.StepAction.FWTractIn == StepActionInfo.MCP) // lot.ChildLots.Clear(); if (lot.ReservationEqp == equip) { lot.ReservationEqp = null; } } catch (Exception e) { WriteHelper.WriteErrorHistory(ErrorLevel.FATAL, string.Format("ErrorMessage : {0} MethodName : {1}", e.Message, System.Reflection.MethodInfo.GetCurrentMethod().Name)); } }
public static bool ExistPrevStepRunWip(AoEquipment aeqp, string productID, string productVersion, string ownerType, FabStep step, decimal remainRundown) { var job = InFlowMaster.GetJobState(productID, ownerType); if (job == null) { return(false); } //자신의 대기재공중 Load가능한 수량 float qty = job.GetCurrenStepWaitWipQty(aeqp, step, productVersion, remainRundown); if (qty > 0) { return(true); } //자신의 직전의 Run중 Load가능한 수량 DateTime targetTime = aeqp.NowDT.AddHours((double)remainRundown); qty += job.GetPrevStepRunWipQty(aeqp, step, productVersion, targetTime); if (qty > 0) { return(true); } return(false); }
internal static void WriteFilterInfo(IHandlingBatch hb, AoEquipment eqp) { FabLot lot = hb.ToFabLot(); string reason = string.Format("{0}/{1}", lot.DispatchFilterInfo.FilterType, lot.DispatchFilterInfo.FilterReason); eqp.EqpDispatchInfo.AddFilteredWipInfo(lot, reason); }
private static bool HasFilterInfo(AoEquipment eqp, FabLot lot) { if (lot.DispatchFilterInfo == null) { return(false); } if (lot.DispatchFilterInfo.FilterType == DispatchFilter.None) { return(false); } WeightFactor wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_PREVENT_SMALL_LOT_FILTER); if (wf == null || wf.Factor == 0) { //자신의 초기 Step일 경우에 Lot Priority 가 1,2,3 일 경우 필터하지 않음 if (lot.CurrentStep == lot.Wip.InitialStep) { if (lot.Wip.Priority == 1 || lot.Wip.Priority == 2 || lot.Wip.Priority == 3) { return(false); } } } return(true); }
/// <summary> /// </summary> /// <param name="aeqp"/> /// <param name="hb"/> /// <param name="state"/> /// <param name="handled"/> public void PROCESS_STATE_CHANGED0(AoEquipment aeqp, IHandlingBatch hb, ProcessStates state, ref bool handled) { try { string status = string.Empty; if (state == ProcessStates.LastLoading || state == ProcessStates.LastUnloading) { status = LoadingStates.BUSY.ToString(); } else if (state == ProcessStates.StartSetup || state == ProcessStates.EndSetup) { status = LoadingStates.SETUP.ToString(); } if (string.IsNullOrEmpty(status)) { return; } SimulationHelper.CollectEqpPlan(hb, aeqp, status); } catch (Exception e) { WriteHelper.WriteErrorHistory(ErrorLevel.FATAL, string.Format("ErrorMessage : {0} MethodName : {1}", e.Message, System.Reflection.MethodInfo.GetCurrentMethod().Name)); } }
internal static Dictionary <string, WaitingWipInfo> SetWatingWipInfo(AoEquipment eqp, List <JobFilterInfo> joblist) { WeightFactor wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_ONGOING_PRODUCT_WIP_PRIORITY); if (wf == null) { return(null); } Dictionary <string, WaitingWipInfo> waiting = new Dictionary <string, WaitingWipInfo>(); foreach (var job in joblist) { var fps = (job.Step.Process as FabProcess).FirstPhotoStep; if (fps == null) { continue; } string stepKey = fps.StepKey; if (waiting.ContainsKey(stepKey)) { continue; } WaitingWipInfo info = ResHelper.GetTargetStepWaitingWip(stepKey); waiting.Add(stepKey, info); } return(waiting); }
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 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); }
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; } } }
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; } } }
/// <summary> /// </summary> /// <param name="wstep"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public IEnumerable <AoEquipment> GET_LOADABLE_EQPS0(WorkStep wstep, ref bool handled, IEnumerable <AoEquipment> prevReturnValue) { try { List <AoEquipment> equipList = new List <AoEquipment>(); if (wstep.Steps.Count == 0) { return(equipList); } List <string> list = SimulationHelper.GetLoadableList(wstep.Steps[0] as MicronBEAssyBEStep); foreach (string eqp in list) { AoEquipment aeqp = AoFactory.Current.GetEquipment(eqp); if (aeqp == null) { continue; } equipList.Add(aeqp); } return(equipList); } catch (Exception e) { WriteHelper.WriteErrorHistory(ErrorLevel.FATAL, string.Format("ErrorMessage : {0} MethodName : {1}", e.Message, System.Reflection.MethodInfo.GetCurrentMethod().Name)); return(default(IEnumerable <AoEquipment>)); } }
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); }
////TODO : 함수 이름 변경 필요 //internal static LayerStats GetLayerCumWipQtyRatio(AoEquipment aeqp) //{ // var eqp = aeqp.ToFabAoEquipment(); // LayerStats sts = new LayerStats(eqp); // return sts; //} internal static Dictionary <string, object> SetMinMaxVaule_WF(AoEquipment eqp, List <JobFilterInfo> joblist) { Dictionary <string, object> dict = new Dictionary <string, object>(); dict[Constants.WF_SETUP_TIME_PRIORITY] = GetMinMax_SetupTime(eqp, joblist); dict[Constants.WF_MAX_QTIME_PRIORITY] = GetMinMax_RemainTime(eqp, joblist); return(dict); }
public static decimal GetInflowQty(JobFilterInfo info, AoEquipment aeqp, decimal inflowHour, int excludeStepCnt) { string productID = info.ProductID; string prodVer = info.ProductVersion; string owerType = info.OwnerType; FabStep step = info.Step; return(GetInflowQty(productID, prodVer, owerType, step, aeqp, inflowHour, excludeStepCnt)); }
//public static Dictionary<string, EqpState> GetEqpDics(string eqpGroup) //{ // if (eqpGroup == null) // return new Dictionary<string, EqpState>(); // Dictionary<string, EqpState> eqpDic; // if (_eqpDic.TryGetValue(eqpGroup, out eqpDic)) // return eqpDic; // return new Dictionary<string, EqpState>(); //} public static decimal GetInflowQty(FabLot lot, AoEquipment aeqp, decimal inflowHour, int excludeStepCnt) { string productID = lot.CurrentProductID; string prodVer = lot.CurrentProductVersion; string owerType = lot.OwnerType; FabStep step = lot.CurrentFabStep; return(GetInflowQty(productID, prodVer, owerType, step, aeqp, inflowHour, excludeStepCnt)); }
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)); }
public static MaskLoadInfo FindLoadInfo(this FabMask mask, FabLot lot, AoEquipment eqp) { var key = GetMaskLoadInfoKey(eqp.EqpID, lot.LotID, lot.CurrentStepID); MaskLoadInfo info; mask.LoadInfosView.TryGetValue(key, out info); return(info); }
/// <summary> /// </summary> /// <param name="entity"/> /// <param name="now"/> /// <param name="target"/> /// <param name="factor"/> /// <param name="ctx"/> /// <returns/> public WeightValue LAYER_BALANCE_FOR_PHOTO(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)); } FabLot lot = entity as FabLot; int checkStepCount = (int)factor.Criteria[0]; if (checkStepCount == 0) { checkStepCount = 10; } var currentStep = lot.CurrentFabStep; var currentProd = lot.FabProduct; FabStep nextPhoto = currentStep.GetNextPhotoNearByMe(currentProd, checkStepCount, out _); LayerStats sts = WeightHelper.GetLayerBalacne(nextPhoto.StdStep.DspEqpGroup); if (sts == null) { AoEquipment aeqp = null; foreach (var eqp in nextPhoto.StdStep.AllEqps) { aeqp = AoFactory.Current.GetEquipment(eqp.EqpID); if (aeqp != null) { break; } } if (aeqp == null) { return(new WeightValue(0)); } sts = WeightHelper.CalcLayerBalance(aeqp); } LayerStats.StepWipStat wipStat = sts.GetWipStat(nextPhoto.StdStepID); string desc = string.Empty; float score = 0f; if (wipStat != null) { score = sts.GetLayerBalanceScore(wipStat, out desc); } return(new WeightValue(score * factor.Factor, desc)); }
public EqpState(FabManager manager, AoEquipment equipment, Dictionary <string, InFlowSteps> steps) { _fabManager = manager; _stepList = steps; _equipment = equipment; Initialize(); }
internal static LayerStats CalcLayerBalance(AoEquipment aeqp) { var eqp = aeqp.ToFabAoEquipment(); LayerStats sts = new LayerStats(eqp); SetLayerBalance(aeqp, sts); return(sts); }
//단위 : 분 public static float GetSetupTime(AoEquipment aeqp, FabLot lot, bool markingAcid = false) { string shopID = lot.CurrentShopID; string stepID = lot.CurrentStepID; string productID = lot.CurrentProductID; string prodVer = lot.CurrentProductVersion; string ownerType = lot.OwnerType; string ownerID = lot.OwnerID; return(GetSetupTime(aeqp, shopID, stepID, productID, prodVer, ownerType, ownerID, markingAcid)); }