Пример #1
0
        /// <summary>
        /// </summary>
        /// <param name="entity"/>
        /// <param name="now"/>
        /// <param name="target"/>
        /// <param name="factor"/>
        /// <param name="ctx"/>
        /// <returns/>
        public WeightValue PREVENT_LAYER_CHANGE_PRIORITY(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));
            }

            FabAoEquipment eqp = target as FabAoEquipment;
            FabLot         lot = entity as FabLot;

            float score = 0f;

            string currentStepID = lot.CurrentStepID;

            //연속진행
            bool isLastPlan = eqp.IsLastPlan(lot);

            if (isLastPlan)
            {
                score = 1;
            }
            else
            {
                var targetEqp = eqp.TargetEqp;
                if (targetEqp.IsMainRunStep(currentStepID))
                {
                    score = 1;
                }
                else
                {
                    //타설비에서 진행 중이면 Step이면 0, 아니면 1
                    bool isExistRunStep;
                    if (ExistRunEqpByDspEqpGroup(eqp, lot, out isExistRunStep))
                    {
                        score = -1;
                    }
                    else if (isExistRunStep)
                    {
                        score = 0;
                    }
                    else
                    {
                        score = 1;
                    }
                }
            }

            string desc = null;

            return(new WeightValue(score * factor.Factor, desc));
        }
Пример #2
0
        /// <summary>
        /// </summary>
        /// <param name="entity"/>
        /// <param name="now"/>
        /// <param name="target"/>
        /// <param name="factor"/>
        /// <param name="ctx"/>
        /// <returns/>
        public WeightValue LOT_PRIORITY(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));
            }

            FabAoEquipment eqp = target as FabAoEquipment;
            FabLot         lot = entity as FabLot;

            if (lot.IsDummy)
            {
                return(new WeightValue(0));
            }

            //if (eqp.EqpID == "THOVN300" && eqp.NowDT >= LcdHelper.StringToDateTime("20200113 090018"))
            //	Console.WriteLine("B");

            bool isLastPlan = eqp.IsLastPlan(lot);

            float maxPriority = ctx.Get <int>(Constants.WF_LOT_PRIORITY, SiteConfigHelper.GetDefaultLotPriority());
            int   lotPriority = lot.Priority;

            float score = 0f;

            int workingCnt = lot.DispatchFilterInfo.WorkingEqpCnt;

            if (isLastPlan == false && workingCnt > 0)
            {
                score = 0f;
            }
            else
            {
                if (maxPriority > 0)
                {
                    score = 1 - (lotPriority / maxPriority);
                }

                //working : score * 2
                if (isLastPlan)
                {
                    score = score * 2;
                }
            }

            string desc = string.Format("[{0}/Max{1}]", lotPriority, maxPriority);

            return(new WeightValue(score * factor.Factor, desc));
        }
Пример #3
0
        public static bool IsLoadable(FabAoEquipment eqp, FabLot lot, bool checkQty = true, bool setCurrEA = true)
        {
            var step    = lot.CurrentFabStep;
            var stdStep = step.StdStep;

            //if (eqp.NowDT >= LcdHelper.StringToDateTime("20190820153409"))
            //{
            //    if (lot.LotID == "LARRAYI0075" && lot.CurrentStepID == "1300")
            //        Console.WriteLine("B");
            //}

            string eqpID      = eqp.EqpID;
            string productID  = lot.CurrentProductID;
            string productVer = lot.CurrentProductVersion;

            var targetEqp = eqp.Target as FabEqp;

            var setInfo = GetEqpArrangeSet(eqpID, targetEqp, stdStep, productID, productVer);

            if (setInfo == null)
            {
                return(false);
            }

            bool isLastPlan = eqp.IsLastPlan(lot);

            List <EqpArrangeInfo> loadableList;
            bool isLoadable = setInfo.IsLoadable(lot, checkQty, isLastPlan, out loadableList);

            if (isLoadable)
            {
                if (setCurrEA)
                {
                    lot.CurrentEqpArrange = new CurrentArrange()
                    {
                        EqpArrrangeSet = setInfo,
                        LoadableList   = loadableList,
                        UsedEqpArrange = null
                    };
                }
            }

            return(isLoadable);
        }
Пример #4
0
        /// <summary>
        /// </summary>
        /// <param name="entity"/>
        /// <param name="now"/>
        /// <param name="target"/>
        /// <param name="factor"/>
        /// <param name="ctx"/>
        /// <returns/>
        public WeightValue REQUIRED_EQP_PRIORITY(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;
            FabAoEquipment eqp = target as FabAoEquipment;

            //if (eqp.EqpID == "THATS400" && (lot.LotID == "TH9C1582N07" || lot.LotID == "TH9C1642N0F"))
            //	Console.WriteLine("B");

            double maxEqpCnt  = ctx.Get(Constants.WF_MAX_REQUIRED_EQP_COUNT, 0d);
            double needEqpCnt = lot.DispatchFilterInfo.NewAssignNeedCount;
            int    workingCnt = lot.DispatchFilterInfo.WorkingEqpCnt;

            float score = 0f;

            if (maxEqpCnt > 0)
            {
                score = (float)(needEqpCnt / maxEqpCnt);
            }

            bool isContinue = eqp.IsLastPlan(lot);

            if (isContinue && needEqpCnt > 0)
            {
                score = 1f;
            }
            else if (needEqpCnt <= 0)
            {
                score = -1f;
            }

            string desc = string.Format("[{0}=REQ:{1}/MAX:{2},WORK:{3}]",
                                        Math.Round(score, 2),
                                        Math.Round(needEqpCnt, 2),
                                        Math.Round(maxEqpCnt, 2),
                                        workingCnt);

            return(new WeightValue(score * factor.Factor, desc));
        }
Пример #5
0
        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);
        }
Пример #6
0
        internal static bool IsLastPlan(this FabAoEquipment eqp, FabLot lot, bool checkProductVersion = true)
        {
            if (lot == null)
            {
                return(false);
            }

            string shopID    = lot.CurrentShopID;
            string stepID    = lot.CurrentStepID;
            string productID = lot.CurrentProductID;

            string productVersion = lot.CurrentProductVersion;
            string ownerType      = lot.OwnerType;
            string ownerID        = lot.OwnerID;

            if (eqp.IsLastPlan(shopID, stepID, productID, productVersion, ownerType, ownerID, checkProductVersion))
            {
                return(true);
            }

            return(false);
        }
Пример #7
0
        /// <summary>
        /// </summary>
        /// <param name="entity"/>
        /// <param name="now"/>
        /// <param name="target"/>
        /// <param name="factor"/>
        /// <param name="ctx"/>
        /// <returns/>
        public WeightValue MIN_MOVEQTY_PRIORITY(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));
            }

            FabAoEquipment eqp  = target as FabAoEquipment;
            var            last = eqp.GetLastPlan();  //eqp.LastPlan;

            float score = 0f;

            if (last == null)
            {
                return(new WeightValue(0, string.Format("[LastPlan NULL, CONT:{0}]", eqp.ContinuousQty)));
            }

            int minMoveQty = (int)factor.Criteria[0];

            if (minMoveQty == 0)
            {
                return(new WeightValue(0, string.Format("[MinMove Not Setting, CONT:{0}]", eqp.ContinuousQty)));
            }

            FabLot lot = entity as FabLot;

            bool isLastPlan = eqp.IsLastPlan(lot);

            if (isLastPlan && eqp.ContinuousQty < minMoveQty)
            {
                score = 1f;
            }

            string desc = string.Format("[MIN:{0}, CONT:{1}, IsLast:{2}]", minMoveQty, eqp.ContinuousQty, isLastPlan);

            return(new WeightValue(score * factor.Factor, desc));
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
0
        private static bool CanMakeDummy(FabAoEquipment eqp, IList <IHandlingBatch> wips, out decimal inflowHours)
        {
            inflowHours = 0;

            var last = eqp.GetLastPlan();             // eqp.LastPlan as FabPlanInfo;

            if (last == null)
            {
                return(false);
            }

            if (IsSomeOneDummyWait(eqp, last))
            {
                return(false);
            }

            WeightFactor wf;

            if (TryGetEqpWeightFactor(eqp, Constants.WF_ALLOW_RUN_DOWN_TIME, out wf) == false)
            {
                return(false);
            }

            inflowHours = (decimal)wf.Criteria[0];
            if (inflowHours <= 0)
            {
                return(false);
            }

            var idleTime = eqp.GetIdleRunTime();

            //AllowRunDown 지나면 기다릴 필요 없음.
            //(IdleRun이 발생시작부터 (jung-임시), Idle 시작부터면 설정된 Inflow 시간 + ProcessTime이됨.
            if (idleTime.TotalHours > Convert.ToDouble(inflowHours))
            {
                return(false);
            }

            //EqpRecipe X Type인 경우는 DummyLot을 만들지 않는다.
            if (eqp.IsEqpRecipeRun)
            {
                return(false);
            }

            //var stdStep = last.FabStep.StdStep;
            //int count = stdStep.GetWorkingEqpCount(last);
            //if (count > 1)
            //    return null;

            //동일한 Spec Lot이 존재하는 경우 대기 X
            if (wips != null && wips.Count > 0)
            {
                var find = wips.FirstOrDefault(t => eqp.IsLastPlan(t.Sample as FabLot));
                if (find != null)
                {
                    return(false);
                }
            }

            //Setup이 필요없는 제품 존재하는 경우 대기 X(2019.12.16 - by.liujian(유건))
            if (wips != null && wips.Count > 0)
            {
                var find = wips.FirstOrDefault(t => ResHelper.IsNeedSetup(eqp, t.Sample as FabLot) == false);
                if (find != null)
                {
                    return(false);
                }
            }

            //CF PHOTO (MAIN/SUB) - remain target

            return(true);
        }