/// <summary> /// </summary> /// <param name="aeqp"/> /// <param name="fs"/> /// <param name="det"/> /// <param name="handled"/> public void ON_PMEVENT3(Mozart.SeePlan.Simulation.AoEquipment aeqp, Mozart.SeePlan.DataModel.PMSchedule fs, Mozart.SeePlan.Simulation.DownEventType det, ref bool handled) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); if (eqp.SetParallelChamberPM(fs, det)) { if (det == DownEventType.Start) { eqp.OnStateChanged(LoadingStates.PM); } return; } if (det == DownEventType.Start) { ResHelper.SetLastLoadingInfo(aeqp, null); aeqp.Loader.Block(); aeqp.WriteHistory(LoadingStates.PM); FabPMSchedule pm = fs as FabPMSchedule; DownMaster.AdjustAheadPMProcessing(eqp, pm); //PM의 경우 OnStateChange 함수를 별도로 호출 필요함. LoadingStates state = GetPMLoadingState(pm.Type); eqp.OnStateChanged(state); FabLoadInfo loadInfo = eqp.LoadInfos.Last(); if (loadInfo.State == LoadingStates.PM) { if (pm.Type == ScheduleType.RENT) { loadInfo.StateInfo = "RENT"; } if (loadInfo.StateInfo != "AHEAD" && LcdHelper.IsEmptyID(pm.Description) == false) { loadInfo.StateInfo = pm.Description; } } } else { aeqp.Loader.Unblock(); aeqp.WriteHistoryAfterBreak(); aeqp.SetModified(); eqp.OnStateChanged(LoadingStates.IDLE); eqp.AvailablePMTime = DateTime.MaxValue; } }
public IHandlingBatch[] SELECT1(DispatcherBase db, AoEquipment aeqp, IList <IHandlingBatch> wips, ref bool handled, IHandlingBatch[] prevReturnValue) { if (InputMart.Instance.GlobalParameters.ApplyFlexialePMSchedule == false) { return(prevReturnValue); } if (prevReturnValue == null) { return(prevReturnValue); } var list = aeqp.DownManager.GetStartScheduleItems(Time.MaxValue); if (list == null || list.Count == 0) { return(prevReturnValue); } FabLot lot = prevReturnValue[0] as FabLot; var eqp = aeqp.ToFabAoEquipment(); var proc = eqp.Processes[0]; var outTime = proc.GetUnloadingTime(lot); bool isLast = eqp.IsLastPlan(lot); bool isNeedSetup = ResHelper.IsNeedSetup(eqp, lot); foreach (var item in list) { var schedule = item.Tag as PeriodSection; var isPM = schedule is PMSchedule; if (isPM == false) { continue; } var pm = schedule as FabPMSchedule; var reaminNextPMStart = pm.StartTime - eqp.NowDT; //하루 이내만 조정 if (reaminNextPMStart.TotalDays > 1) { continue; } bool isAdjust = false; FabPMSchedule adjust = pm.Clone() as FabPMSchedule; if (isLast) { if ((DateTime)outTime < pm.LimitDelayTime && outTime > pm.StartTime) { adjust.StartTime = (DateTime)outTime; adjust.EndTime = adjust.StartTime.AddMinutes(pm.InputDuration.TotalMinutes); adjust.Description = "DELAY"; adjust.AllowAheadTime = (float)(outTime - eqp.Now).TotalMinutes; adjust.ScheduleType = DownScheduleType.ShiftBackward; aeqp.DownManager.AdjustEvent(item, adjust); isAdjust = true; } } else { if (reaminNextPMStart.TotalMinutes < pm.AllowAheadTime) { prevReturnValue = null; adjust.StartTime = aeqp.NowDT; adjust.EndTime = adjust.StartTime.AddMinutes(pm.InputDuration.TotalMinutes); if (adjust.Description != "DELAY") { adjust.Description = "AHEAD"; } adjust.IsNeedAdjust = false; aeqp.DownManager.AdjustEvent(item, adjust); isAdjust = true; } } if (isAdjust == false && pm.StartTime < outTime) { float setupTime = 0f; if (isNeedSetup) { setupTime = SetupMaster.GetSetupTime(aeqp, lot); } adjust.StartTime = (DateTime)(outTime + Time.FromMinutes(setupTime)); adjust.EndTime = adjust.StartTime.AddMinutes(pm.InputDuration.TotalMinutes); aeqp.DownManager.AdjustEvent(item, adjust); } } //var data = aeqp.DownManager.GetStartScheduleItems(Time.MaxValue); return(prevReturnValue); }