using System; using System.Collections.Generic; using System.Diagnostics; using Aitex.Core.RT.Event; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; namespace Aitex.Core.RT.Routine { public class ModuleRoutine : SeqenecRoutine { #region Variables public delegate RoutineState RoutineFunc(T arg); /// /// 用于统计Routine耗时的计时器。 /// protected readonly Stopwatch SwStatisticElapse; protected string _stepName; protected TimeSpan _stepSpan = new TimeSpan(0, 0, 0, 0); protected DateTime _stepStartTime; private static object locker = new object(); #endregion #region Constuctors public ModuleRoutine(string module) { Module = module; SwStatisticElapse = new Stopwatch(); } #endregion #region Properties /// /// 返回当前Routine所述的模组 /// public string Module { get; protected set; } /// /// 返回当前Routine的名称 /// public string Name { get; protected set; } public string StepName => _stepName; public TimeSpan StepLeftTime { get { if (_stepSpan.TotalMilliseconds < 1.0) { return _stepSpan; } return _stepSpan - (DateTime.Now - _stepStartTime); } } #endregion #region Methods public virtual Result Monitor() { try { MonitorBody(); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } SwStatisticElapse.Stop(); Notify($"Finished ! Elapsed time: {(int)(SwStatisticElapse.ElapsedMilliseconds / 1000)} s"); return Result.DONE; } public virtual Result Start(params object[] args) { Reset(); SwStatisticElapse.Restart(); return StartBody(args); } public virtual void Abort() { } protected virtual Result StartBody(params object[] args) { return Result.RUN; } protected virtual void MonitorBody() { } protected void Notify(string message) { EV.PostInfoLog(Module, Name + ", " + message); } protected void Stop(string failReason) { EV.PostAlarmLog(Module, Name + " failed, " + failReason); } public void Abort(string failReason) { EV.PostAlarmLog(Module, Name + " " + failReason); } public void TimeDelay(int id, string stepName, double time) { Tuple tuple = Delay(id, delegate { Notify($"Delay {time} seconds"); _stepSpan = new TimeSpan(0, 0, 0, (int)time); _stepStartTime = DateTime.Now; _stepName = stepName; return true; }, time * 1000.0); if (tuple.Item1 && tuple.Item2 == Result.RUN) { throw new RoutineBreakException(); } } public void TimeDelay(int id, double time) { Tuple tuple = Delay(id, delegate { Notify($"Delay {time} seconds"); _stepSpan = new TimeSpan(0, 0, 0, (int)time); _stepStartTime = DateTime.Now; return true; }, time * 1000.0); if (tuple.Item1 && tuple.Item2 == Result.RUN) { throw new RoutineBreakException(); } } protected void ExecuteRoutine(int id, List<(IRoutine routine, object[] args)> routines) { Tuple tuple = ExecuteAndWait(id, routines); if (tuple.Item1) { if (tuple.Item2 == Result.FAIL) { throw new RoutineFaildException(); } if (tuple.Item2 == Result.RUN) { throw new RoutineBreakException(); } } } protected void ExecuteRoutine(int id, List routines) { Tuple tuple = ExecuteAndWait(id, routines); if (tuple.Item1) { if (tuple.Item2 == Result.FAIL) { throw new RoutineFaildException(); } if (tuple.Item2 == Result.RUN) { throw new RoutineBreakException(); } } } protected void ExecuteRoutine(int id, IRoutine routine, params object[] args) { Tuple tuple = ExecuteAndWait(id, routine, args); if (tuple.Item1) { if (tuple.Item2 == Result.FAIL) { throw new RoutineFaildException(); } if (tuple.Item2 == Result.RUN) { throw new RoutineBreakException(); } } } protected void PerformStep(T step, RoutineFunc func, T1 param1) { int num = Convert.ToInt32(step); RoutineState routineState = func(param1); } public void Loop(int id, int count) { Tuple tuple = Loop(id, delegate { Notify($"Start loop {base.LoopCounter + 1}/{count}"); return true; }, count); if (tuple.Item1 && tuple.Item2 == Result.FAIL) { throw new RoutineFaildException(); } } public void EndLoop(int id) { Tuple tuple = EndLoop(id, delegate { Notify("Loop finished"); return true; }); if (tuple.Item1) { throw new RoutineBreakException(); } } /// /// 转移产品。 /// /// /// /// /// /// /// protected virtual void Transfer(int id, ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo) { var ret = Execute(id, () => { Notify($"Transfer {moduleFrom}.{slotFrom} -> {moduleTo}.{slotTo}"); // 产品到达抓取位置后,Slot0 转移到 Slot1 WaferManager.Instance.WaferMoved(moduleFrom, slotFrom, moduleTo, slotTo); return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } } } #endregion } }