using System; using System.Diagnostics; using System.Linq; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Utilities; using Aitex.Sorter.Common; using MECF.Framework.Common.Alarms; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using FurnaceRT.Equipments.Systems; using static Aitex.Core.RT.Device.Unit.IoAutoShutter; using Aitex.Core.Util; using MECF.Framework.Common.Device.Bases; using Aitex.Core.RT.Log; using FurnaceRT.Devices; namespace FurnaceRT.Equipments.Boats { public partial class BoatModule : ModuleFsmDevice, IModuleDevice { public enum STATE { Init, Idle, Error, Homing, InTransfer, ZAxisMoving, ZAxisManualMoving, RAxisMoving, RAxisMovingTest, ZAxisMovingTest, ShutterCycleTest, MovingTest, BoatMoving, } public enum MSG { Home, Reset, Init, Error, Abort, InTransfer, TransferComplete, ZAxisManualMove, ZAxisMove, RAxisMove, RAxisMoveTest, ZAxisMoveTest, ShutterCycleTest, MoveTest, ZAxisManualMoveRetry, ZAxisMoveRetry, RAxisMoveRetry, BoatMove, BoatMoveRetry, } public bool IsReady { get { return FsmState == (int)STATE.Idle; } } public bool IsError { get { return FsmState == (int)STATE.Error; } } public bool IsInit { get { return FsmState == (int)STATE.Init; } } public event Action OnEnterError; private bool _jobDone; private bool _isInit; private Stopwatch _timerNotifyJobDone = new Stopwatch(); private BoatHome _home; private BoatZAxisMove _zAxisMove; private BoatZAxisManualMove _zAxisManualMove; private BoatRAxisMove _rAxisMove; private BoatRAxisMoveCycleTest _rAxisMoveCycleTest; private BoatZAxisMoveCycleTest _zAxisMoveCycleTest; private BoatMoveCycleTest _moveCycleTest; private BoatShutterCycleTest _shutterCycleTest; private BoatMove _boatMove; public bool IsExcuteRoutineFailed { get; set; } public bool IsBoatElevatorAtHomePosition => ZAxisDevice == null ? false : ZAxisDevice.CheckServoAtPosition("HomePosition") && ZAxisDevice.IsReady; public bool IsBoatRotationAtHomePosition => RAxisDevice == null ? false : RAxisDevice.IsHomeDone && RAxisDevice.IsReady; public BoatModule(ModuleName module) : base() { Name = module.ToString(); Module = module.ToString(); IsOnline = true; } public override bool Initialize() { InitRoutine(); InitDevice(); InitFsm(); InitOp(); InitData(); InitAlarmEvent(); Singleton.Instance.OnAlarmEvent += Instance_OnAlarmEvent; return base.Initialize(); } private void Instance_OnAlarmEvent(EventItem item) { if (item != null && item.Level == EventLevel.Alarm && (item.Source == Name || item.Source == Module)) { DEVICE.GetDevice("System.SignalTower")?.Reset(); LOG.Write($"{item.Source} {item.EventEnum} {item.Description}\n"); PostMsg(MSG.Error); } } private void InitRoutine() { _home = new BoatHome(this); _zAxisMove = new BoatZAxisMove(this); _zAxisManualMove = new BoatZAxisManualMove(this); _rAxisMove = new BoatRAxisMove(this); _rAxisMoveCycleTest = new BoatRAxisMoveCycleTest(this); _zAxisMoveCycleTest = new BoatZAxisMoveCycleTest(this); _shutterCycleTest = new BoatShutterCycleTest(this); _moveCycleTest = new BoatMoveCycleTest(this); _boatMove = new BoatMove(this); } private void InitData() { DATA.Subscribe($"{Module}.Status", () => IsExcuteRoutineFailed ? STATE.Error.ToString() : StringFsmStatus); DATA.Subscribe($"{Module}.IsError", () => IsError); DATA.Subscribe($"{Module}.IsOnline", () => IsOnline); DATA.Subscribe($"{Module}.BoatTestCycledCount", () => _moveCycleTest.LoopCounter); DATA.Subscribe($"{Module}.ShutterCycledCount", () => _shutterCycleTest.LoopCounter); } private void InitOp() { OP.Subscribe($"{Module}.Home", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Home)); OP.Subscribe($"{Module}.Abort", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Abort)); OP.Subscribe($"{Module}.Reset", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Reset)); OP.Subscribe($"{Module}.ZAxisMove", (string cmd, object[] args) => CheckToPostMessage((int)MSG.ZAxisMove, args)); OP.Subscribe($"{Module}.ZAxisManualMove", (string cmd, object[] args) => CheckToPostMessage((int)MSG.ZAxisManualMove, args)); OP.Subscribe($"{Module}.RAxisMove", (string cmd, object[] args) => CheckToPostMessage((int)MSG.RAxisMove, args)); OP.Subscribe($"{Module}.RAxisMovingTest", (string cmd, object[] args) => CheckToPostMessage((int)MSG.RAxisMoveTest, args)); OP.Subscribe($"{Module}.ZAxisMovingTest", (string cmd, object[] args) => CheckToPostMessage((int)MSG.ZAxisMoveTest, args)); OP.Subscribe($"{Module}.ShutterCycleTest", (string cmd, object[] args) => CheckToPostMessage((int)MSG.ShutterCycleTest, args)); OP.Subscribe($"{Module}.MovingTest", (string cmd, object[] args) => CheckToPostMessage((int)MSG.MoveTest, args)); OP.Subscribe($"{Name}.SetBoatZAxisSpeed", SetBoatZAxisSpeed); OP.Subscribe($"{Name}.SetBoatRAxisSpeed", SetBoatRAxisSpeed); OP.Subscribe($"{Name}.SetBoatRAxisAngle", SetBoatRAxisAngle); OP.Subscribe($"{Name}.BoatZAxisStop", SetBoatZAxisStop); OP.Subscribe($"{Name}.BoatRAxisStop", SetBoatRAxisStop); OP.Subscribe($"{Module}.AlarmAction", (string cmd, object[] args) => { Enum.TryParse(args[0].ToString(), out AlarmAction alarmAction); string eventName = null; if (args.Length > 1) eventName = args[1].ToString(); if (eventName != null) { EV.ClearAlarmEvent(eventName); var item = _triggeredAlarmList.FirstOrDefault(x => x.EventEnum == eventName); if (item != null) { item.Reset(); _triggeredAlarmList.Remove(item); } if (item != null) { switch (alarmAction) { case AlarmAction.Retry: { CheckToPostMessage((int)item.RetryMessage, item.RetryMessageParas); } break; case AlarmAction.Abort: { CheckToPostMessage((int)MSG.Abort); } break; case AlarmAction.Clear: { int alarmCount = 0; var alarms = EV.GetAlarmEvent(); foreach (var alarm in alarms) { if (alarm.Level == EventLevel.Alarm && alarm.Source == Name) alarmCount++; } if (alarmCount == 0) CheckToPostMessage((int)MSG.Reset); } break; case AlarmAction.Continue: { int alarmCount = 0; var alarms = EV.GetAlarmEvent(); foreach (var alarm in alarms) { if (alarm.Level == EventLevel.Alarm && alarm.Source == Name) alarmCount++; } if (alarmCount == 0) CheckToPostMessage((int)MSG.Reset); } break; } } } return true; }); } private void InitFsm() { EnumLoop.ForEach((item) => { MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { MapMessage((int)item, item.ToString()); }); EnableFsm(100, STATE.Idle); //Init Transition(STATE.Init, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Error, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Idle, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Homing, FSM_MSG.TIMER, FsmMonitorHomeTask, STATE.Idle); Transition(STATE.Homing, MSG.Error, null, STATE.Init); Transition(STATE.Homing, MSG.Abort, FsmAbortTask, STATE.Init); EnterExitTransition(STATE.Idle, FsmEnterIdle, FSM_MSG.NONE, FsmExitIdle); Transition(STATE.Idle, MSG.Abort, null, STATE.Idle); Transition(STATE.Idle, MSG.Reset, null, STATE.Idle); Transition(STATE.Init, MSG.Reset, null, STATE.Init); Transition(STATE.Error, MSG.Abort, null, STATE.Error); //Error AnyStateTransition(MSG.Error, FsmOnError, STATE.Error); Transition(STATE.Error, MSG.Reset, FsmReset, STATE.Idle); EnterExitTransition(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError); //ZAxisMove,open shutter Transition(STATE.Error, MSG.ZAxisMoveRetry, FsmStartZAxisMove, STATE.ZAxisMoving); Transition(STATE.Idle, MSG.ZAxisMove, FsmStartZAxisMove, STATE.ZAxisMoving); Transition(STATE.ZAxisMoving, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.ZAxisMoving, MSG.Abort, FsmAbortTask, STATE.Idle); //ZAxisManualMove,not open shutter Transition(STATE.Error, MSG.ZAxisManualMoveRetry, FsmStartZAxisManualMove, STATE.ZAxisManualMoving); Transition(STATE.Idle, MSG.ZAxisManualMove, FsmStartZAxisManualMove, STATE.ZAxisManualMoving); Transition(STATE.ZAxisManualMoving, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.ZAxisManualMoving, MSG.Abort, FsmAbortTask, STATE.Idle); //RAxisMove Transition(STATE.Error, MSG.RAxisMoveRetry, FsmStartRAxisMove, STATE.RAxisMoving); Transition(STATE.Idle, MSG.RAxisMove, FsmStartRAxisMove, STATE.RAxisMoving); Transition(STATE.RAxisMoving, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.RAxisMoving, MSG.Abort, FsmAbortTask, STATE.Idle); //RAxisMoveCycleTest Transition(STATE.Idle, MSG.RAxisMoveTest, FsmStartRAxisMoveTest, STATE.RAxisMovingTest); Transition(STATE.RAxisMovingTest, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.RAxisMovingTest, MSG.Abort, FsmAbortTask, STATE.Idle); //ZAxisMoveCycleTest Transition(STATE.Idle, MSG.ZAxisMoveTest, FsmStartZAxisMoveTest, STATE.ZAxisMovingTest); Transition(STATE.ZAxisMovingTest, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.ZAxisMovingTest, MSG.Abort, FsmAbortTask, STATE.Idle); //ShutterCycleTest Transition(STATE.Idle, MSG.ShutterCycleTest, FsmStartShutterCycleTest, STATE.ShutterCycleTest); Transition(STATE.ShutterCycleTest, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.ShutterCycleTest, MSG.Abort, FsmAbortTask, STATE.Idle); //MoveCycleTest Transition(STATE.Idle, MSG.MoveTest, FsmStartMoveTest, STATE.MovingTest); Transition(STATE.MovingTest, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.MovingTest, MSG.Abort, FsmAbortTask, STATE.Idle); //BoatMove Transition(STATE.Error, MSG.BoatMoveRetry, FsmStartBoatMove, STATE.BoatMoving); Transition(STATE.Idle, MSG.BoatMove, FsmStartBoatMove, STATE.BoatMoving); Transition(STATE.BoatMoving, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.BoatMoving, MSG.Abort, FsmAbortTask, STATE.Idle); Transition(STATE.Idle, MSG.InTransfer, null, STATE.InTransfer); Transition(STATE.InTransfer, MSG.InTransfer, null, STATE.InTransfer); Transition(STATE.InTransfer, MSG.TransferComplete, null, STATE.Idle); Transition(STATE.InTransfer, MSG.Abort, null, STATE.Idle); } public bool Home(out string reason) { if (!CheckToPostMessage((int)MSG.Home)) { reason = $"Can not home in {StringFsmStatus} status"; return false; } reason = string.Empty; return true; } public void NoteJobStart() { _jobDone = false; } public void NoteJobComplete() { _timerNotifyJobDone.Restart(); _jobDone = true; } public override void Monitor() { base.Monitor(); } public override void Reset() { if (IsError) { CheckToPostMessage((int)MSG.Reset); } } private bool FsmReset(object[] param) { return true; } private bool FsmOnError(object[] param) { if (FsmState == (int)STATE.Error) { return false; } AbortRoutine(); if (FsmState == (int)STATE.Init) return false; return true; } private bool FsmExitIdle(object[] param) { return true; } private bool FsmEnterIdle(object[] param) { return true; } private bool FsmExitError(object[] param) { return true; } private bool FsmEnterError(object[] param) { if (OnEnterError != null) OnEnterError(Module); return true; } private bool FsmAbortTask(object[] param) { AbortRoutine(); return true; } private bool FsmToInit(object[] param) { return true; } private bool FsmToIdle(object[] param) { return true; } private bool FsmStartHome(object[] param) { Result ret = StartRoutine(_home); if (ret == Result.FAIL || ret == Result.DONE) return false; _isInit = false; return ret == Result.RUN; } private bool FsmStartZAxisMove(object[] param) { _zAxisMove.Init(param[0].ToString(), param[1].ToString()); Result ret = StartRoutine(_zAxisMove); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartZAxisManualMove(object[] param) { _zAxisManualMove.Init(param[0].ToString(), param.Length > 1 ? param[1].ToString() : "0"); Result ret = StartRoutine(_zAxisManualMove); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartRAxisMove(object[] param) { _rAxisMove.Init(param[0].ToString(), param.Length > 1 ? param[1].ToString() : "0", param.Length > 2 ? param[2].ToString() : "0"); Result ret = StartRoutine(_rAxisMove); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartMoveTest(object[] param) { _moveCycleTest.Init(param[0].ToString(), param[1].ToString(), param[2].ToString()); Result ret = StartRoutine(_moveCycleTest); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartRAxisMoveTest(object[] param) { _rAxisMoveCycleTest.Init(param[0].ToString()); Result ret = StartRoutine(_rAxisMoveCycleTest); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartZAxisMoveTest(object[] param) { _zAxisMoveCycleTest.Init(param[0].ToString(), param[1].ToString()); Result ret = StartRoutine(_zAxisMoveCycleTest); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartShutterCycleTest(object[] param) { _shutterCycleTest.Init(); Result ret = StartRoutine(_shutterCycleTest); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartBoatMove(object[] param) { _boatMove.Init(param[0].ToString(), param[1].ToString(), param[2].ToString()); Result ret = StartRoutine(_boatMove); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmMonitorHomeTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } if (ret == Result.DONE) { _isInit = true; return true; } return false; } private bool FsmMonitorTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } return ret == Result.DONE; } public bool CheckPrepareMove(out string reason, bool isNeedCheckShutter = true) { reason = string.Empty; //if (!SensorPS13LStatus.Value) //{ // reason = "PS13 not true, tube not ATM"; // return false; //} if (!SensorVAC1.Value) { reason = "VAC1 not true"; return false; } if (!SensorVAC2.Value) { reason = "VAC2 not true"; return false; } if (!SensorVAC3.Value) { reason = "VAC3 not true"; return false; } if (!SensorBoatUnloadInterlock.Value) { reason = "boat unload interlock is not OK, please check VAC1,VAV2,VAC3,PS13 status"; return false; } if (isNeedCheckShutter && ShutterDevice.OpenCloseStatus != DeviceStatus.Open) { reason = "shutter not open"; return false; } return true; } public void NoteTransferStart() { CheckToPostMessage((int)MSG.InTransfer); } public void NoteTransferStop() { if (FsmState == (int)STATE.InTransfer) CheckToPostMessage((int)MSG.TransferComplete); } public void ZAxisMove(string position, string speed) { CheckToPostMessage((int)MSG.ZAxisMove, position, speed); } public void BoatMove(string command, string targetPosition, float speed) { CheckToPostMessage((int)MSG.BoatMove, command, targetPosition, speed); } } }