using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
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.Algorithm;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.CommonData.Prewet;
using MECF.Framework.Common.Device.ResistivityProbe;
using MECF.Framework.Common.Device.Rinse;
using MECF.Framework.Common.Persistent.Prewet;
using MECF.Framework.Common.Persistent.Rinse;
using MECF.Framework.Common.RecipeCenter;
using MECF.Framework.Common.ToolLayout;
using MECF.Framework.Common.TwinCat;
using System.Collections.Generic;
using System.Reflection;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Rinse;
using CyberX8_RT.Devices.Resistivity;
using CyberX8_RT.Modules.Prewet;
using MECF.Framework.Common.IOCore;
namespace CyberX8_RT.Devices.Rinse
{
public class RinseDevice : BaseDevice, IDevice
{
private enum RinseOperation
{
None
}
#region 常量
private const string WATER_LEVEL="WaterLevel";
private const string WAFER_HOLDER_CLAMP="WaferHolderClamp";
private const string N2_VALVE="N2Valve";
private const string FILL_VALVE="FillValve";
private const string DRAIN_VALVE="DrainValve";
private const string WASTE_VALVE="WasteValve";
private const string RESISTIVITY="Resistivity";
private const string PERSISTENT_VALUE = "PersistentValue";
private const string RINSEDATA = "RinseData";
private const string RINSEITEM = "RinseItem";
private const string RESISTIVITYVALUE = "Resistivity";
#endregion
#region 内部变量
///
/// 数据
///
private RinseData _rinseData = new RinseData();
///
/// Rinse 持久性数值对象
///
private RinsePersistentValue _rinsePersistentValue;
///
/// 变量是否初始化字典
///
private Dictionary _variableInitializeDic = new Dictionary();
///
/// ByPass Inter Locks
///
private bool _bypassInterLocks = false;
///
/// RinseItem
///
private RinseItem _rinseItem = new RinseItem();
///
/// 工艺当前执行小步骤
///
private string _currentStateMachine = "Init";
///
/// 工艺当前执行大步骤
///
private string _currentStatus = "Init";
///
/// 水阻值
///
private double _resistivityValue;
///
/// 水阻计控制器
///
private ResistivityController _resistivityController;
#endregion
#region 属性
///
/// Rinse数据
///
public RinseData RinseData { get { return _rinseData; } }
///
/// 所有io变量是否初始化
///
public bool IOInitialized { get { return AllIoVariableInitialized(); } }
///
/// 所有io变量是否初始化
///
public RinseItem RinseItem { get { return _rinseItem; } }
///
/// 当前状态机
///
public string CurrentStateMachine { get { return _currentStateMachine; } }
#endregion
///
/// 构造函数
///
///
///
public RinseDevice(string moduleName) : base(moduleName, moduleName, moduleName, moduleName)
{
}
///
/// 初始化
///
///
public bool Initialize()
{
SubscribeData();
SubscribeValueAction();
InitializeOperation();
return true;
}
///
/// 订阅数据
///
private void SubscribeData()
{
_rinsePersistentValue = RinsePersistentManager.Instance.GetRinsePersistentValue(Module);
if (_rinsePersistentValue == null)
{
LOG.WriteLog(eEvent.ERR_RINSE, Module, "Persistent Value Object is not exist");
}
_rinseItem = RinseItemManager.Instance.GetRinseItem(Module);
_resistivityController = DEVICE.GetDevice(RinseItem.ResistivityID);
DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _rinsePersistentValue,SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.{RINSEDATA}", () => _rinseData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.CurrentStateMachine", () => _currentStateMachine, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.CurrentStatus", () => _currentStatus, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.Resistivity.ID", () => _resistivityController != null ? _resistivityController.Module : "", SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.{RESISTIVITYVALUE}", () => {
if (_resistivityController != null)
{
string value = _resistivityController.ResisitivityValue;
if(double.TryParse(value, out _resistivityValue))
{
return _resistivityValue;
}
else
{
return 0;
}
}
else
{
return 0;
}
}, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.WaterLevel", () => RinseData.WaterLevel, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.DIFillEnable",()=>RinseData.FillValve, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.DrainEnable", () => RinseData.DrainValve, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.N2Enable",()=>RinseData.N2Valve, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.WaferShuttleClamped",()=>RinseData.WaferHolderClamp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
DATA.Subscribe($"{Module}.WasteEnable", () => RinseData.WasteValve, SubscriptionAttribute.FLAG.IgnoreSaveDB);
}
///
/// 订阅变量数值发生变化
///
private void SubscribeValueAction()
{
BeckhoffIoSubscribeUpdateVariable(WATER_LEVEL);
BeckhoffIoSubscribeUpdateVariable(WASTE_VALVE);
BeckhoffIoSubscribeUpdateVariable(WAFER_HOLDER_CLAMP);
BeckhoffIoSubscribeUpdateVariable(N2_VALVE);
BeckhoffIoSubscribeUpdateVariable(FILL_VALVE);
BeckhoffIoSubscribeUpdateVariable(DRAIN_VALVE);
}
///
/// 初始化Operation
///
private void InitializeOperation()
{
OP.Subscribe($"{Module}.ClampValveOn", (cmd, args) => { return WaferHolderClampValveOn(); });
OP.Subscribe($"{Module}.ClampValveOff", (cmd, args) => { return WaferHolderClampValveOff(); });
OP.Subscribe($"{Module}.N2ValveOn", (cmd, args) => { return N2ValveOn(); });
OP.Subscribe($"{Module}.N2ValveOff", (cmd, args) => { return N2ValveOff(); });
OP.Subscribe($"{Module}.FillValveOn", (cmd, args) => { return FillValveOn(); });
OP.Subscribe($"{Module}.FillValveOff", (cmd, args) => { return FillValveOff(); });
OP.Subscribe($"{Module}.DrainValveOn", (cmd, args) => { return DrainValveOn(); });
OP.Subscribe($"{Module}.DrainValveOff", (cmd, args) => { return DrainValveOff(); });
OP.Subscribe($"{Module}.WasteValveOn", (cmd, args) => { return WasteValveOff() ;});
OP.Subscribe($"{Module}.WasteValveOff", (cmd, args) => { return WasteValveOn() ;});
OP.Subscribe($"{Module}.ByPassInterLocks", (cms, args) => { _bypassInterLocks = (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);
}
///
/// 订阅IO变量
///
///
private void BeckhoffIoSubscribeUpdateVariable(string variable)
{
_variableInitializeDic[variable] = false;
IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue);
}
///
/// 更新变量数值
///
///
///
private void UpdateVariableValue(string variable, object value)
{
if (!RinseData.IsDataInitialized)
{
RinseData.IsDataInitialized = true;
}
PropertyInfo property = RinseData.GetType().GetProperty(variable);
if (property != null)
{
property.SetValue(RinseData, value);
}
if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable])
{
_variableInitializeDic[variable] = true;
}
}
///
/// 是否所有IO变量初始化完成
///
///
private bool AllIoVariableInitialized()
{
foreach (string item in _variableInitializeDic.Keys)
{
if (!_variableInitializeDic[item])
{
LOG.WriteLog(eEvent.ERR_DRYER, Module, $"{item} is not initialized");
return false;
}
}
return true;
}
#region Operation
///
/// DisabledAction
///
///
///
///
private bool DisabledOperation(string cmd, object[] args)
{
string currentOperation = "Disabled";
RinseEntity rinseEntity = Singleton.Instance.GetModule(Module);
if (rinseEntity == null || _rinsePersistentValue == null) return false;
if (_rinsePersistentValue.OperatingMode != "Disabled") rinseEntity.EnterInit();
_rinsePersistentValue.OperatingMode = currentOperation;
RinsePersistentManager.Instance.UpdatePersistentValue(Module);
return true;
}
///
/// ManualAction
///
///
///
///
private bool ManualOperation(string cmd, object[] args)
{
string currentOperation = "Manual";
RinseEntity rinseEntity = Singleton.Instance.GetModule(Module);
if (rinseEntity == null || _rinsePersistentValue == null) return false;
if (_rinsePersistentValue.OperatingMode == "Auto" && rinseEntity.IsBusy)
{
LOG.WriteLog(eEvent.ERR_RINSE, Module, $"{Module} is Busy, can't change to manual mode");
return false;
}
if (_rinsePersistentValue.OperatingMode != "Manual") rinseEntity.EnterInit();
_rinsePersistentValue.OperatingMode = currentOperation;
RinsePersistentManager.Instance.UpdatePersistentValue(Module);
return true;
}
///
/// AutoAction
///
///
///
///
private bool AutoOperation(string cmd, object[] args)
{
string currentOperation = "Auto";
RinseEntity rinseEntity = Singleton.Instance.GetModule(Module);
if (rinseEntity == null || _rinsePersistentValue == null) return false;
if (_rinsePersistentValue.OperatingMode != "Auto") rinseEntity.EnterInit();
_rinsePersistentValue.OperatingMode = currentOperation;
RinsePersistentManager.Instance.UpdatePersistentValue(Module);
return true;
}
///
/// EngineeringModeAction
///
///
///
///
private bool EngineeringModeOperation(string cmd, object[] args)
{
string currentRecipeOperation = "Engineering";
_rinsePersistentValue.RecipeOperatingMode = currentRecipeOperation;
RinsePersistentManager.Instance.UpdatePersistentValue(Module);
return true;
}
///
/// ProductionAction
///
///
///
///
private bool ProductionModeOperation(string cmd, object[] args)
{
string currentRecipeOperation = "Production";
_rinsePersistentValue.RecipeOperatingMode = currentRecipeOperation;
RinsePersistentManager.Instance.UpdatePersistentValue(Module);
return true;
}
#endregion
///
/// 更新当前工艺小步骤
///
///
public void UpdateStateMachine(string tmp)
{
_currentStateMachine = tmp;
}
///
/// 更新当前工艺大步骤
///
///
public void UpdateStatus(string tmp)
{
_currentStatus = tmp;
}
#region Wafer Holder Clamp Valve
///
/// Wafer Holder Clamp Valve On
///
///
public bool WaferHolderClampValveOn()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WAFER_HOLDER_CLAMP}");
return IOModuleManager.Instance.WriteIoValue(ioName, true);
}
///
/// Wafer Holder Clamp Valve Off
///
///
public bool WaferHolderClampValveOff()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WAFER_HOLDER_CLAMP}");
return IOModuleManager.Instance.WriteIoValue(ioName, false);
}
#endregion
#region N2 Valve
///
/// N2 Valve On
///
///
public bool N2ValveOn()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{N2_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, true);
}
///
/// N2 Valve Off
///
///
public bool N2ValveOff()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{N2_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, false);
}
#endregion
#region Fill Valve
///
/// Fill Valve On
///
///
public bool FillValveOn()
{
if(!_bypassInterLocks)
{
//Clamp Status必须为Clamped
if(!_rinseData.WaferHolderClamp)
{
LOG.WriteLog(eEvent.ERR_RINSE, Module, "Clamp Status is not Clamped");
return false;
}
}
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{FILL_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, true);
}
///
/// Fill Valve Off
///
///
public bool FillValveOff()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{FILL_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, false);
}
#endregion
#region Drain Valve
///
/// Drain Valve On
///
///
public bool DrainValveOn()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{DRAIN_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, true);
}
///
/// Drain Valve Off
///
///
public bool DrainValveOff()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{DRAIN_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, false);
}
#endregion
#region Waste Valve
///
/// Waste Valve On
///
///
public bool WasteValveOn()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WASTE_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, true);
}
///
/// Waste Valve Off(等价于Metal Valve On)
///
///
public bool WasteValveOff()
{
string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WASTE_VALVE}");
return IOModuleManager.Instance.WriteIoValue(ioName, false);
}
#endregion
public void Monitor()
{
}
public void Reset()
{
}
public void Terminate()
{
}
}
}