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 bool IsFilterDummyWaitEqp(this JobFilterInfo info, FabAoEquipment eqp, List <FabAoEquipment> eqpList) { if (eqpList == null) { return(false); } WeightFactor wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_DUMMY_WAIT_EQP_FILTER); if (wf == null || wf.Factor == 0) { return(false); } //연속진행인 경우 if (info.IsRunning) { return(false); } var waitEqps = eqpList.FindAll(x => x.IsDummyWait); bool isFilter = waitEqps.Count > 0; return(isFilter); }
internal static double GetNewAssignNeedCnt(this JobFilterInfo info, FabAoEquipment eqp, double inflowHour, double workCnt) { double reqCnt = info.GetRequiredEqpCnt(eqp, (decimal)inflowHour); double needCnt = GetNewAssignNeedCnt(reqCnt, workCnt); return(needCnt); }
private static bool IsFilterRunMode(this JobFilterInfo info, FabAoEquipment eqp, List <JobFilterInfo> jobList) { WeightFactor wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_RUN_MODE_FILTER); if (wf == null || wf.Factor == 0) { return(false); } //연속진행인 경우 if (info.IsRunning) { return(false); } string eqpGroup = eqp.TargetEqp.EqpGroup; string runMode = eqp.GetCurrentRunMode(); var branchStep = BranchStepMaster.GetBranchStep(eqpGroup, runMode); if (branchStep == null) { return(false); } if (branchStep.IsAllProduct) { return(false); } var productList = branchStep.ProductList; if (productList == null || productList.Count == 0) { return(false); } string productID = info.ProductID; string ownerType = info.OwnerType; bool isFilter = true; if (branchStep.IsLoadable(productID, ownerType)) { isFilter = false; } if (isFilter) { string defaultOwnerType = SiteConfigHelper.GetDefaultOwnerType(); if (ExistRemainWip(jobList, productList, defaultOwnerType) == false) { isFilter = false; } } return(isFilter); }
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 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 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); }
public static int GetWorkingEqpCount(this FabStdStep stdStep, JobFilterInfo info, bool checkProductVersion = true, bool onlyParent = true) { if (info == null) { return(0); } string productID = info.ProductID; string prodVer = info.ProductVersion; string ownerType = info.OwnerType; string ownerID = info.OwnerID; return(GetWorkingEqpCount(stdStep, productID, prodVer, ownerType, ownerID, checkProductVersion, onlyParent)); }
public static List <FabAoEquipment> InitJobFilterInfo(this JobFilterInfo info, FabAoEquipment eqp, Dictionary <string, List <FabAoEquipment> > workingEqps) { info.IsRunning = eqp.CheckIsRunning(info); var key = FilterHelper.GetJobFilterKey(info); List <FabAoEquipment> eqpList; workingEqps.TryGetValue(key, out eqpList); if (eqpList == null || eqpList.Count == 0) { info.IsNoAssign = true; } info.SetHarmonicTactInfo(eqp, eqpList); info.SetSetupTime(eqp); return(eqpList); }
private static double GetRequiredEqpCnt(this JobFilterInfo info, FabAoEquipment eqp, decimal inflowHour) { decimal inflowQty = InFlowAgent.GetInflowQty(info, eqp, inflowHour, 0); decimal avtTact = info.HarmonicAvgTact; if (eqp.IsParallelChamber) { avtTact = info.HarmonicAvgTact / eqp.GetChamberCapacity(); } decimal inflowSec = inflowHour * 3600; double requiredEqp = Convert.ToSingle(inflowQty * avtTact / Math.Max(inflowSec, 1)); if (requiredEqp <= 0) { requiredEqp = 0; } return(requiredEqp); }
private static bool IsFilterNewEqpAssign(JobFilterInfo info, FabAoEquipment eqp, double inflowHour, int workCnt, out string reason) { reason = string.Empty; double needCnt = Math.Round(info.GetNewAssignNeedCnt(eqp, inflowHour, workCnt), 2); bool isFilter = needCnt < 1; if (isFilter) { reason = string.Format("HOUR({0}):REQ({1}), WORK({2}):{3} < 1", Math.Round(inflowHour, 2), Math.Round(needCnt, 2), workCnt, needCnt); } info.NewAssignNeedCount = needCnt; return(needCnt < 1); }
public static bool CheckIsRunning(this FabAoEquipment eqp, JobFilterInfo info) { if (eqp.Loader.IsBlocked()) { return(false); } string shopID = eqp.TargetEqp.ShopID; string stepID = info.Step.StepID; string productID = info.ProductID; string productVer = info.ProductVersion; string ownerType = info.OwnerType; string ownerID = info.OwnerID; if (eqp.IsLastPlan(shopID, stepID, productID, productVer, ownerType, ownerID)) { return(true); } return(false); }
private object CreateInstance(JobActivatorScope scope, ActivationContext context) { var filterInfo = new JobFilterInfo(_filterProvider.GetFilters(context.BackgroundJob.Job)); BeforeActivation(context, filterInfo.ActivationFilters); var activatedContext = ActivateJob(scope, context); AfterActivation(activatedContext, filterInfo.ActivationFilters); if (activatedContext.Exception != null) { throw activatedContext.Exception; } if (activatedContext.Instance == null) { throw new InvalidOperationException( String.Format("JobActivator returned NULL instance of the '{0}' type.", context.BackgroundJob.Job.Type)); } return(activatedContext.Instance); }
private static bool IsFilterInflowMoreThenRemainArrMtype(this JobFilterInfo info, FabAoEquipment eqp) { if (InputMart.Instance.GlobalParameters.ApplyArrangeMType == false) { return(false); } WeightFactor wf; WeightHelper.TryGetEqpWeightFactor(eqp, Constants.WF_MIN_MOVEQTY_PRIORITY, out wf); if (wf == null || wf.Factor == 0) { return(false); } FabLot lot = info.Sample; if (info.IsRunning) { return(false); } if (lot == null) { return(false); } var list = lot.CurrentEqpArrange.EqpArrrangeSet.Items.FindAll(x => x.ActivateType == ActivateType.M); if (list == null || list.Count == 0) { return(false); } float minMoveQty = (int)wf.Criteria[0] / 2; float tactTime = (float)SiteConfigHelper.GetDefaultTactTime().TotalSeconds; StepTime st = info.Step.GetStepTime(eqp.EqpID, info.ProductID); if (st != null) { tactTime = st.TactTime; } Time inflowTime = Time.FromSeconds(minMoveQty * tactTime); decimal inflowQty = InFlowAgent.GetInflowQty(lot, eqp, (decimal)inflowTime.TotalHours, 0); Time endTime = eqp.Now + inflowTime; bool isContinueNextDay = ShopCalendar.StartTimeOfNextDay(eqp.NowDT) <= endTime; foreach (var item in list) { int remainQty = item.RemainQty; if (isContinueNextDay && item.IsDailyMode) { remainQty += item.LimitQty; } //limit(M) 잔여 수량이 MIN_MOVEQTY의 1 / 2 이상인 경우 체크 제외. if (remainQty >= minMoveQty) { continue; } if (remainQty < inflowQty) { info.FilterReason = string.Format("Remain:{0} < Inflow:{1}", remainQty, inflowQty); return(true); } } return(false); }
public static void SetHarmonicTactInfo(this JobFilterInfo info, AoEquipment aeqp, List <FabAoEquipment> eqplist) { info.HarmonicTact = GetHarmonicTact(aeqp, eqplist, info); info.HarmonicAvgTact = info.HarmonicTact * (eqplist == null ? 1 : eqplist.Count); }
public static string GetJobFilterKey(JobFilterInfo info) { return(ResHelper.CreateKeyForJobFilter(info.Step.ShopID, info.Step.StepID, info.ProductID, info.ProductVersion, info.OwnerType)); }
private static decimal GetHarmonicTact(AoEquipment aeqp, List <FabAoEquipment> eqplist, JobFilterInfo info) { List <FabAoEquipment> assigned = new List <FabAoEquipment>(); if (eqplist != null) { assigned.AddRange(eqplist); } //신규 추가인 경우 해당 설비를 포함하여 TactTime 계산 if (info.IsRunning == false) { assigned.Add(aeqp as FabAoEquipment); } decimal harmonicTact = TimeHelper.GetHarmonicTactTime(info.Step, assigned, info.ProductID); return(harmonicTact); }
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); }
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()); }
private static bool IsFilterNewEqpAssign(this JobFilterInfo info, FabAoEquipment eqp, List <FabAoEquipment> workingEqpList) { WeightFactor wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_NEW_EQP_ASSIGN_FILTERING); if (wf == null || wf.Factor == 0) { return(false); } //연속진행인 경우 if (info.IsRunning) { return(false); } //Setup이 필요없는 제품의 경우 Filter 제외(2019.12.16 - by.liujian(유건)) if (eqp.IsParallelChamber == false) { var setupTime = info.SetupTime; if (setupTime <= 0) { return(false); } } ////NoAssign 제품의 경우는 IsFilterSetup로 체크(bong - J/C 증가로 제외) //if (info.IsNoAssign) // return false; //if (eqp.EqpID == "FHMPH100" && eqp.NowDT >= LcdHelper.StringToDateTime("20200113 203008")) // Console.WriteLine("B"); double param1 = (double)wf.Criteria[0]; double param2 = (double)wf.Criteria[1]; //if (info.IsNoAssign) //{ // WeightFactor awf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_ALLOW_RUN_DOWN_TIME); // if (awf != null && awf.Factor != 0) // param1 = param1 + Convert.ToDouble(awf.Criteria[0]); //} int workCnt = workingEqpList != null ? workingEqpList.Count : 0; //param1 string reason; bool isFilter = IsFilterNewEqpAssign(info, eqp, param1, workCnt, out reason); //param2 if (isFilter == false && workCnt > 0) { if (param2 > param1) { isFilter = IsFilterNewEqpAssign(info, eqp, param2, workCnt, out reason); } } if (isFilter) { info.FilterReason = reason; } 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); }