using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Sorter.Common; using DocumentFormat.OpenXml.Wordprocessing; using MECF.Framework.Common.Device.Bases; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using FurnaceRT.Equipments.Systems; namespace FurnaceRT.Equipments.LPs { public class LoadPortAutoLoad : ModuleRoutine, IRoutine { enum RoutineStep { Load, BuzzerOn, BuzzerOff, CheckAccessSwitch1, CheckAccessSwitch2, } private LoadPortModule _lpModule; private int _timeout = 0; private int _accessSwitchTimeout = 0; private int _carrierInOrOutDelayTime = 0; private bool _buzzerOn; private bool _accessSwitchPressedBeforeCarrierIn; private bool _accessSwitchPressedAfterCarrierIn; private bool _isBypassAccessSwitchPressedTimeout; private RoutineStep _routineStep; public LoadPortAutoLoad(LoadPortModule lpModule) { _lpModule = lpModule; Module = lpModule.Module; Name = "Load"; } public void Init(bool isHasAlarm) { _isHasAlarm = isHasAlarm; } public Result Start(params object[] objs) { if (!_isHasAlarm) { Reset(); } else { List stepLst = new List(Steps.ToArray()); stepLst.Remove((int)_routineStep); Steps = new Stack(stepLst); _isHasAlarm = false; ResetState(); } _timeout = SC.GetValue($"LoadPort.{Module}.MotionTimeout"); if (_lpModule.IsReleased) { EV.PostInfoLog(Module, $"{Module} already at release position"); return Result.DONE; } _lpModule.LoadFailAlarm.RetryMessage = (int)LoadPortModule.MSG.AutoLoadRetry; _lpModule.LoadTimeoutAlarm.RetryMessage = (int)LoadPortModule.MSG.AutoLoadRetry; var para = new List { true }; _lpModule.LoadFailAlarm.RetryMessageParas = para.ToArray(); _lpModule.LoadTimeoutAlarm.RetryMessageParas = para.ToArray(); _buzzerOn = SC.GetValue("LoadPort.BuzzerSetting.BuzzerOnWhenUnloading"); _accessSwitchPressedBeforeCarrierIn = SC.GetValue("LoadPort.LoadPortSwitch.AccessSwitchPressedBeforeCarrierIn"); _accessSwitchPressedAfterCarrierIn = SC.GetValue("LoadPort.LoadPortSwitch.AccessSwitchPressedAfterCarrierIn"); _isBypassAccessSwitchPressedTimeout = SC.GetStringValue("LoadPort.LoadPortSwitch.OperationSwitchPressedAfterCarrierOut") == "Continue"; _accessSwitchTimeout = SC.GetValue("LoadPort.LoadPortSwitch.AccessSwitchTimeout"); _carrierInOrOutDelayTime = SC.GetValue("LoadPort.LoadPortSwitch.CarrierInOrOutDelayTime"); Notify($"{Module} unload start"); return Result.RUN; } public void Abort() { _lpModule.Stop(); } public override Result Monitor() { try { //_accessSwitchPressedBeforeCarrierIn //等待Access Switch按键按下 if (_accessSwitchPressedBeforeCarrierIn) CheckAccessSwitch((int)RoutineStep.CheckAccessSwitch1, _accessSwitchTimeout); else Delay((int)RoutineStep.CheckAccessSwitch1, _carrierInOrOutDelayTime); Load((int)RoutineStep.Load, _timeout); if(_buzzerOn) BuzzerOn((int)RoutineStep.BuzzerOn, true); //_accessSwitchPressedAfterCarrierIn //等待Access Switch按键按下 if (_accessSwitchPressedAfterCarrierIn) CheckAccessSwitch((int)RoutineStep.CheckAccessSwitch2, _accessSwitchTimeout); if (_buzzerOn) BuzzerOn((int)RoutineStep.BuzzerOff, false); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException ex) { return Result.FAIL; } Notify($"{Name} finished"); return Result.DONE; } private void CheckAccessSwitch(int id, int timeout) { Tuple ret = ExecuteAndWait(id, () => { Notify($"{Module} check access switch"); return true; }, () => { return _lpModule.IsClamp; }, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { if(_isBypassAccessSwitchPressedTimeout) { throw (new RoutineBreakException()); } else { _lpModule.UnloadTimeoutAlarm.Set($"unload timeout, can not complete in {timeout} seconds"); throw (new RoutineFaildException()); } } else throw (new RoutineBreakException()); } } private void Load(int id, int timeout) { _routineStep = (RoutineStep)Enum.Parse(typeof(RoutineStep), id.ToString()); Tuple ret = ExecuteAndWait(id, () => { Notify($"{Module} load"); if (!_lpModule.LoadLoadPort(out string reason)) { _lpModule.LoadFailAlarm.Set(reason); return false; } return true; }, () => { return _lpModule.IsReleased; }, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { _lpModule.LoadTimeoutAlarm.Set($"load timeout, can not complete in {timeout} seconds"); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } private void BuzzerOn(int id, bool isOn) { Tuple ret = Execute(id, () => { Notify($"Buzzer {(isOn ? "on" : "off")}"); DEVICE.GetDevice($"{ModuleName.System}.{ModuleName.SignalTower}").IsAutoSetLight = !isOn; DEVICE.GetDevice($"{ModuleName.System}.{ModuleName.SignalTower}").SetLight(LightType.Buzzer1, isOn ? TowerLightStatus.On : TowerLightStatus.Off); return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } else throw new RoutineBreakException(); } } } }