using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Beckhoff.ModuleIO; using MECF.Framework.Common.CommonData.PlatingCell; using MECF.Framework.Common.CommonData.Reservoir; using MECF.Framework.Common.IOCore; using MECF.Framework.Common.Persistent.Reservoirs; using MECF.Framework.Common.ToolLayout; using PunkHPX8_Core; using PunkHPX8_RT.Devices.LinMot; using PunkHPX8_RT.Devices.PowerSupplier; using PunkHPX8_RT.Devices.Reservoir; using PunkHPX8_RT.Modules; using PunkHPX8_RT.Modules.PlatingCell; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Devices.PlatingCell { public class PlatingCellDevice : BaseDevice, IDevice { #region 常量 private const string PERSISTENT_VALUE = "PersistentValue"; private const string AUTO = "Auto"; private const string MANUAL = "Manual"; private const string STRATUS = "Stratus"; private const string DISABLED = "Disabled"; private const string IS_HEAD_TILT = "IsHeadTilt"; private const string IS_HEAD_VERTICAL = "IsHeadVertical"; private const string CLAMSHELL_DISTANCE = "ClamShellDistance"; private const string CLAMSHELL_CYLINDER_PRESSURE = "ClamShellCylinderPressure"; private const string OVERFLOW_LEVEL = "OverFlowLevel"; private const string CLAMSHELL_CLOSE = "ClamShellClose"; private const string HEAD_TILT = "HeadTilt"; #endregion #region 内部变量 /// 变量是否初始化字典 /// private Dictionary _variableInitializeDic = new Dictionary(); /// /// 操作当前状态 /// protected RState _status; /// /// 持久化数据 /// protected PlatingCellPersistentValue _persistentValue; /// /// PlatingCell项 /// private PlatingCellItem _platingCellItem; #endregion #region 属性 /// /// 状态 /// public RState Status { get { return _status; } } /// /// 是否禁用 /// public bool IsDisable { get { return _persistentValue == null || _persistentValue.OperatingMode == DISABLED; } } /// /// 操作模式 /// public string OperationMode { get { return _persistentValue.OperatingMode; } } /// /// 工程模式 /// public string EngineerMode { get { return _persistentValue.RecipeOperatingMode; } } /// /// 是否为Auto /// public bool IsAuto { get { return _persistentValue != null ? _persistentValue.OperatingMode == AUTO : false; } } /// /// 是否为Auto /// public bool IsManual { get { return _persistentValue != null ? _persistentValue.OperatingMode == MANUAL : false; } } #endregion #region 共享变量 /// /// 数据 /// protected PlatingCellData _platingCellData = new PlatingCellData(); #endregion /// /// 构造函数 /// /// public PlatingCellDevice(string moduleName) : base(moduleName, moduleName, moduleName, moduleName) { } /// /// 初始化 /// /// public virtual bool Initialize() { InitializeParameter(); SubscribeData(); InitializeOperation(); SubscribeValueAction(); return true; } /// /// 定时器执行 /// public virtual bool OnTimer(int interval) { return true; } /// /// 初始化参数 /// private void InitializeParameter() { _persistentValue = PlatingCellPersistentManager.Instance.GetPlatingCellPersistentValue(Module); if (_persistentValue == null) { LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Persistent Value Object is not exist"); } _platingCellItem = PlatingCellItemManager.Instance.GetPlatingCellItem(Module); if (_platingCellItem != null) { } } protected virtual void SubscribeValueAction() { IoSubscribeUpdateVariable(IS_HEAD_TILT); IoSubscribeUpdateVariable(IS_HEAD_VERTICAL); IoSubscribeUpdateVariable(CLAMSHELL_DISTANCE); IoSubscribeUpdateVariable(CLAMSHELL_CYLINDER_PRESSURE); IoSubscribeUpdateVariable(OVERFLOW_LEVEL); IoSubscribeUpdateVariable(CLAMSHELL_CLOSE); IoSubscribeUpdateVariable(HEAD_TILT); } /// /// 订阅IO变量 /// /// protected void IoSubscribeUpdateVariable(string variable) { _variableInitializeDic[variable] = false; IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue); } /// /// 更新变量数值 /// /// /// private void UpdateVariableValue(string variable, object value) { if (!_platingCellData.IsDataInitialized) { _platingCellData.IsDataInitialized = true; } PropertyInfo property = _platingCellData.GetType().GetProperty(variable); if (property != null) { property.SetValue(_platingCellData, value); } if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable]) { _variableInitializeDic[variable] = true; } } /// /// 写变量 /// /// /// /// protected bool WriteVariableValue(string variable, object value) { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{variable}"); return IOModuleManager.Instance.WriteIoValue(ioName, value); } /// /// 订阅数据 /// private void SubscribeData() { DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _persistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 初始化操作 /// protected virtual void InitializeOperation() { 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}.SetPlatingCellWaferSize", (cmd, args) => { return SetPlatingCellWaferSize(cmd, args); }); OP.Subscribe($"{Module}.ClamShellClose", (cmd, para) => { return ClamShellClose(); }); OP.Subscribe($"{Module}.ClamShellOpen", (cmd, para) => { return ClamShellOpen(); }); OP.Subscribe($"{Module}.HeadtTilt", (cmd, para) => { return HeadtTiltAction(); }); OP.Subscribe($"{Module}.HeadVertical", (cmd, para) => { return HeadtVerticalAction(); }); } #region Operation public bool ClamShellClose() { return WriteVariableValue(CLAMSHELL_CLOSE, true); } public bool ClamShellOpen() { return WriteVariableValue(CLAMSHELL_CLOSE, false); } public bool HeadtTiltAction() { return WriteVariableValue(HEAD_TILT, true); } public bool HeadtVerticalAction() { return WriteVariableValue(HEAD_TILT, false); } /// /// DisabledAction /// /// /// /// public bool DisabledOperation(string cmd, object[] args) { string currentOperation = "Disabled"; PlatingCellEntity platingCellEntity = Singleton.Instance.GetModule(Module); if (platingCellEntity != null && _persistentValue != null && _persistentValue.OperatingMode != currentOperation) { string preOperation = _persistentValue.OperatingMode; if (platingCellEntity.IsBusy) { LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} is Busy, can't switch to Disabled mode"); return false; } //if (SchedulerMetalTimeManager.Instance.Contained(Module)) //{ // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} is in scheduler, can't switch to Disabled mode"); // return false; //} platingCellEntity.EnterInit(); _persistentValue.OperatingMode = currentOperation; LOG.WriteLog(eEvent.INFO_METAL, Module, $"Operating mode is switched from {preOperation} to {currentOperation}"); } PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// ManualAction /// /// /// /// public bool ManualOperation(string cmd, object[] args) { string currentOperation = "Manual"; PlatingCellEntity platingCellEntity = Singleton.Instance.GetModule(Module); if (platingCellEntity != null && _persistentValue != null && _persistentValue.OperatingMode != currentOperation) { string preOperation = _persistentValue.OperatingMode; if (platingCellEntity.IsBusy) { LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} is Busy, can't switch to Manual mode"); return false; } //if (SchedulerMetalTimeManager.Instance.Contained(Module)) //{ // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} is in scheduler, can't switch to Manual mode"); // return false; //} platingCellEntity.EnterInit(); _persistentValue.OperatingMode = currentOperation; LOG.WriteLog(eEvent.INFO_METAL, Module, $"Operating mode is switched from {preOperation} to {currentOperation}"); } PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// AutoAction /// /// /// /// public bool AutoOperation(string cmd, object[] args) { string currentOperation = "Auto"; PlatingCellEntity platingCellEntity = Singleton.Instance.GetModule(Module); if (platingCellEntity != null && _persistentValue != null && _persistentValue.OperatingMode != currentOperation) { string preOperation = _persistentValue.OperatingMode; if (platingCellEntity.IsBusy) { LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} is Busy, can't switch to Auto mode"); return false; } platingCellEntity.EnterInit(); _persistentValue.OperatingMode = currentOperation; LOG.WriteLog(eEvent.INFO_METAL, Module, $"Operating mode is switched from {preOperation} to {currentOperation}"); } PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// EngineeringModeAction /// /// /// /// private bool EngineeringModeOperation(string cmd, object[] args) { string currentRecipeOperation = "Engineering"; if (_persistentValue != null) { _persistentValue.RecipeOperatingMode = currentRecipeOperation; } PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// ProductionAction /// /// /// /// private bool ProductionModeOperation(string cmd, object[] args) { string currentRecipeOperation = "Production"; if (_persistentValue != null) { _persistentValue.RecipeOperatingMode = currentRecipeOperation; } PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module); return true; } private bool SetPlatingCellWaferSize(string cmd, object[] args) { string metalWaferSize = args[0] as string; if (_persistentValue != null) { _persistentValue.PlatingCellWaferSize = int.Parse(metalWaferSize); } PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module); return true; } #endregion public virtual void Monitor() { } public virtual void Reset() { } public virtual void Terminate() { } } }