/// <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; } }
/// <summary> /// </summary> /// <param name="aeqp"/> /// <param name="handled"/> public void ON_EQP_START0(AoEquipment aeqp, ref bool handled) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); var eqpState = eqp.Target.State; if (eqpState == ResourceState.Up) { if (eqp.IsProcessing == false) { eqp.OnStateChanged(LoadingStates.IDLE); } } else if (eqpState == ResourceState.Down) { eqp.OnStateChanged(LoadingStates.DOWN); } }
public static float CheckAheadSetupTime(this FabAoEquipment eqp, float setupTime, FabLot lot) { DateTime now = eqp.NowDT; float addIdleSetupTime = 0f; string stepID = lot.CurrentStepID; string productID = lot.CurrentProductID; if (setupTime > 0 && eqp.AvailableSetupTime < now) { DateTime availableTime = GetAvailableSetupTime(eqp, now); DateTime aheadSetupStart = LcdHelper.Max(availableTime, (now.AddMinutes(-setupTime))); //IDLE에 따른 추가 Setup시간 반영 (AheadSetup에 따라 Idle 시간이 판단됨, 추가 IDLE_SETUP TIME은 Ahead미반영) addIdleSetupTime = SetupMaster.GetAdditionalSetupTime(eqp, stepID, productID, aheadSetupStart); if (addIdleSetupTime > 0) { lot.CurrentFabPlan.IsIdleSetup = true; } if (aheadSetupStart < now) { setupTime = setupTime - (float)(now - aheadSetupStart).TotalMinutes; eqp.AvailableSetupTime = aheadSetupStart; if (setupTime == 0 && addIdleSetupTime == 0) { eqp.OnStateChanged(LoadingStates.SETUP, lot); } } else { eqp.AvailableSetupTime = DateTime.MaxValue; } return(setupTime + addIdleSetupTime); } //AheadSetup이 아닐 경우(또는 Setup시간이 0 이지만 추가 Setup이 있을 경우 Setup을 함) //기존: Setup이 필요하지만 Setup시간이 0이면 Setup을 하지 않음 //변경 : Setup이 필요하지만 Setup시간이 0 이어도 추가 Setup 정보가 있을 경우 Setup을 함. addIdleSetupTime = SetupMaster.GetAdditionalSetupTime(eqp, stepID, productID, now); if (addIdleSetupTime > 0) { lot.CurrentFabPlan.IsIdleSetup = true; } setupTime += addIdleSetupTime; return(setupTime); }
/// <summary> /// </summary> /// <param name="aeqp"/> /// <param name="fs"/> /// <param name="det"/> /// <param name="handled"/> public void ON_FAILURE_EVENT1(Mozart.SeePlan.Simulation.AoEquipment aeqp, Mozart.SeePlan.DataModel.FailureSchedule fs, Mozart.SeePlan.Simulation.DownEventType det, ref bool handled) { FabAoEquipment eqp = aeqp.ToFabAoEquipment(); if (det == DownEventType.End) { aeqp.Loader.Unblock(); aeqp.WriteHistoryAfterBreak(); } else { ResHelper.SetLastLoadingInfo(aeqp, null); aeqp.WriteHistory(LoadingStates.DOWN); aeqp.Loader.Block(); //eqp.AddLoadPlan(LoadStates.DOWN, aeqp.NowDT); eqp.OnStateChanged(LoadingStates.DOWN); } }