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
}
}