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.SRD; using MECF.Framework.Common.Persistent.Prewet; using MECF.Framework.Common.Persistent.SRD; using MECF.Framework.Common.TwinCat; using CyberX8_Core; using System.Reflection; using CyberX8_RT.Modules.Rinse; using CyberX8_RT.Modules; using CyberX8_RT.Modules.SRD; using CyberX8_RT.Devices.AXIS; using MECF.Framework.Common.Persistent.Rinse; using System.Security.Principal; using MECF.Framework.Common.IOCore; namespace CyberX8_RT.Devices.SRD { public class SrdCommonDevice : BaseDevice, IDevice { /// /// Srd操作枚举 /// private enum SrdCommonOperation { None, DoorClose, DoorOpen, ChuckVacuumOn, ChuckVacuumOff, } #region 常量 private const string FLUID_CONTAINMENT = "FluidContainment"; private const string VACUUM_VALUE = "VacuumValue"; private const string WAFER_PRESENCE = "WaferPresence"; private const string WAFER_PRESENCE_STATUS = "WaferPresenceStatus"; private const string WATER_PRESSURE = "WaterPressure"; private const string DOOR_CLOSE="DoorClose"; private const string DOOR_CLOSED = "DoorClosed"; private const string DOOR_OPENED = "DoorOpened"; private const string WATER_ABOVE="WaterAbove"; private const string WATER_BELOW = "WaterBelow"; private const string CHUCK_VACUUM="ChuckVacuum"; private const string EXHAUST_ON="ExhaustOn"; private const string COMMON_DATA = "CommonData"; private const string PERSISTENT_VALUE= "PersistentValue"; #endregion #region 内部变量 /// /// Common数据 /// private SrdCommonData _commonData = new SrdCommonData(); /// /// 状态 /// private RState _status; /// /// 当前操作 /// private SrdCommonOperation _currentOperation; /// /// Wafer Presence /// private string _waferPresence; /// /// Persistent Value对象 /// private SRDPersistentValue _srdPersistentValue; /// /// IsWaferPresence /// private bool _isWaferPresence = true; /// /// Total Device /// private TotalSRDDevice _totalSRDDevice; #region Routine /// /// Close Routine /// private SrdCommonDoorCloseRoutine _doorCloseRoutine; /// /// Vacuum Routine /// private SrdCommonChuckVacuumRoutine _chuckVacuumRoutine; #endregion #endregion #region 属性 /// /// Common数据 /// public SrdCommonData CommonData { get { return _commonData; } } /// /// 状态 /// public RState Status { get { return _status; } } /// /// Wafer Presence /// public string WaferPresence { get { return _waferPresence; } } /// /// IsWaferPresence /// public bool IsWaferPresence { get { return _isWaferPresence; } } #endregion /// /// 构造函数 /// /// /// public SrdCommonDevice(string moduleName) : base(moduleName, "Common", "Common", "Common") { } /// /// 初始化 /// /// public bool Initialize() { InitializeRoutine(); SubscribeData(); SubscribeValueAction(); InitializeOperation(); return true; } /// /// 初始化Routine /// private void InitializeRoutine() { _doorCloseRoutine = new SrdCommonDoorCloseRoutine(Module); _chuckVacuumRoutine = new SrdCommonChuckVacuumRoutine(Module); } /// /// 订阅数据 /// private void SubscribeData() { _srdPersistentValue = SRDPersistentManager.Instance.GetModulePersistentValue(Module); if(_srdPersistentValue==null) { LOG.WriteLog(eEvent.ERR_SRD, Module, "Persistent Value Object is not exist"); } DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _srdPersistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{COMMON_DATA}", () => _commonData, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{WAFER_PRESENCE_STATUS}", () => _waferPresence, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsWaferPresence", () => IsWaferPresence, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 订阅变量数值发生变化 /// private void SubscribeValueAction() { IOModuleManager.Instance.SubscribeModuleVariable(Module, VACUUM_VALUE, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, WAFER_PRESENCE, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, DOOR_CLOSE, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, DOOR_CLOSED, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, DOOR_OPENED, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, WATER_ABOVE, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, WATER_BELOW, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, CHUCK_VACUUM, UpdateVariableValue); IOModuleManager.Instance.SubscribeModuleVariable(Module, EXHAUST_ON, UpdateVariableValue); } /// /// 初始化操作 /// private void InitializeOperation() { OP.Subscribe($"{Module}.{Name}.DoorClose", DoorCloseAction); OP.Subscribe($"{Module}.{Name}.DoorOpen", DoorOpenAction); OP.Subscribe($"{Module}.{Name}.WaterAboveOn", WaterAboveOnAction); OP.Subscribe($"{Module}.{Name}.WaterAboveOff", WaterAboveOffAction); OP.Subscribe($"{Module}.{Name}.WaterBelowOn", WaterBelowOnAction); OP.Subscribe($"{Module}.{Name}.WaterBelowOff", WaterBelowOffAction); OP.Subscribe($"{Module}.{Name}.ChuckVacuumOn", ChuckVacuumOnAction); OP.Subscribe($"{Module}.{Name}.ChuckVacuumOff", ChuckVacuumOffAction); OP.Subscribe($"{Module}.{Name}.ExhaustOn", ExhaustOnAction); OP.Subscribe($"{Module}.{Name}.ExhaustOff", ExhaustOffAction); OP.Subscribe($"{Module}.KeyDown", KeyDownAction); OP.Subscribe($"{Module}.DisabledAction", DisabledOperation); OP.Subscribe($"{Module}.ManualAction", ManualOperation); OP.Subscribe($"{Module}.AutoAction", AutoOperation); OP.Subscribe($"{Module}.EngineeringModeAction", EngineeringModeOperation); OP.Subscribe($"{Module}.ProductionModeAction", ProductionModeOperation); OP.Subscribe($"{Module}.UpdateIsWaferPresenceAction", UpdateIsWaferPresenceAction); } /// 更新变量数值 /// /// /// private void UpdateVariableValue(string variable, object value) { if(!CommonData.IsDataInitialized) { CommonData.IsDataInitialized = true; } PropertyInfo property = CommonData.GetType().GetProperty(variable); if (property != null) { property.SetValue(CommonData, value); } UpdateWaferPresence(variable, value); } /// /// 更新Wafer Presence /// private void UpdateWaferPresence(string variable,object value) { if (variable == WAFER_PRESENCE&&value is double) { UpdateWaferPresence((double)value); } } /// /// 更新Wafer Presence /// /// private void UpdateWaferPresence(double waferPresence) { if (_srdPersistentValue != null) { if (waferPresence > _srdPersistentValue.EmptyThreshold) { _waferPresence = "Empty"; } else if (waferPresence >= _srdPersistentValue.WellPlacedHighThreshold && waferPresence <= _srdPersistentValue.EmptyThreshold) { _waferPresence = "PoorlyPlaced"; } else if (waferPresence < _srdPersistentValue.WellPlacedLowThreshold) { _waferPresence = "PoorlyPlaced"; } else { _waferPresence = "WellPlaced"; } } } #region Operation #region OperationStatus /// /// DisabledAction /// /// /// /// private bool DisabledOperation(string cmd, object[] args) { string currentOperation = "Disabled"; SRDEntity srdEntity = Singleton.Instance.GetModule(Module); if (srdEntity == null || _srdPersistentValue == null) return false; if (_srdPersistentValue.OperatingMode != "Disabled") srdEntity.EnterInit(); SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation); return true; } /// /// ManualAction /// /// /// /// private bool ManualOperation(string cmd, object[] args) { string currentOperation = "Manual"; SRDEntity srdEntity = Singleton.Instance.GetModule(Module); if (srdEntity == null || _srdPersistentValue == null) return false; if (_srdPersistentValue.OperatingMode == "Auto" && srdEntity.IsBusy) { LOG.WriteLog(eEvent.ERR_SRD, Module, $"{Module} is Busy, can't change to manual mode"); return false; } if (_srdPersistentValue.OperatingMode != "Manual") srdEntity.EnterInit(); SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation); return true; } /// /// AutoAction /// /// /// /// private bool AutoOperation(string cmd, object[] args) { string currentOperation = "Auto"; SRDEntity srdEntity = Singleton.Instance.GetModule(Module); if (srdEntity == null || _srdPersistentValue == null) return false; if (_srdPersistentValue.OperatingMode != "Auto") srdEntity.EnterInit(); SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation); return true; } /// /// EngineeringModeAction /// /// /// /// private bool EngineeringModeOperation(string cmd, object[] args) { string currentRecipeOperation = "Engineering"; SRDPersistentManager.Instance.UpdateRecipeOperationModeValue(Module, currentRecipeOperation); return true; } /// /// ProductionAction /// /// /// /// private bool ProductionModeOperation(string cmd, object[] args) { string currentRecipeOperation = "Production"; SRDPersistentManager.Instance.UpdateRecipeOperationModeValue(Module, currentRecipeOperation); return true; } #endregion #region keydown private bool KeyDownAction(string cmd, object[] args) { string variableName = args[0].ToString(); PropertyInfo property = _srdPersistentValue.GetType().GetProperty(variableName); if(property!=null) { property.SetValue(_srdPersistentValue, args[1]); } SRDPersistentManager.Instance.UpdateModulePersistentValue(Module); UpdateWaferPresence(CommonData.WaferPresence); return true; } #endregion #region Door /// /// Door Close操作 /// public bool DoorCloseAction(string cmd, object[] args) { if (!JudgeRunningState(SrdCommonOperation.DoorClose)) { _currentOperation = SrdCommonOperation.DoorClose; _status = _doorCloseRoutine.Start(true); return _status==RState.Running; } else { return false; } } /// /// Door Open操作 /// public bool DoorOpenAction(string cmd, object[] args) { if (!JudgeRunningState(SrdCommonOperation.DoorOpen)) { _currentOperation = SrdCommonOperation.DoorOpen; _status = _doorCloseRoutine.Start(false); return _status==RState.Running; } else { return false; } } #endregion #region Exhaust On /// /// Exhaust On /// /// /// /// public bool ExhaustOnAction(string cmd, object[] args) { return ExhaustOn(); } /// /// Exhaust Off /// /// /// /// public bool ExhaustOffAction(string cmd, object[] args) { return ExhaustOff(); } /// /// Exhaust On(不确认信号) /// /// public bool ExhaustOn() { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{EXHAUST_ON}"); return IOModuleManager.Instance.WriteIoValue(ioName, true); } /// /// Exhaust On(不确认信号) /// /// public bool ExhaustOff() { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{EXHAUST_ON}"); return IOModuleManager.Instance.WriteIoValue(ioName, false); } #endregion #region Chuck Vacuum /// /// Chuck Vacuum操作 /// public bool ChuckVacuumOnAction(string cmd, object[] args) { if (!JudgeRunningState(SrdCommonOperation.ChuckVacuumOn)) { _currentOperation = SrdCommonOperation.ChuckVacuumOn; _status = _chuckVacuumRoutine.Start(false); return _status==RState.Running; } else { return false; } } /// /// chuck Vacuum Off操作 /// public bool ChuckVacuumOffAction(string cmd, object[] args) { if (!JudgeRunningState(SrdCommonOperation.ChuckVacuumOff)) { _currentOperation = SrdCommonOperation.ChuckVacuumOff; _status= _chuckVacuumRoutine.Start(true); return _status==RState.Running; } else { return false; } } #endregion #region Water Above /// /// Water Above On操作 /// public bool WaterAboveOnAction(string cmd, object[] args) { return WaterAboveOn(); } /// /// water above Off操作 /// public bool WaterAboveOffAction(string cmd, object[] args) { return WaterAboveOff(); } /// /// Water Above On(不确认信号) /// /// public bool WaterAboveOn() { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ABOVE}"); return IOModuleManager.Instance.WriteIoValue(ioName, true); } /// /// Water Above Off(不确认信号) /// /// public bool WaterAboveOff() { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ABOVE}"); return IOModuleManager.Instance.WriteIoValue(ioName, false); } #endregion #region Water Below /// /// Water Below On操作 /// public bool WaterBelowOnAction(string cmd, object[] args) { return WaterBelowOn(); } /// /// water Below Off操作 /// public bool WaterBelowOffAction(string cmd, object[] args) { return WaterBelowOff(); } /// /// Water Below On(不确认信号) /// /// public bool WaterBelowOn() { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_BELOW}"); return IOModuleManager.Instance.WriteIoValue(ioName, true); } /// /// Water Below Off(不确认信号) /// /// public bool WaterBelowOff() { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_BELOW}"); return IOModuleManager.Instance.WriteIoValue(ioName, false); } #endregion /// /// Update IsWaferPresence 标志位 /// /// /// /// public bool UpdateIsWaferPresenceAction(string cmd, object[] args) { _isWaferPresence = (bool)args[0]; return true; } /// /// 判定运行状态 /// /// private bool JudgeRunningState(SrdCommonOperation operation) { if (_status == RState.Running) { EV.PostAlarmLog($"{Module}", eEvent.ERR_SRD, $"{Module} current execute {_currentOperation},cannot {operation}"); return true; } return false; } /// /// ErrorOperation /// public void EnterErrorOperation() { //关闭风扇 if (CommonData.ExhaustOn) { bool result = ExhaustOffAction("", null); if (!result) { LOG.WriteLog(eEvent.ERR_SRD, Module, "EnterError: Exhaust Off is failed"); } } //关闭WaterAbove if (CommonData.WaterAbove) { bool result = WaterAboveOff(); if (!result) { LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Above Off is failed"); } } //关闭WaterBelow if (CommonData.WaterBelow) { bool result = WaterBelowOff(); if (!result) { LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Below Off is failed"); } } //停电机 JetAxisBase _armAxis = DEVICE.GetDevice($"{Module}.Arm"); if (_armAxis != null && _armAxis.IsRun) _armAxis.StopPositionOperation(); JetAxisBase _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); if (_rotationAxis != null && _rotationAxis.IsRun) _rotationAxis.StopPositionOperation(); } #endregion /// /// 定时器 /// /// public bool OnTimer() { if (_status == RState.Running) { if (_currentOperation != SrdCommonOperation.None) { IRoutine routine = GetCurrentRoutine(_currentOperation); if (routine != null) { CheckRoutineState(routine, _currentOperation); } else { EndOperation(); } } } //将公有的数据赋值于对象的数值 if (_totalSRDDevice == null) { _totalSRDDevice = DEVICE.GetDevice("SRD"); } if (_totalSRDDevice != null) { CommonData.FluidContainment = _totalSRDDevice.FluidContainment; CommonData.WaterPressure = _totalSRDDevice.WaterPressure; } return true; } /// /// 获取当前操作对应的Routine /// /// /// private IRoutine GetCurrentRoutine(SrdCommonOperation currentOperation) { switch (currentOperation) { case SrdCommonOperation.DoorClose: case SrdCommonOperation.DoorOpen: return _doorCloseRoutine; case SrdCommonOperation.ChuckVacuumOn: case SrdCommonOperation.ChuckVacuumOff: return _chuckVacuumRoutine; default: return null; } } /// /// 检验Routine状态 /// /// /// private void CheckRoutineState(IRoutine routine, SrdCommonOperation currentOperation) { RState state = routine.Monitor(); if (state == RState.End) { EndOperation(); } else if (state == RState.Failed || state == RState.Timeout) { LOG.WriteLog(eEvent.ERR_SRD, $"{Module}", $"{currentOperation} error"); EndOperation(); } } /// /// 结束操作 /// private void EndOperation() { _status = RState.End; _currentOperation = SrdCommonOperation.None; } #region 设备接口 /// /// 监控 /// public void Monitor() { } public void Reset() { } public void Terminate() { } #endregion } }