public WeightValue ALLOW_RUN_DOWN_TIME(ISimEntity entity, DateTime now, ActiveObject target, WeightFactor factor, IDispatchContext ctx) { FabAoEquipment eqp = target as FabAoEquipment; FabLot lot = entity as FabLot; var wf = WeightHelper.GetWeightFactor(eqp.Target.Preset, Constants.WF_ALLOW_RUN_DOWN_TIME); if (wf == null || wf.Factor == 0) { return(new WeightValue(0)); } decimal inflowHour = (decimal)wf.Criteria[0]; var idleTime = eqp.GetIdleRunTime(); decimal adjustHour = inflowHour - Convert.ToDecimal(idleTime.TotalHours); if (adjustHour < 0) { return(new WeightValue(0)); } var inflowQty = InFlowMaster.GetAllowRunDownWip(eqp, lot.CurrentProductID, lot.OrigProductVersion, lot.OwnerType, lot.CurrentStep as FabStep, adjustHour); float score = 0f; if (inflowQty > 0) { score = 1f; } string desc = string.Format("[inflow:{0}]", inflowQty); return(new WeightValue(score * factor.Factor, desc)); }
/// <summary> /// </summary> /// <param name="hb"/> /// <param name="ao"/> /// <param name="now"/> /// <param name="handled"/> public void ON_START_TASK0(Mozart.SeePlan.Simulation.IHandlingBatch hb, Mozart.Simulation.Engine.ActiveObject ao, DateTime now, ref bool handled) { FabLot lot = hb.ToFabLot(); hb.Apply((x, y) => LoadHelper.OnStartTask(x as FabLot)); InFlowMaster.ChangeWipLocation(hb, EventType.TrackIn); if (ao is AoEquipment) { FabAoEquipment eqp = ao as FabAoEquipment; MaskMaster.StartTask(lot, eqp); JigMaster.StartTask(lot, eqp); //TODO : 설비의 Property로 작성필요 (LastPlan의 Plan을 보고) if (lot.CurrentFabPlan.CurrentRecipeTime != null) { eqp.IsEqpRecipeRun = true; } else { eqp.IsEqpRecipeRun = false; } } OutCollector.Write_Rtd_LotUpkTracking(lot); }
/// <summary> /// </summary> /// <param name="aoFactory"/> /// <param name="handled"/> public void ON_DONE0(Mozart.SeePlan.Simulation.AoFactory aoFactory, ref bool handled) { MaskMaster.OnDone(aoFactory); OutCollector.OnDone(aoFactory); InFlowMaster.Reset(); }
//public Step GET_NEXT_STEP1(Mozart.SeePlan.Simulation.ILot lot, Mozart.SeePlan.DataModel.LoadInfo loadInfo, Mozart.SeePlan.DataModel.Step step, DateTime now, ref bool handled, Mozart.SeePlan.DataModel.Step prevReturnValue) //{ // FabPlanInfo plan = loadInfo as FabPlanInfo; // FabProduct prod = plan.Product; // FabLot mlot = lot as FabLot; // #region PartChange // if (prod.HasNextInterBom) // { // FabInterBom bom; // prod.TryGetNextInterRoute(step as FabStep, out bom); // if (bom != null) // { // plan.InterBom = bom; // mlot.Product = bom.ChangeProduct; // } // } // #endregion // if (plan.InterBom != null) // return plan.InterBom.ChangeStep; // return step.GetDefaultNextStep(); //} /// <summary> /// </summary> /// <param name="hb"/> /// <param name="handled"/> public void ON_DONE0(Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled) { FabLot lot = hb.ToFabLot(); InFlowMaster.OnDoneWipLocation(hb); if (SimHelper.IsTftRunning) { InOutProfileMaster.AddOut(lot, AoFactory.Current.NowDT); } }
/// <summary> /// </summary> /// <param name="da"/> /// <param name="hb"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public bool IS_HOLD0(DispatchingAgent da, IHandlingBatch hb, ref bool handled, bool prevReturnValue) { FabLot lot = hb.ToFabLot(); //FabWipInfo wip = lot.Wip; //FabPlanInfo plan = lot.CurrentFabPlan; if (lot.IsInitHold) { InFlowMaster.ChangeWipLocation(hb, EventType.StartTOWait); return(true); } return(false); }
/// <summary> /// Batch Input으로 처음들어오는 곳 /// </summary> /// <param name="factory"/> /// <param name="hb"/> /// <param name="handled"/> public void ON_RELEASE0(AoFactory factory, IHandlingBatch hb, ref bool handled) { hb.MoveFirst(factory.NowDT); FabLot lot = hb.ToFabLot(); if (lot.ReleasePlan != null) { lot.ReleasePlan.IsRelease = true; } InFlowMaster.ChangeWipLocation(hb, EventType.Release); OutCollector.CollectInputLot(lot); OutCollector.WriteInputLotLog(lot, factory.NowDT); }
/// <summary> /// </summary> /// <param name="factory"/> /// <param name="hb"/> /// <param name="handled"/> public void LOCATE_FOR_DISPATCH1(Mozart.SeePlan.Simulation.AoFactory factory, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled) { FabLot lot = hb.ToFabLot(); if (CheckSimulationRunType(lot) == false) { return; } if (hb.IsFinished) { factory.Router.AddInitial((Entity)hb, hb.IsFinished); } else { //InPortWip 처리 if (InitInPortWip(factory, hb)) { return; } var router = EntityControl.Instance; string dispatchKey = router.GetLotDispatchingKey(hb); DispatchingAgent da = factory.GetDispatchingAgent(dispatchKey); if (da == null) { if (factory.DispatchingAgents.Count > 0) { ModelContext.Current.ErrorLister.Write("Entity/WipInit/LocateForDispatch", Mozart.DataActions.ErrorType.Warning, Strings.CAT_SIM_SECONDRESOURCE, string.Format(Strings.WARN_INVALID_IMPLEMENTATION, "Entity/WipInit/LocateForDispatch")); da = factory.DispatchingAgents.FirstOrDefault().Value; } else { throw new InvalidOperationException(Strings.EXCEPTION_NO_REGISTERED_DISPATCHINGAGENT); } } InFlowMaster.ChangeWipLocation(hb, EventType.StartTOWait); da.Take(hb); } }
/// <summary> /// </summary> /// <param name="hb"/> /// <param name="now"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public IHandlingBatch[] STEP_CHANGE0(Mozart.SeePlan.Simulation.IHandlingBatch hb, DateTime now, ref bool handled, Mozart.SeePlan.Simulation.IHandlingBatch[] prevReturnValue) { FabLot lot = hb.ToFabLot(); FabPlanInfo plan = lot.CurrentFabPlan; /* * StepChange */ ILot[] lots = hb.StepChange(now); //설비의 OutPort에서 Lot을 모으는 InterceptMove를 사용할 경우 해당 위치에서 별도 집계 필요함. InFlowMaster.ChangeWipLocation(hb, EventType.TrackOut); //FabPlanInfo prev = lot.PreviousFabPlan; ////InLineMap 다음StepSkip //if (prev.IsLoaded && prev.FabStep.StdStep.IsBaseEqp(prev.ResID)) //{ // plan = lot.CurrentFabPlan; // plan.TransferStartTime = now; // plan.TransferEndTime = now; // plan.EqpInEndTime = now; // plan.EqpInStartTime = now; // plan.Start(now, null); // plan.End(now, null); // lots = hb.StepChange(now); //} QTimeMaster.StepChange(lots, now); return(lots); }
private bool InitInPortWip(AoFactory factory, IHandlingBatch hb) { FabLot lot = hb.ToFabLot(); //if (lot.LotID == "TH961377N00") // Console.WriteLine(); if (lot.IsInPortWip == false) { return(false); } var wipInitiator = ServiceLocator.Resolve <WipInitiator>(); string eqpID = wipInitiator.GetLoadingEquipment(hb); AoEquipment eqp; if (string.IsNullOrEmpty(eqpID) || factory.Equipments.TryGetValue(eqpID, out eqp) == false) { Logger.Warn("Can't Locate InportWip to Eqp {0}, check input data!", eqpID ?? "-"); #region Write ErrorHistory ErrHist.WriteIf(string.Format("LocateInportWip{0}", lot.LotID), ErrCategory.SIMULATION, ErrLevel.INFO, lot.CurrentFactoryID, lot.CurrentShopID, lot.LotID, lot.CurrentProductID, lot.CurrentProductVersion ?? lot.Wip.ProductVersion, lot.CurrentProcessID, eqpID, lot.CurrentStepID, "NOT FOUND EQP", "Can't Locate InportWip"); #endregion return(false); } else { FabAoEquipment feqp = eqp.ToFabAoEquipment(); //Inport Wip (M잔여 수량 체크 X) if (EqpArrangeMaster.IsLoadable(feqp, lot, false) == false) { #region Write ErrorHistory ErrHist.WriteIf(string.Format("LocateInportWip{0}", lot.LotID), ErrCategory.SIMULATION, ErrLevel.INFO, lot.CurrentFactoryID, lot.CurrentShopID, lot.LotID, lot.CurrentProductID, lot.CurrentProductVersion ?? lot.Wip.ProductVersion, lot.CurrentProcessID, eqpID, lot.CurrentStepID, "NOT FOUND EQP_ARRANGE", "Can't Locate InportWip"); #endregion return(false); } if (feqp.InitInPortWips == null) { feqp.InitInPortWips = new List <IHandlingBatch>(); } feqp.InitInPortWips.Add(hb); InFlowMaster.ChangeWipLocation(hb, EventType.StartTOWait); return(true); } }
/// <summary> /// </summary> /// <param name="factory"/> /// <param name="hb"/> /// <param name="handled"/> public void LOCATE_FOR_RUN0(Mozart.SeePlan.Simulation.AoFactory factory, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled) { var wipInitiator = ServiceLocator.Resolve <WipInitiator>(); FabLot lot = hb.Sample as FabLot; string eqpID = wipInitiator.GetLoadingEquipment(hb); AoEquipment aeqp = factory.GetEquipment(eqpID); if (aeqp == null) { //If there is not Equipment, handle through Bucketing. factory.AddToBucketer(hb); Logger.Warn("Eqp {0} is invalid, so locate running wip to dummy bucket. check input data!", eqpID ?? "-"); } else { //// Checks WIP state that is Run, but processing is completed and located in Outport. //bool trackOut = wipInitiator.CheckTrackOut(factory, hb); //if (trackOut) //{ // aeqp.AddOutBuffer(hb); //} //else //{ // aeqp.AddRun(hb); //} var eqp = aeqp.Target as FabEqp; var runWips = eqp.InitRunWips; bool lastRunWip = runWips[runWips.Count - 1] == lot; if (eqp.State == ResourceState.Up && lastRunWip) { MaskMaster.InitLocate(aeqp, hb); JigMaster.InitLocate(aeqp, hb); aeqp.AddRun(hb); //※초기Run재공은 OnTrackIn 이벤트 발생안함. } else { DateTime tkInTime = lot.Wip.LastTrackInTime; var procTimeInfo = aeqp.GetProcessTime(hb); double processTime = procTimeInfo.FlowTime.TotalSeconds + (procTimeInfo.TactTime.TotalSeconds * (hb.UnitQty - 1)); DateTime tkOutTime = tkInTime.AddSeconds(processTime); Time delay = Time.Max((tkOutTime - aeqp.NowDT), Time.Zero); if (delay > Time.Zero) { object[] args = new object[2] { aeqp, hb }; aeqp.AddTimeout(delay, SimHelper.OnEqpOutBuffer, args); InFlowMaster.ChangeWipLocation(hb, EventType.TrackIn); lot.CurrentPlan.LoadedResource = eqp; } else { aeqp.AddOutBuffer(hb); } } } }
/// <summary> /// </summary> /// <param name="entity"/> /// <param name="now"/> /// <param name="target"/> /// <param name="factor"/> /// <param name="ctx"/> /// <returns/> public WeightValue NEXT_STEP_CONTINUOUS_PRODUCTION_PRIORITY(Mozart.Simulation.Engine.ISimEntity entity, DateTime now, Mozart.Simulation.Engine.ActiveObject target, Mozart.SeePlan.DataModel.WeightFactor factor, Mozart.SeePlan.Simulation.IDispatchContext ctx) { FabAoEquipment eqp = target as FabAoEquipment; WeightFactor wf; WeightHelper.TryGetEqpWeightFactor(eqp, Constants.WF_NEXT_STEP_CONTINUOUS_PRODUCTION_PRIORITY, out wf); FabLot lot = entity as FabLot; string desc = string.Empty; float score = 0; int checkStepCount = (int)wf.Criteria[0]; int minLimitQty = (int)wf.Criteria[1]; int maxLimitQty = (int)wf.Criteria[2]; var currentStep = lot.CurrentFabStep; var currentProd = lot.FabProduct; FabStep nextPhotoStep = currentStep.GetNextPhotoNearByMe(currentProd, checkStepCount, out int idx); if (nextPhotoStep == null) { score = 0f; } else { var job = InFlowMaster.GetJobState(lot); if (job == null) { return(new WeightValue(0)); } int nextPhlWipQty = job.GetStepWips(nextPhotoStep, WipType.Total); if (nextPhlWipQty <= maxLimitQty && nextPhlWipQty > minLimitQty) { bool checkProductVersion = false; var workingEqps = currentStep.StdStep.GetWorkingEqpList(lot, checkProductVersion); int workingCnt = workingEqps == null ? 0 : workingEqps.Count; Decimal curStepTactTime = TimeHelper.GetAvgTactTimeForEqps(currentStep, currentProd, workingEqps); var targetWorkingEqps = nextPhotoStep.StdStep.GetWorkingEqpList(lot, checkProductVersion); int targetWorkingCnt = targetWorkingEqps == null ? 0 : targetWorkingEqps.Count; Decimal nextPhotoStepTactTime = TimeHelper.GetAvgTactTimeForEqps(nextPhotoStep, currentProd, targetWorkingEqps); if ((workingCnt / curStepTactTime) < (targetWorkingCnt / nextPhotoStepTactTime)) { score = 1f; } desc = string.Format("[Working:{0}, Next_Photo:{1}]", workingCnt, targetWorkingCnt); } else if (nextPhlWipQty <= minLimitQty) { float s = idx; float m = checkStepCount; float r = m == 0 ? 0 : (float)Math.Round(s / m, 3); score = 1 - r; int adv = 2; score *= adv; desc = string.Format("[NextPhotoStepWipQty:{0}, Adv:{1}]", nextPhlWipQty, adv); } } return(new WeightValue(score * wf.Factor, desc)); }
/// <summary> /// </summary> /// <param name="entity"/> /// <param name="now"/> /// <param name="target"/> /// <param name="factor"/> /// <param name="ctx"/> /// <returns/> public WeightValue SMALL_BATCH_MERGE_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)); } int baseQty = (int)factor.Criteria[0]; int checkStepCount = (int)factor.Criteria[1]; FabAoEquipment eqp = target as FabAoEquipment; FabLot lot = entity as FabLot; //if (eqp.IsLastPlan(lot.CurrentShopID, lot.CurrentStepID, lot.CurrentProductID, Constants.NULL_ID, lot.OwnerType, lot.OwnerID)) // return new WeightValue(1 * factor.Factor, string.Format("[IsLast:Y]")); FabStep currentStep = lot.CurrentFabStep; var currentProd = lot.FabProduct; FabStep prevStep = currentStep.GetPrevMainStep(lot.FabProduct, true); StepTat tat = null; if (prevStep != null) { tat = prevStep.GetTat(lot.CurrentProductID, true); } if (tat == null) { tat = currentStep.GetDefaultTAT(); } var job = InFlowMaster.GetJobState(lot); if (job == null) { return(new WeightValue(0)); } int waitQty = job.GetCurrenStepWaitWipQty(eqp, currentStep, Constants.NULL_ID, (decimal)TimeSpan.FromMinutes(tat.RunTat).TotalHours); if (waitQty > baseQty) { return(new WeightValue(0, string.Format("[Wait:{0}>{1}:Base]", waitQty, baseQty))); } int prevWipQty = job.GetPrevStepRunWipQty(eqp, currentStep, Constants.NULL_ID, now.AddMinutes(tat.TAT)); if (prevWipQty > 0) { return(new WeightValue(0, string.Format("[PrevRunWip:{0}>0", prevWipQty))); } int nextWipQty = 0; var nextStepList = currentStep.GetNextStepList(currentProd, checkStepCount); foreach (FabStep next in nextStepList) { nextWipQty += job.GetStepWips(next, WipType.Total); } int runQty = job.GetStepWips(currentStep, WipType.Run); if (runQty + nextWipQty == 0) { return(new WeightValue(0, string.Format("[Run:{0} + NextQty:{1} = 0]", runQty, nextWipQty))); } return(new WeightValue(1 * factor.Factor, string.Format("[Run:{0} + NextQty:{1}>0]", runQty, nextWipQty))); }
public WeightValue SMALL_LOT(ISimEntity entity, DateTime now, ActiveObject target, WeightFactor factor, IDispatchContext ctx) { if (factor.Factor == 0) { return(new WeightValue(0)); } FabAoEquipment eqp = target as FabAoEquipment; FabLot lot = entity as FabLot; int smallSize = (int)factor.Criteria[0]; if (smallSize == 0) { return(new WeightValue(0)); } int stepCount = (int)factor.Criteria[1]; if (stepCount == 0) { return(new WeightValue(0)); } var job = InFlowMaster.GetJobState(lot); if (job == null) { return(new WeightValue(0)); } int currentUnitQty = lot.UnitQty; string shopID = lot.CurrentShopID; string productID = lot.CurrentProductID; string productVer = lot.CurrentProductVersion; bool isLastPlan = ResHelper.IsLastPlan(eqp, lot); float score = 0f; if (isLastPlan) { score = 1f; } FabStep step = lot.CurrentFabStep; string stepType = step.StepType; int cnt = 0; int runQty = 0; int waitQty = 0; int total = 0; while (cnt < stepCount) { List <FabStep> preSteps = step.GetPrevSteps(productID); List <FabLot> runWips = job.GetPrevStepWipList(step, WipType.Run, productVer); List <FabLot> waitWips = job.GetPrevStepWipList(step, WipType.Wait, productVer); if (runWips.Count <= 0 && waitWips.Count <= 0) { cnt++; continue; } int prevRunQty = runWips.Sum(x => x.UnitQty); int preWaitQty = waitWips.Sum(x => x.UnitQty); runQty += prevRunQty; waitQty += preWaitQty; total += runQty + waitQty; foreach (FabStep prevStep in preSteps) { if (prevStep.StepType == "MAIN") { step = prevStep; } if (step == null) { continue; } } cnt++; } int compareQty = currentUnitQty + total; string desc = string.Format("[SmallSize:{0}, CompareQty:{1}, IsLast:{2}]", smallSize, compareQty, isLastPlan); if (compareQty > smallSize) { score = 1f; } return(new WeightValue(score * factor.Factor, desc)); }