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); }
private static void CreateFabManager() { foreach (var item in GetDspEqpGroups()) { InFlowMaster.AddFabMananger(item); } }
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); }
private static bool ExistInflowWip(FabAoEquipment eqp, JobFilterInfo info) { var wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_ALLOW_RUN_DOWN_TIME); if (wf == null || wf.Factor == 0) { return(false); } decimal inflowHour = (decimal)wf.Criteria[0]; if (inflowHour <= 0) { return(false); } var idleTime = eqp.GetIdleRunTime(); decimal adjustHour = inflowHour - Convert.ToDecimal(idleTime.TotalHours); if (adjustHour <= 0) { return(false); } var inflowQty = InFlowMaster.GetAllowRunDownWip(eqp, info.ProductID, info.ProductVersion, info.OwnerType, info.Step, adjustHour); return(inflowQty > 0); }
private static void OnDoneWipLocation(FabLot lot) { JobState job = InFlowMaster.GetJobState(JobState.GetKey(lot)); if (job != null) { job.RemoveWip(WipType.Wait, lot, lot.CurrentFabStep); } }
public static FabManager GetFabManager(string dspEqpGroupID) { if (string.IsNullOrEmpty(dspEqpGroupID)) { return(null); } return(InFlowMaster.GetManager(dspEqpGroupID)); }
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); }
private static void BuildFabManager() { foreach (string resGrpID in GetDspEqpGroups()) { var mgr = InFlowMaster.GetManager(resGrpID); if (mgr == null) { continue; } mgr.Build(); } }
//CHECK : jung (버전별 프로파일 확인여부) public static decimal GetInflowQty(string productID, string productVer, string ownerType, FabStep step, AoEquipment aeqp, decimal inflowHour, int excludeStepCnt) { var job = InFlowMaster.GetJobState(productID, ownerType); if (job == null || step == null) { return(0); } WipProfile profile = job.GetWipProfile(step, productVer); if (profile == null) { profile = job.CreateWipProfile(step, productVer, excludeStepCnt, aeqp.Target.Preset as FabWeightPreset, aeqp, inflowHour); profile.CalcProfile(); } return(job.GetInflowWip(profile, inflowHour)); }
private static bool EixstRemainStepPlan_Wait(FabLot lot, LineType lineType) { var step = lot.CurrentFabStep; var job = InFlowMaster.GetJobState(lot); if (job == null) { return(false); } var list = job.GetStepWipList(step, WipType.Wait); if (list == null || list.Count == 0) { return(false); } foreach (var it in list) { if (it.CurrentFabPlan == null) { continue; } var stepTarget = it.CurrentFabPlan.MainTarget; if (stepTarget == null) { continue; } if (stepTarget.Mo.LineType == lineType) { return(true); } } return(false); }
public LayerStats(FabAoEquipment eqp) { var factor = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_LAYER_BALANCE_PRIORITY); if (factor == null) { return; } string dspEqpGroupID = eqp.DspEqpGroupID; List <FabStdStep> steps = SimHelper.GetDspEqpSteps(dspEqpGroupID); for (int i = 0; i < steps.Count; i++) { FabStdStep step = steps[i]; int qty = InFlowMaster.GetStepWipQtyforLayerBalance(step.BalanceSteps); StepWipStat stat; if (dic.TryGetValue(step.StepID, out stat) == false) { stat = new StepWipStat(this, step); dic.Add(step.StepID, stat); } stat.AddQty(qty); } this.MinQty = decimal.MaxValue; this.MaxQty = decimal.MinValue; foreach (StepWipStat stat in dic.Values) { this.MinQty = Math.Min(stat.GapQty, this.MinQty); this.MaxQty = Math.Max(stat.GapQty, this.MaxQty); } }
private static void BuildEqpStates() { foreach (FabAoEquipment eqp in Factory.Equipments.Values) { if (SimHelper.IsTftRunning) { if (eqp.ShopID == Constants.CellShop) { continue; } } else { if (eqp.ShopID != Constants.CellShop) { continue; } } string eqpID = eqp.EqpID; string dspEqpGroupID = eqp.DspEqpGroupID; Dictionary <string, EqpState> eqpDic; if (_eqpDic.TryGetValue(dspEqpGroupID, out eqpDic) == false) { _eqpDic[dspEqpGroupID] = eqpDic = new Dictionary <string, EqpState>(); } FabManager fabMgr = InFlowMaster.GetManager(dspEqpGroupID); if (fabMgr == null) { continue; } eqpDic[eqpID] = new EqpState(fabMgr, eqp, InFlowMaster.GetInFlowSteps(eqpID)); } }
private static bool IsFilterSetup(this JobFilterInfo info, AoEquipment aeqp) { WeightFactor wf = WeightHelper.GetWeightFactor(aeqp.Target.Preset, Constants.WF_SETUP_FILTERING); if (wf == null || wf.Factor == 0) { return(false); } FabLot lot = info.Sample; if (lot == null) { return(false); } FabAoEquipment eqp = aeqp.ToFabAoEquipment(); var step = info.Step; //if (eqp.EqpID == "CHPIL300" && eqp.NowDT >= LcdHelper.StringToDateTime("20200119 105032") // && lot.CurrentProductID == "CW42512AB000") // Console.WriteLine("B"); if (eqp.IsLastPlan(lot)) { return(false); } double setupTime = info.SetupTime; if (setupTime <= 0) { return(false); } double ratio = Convert.ToDouble(wf.Criteria[0]); double continuousQty = info.WaitSum; if (continuousQty > 0) { continuousQty += InFlowMaster.GetContinuousQty(lot, step); } if (eqp.IsParallelChamber) { continuousQty = continuousQty / eqp.GetChamberCapacity(); } var st = step.GetStepTime(aeqp.EqpID, info.ProductID); if (st == null) { return(false); } double tactTime = st.TactTime; double workSec = Math.Round(continuousQty * tactTime, 2); double setupSec = Math.Round(setupTime * 60 * ratio, 2); bool isFilter = workSec < setupSec; if (isFilter == false) { return(false); } //단순 Setup > Tact Time 일 경우 Inflow를 고려 //다른 곳에서 진행중인가? Yes : 필터, No: 소량검사 if (SimHelper.IsAnyWorking(eqp, lot) == false) { //기다려도 오지 않는 작은 Lot인가? Yes : 필터하지 않음. No : 필터 if (IsWaitSmallSizeLot(aeqp, info, lot, continuousQty, setupTime, ratio, st)) { isFilter = false; } } if (isFilter) { info.FilterReason = string.Format("SetupTime:{0} > {1}(Qty:{2} * Tact:{3})", setupSec, workSec, continuousQty, st.TactTime); } return(isFilter); }
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 void Management() { InFlowMaster.UpdateLoadedEqpList(Factory.Equipments); InFlowMaster.Management(NowDT); }