Exemple #1
0
        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);
        }
Exemple #2
0
 private static void CreateFabManager()
 {
     foreach (var item in GetDspEqpGroups())
     {
         InFlowMaster.AddFabMananger(item);
     }
 }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        private static void OnDoneWipLocation(FabLot lot)
        {
            JobState job = InFlowMaster.GetJobState(JobState.GetKey(lot));

            if (job != null)
            {
                job.RemoveWip(WipType.Wait, lot, lot.CurrentFabStep);
            }
        }
Exemple #6
0
        public static FabManager GetFabManager(string dspEqpGroupID)
        {
            if (string.IsNullOrEmpty(dspEqpGroupID))
            {
                return(null);
            }

            return(InFlowMaster.GetManager(dspEqpGroupID));
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        private static void BuildFabManager()
        {
            foreach (string resGrpID in GetDspEqpGroups())
            {
                var mgr = InFlowMaster.GetManager(resGrpID);

                if (mgr == null)
                {
                    continue;
                }

                mgr.Build();
            }
        }
Exemple #9
0
        //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));
        }
Exemple #10
0
        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);
        }
Exemple #11
0
        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);
            }
        }
Exemple #12
0
        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));
            }
        }
Exemple #13
0
        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);
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        //주기적으로 실행
        public static void Management()
        {
            InFlowMaster.UpdateLoadedEqpList(Factory.Equipments);

            InFlowMaster.Management(NowDT);
        }