using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Beckhoff.ModuleIO; using MECF.Framework.Common.CommonData.Loader; using MECF.Framework.Common.TwinCat; using MECF.Framework.Common.Utilities; using CyberX8_Core; using CyberX8_RT.Devices.AXIS.CANOpen; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using MECF.Framework.Common.IOCore; namespace CyberX8_RT.Devices.Loader { public class LoaderSideDevice : BaseDevice, IDevice { /// /// /// private enum LoaderSideOperation { None, DoorOn, DoorOff, VacuumOn, VacuumOff, WhBladderOn, WhBladderOff, TransBladderOn, TransBladderOff, TransHighOn, TransHighOff, BernoulliBladderOn, BernoulliBladderOff, BernoulliN2On, BernoulliN2Off, Load, Unload, InstallCRS, StartCycle, StopCycle } #region 常量 private const string WAFER_PRESENT = "WaferPresent"; private const string DOOR_UNLOCK = "DoorUnlock"; private const string DOOR_UPPER_LOCKED = "DoorUpperLocked"; private const string DOOR_UPPER_UNLOCKED = "DoorUpperUnlocked"; private const string DOOR_LOWER_LOCKED = "DoorLowerLocked"; private const string DOOR_LOWER_UNLOCKED = "DoorLowerUnlocked"; private const string CRS_VACUUM="CRSVacuum"; private const string CRS_VACUUM_VALUE = "CRSVacuumValue"; private const string WH_BLADDER = "WHBladder"; private const string WH_BLADDER_PRESSURE="WHBladderPressure"; private const string TRANS_BLADDER="TransBladder"; private const string TRANS_HIGH="TransHigh"; private const string TRANS_RETRACTED="TransRetracted"; private const string TRANS_PRESSURE = "TransPressure"; private const string BERNOULLI_BLADDER= "BernoulliBladder"; private const string BERNOULLI_EXTENDED="BernoulliExtended"; private const string BERNOULLI_N2="BernoulliN2"; private const string BERNOULLI_N2_SECOND = "BernoulliN2Second"; private const string BERNOULLI_PRESSURE="BernoulliPressure"; private const string WAFER_HOLDER_LOCKED = "WaferHolderLocked"; private const string BERNOULLI_BLADDER_PRESSURE="BernoulliBladderPressure"; private const string SIDE_DATA = "SideData"; private const string CURRENT_OPERATION = "CurrentOperation"; #endregion #region 内部变量 /// /// 数据 /// private LoaderSideData _siderData=new LoaderSideData(); /// /// 状态 /// private RState _status; /// /// 当前操作 /// private LoaderSideOperation _currentOperation; /// /// 变量是否初始化字典 /// private Dictionary _variableInitializeDic = new Dictionary(); /// /// 当前次数 /// private string _currentCycle = ""; #region routine /// /// door lock routine /// private LoaderSideDoorLockRoutine _doorlockRoutine; /// /// Vacuum Routine /// private LoaderSideVacuumRoutine _vacuumRoutine; /// /// WH Bladder Routine /// private LoaderSideWhBladderRoutine _whBladderRoutine; /// /// Trans Bladder Routine /// private LoaderSideTransBladderRoutine _transBladderRoutine; /// /// Trans High Pressure Routine /// private LoaderSideTransHighRoutine _transHighPressureRoutine; /// /// Bernoulli Bladder Routine /// private LoaderSideBernoulliBladderRoutine _bernoulliBladderRoutine; /// /// Load Routine /// private LoaderLoadRoutine _loadRoutine; /// /// Unload Routine /// private LoaderUnloadRoutine _unloadRoutine; /// /// Install Routine /// private LoaderInstallCRSRoutine _installCRSRoutine; /// /// Cycle Routine /// private LoaderSideCycleRoutine _cycleRoutine; #endregion #endregion #region 属性 /// /// 数据 /// public LoaderSideData SideData { get { return _siderData; } set { _siderData = value; } } /// /// 状态 /// public RState Status { get { return _status; } } /// /// 当前次数 /// public String CurrentCycle { get { return _currentCycle; } } /// /// 所有io变量是否初始化 /// public bool IOInitialized { get { return IOVariableDictionaryUtil.AllIoVariableInitialized(eEvent.ERR_LOADER,Module,_variableInitializeDic); } } #endregion /// /// 构造函数 /// /// /// public LoaderSideDevice(string moduleName,string name):base(moduleName,name,name,name) { } /// /// 初始化 /// /// public bool Initialize() { SubscribeData(); SubscribeValueAction(); InitializeRoutine(); InitializeOperation(); return true; } /// /// 初始化Routine /// private void InitializeRoutine() { _doorlockRoutine = new LoaderSideDoorLockRoutine($"{Module}.{Name}"); _vacuumRoutine = new LoaderSideVacuumRoutine($"{Module}.{Name}"); _whBladderRoutine = new LoaderSideWhBladderRoutine($"{Module}.{Name}"); _transBladderRoutine = new LoaderSideTransBladderRoutine($"{Module}.{Name}"); _transHighPressureRoutine = new LoaderSideTransHighRoutine($"{Module}.{Name}"); _bernoulliBladderRoutine = new LoaderSideBernoulliBladderRoutine($"{Module}.{Name}"); _loadRoutine = new LoaderLoadRoutine(Module,Name); _unloadRoutine = new LoaderUnloadRoutine(Module,Name); _installCRSRoutine = new LoaderInstallCRSRoutine(Module,Name); _cycleRoutine = new LoaderSideCycleRoutine(Module, Name); } /// /// 订阅数据 /// private void SubscribeData() { DATA.Subscribe($"{Module}.{Name}.{SIDE_DATA}", () => _siderData,SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.CurrentCycle", () => _currentCycle, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.CurrentCycleStep", () => { if(_currentOperation==LoaderSideOperation.StartCycle) { return _cycleRoutine.CurrentStep; } else { return ""; } }, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.{CURRENT_OPERATION}", () => _currentOperation.ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.CRSVacuumValue",()=>_siderData.CRSVacuumValue, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.CRSVacuum", () => _siderData.CRSVacuum, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.BernoulliPressure", () => _siderData.BernoulliPressure, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.BernoulliBladder", () => _siderData.BernoulliBladder, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.BernoulliBladderPressure", () => _siderData.BernoulliBladderPressure, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.BernoulliExtended", () => _siderData.BernoulliExtended, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.BernoulliN2", () => _siderData.BernoulliN2, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.BernoulliN2Second", () => _siderData.BernoulliN2Second, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.DoorLowerLocked", () => _siderData.DoorLowerLocked, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.DoorLowerUnlocked", () => _siderData.DoorLowerUnlocked, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.DoorUpperLocked", () => _siderData.DoorUpperLocked, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.DoorUpperUnlocked", () => _siderData.DoorUpperUnlocked, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.TransBladder", () => _siderData.TransBladder, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.TransHigh", () => _siderData.TransHigh, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.TransPressure", () => _siderData.TransPressure, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.TransRetracted", () => _siderData.TransRetracted, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.WaferPresent", () => _siderData.WaferPresent, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.WSBladder", () => _siderData.WHBladder, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.WSBladderPressure", () => _siderData.WHBladderPressure, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 订阅变量数值发生变化 /// private void SubscribeValueAction() { BeckhoffIoSubscribeUpdateVariable(WAFER_PRESENT); BeckhoffIoSubscribeUpdateVariable(DOOR_UNLOCK); BeckhoffIoSubscribeUpdateVariable(DOOR_UPPER_LOCKED); BeckhoffIoSubscribeUpdateVariable(DOOR_UPPER_UNLOCKED); BeckhoffIoSubscribeUpdateVariable(DOOR_LOWER_LOCKED); BeckhoffIoSubscribeUpdateVariable(DOOR_LOWER_UNLOCKED); BeckhoffIoSubscribeUpdateVariable(CRS_VACUUM); BeckhoffIoSubscribeUpdateVariable(CRS_VACUUM_VALUE); BeckhoffIoSubscribeUpdateVariable(WH_BLADDER); BeckhoffIoSubscribeUpdateVariable(WH_BLADDER_PRESSURE); BeckhoffIoSubscribeUpdateVariable(TRANS_BLADDER); BeckhoffIoSubscribeUpdateVariable(TRANS_HIGH); BeckhoffIoSubscribeUpdateVariable(TRANS_RETRACTED); BeckhoffIoSubscribeUpdateVariable(TRANS_PRESSURE); BeckhoffIoSubscribeUpdateVariable(BERNOULLI_BLADDER); BeckhoffIoSubscribeUpdateVariable(BERNOULLI_EXTENDED); BeckhoffIoSubscribeUpdateVariable(BERNOULLI_N2); BeckhoffIoSubscribeUpdateVariable(BERNOULLI_N2_SECOND); BeckhoffIoSubscribeUpdateVariable(BERNOULLI_PRESSURE); BeckhoffIoSubscribeUpdateVariable(WAFER_HOLDER_LOCKED); BeckhoffIoSubscribeUpdateVariable(BERNOULLI_BLADDER_PRESSURE); } /// /// 订阅IO变量 /// /// private void BeckhoffIoSubscribeUpdateVariable(string variable) { _variableInitializeDic[variable] = false; IOModuleManager.Instance.SubscribeModuleVariable($"{Module}.{Name}", variable, UpdateVariableValue); } /// /// 初始化操作 /// private void InitializeOperation() { OP.Subscribe($"{Module}.{Name}.DoorLockOn",(cmd,args)=> { return DoorLockOnAction(); }); OP.Subscribe($"{Module}.{Name}.DoorLockOff",(cmd,args)=> { return DoorLockOffAction(); }); OP.Subscribe($"{Module}.{Name}.VacuumOn", VacuumOnAction); OP.Subscribe($"{Module}.{Name}.VacuumOff", VacuumOffAction); OP.Subscribe($"{Module}.{Name}.WhBladderOn", WhBladderOnAction); OP.Subscribe($"{Module}.{Name}.WhBladderOff", WhBladderOffAction); OP.Subscribe($"{Module}.{Name}.TransBladderOn", TransBladderOnAction); OP.Subscribe($"{Module}.{Name}.TransBladderOff", TransBladderOffAction); OP.Subscribe($"{Module}.{Name}.TransHighOn", TransHighPressureOnAction); OP.Subscribe($"{Module}.{Name}.TransHighOff", TransHighPressureOffAction); OP.Subscribe($"{Module}.{Name}.BernoulliBladderOn", BernoulliBladderOnAction); OP.Subscribe($"{Module}.{Name}.BernoulliBladderOff", BernoulliBladderOffAction); OP.Subscribe($"{Module}.{Name}.BernoulliN2On", BernoulliN2OnAction); OP.Subscribe($"{Module}.{Name}.BernoulliN2Off", BernoulliN2OffAction); OP.Subscribe($"{Module}.{Name}.Load", LoadAction); OP.Subscribe($"{Module}.{Name}.Unload", UnloadAction); OP.Subscribe($"{Module}.{Name}.InstallCRS", InstallCRSAction); OP.Subscribe($"{Module}.{Name}.StartCycle", StartCycleAction); OP.Subscribe($"{Module}.{Name}.StopCycle", StopCycleAction); } #region Operation /// /// Door Lock On操作 /// public bool DoorLockOnAction() { if (!JudgeRunningState(LoaderSideOperation.DoorOn)) { _currentOperation = LoaderSideOperation.DoorOn; _status = _doorlockRoutine.Start(true); return true; } else { return false; } } /// /// Door Lock Off操作 /// public bool DoorLockOffAction() { if (!JudgeRunningState(LoaderSideOperation.DoorOff)) { _currentOperation = LoaderSideOperation.DoorOff; _status = _doorlockRoutine.Start(false); return true; } else { return false; } } /// /// Vacuum On 操作 /// private bool VacuumOnAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.VacuumOn)) { _currentOperation = LoaderSideOperation.VacuumOn; _status = _vacuumRoutine.Start(true); return true; } else { return false; } } /// /// Vacuum On 操作 /// private bool VacuumOffAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.VacuumOff)) { _currentOperation = LoaderSideOperation.VacuumOff; _status = _vacuumRoutine.Start(false); return true; } else { return false; } } /// /// WH Bladder On 操作 /// private bool WhBladderOnAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.WhBladderOn)) { _currentOperation = LoaderSideOperation.WhBladderOn; _status = _whBladderRoutine.Start(true); return true; } else { return false; } } /// /// WH Bladder Off 操作 /// private bool WhBladderOffAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.WhBladderOff)) { _currentOperation = LoaderSideOperation.WhBladderOff; _status = _whBladderRoutine.Start(false); return true; } else { return false; } } /// /// Trans Bladder On 操作 /// private bool TransBladderOnAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.TransBladderOn)) { _currentOperation = LoaderSideOperation.TransBladderOn; _status = _transBladderRoutine.Start(true); return true; } else { return false; } } /// /// Trans Bladder Off 操作 /// private bool TransBladderOffAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.TransBladderOff)) { _currentOperation = LoaderSideOperation.TransBladderOff; _status = _transBladderRoutine.Start(false); return true; } else { return false; } } /// /// Trans High Pressure On 操作 /// private bool TransHighPressureOnAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.TransHighOn)) { _currentOperation = LoaderSideOperation.TransHighOn; _status = _transHighPressureRoutine.Start(true); return true; } else { return false; } } /// /// Trans High Pressure Off 操作 /// private bool TransHighPressureOffAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.TransHighOff)) { _currentOperation = LoaderSideOperation.TransHighOff; _status = _transHighPressureRoutine.Start(false); return true; } else { return false; } } /// /// Bernoulli Bladder On 操作 /// private bool BernoulliBladderOnAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.BernoulliBladderOn)) { _currentOperation = LoaderSideOperation.BernoulliBladderOn; _status = _bernoulliBladderRoutine.Start(true); return true; } else { return false; } } /// /// Bernoulli Bladder Off 操作 /// private bool BernoulliBladderOffAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.BernoulliBladderOff)) { _currentOperation = LoaderSideOperation.BernoulliBladderOff; _status = _bernoulliBladderRoutine.Start(false); return true; } else { return false; } } /// /// Bernoulli N2 On 操作 /// public bool BernoulliN2OnAction(string cmd, object[] args) { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{Name}.{BERNOULLI_N2}"); bool result = IOModuleManager.Instance.WriteIoValue(ioName, true); return result; } /// /// Bernoulli N2 Off 操作 /// public bool BernoulliN2OffAction(string cmd, object[] args) { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{Name}.{BERNOULLI_N2}"); bool result = IOModuleManager.Instance.WriteIoValue(ioName, false); return result; } /// /// Load 操作 /// public bool LoadAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.Load)) { _currentOperation = LoaderSideOperation.Load; _status = _loadRoutine.Start(); return true; } else { return false; } } /// /// Unload 操作 /// public bool UnloadAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.Unload)) { _currentOperation = LoaderSideOperation.Unload; _status = _unloadRoutine.Start(); return true; } else { return false; } } /// /// Install CRS 操作 /// private bool InstallCRSAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.InstallCRS)) { _currentOperation = LoaderSideOperation.InstallCRS; _status = _installCRSRoutine.Start(); return true; } else { return false; } } /// /// StartCycle 操作 /// private bool StartCycleAction(string cmd, object[] args) { if (!JudgeRunningState(LoaderSideOperation.StartCycle)) { _currentOperation = LoaderSideOperation.StartCycle; _status = _cycleRoutine.Start(args); bool result= _status == RState.Running ; if(result) { _currentCycle = _cycleRoutine.CurrentCycle.ToString(); } else { _currentCycle = ""; } return result; } else { return false; } } /// /// StopCycle 操作 /// private bool StopCycleAction(string cmd, object[] args) { if (_currentOperation==LoaderSideOperation.StartCycle) { AbortRoutine(); return true; } else { return true; } } /// /// 判定运行状态 /// /// private bool JudgeRunningState(LoaderSideOperation operation) { if (_status == RState.Running) { EV.PostAlarmLog($"{Module}.{Name}", eEvent.ERR_LOADER, $"{Module}.{Name} current execute {_currentOperation},cannot {operation}"); return true; } return false; } #endregion /// 更新变量数值 /// /// /// private void UpdateVariableValue(string variable, object value) { PropertyInfo property = SideData.GetType().GetProperty(variable); if (property != null) { property.SetValue(SideData, value); } } /// /// 定时器 /// /// public bool OnTimer() { if (_status == RState.Running) { if (_currentOperation != LoaderSideOperation.None) { IRoutine routine = GetCurrentRoutine(_currentOperation); if (routine != null) { CheckRoutineState(routine, _currentOperation); } else { EndOperation(RState.End); } if(_currentOperation==LoaderSideOperation.StartCycle) { _currentCycle = _cycleRoutine.CurrentCycle.ToString(); } } } return true; } /// /// 获取当前操作对应的Routine /// /// /// private IRoutine GetCurrentRoutine(LoaderSideOperation currentOperation) { switch (currentOperation) { case LoaderSideOperation.DoorOn: case LoaderSideOperation.DoorOff: return _doorlockRoutine; case LoaderSideOperation.VacuumOn: case LoaderSideOperation.VacuumOff: return _vacuumRoutine; case LoaderSideOperation.WhBladderOn: case LoaderSideOperation.WhBladderOff: return _whBladderRoutine; case LoaderSideOperation.TransBladderOn: case LoaderSideOperation.TransBladderOff: return _transBladderRoutine; case LoaderSideOperation.TransHighOn: case LoaderSideOperation.TransHighOff: return _transHighPressureRoutine; case LoaderSideOperation.BernoulliBladderOn: case LoaderSideOperation.BernoulliBladderOff: return _bernoulliBladderRoutine; case LoaderSideOperation.Load: return _loadRoutine; case LoaderSideOperation.Unload: return _unloadRoutine; case LoaderSideOperation.InstallCRS: return _installCRSRoutine; case LoaderSideOperation.StartCycle: return _cycleRoutine; default: return null; } } /// /// 检验Routine状态 /// /// /// private void CheckRoutineState(IRoutine routine, LoaderSideOperation currentOperation) { RState state = routine.Monitor(); if (state == RState.End) { EndOperation(RState.End); } else if (state == RState.Failed || state == RState.Timeout) { LOG.WriteLog(eEvent.ERR_LOADER, $"{Module}.{Name}", $"{currentOperation} error"); EndOperation(RState.Failed); } } /// /// 结束操作 /// private void EndOperation(RState state) { _status = state; _currentOperation = LoaderSideOperation.None; } /// /// 中止Routine /// public void AbortRoutine() { IRoutine routine = GetCurrentRoutine(_currentOperation); if(routine!=null) { routine.Abort(); _currentOperation=LoaderSideOperation.None; _status = RState.End; _currentCycle = ""; } } #region 设备接口 /// /// 监控 /// public void Monitor() { } public void Reset() { } public void Terminate() { AbortRoutine(); } #endregion } }