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; using MECF.Framework.Common.CommonData.Dryer; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Persistent.Dryer; using MECF.Framework.Common.TwinCat; using MECF.Framework.Common.Utilities; using CyberX8_Core; using CyberX8_RT.Devices.Facilities; using System.Collections.Generic; using System.Reflection; using CyberX8_RT.Modules.Dryer; using CyberX8_RT.Modules; using MECF.Framework.Common.IOCore; namespace CyberX8_RT.Devices.Dryer { public class DryerDevice : BaseDevice, IDevice { #region 常量 private const string POWER_CONTROL = "PowerControl"; private const string EXHAUST_PRESSURE = "ExhaustPressure"; private const string BLOWER_HIGH = "BlowerHigh"; private const string EXHAUST_LIMIT_DATA = "ExhaustLimitData"; private const string EXHAUST_PRESSURE_VALUE = "ExhaustPressure"; private const string COMMON_DATA = "CommonData"; private const string PERSISTENT_VALUE = "PersistentValue"; #endregion /// /// Dryer操作枚举 /// private enum DryerCommonOperation { None, ControlPowerOn, ControlPowerOff, BlowerHigh, BlowerLow } #region 内部变量 /// /// 公用数据 /// private DryerCommonData _dryerCommonData; /// /// 状态 /// private RState _status; /// /// 当前操作 /// private DryerCommonOperation _currentOperation; /// /// Blower High Routine /// private DryerBlowerHighRoutine _blowerHighRoutine; /// /// ByPass /// private bool _byPass = false; /// /// Facilities /// private SystemFacilities _facilities; /// /// 变量是否初始化字典 /// private Dictionary _variableInitializeDic = new Dictionary(); /// /// 定时器Job /// PeriodicJob _periodicJob = null; /// /// Dryer 持久性数值对象 /// private DryerPersistentValue _dryerPersistentValue; #endregion #region 属性 /// /// 公用数据对象 /// public DryerCommonData CommonData { get { return _dryerCommonData; } } /// /// 所有io变量是否初始化 /// public bool IOInitialized { get { return IOVariableDictionaryUtil.AllIoVariableInitialized(eEvent.ERR_DRYER,Module,_variableInitializeDic); } } /// /// 状态 /// public RState Status { get { return _status; } } /// /// ByPass /// public bool Bypass { get { return _byPass; } } /// /// FacilityCommonLimitData /// public CommonLimitData FacilityCommonLimitData { get { return _facilities.GetCommonLimitDataByName(EXHAUST_PRESSURE_VALUE); } } #endregion /// /// 构造函数 /// /// /// public DryerDevice(string moduleName) : base(moduleName, moduleName,moduleName,moduleName) { _periodicJob = new PeriodicJob(100, OnTimer, $"{Module}.OnTimer", true); _dryerCommonData = new DryerCommonData(); } /// /// 初始化 /// /// public bool Initialize() { InitializeRoutine(); SubscribeData(); SubscribeValueAction(); InitializeOperation(); return true; } /// /// 初始化Routine /// private void InitializeRoutine() { _blowerHighRoutine = new DryerBlowerHighRoutine(Module, this); } /// /// 订阅数据 /// private void SubscribeData() { _dryerPersistentValue = DryerPersistentManager.Instance.GetDryerPersistentValue(Module); if (_dryerPersistentValue == null) { LOG.WriteLog(eEvent.ERR_DRYER, Module, "Persistent Value Object is not exist"); } DATA.Subscribe($"{Module}.{EXHAUST_LIMIT_DATA}", ()=>GetExhaustLimitData(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{COMMON_DATA}", () => CommonData, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _dryerPersistentValue,SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.ExhaustPressure",()=>CommonData.ExhaustPressure, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.PowerControl", () => CommonData.PowerControl, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.BlowerHigh", () => CommonData.BlowerHigh, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 获取Exhaust Limit 数据 /// /// private CommonLimitData GetExhaustLimitData() { if (_facilities == null) { _facilities = DEVICE.GetDevice("System.Facilities"); } if (_facilities == null) { return null; } return _facilities.GetCommonLimitDataByName(EXHAUST_PRESSURE_VALUE); } /// /// 订阅变量数值发生变化 /// private void SubscribeValueAction() { _variableInitializeDic[POWER_CONTROL] = false; IOModuleManager.Instance.SubscribeModuleVariable(Module, POWER_CONTROL, UpdateVariableValue); _variableInitializeDic[BLOWER_HIGH] = false; IOModuleManager.Instance.SubscribeModuleVariable(Module, BLOWER_HIGH, UpdateVariableValue); _variableInitializeDic[EXHAUST_PRESSURE] = false; IOModuleManager.Instance.SubscribeModuleVariable(Module, EXHAUST_PRESSURE, UpdateVariableValue); } /// 更新变量数值 /// /// /// 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); } if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable]) { _variableInitializeDic[variable] = true; } if(variable==BLOWER_HIGH) { if (CommonData.BlowerHigh) { DryerAutoOff.Instance.Stop(); } else if(CommonData.PowerControl) { DryerAutoOff.Instance.Start(); } } else if(variable==POWER_CONTROL) { if (CommonData.PowerControl) { DryerAutoOff.Instance.Start(); } else { DryerAutoOff.Instance.Stop(); } } } /// /// 初始化操作 /// private void InitializeOperation() { OP.Subscribe($"{Module}.PowerControlOn", PowerControlOnAction); OP.Subscribe($"{Module}.PowerControlOff", PowerControlOffAction); OP.Subscribe($"{Module}.BlowerHigh",BlowerHighAction); OP.Subscribe($"{Module}.BlowerLow", BlowerLowOnAction); OP.Subscribe($"{Module}.ByPass", (cmd, args) => { _byPass = (bool)args[0]; return true; }); 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); } /// /// 定时器 /// /// private bool OnTimer() { if (_status == RState.Running) { if (_currentOperation != DryerCommonOperation.None) { IRoutine routine = GetCurrentRoutine(_currentOperation); if (routine != null) { CheckRoutineState(routine, _currentOperation); } else { EndOperation(RState.End); } } } return true; } #region Action #region Power Control /// /// Power Control On操作 /// private bool PowerControlOnAction(string cmd, object[] args) { return PowerControlOn(); } /// /// Power Control Off操作 /// private bool PowerControlOffAction(string cmd, object[] args) { return PowerControlOff(); } /// /// Power Control On /// /// public bool PowerControlOn() { string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{POWER_CONTROL}"); bool result= IOModuleManager.Instance.WriteIoValue(ioName, true); if (result) { LOG.WriteLog(eEvent.INFO_DRYER, Module, "Power Control On Success"); } return result; } /// /// Power Control Off /// /// public bool PowerControlOff() { //检验任一HVD处于High On状态 if(CheckDryersIsInBlowerHigh()) { return false; } string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{POWER_CONTROL}"); bool result = IOModuleManager.Instance.WriteIoValue(ioName, false); if(result) { LOG.WriteLog(eEvent.INFO_DRYER, Module, "Power Control Off Success"); } return result; } /// /// 检验是否Dryers是否有处于BlowerHigh状态 /// /// public bool CheckDryersIsInBlowerHigh(bool error=true) { bool dryer1High = CheckDryerModuleIsInBlowerHigh(ModuleName.Dryer1); eEvent eEvent = eEvent.ERR_DRYER; if(!error) { eEvent = eEvent.INFO_DRYER; } if(dryer1High) { LOG.WriteLog(eEvent, Module, "Dryer1 is high on"); return true; } bool dryer2High = CheckDryerModuleIsInBlowerHigh(ModuleName.Dryer2); if (dryer2High) { LOG.WriteLog(eEvent, Module, "Dryer2 is high on"); return true; } bool dryer3High = CheckDryerModuleIsInBlowerHigh(ModuleName.Dryer3); if (dryer3High) { LOG.WriteLog(eEvent, Module, "Dryer3 is high on"); return true; } return false; } /// /// 检验Dryer模块是否处于Blower High /// /// /// private bool CheckDryerModuleIsInBlowerHigh(ModuleName moduleName) { if (ModuleHelper.IsInstalled(moduleName)) { DryerDevice dryerDevice1 = DEVICE.GetDevice(moduleName.ToString()); if (dryerDevice1 != null) { if (dryerDevice1.CommonData.BlowerHigh) { return true; } } } return false; } #endregion #region Blower High /// /// Blow High动作 /// /// /// /// public bool BlowerHighAction(string cmd, object[] args) { if(JudgeRunningState(DryerCommonOperation.BlowerHigh)) { return false; } if(CheckDryerModulePowerOff(ModuleHelper.Converter(Module))) { LOG.WriteLog(eEvent.ERR_DRYER, Module, $"{Module} is Power off"); return false; } _currentOperation = DryerCommonOperation.BlowerHigh; _status = _blowerHighRoutine.Start(_byPass); return _status == RState.Running; } /// /// Blower High On /// /// public bool BlowerHighOn() { if(CheckDryerModulePowerOff(ModuleHelper.Converter(Module))) { LOG.WriteLog(eEvent.ERR_DRYER, Module, $"{Module} is Power off"); return false; } CommonLimitData commonLimitData = GetExhaustLimitData(); if (commonLimitData.IsWarning || commonLimitData.IsError) { LOG.WriteLog(eEvent.ERR_DRYER, Module, "Exhuast Pressure is Abnormal"); return false; } string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{BLOWER_HIGH}"); bool result = IOModuleManager.Instance.WriteIoValue(ioName, true); if (result) { LOG.WriteLog(eEvent.INFO_DRYER, Module, "Blower High On Success"); } return result; } /// /// 检验Dryer模块是否处于PowerOff /// /// /// private bool CheckDryerModulePowerOff(ModuleName moduleName) { if (ModuleHelper.IsInstalled(moduleName)) { DryerDevice dryerDevice1 = DEVICE.GetDevice(moduleName.ToString()); if (dryerDevice1 != null) { if (dryerDevice1.IOInitialized&&!dryerDevice1.CommonData.PowerControl) { return true; } } } return false; } /// /// 检验是否Dryers是否有处于BlowerHigh状态 /// /// private bool CheckDryersPowerOff() { bool dryer1High = CheckDryerModulePowerOff(ModuleName.Dryer1); if (dryer1High) { LOG.WriteLog(eEvent.ERR_DRYER, Module, "Dryer1 is power off"); return true; } bool dryer2High = CheckDryerModulePowerOff(ModuleName.Dryer2); if (dryer2High) { LOG.WriteLog(eEvent.ERR_DRYER, Module, "Dryer2 is power off"); return true; } bool dryer3High = CheckDryerModulePowerOff(ModuleName.Dryer3); if (dryer3High) { LOG.WriteLog(eEvent.ERR_DRYER, Module, "Dryer3 is power off"); return true; } return false; } #endregion #region Blower Low /// /// Blower Low On Action /// /// /// /// private bool BlowerLowOnAction(string cmd, object[] args) { return BlowerLowOn(); } /// /// Blower Low On /// /// public bool BlowerLowOn() { //High off string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{BLOWER_HIGH}"); bool result= IOModuleManager.Instance.WriteIoValue(ioName, false); if(result) { string controlPowerOnName= BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{POWER_CONTROL}"); result= IOModuleManager.Instance.WriteIoValue(controlPowerOnName, true); } return result; } #endregion /// /// 判定运行状态 /// /// private bool JudgeRunningState(DryerCommonOperation operation) { if (_status == RState.Running) { LOG.WriteLog(eEvent.ERR_DRYER, Module, $"{Module} current execute {_currentOperation},cannot {operation}"); return true; } return false; } #endregion /// /// 获取当前操作对应的Routine /// /// /// private IRoutine GetCurrentRoutine(DryerCommonOperation currentOperation) { switch (currentOperation) { case DryerCommonOperation.BlowerHigh: return _blowerHighRoutine; default: return null; } } /// /// 检验Routine状态 /// /// /// private void CheckRoutineState(IRoutine routine, DryerCommonOperation currentOperation) { RState state = routine.Monitor(); if (state == RState.End) { EndOperation(RState.End); } else if (state == RState.Failed || state == RState.Timeout) { LOG.WriteLog(eEvent.ERR_DRYER, $"{Module}", $"{currentOperation} error"); EndOperation(RState.Failed); } } /// /// 结束操作 /// private void EndOperation(RState state) { _status = state; _currentOperation = DryerCommonOperation.None; } /// /// DisabledAction /// /// /// /// private bool DisabledOperation(string cmd, object[] args) { string currentOperation = "Disabled"; DryerEntity dryerEntity = Singleton.Instance.GetModule(Module); if(dryerEntity == null || _dryerPersistentValue == null) return false; if (_dryerPersistentValue.OperatingMode != "Disabled") dryerEntity.EnterInit(); _dryerPersistentValue.OperatingMode = currentOperation; DryerPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// ManualAction /// /// /// /// private bool ManualOperation(string cmd, object[] args) { string currentOperation = "Manual"; DryerEntity dryerEntity = Singleton.Instance.GetModule(Module); if (dryerEntity == null || _dryerPersistentValue == null) return false; if(_dryerPersistentValue.OperatingMode == "Auto" && dryerEntity.IsBusy) { LOG.WriteLog(eEvent.ERR_DRYER, Module, $"{Module} is Busy, can't change to manual mode"); return false; } if (_dryerPersistentValue.OperatingMode != "Manual") dryerEntity.EnterInit(); _dryerPersistentValue.OperatingMode = currentOperation; DryerPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// AutoAction /// /// /// /// private bool AutoOperation(string cmd, object[] args) { string currentOperation = "Auto"; DryerEntity dryerEntity = Singleton.Instance.GetModule(Module); if (dryerEntity == null || _dryerPersistentValue == null) return false; if (_dryerPersistentValue.OperatingMode != "Auto") dryerEntity.EnterInit(); _dryerPersistentValue.OperatingMode= currentOperation; DryerPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// EngineeringModeAction /// /// /// /// private bool EngineeringModeOperation(string cmd, object[] args) { string currentRecipeOperation = "Engineering"; _dryerPersistentValue.RecipeOperatingMode = currentRecipeOperation; DryerPersistentManager.Instance.UpdatePersistentValue(Module); return true; } /// /// ProductionAction /// /// /// /// private bool ProductionModeOperation(string cmd, object[] args) { string currentRecipeOperation = "Production"; _dryerPersistentValue.RecipeOperatingMode= currentRecipeOperation; DryerPersistentManager.Instance.UpdatePersistentValue(Module); return true; } #region 设备接口 /// /// 监控 /// public void Monitor() { } public void Reset() { } /// /// 中止 /// public void Terminate() { _periodicJob.Stop(false); } #endregion } }