/// <summary> /// </summary> /// <param name="cproc"/> /// <param name="hb"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public string[] GET_LOADABLE_CHAMBERS1(Mozart.SeePlan.Simulation.AoChamberProc2 cproc, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled, string[] prevReturnValue) { var eqp = cproc.Parent as FabAoEquipment; var lot = hb.ToFabLot(); //if (eqp.EqpID == "THCVD300" && lot != null && lot.LotID == "TH011661N0H") // Console.WriteLine("B"); var info = eqp.EqpDispatchInfo; //var loadableList = eqp.GetLoadableSubEqps(lot, false); var loadableList = eqp.GetLoadableSubEqps(lot); int count = loadableList == null ? 0 : loadableList.Count; string[] arr = new string[count]; //loadable sub eqp별 EqpDispatchInfo 설정 if (loadableList != null) { for (int i = 0; i < count; i++) { var subEqp = loadableList[i]; arr[i] = subEqp.SubEqpID; subEqp.EqpDispatchInfo = info; } } eqp.EndDispatch_ParallelChamber(); return(arr); }
/// <summary> /// </summary> /// <param name="aeqp"/> /// <param name="hb"/> /// <param name="state">SETUP/BUSY/IDLERUN/IDLE/WAIT_SETUP(PM/DOUWN 호출 안됨)</param> /// <param name="handled"/> public void LOADING_STATE_CHANGED0(Mozart.SeePlan.Simulation.AoEquipment aeqp, Mozart.SeePlan.Simulation.IHandlingBatch hb, Mozart.SeePlan.Simulation.LoadingStates state, ref bool handled) { var eqp = aeqp.ToFabAoEquipment(); var now = eqp.NowDT; if (eqp.IsParallelChamber) { return; } if (ModelContext.Current.EndTime == now) { return; } //PM/Down 이벤트 예외사항 처리 if (SimHelper.IgnoreStateChange(eqp, state)) { return; } var lot = hb.ToFabLot(); if (state == LoadingStates.SETUP || state == LoadingStates.BUSY) { SetCurrentMask(eqp, lot); } eqp.OnStateChanged(state, lot); }
/// <summary> /// </summary> /// <param name="hb"/> /// <param name="handled"/> public void ON_TRANSFERED0(Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled) { FabLot lot = hb.ToFabLot(); FabPlanInfo plan = lot.CurrentFabPlan; plan.TransferEndTime = AoFactory.Current.NowDT; }
/// <summary> /// </summary> /// <param name="da"/> /// <param name="hb"/> /// <param name="destCount"/> /// <param name="handled"/> public void ON_NOT_FOUND_DESTINATION0(Mozart.SeePlan.Simulation.DispatchingAgent da, Mozart.SeePlan.Simulation.IHandlingBatch hb, int destCount, ref bool handled) { FabLot lot = hb.ToFabLot(); //TODO: if (lot.CurrentFabStep.StdStep.IsMandatory) { ErrHist.WriteIf(string.Format("{0}/{1}/{2}", "NotFoundArrange", lot.CurrentFabStep.StepID, lot.CurrentProductID), ErrCategory.SIMULATION, ErrLevel.INFO, lot.CurrentFactoryID, lot.CurrentShopID, lot.LotID, lot.CurrentProductID, lot.CurrentProductVersion ?? lot.Wip.ProductVersion, lot.CurrentProcessID, Constants.NULL_ID, lot.CurrentStepID, "ON NOT FOUND DESTINATION0", string.Format("Check Arrange → LOT_ID:{0}", lot.ToString()) ); return; } da.Factory.AddToBucketer(hb); }
/// <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="aeqp"/> /// <param name="hb"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public DateTime FIX_START_TIME0(Mozart.SeePlan.Simulation.AoEquipment aeqp, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled, DateTime prevReturnValue) { FabLot lot = hb.ToFabLot(); var now = aeqp.NowDT; var trackInTime = lot.Wip.LastTrackInTime; //한개의 RunWip만 설비에 투입가능하도록 처리(LOCATE_FOR_RUN0)하여 조정 필요없음. ////RunWip 수량을 고려하여 마지막 RunWip의 TrackInTime을 기준으로 이전 RunWip의 TrackInTime 조정 //var runList = (aeqp.Target as FabEqp).InitRunWips; //if(runList != null) //{ // //해당 Lot 삭제 // if (runList.Remove(lot) == false) // Logger.MonitorInfo("[WARNING] mismatch run wip : LOT_ID={0}", lot.LotID); // int count = runList.Count; // if (runList != null && count > 0) // { // var prevlot = runList[count - 1]; // DateTime outTime = prevlot.Wip.LastTrackInTime; // for (int i = count - 2; i >= 0; i--) // { // var currLot = runList[i]; // if (currLot.UnitQty <= 0) // continue; // FabStep wipStep = currLot.Wip.InitialStep as FabStep; // float currTactTime = wipStep.GetTactTime(eqpID, currLot.CurrentProductID); // DateTime availableTime = outTime.AddSeconds(-(currTactTime * currLot.UnitQty)); // DateTime tkTime = currLot.Wip.LastTrackInTime; // outTime = LcdHelper.Min(tkTime, availableTime); // } // float tactTime = lot.CurrentFabStep.GetTactTime(eqpID, lot.CurrentProductID); // outTime = outTime.AddSeconds(-(tactTime * lot.UnitQty)); // trackInTime = LcdHelper.Min(outTime, trackInTime); // } //} //TODO : WriteErrorHist if (trackInTime == DateTime.MinValue || trackInTime == DateTime.MaxValue) { trackInTime = aeqp.NowDT; } else if (trackInTime > now) { trackInTime = now; } return(trackInTime); }
/// <summary> /// </summary> /// <param name="aeqp"/> /// <param name="loadableChambers"/> /// <param name="hb"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public ISet <string> GET_NEED_SETUP_CHAMBERS0(Mozart.SeePlan.Simulation.AoEquipment aeqp, Mozart.SeePlan.Simulation.ChamberInfo[] loadableChambers, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled, ISet <string> prevReturnValue) { FabLot lot = hb.ToFabLot(); FabEqp eqp = aeqp.Target as FabEqp; List <FabSubEqp> list = ChamberMaster.GetSubEqps(eqp, loadableChambers); return(ChamberMaster.GetNeedSetupChamberIDs(list, lot)); }
//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="hb"/> /// <param name="ao"/> /// <param name="now"/> /// <param name="handled"/> public void ON_END_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.OnEndTask(x as FabLot)); if (ao is AoEquipment) { FabAoEquipment aeqp = ao as FabAoEquipment; MaskMaster.EndTask(lot, aeqp); JigMaster.EndTask(lot, aeqp); } }
/// <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="aeqp"/> /// <param name="hb"/> /// <param name="state">WaitSetup/StartSetup/EndSetup/FirstLoading/LastLoading/FirstUnloading/LastUnloading</param> /// <param name="handled"/> public void PROCESS_STATE_CHANGED0(Mozart.SeePlan.Simulation.AoEquipment aeqp, Mozart.SeePlan.Simulation.IHandlingBatch hb, Mozart.SeePlan.Simulation.ProcessStates state, ref bool handled) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); FabLot lot = hb.ToFabLot(); var now = aeqp.NowDT; if (eqp.EqpID == "THCVD300") { Console.WriteLine(); } //Setup이 있을 경우 FirstLoading이 없음. if (state == ProcessStates.FirstLoading) { DispatchLogHelper.WriteDispatchLog_ParallelChamber(eqp, lot); eqp.LastLoadingTime = now; //if (eqp.LastLoadingTime >= eqp.LastIdleStartTime) // eqp.LastIdleStartTime = DateTime.MinValue; //eqp.LastIdleRunStartTime = DateTime.MinValue; eqp.LoadCount++; } //else if (state == ProcessStates.LastLoading) //{ // eqp.LastIdleRunStartTime = now; //} //else if (state == ProcessStates.LastUnloading) //{ // eqp.LastIdleStartTime = now; //} else if (state == ProcessStates.StartSetup) { DispatchLogHelper.WriteDispatchLog_ParallelChamber(eqp, lot); } else if (state == ProcessStates.EndSetup) { eqp.LoadCount = 1; eqp.SetupCount++; //eqp.LastIdleStartTime = DateTime.MinValue; //eqp.LastIdleRunStartTime = DateTime.MinValue; } }
/// <summary> /// </summary> /// <param name="da"/> /// <param name="hb"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public Time GET_HOLD_TIME0(Mozart.SeePlan.Simulation.DispatchingAgent da, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled, Mozart.Simulation.Engine.Time prevReturnValue) { Time t = Time.Zero; FabLot lot = hb.ToFabLot(); FabWipInfo wip = lot.Wip; //FabPlanInfo plan = lot.CurrentFabPlan; if (lot.IsInitHold) { t = wip.AvailableTime - da.NowDT; lot.HoldStartTime = da.NowDT; lot.HoldTime = t; lot.IsInitHold = false; // Hold → ExitHold → IsHold 이므로 false로 설정해야됨. 바꿔주지 않을 경우 계속 Hold됨. } return(t); }
/// <summary> /// </summary> /// <param name="da"/> /// <param name="hb"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public bool IS_BUCKET_PROCESSING0(Mozart.SeePlan.Simulation.DispatchingAgent da, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled, bool prevReturnValue) { FabLot lot = hb.ToFabLot(); if (lot.LotID == "TH930454N01") { Console.WriteLine(); } FabStep step = hb.CurrentStep as FabStep; if (step.IsMandatoryStep == false) { return(true); } //if(step.StdStep != null && step.StdStep.) // return true; return(false); }
/// <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); }
/// <summary> /// </summary> /// <param name="factory"/> /// <param name="hb"/> /// <param name="handled"/> /// <param name="prevReturnValue"/> /// <returns/> public bool LOCATE_FOR_OTHERS0(Mozart.SeePlan.Simulation.AoFactory factory, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled, bool prevReturnValue) { FabLot lot = hb.ToFabLot(); if (lot.LotID == "TH9A1308N3B") { Console.WriteLine(); } if (lot.IsHold || lot.IsMove) { var router = EntityControl.Instance; string dispatchKey = router.GetLotDispatchingKey(hb); DispatchingAgent da = factory.GetDispatchingAgent(dispatchKey); lot.IsInitHold = true; da.Take(hb); return(true); } return(false); }
/// <summary> /// </summary> /// <param name="dispatchingAgent"/> /// <param name="hb"/> /// <param name="handled"/> public void ON_HOLD_EXIT0(Mozart.SeePlan.Simulation.DispatchingAgent dispatchingAgent, Mozart.SeePlan.Simulation.IHandlingBatch hb, ref bool handled) { FabLot lot = hb.ToFabLot(); lot.HoldTime = 0; }