internal static void ModifiyDownScheduleAfterStart(this FabAoEquipment eqp) { var downManager = eqp.DownManager; if (downManager == null) { return; } DateTime now = eqp.NowDT; var startItems = downManager.GetStartScheduleItems(Time.MaxValue); var lastEndTime = Time.MinValue; var ignoreBlock = new List <string>(); foreach (var item in startItems) { var schedule = item.Tag as PeriodSection; var rule = schedule.ScheduleType; if (rule != DownScheduleType.ShiftBackward && rule != DownScheduleType.ShiftBackwardStartTimeOnly && rule != DownScheduleType.Cancel) { continue; } var componentID = string.Empty; var isPM = schedule is PMSchedule; if (isPM) { var pm = schedule as PMSchedule; if (pm.PMType == PMType.Component) { componentID = pm.ComponentID; } } if (!ignoreBlock.Contains(componentID) && eqp.IsBlocked(componentID)) { continue; } var remainEndTime = eqp.GetRemainTimeToEnd(componentID); if (lastEndTime > remainEndTime) { remainEndTime = lastEndTime; } var wait = item.EventTime - now; if (remainEndTime != Time.MaxValue && wait >= Time.Zero && wait < remainEndTime) { var adjStartTime = now.AddSeconds(remainEndTime.TotalSeconds); var adjEndTime = DateTime.MaxValue; var adjSchedule = (PeriodSection)schedule.Clone(); var adjusted = false; switch (rule) { case DownScheduleType.ShiftBackward: adjEndTime = adjStartTime.Add(schedule.Duration); adjSchedule.StartTime = adjStartTime; adjSchedule.EndTime = adjEndTime; downManager.AdjustEvent(item, adjSchedule); adjusted = true; lastEndTime = adjEndTime - now; break; case DownScheduleType.ShiftBackwardStartTimeOnly: var newDownDuration = schedule.EndTime - adjStartTime; downManager.CancelEvent(item); if (newDownDuration > TimeSpan.Zero) { //adjEndTime = now.Add(newDownDuration); adjSchedule.StartTime = adjStartTime; //adjSchedule.EndTime = adjEndTime; downManager.AddEvent(adjSchedule); adjusted = true; lastEndTime = adjSchedule.EndTime - now; } break; case DownScheduleType.Cancel: downManager.CancelEvent(item); break; } if (adjusted && adjSchedule is PMSchedule && eqp.IsParallelChamber) { var pm = adjSchedule as PMSchedule; if (pm.PMType == PMType.Full) { eqp.Loader.Block(); } else { var cproc = eqp.Processes[0] as AoChamberProc2; var block = true; foreach (var c in cproc.Chambers) { if (c.Label == componentID) { if (c.BlockEndTime < now && !ignoreBlock.Contains(componentID)) { ignoreBlock.Add(componentID); } c.BlockEndTime = pm.EndTime; } else if (c.Active) { block = false; } } if (block) { eqp.Loader.Block(); } } } else { eqp.Loader.Block(); } } } }