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;
using Aitex.Core.Common;

namespace CyberX8_RT.Devices.SRD
{
    public class SrdCommonDevice : BaseDevice, IDevice
    {
        /// <summary>
        /// Srd操作枚举
        /// </summary>
        private enum SrdCommonOperation
        {
            None,
            DoorClose,
            DoorOpen,
            ChuckVacuumOn,
            ChuckVacuumOff,
            LiftUpOn,
            LiftUpOff,
            FlippersIn,
            FlippersOut,
            ChuckATMClick
        }

        #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";

        private const string CHUCK_ATM_ON = "ChuckATMOn";
        private const string CHUCK_VACUUM_OK = "ChuckVacuumOK";
        private const string WAFER_PRESENT = "WaferPresent";
        private const string LIFT_UP = "LiftUp";
        private const string LIFT_UP_STATUS = "LiftUpStatus";
        private const string FLIPPER1_OUT_100_STATUS = "Flipper1Out100Status";
        private const string FLIPPER2_OUT_100_STATUS = "Flipper2Out100Status";
        private const string FLIPPER3_OUT_100_STATUS = "Flipper3Out100Status";
        private const string FLIPPER1_OUT_150_STATUS = "Flipper1Out150Status";
        private const string FLIPPER2_OUT_150_STATUS = "Flipper2Out150Status";
        private const string FLIPPER3_OUT_150_STATUS = "Flipper3Out150Status";
        private const string FLIPPER1_OUT_200_STATUS = "Flipper1Out200Status";
        private const string FLIPPER2_OUT_200_STATUS = "Flipper2Out200Status";
        private const string FLIPPER3_OUT_200_STATUS = "Flipper3Out200Status";
        private const string FLIPPERS_IN_100 = "FlippersIn100";
        private const string FLIPPERS_IN_150 = "FlippersIn150";
        private const string FLIPPERS_IN_200 = "FlippersIn200";
        private const string WATER_FLOW = "WaterFlow";
        private const string WATER_ON = "WaterOn";
        private const string N2_ON= "N2On";
        #endregion

        #region 内部变量
        /// <summary>
        /// Common数据
        /// </summary>
        private SrdCommonData _commonData = new SrdCommonData();
        /// <summary>
        /// 状态
        /// </summary>
        private RState _status;
        /// <summary>
        /// 当前操作
        /// </summary>
        private SrdCommonOperation _currentOperation;
        /// <summary>
        /// Wafer Presence
        /// </summary>
        private string _waferPresence;
        /// <summary>
        /// Persistent Value对象
        /// </summary>
        private SRDPersistentValue _srdPersistentValue;
        /// <summary>
        /// IsWaferPresence
        /// </summary>
        private bool _isWaferPresence = true;
        /// <summary>
        /// Total Device
        /// </summary>
        private TotalSRDDevice _totalSRDDevice;
        #region Routine
        /// <summary>
        /// Close Routine
        /// </summary>
        private SrdCommonDoorCloseRoutine _doorCloseRoutine;
        /// <summary>
        /// Vacuum Routine
        /// </summary>
        private SrdCommonChuckVacuumRoutine _chuckVacuumRoutine;
        /// <summary>
        /// Lift Up routine
        /// </summary>
        private SrdCommonLiftUpRoutine _liftUpRoutine;
        /// <summary>
        /// Flippers Routine
        /// </summary>
        private SrdCommonFlipperRoutine _flipperRoutine;
        /// <summary>
        /// Chuck ATM Click Routine
        /// </summary>
        private SrdCommonChuckATMRoutine _chuckATMRoutine;
        #endregion

        #endregion

        #region 属性
        /// <summary>
        /// Common数据
        /// </summary>
        public SrdCommonData CommonData
        {
            get { return _commonData; }
        }
        /// <summary>
        /// 状态
        /// </summary>
        public RState Status { get { return _status; } }
        /// <summary>
        /// Wafer Presence
        /// </summary>
        public string WaferPresence 
        {
            get { return _waferPresence; }
        }
        /// <summary>
        /// IsWaferPresence
        /// </summary>
        public bool IsWaferPresence
        {
            get { return _isWaferPresence; }
        }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="moduleName"></param>
        /// <param name="name"></param>
        public SrdCommonDevice(string moduleName) : base(moduleName, "Common", "Common", "Common")
        {
        }      
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public bool Initialize()
        {
            InitializeRoutine();
            SubscribeData();
            SubscribeValueAction();
            InitializeOperation();
            return true;
        }
        /// <summary>
        /// 初始化Routine
        /// </summary>
        private void InitializeRoutine()
        {
            _doorCloseRoutine = new SrdCommonDoorCloseRoutine(Module);
            _chuckVacuumRoutine = new SrdCommonChuckVacuumRoutine(Module);
            _liftUpRoutine = new SrdCommonLiftUpRoutine(Module);
            _flipperRoutine = new SrdCommonFlipperRoutine(Module);
            _chuckATMRoutine = new SrdCommonChuckATMRoutine(Module);    
        }
        /// <summary>
        /// 订阅数据
        /// </summary>
        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);
        }
        /// <summary>
        /// 订阅变量数值发生变化
        /// </summary>
        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);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, CHUCK_ATM_ON, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, CHUCK_VACUUM_OK, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, WAFER_PRESENT, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, LIFT_UP, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, LIFT_UP_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER1_OUT_100_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER2_OUT_100_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER3_OUT_100_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER1_OUT_150_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER2_OUT_150_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER3_OUT_150_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER1_OUT_200_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER2_OUT_200_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPER3_OUT_200_STATUS, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPERS_IN_100, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPERS_IN_150, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, FLIPPERS_IN_200, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, WATER_FLOW, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, N2_ON, UpdateVariableValue);
            IOModuleManager.Instance.SubscribeModuleVariable(Module, WATER_ON, UpdateVariableValue);

        }
        /// <summary>
        /// 初始化操作
        /// </summary>
        private void InitializeOperation()
        {
            OP.Subscribe($"{Module}.{Name}.DoorClose", DoorCloseAction);
            OP.Subscribe($"{Module}.{Name}.DoorOpen", DoorOpenAction);
            OP.Subscribe($"{Module}.{Name}.WaterOn", WaterOnAction);
            OP.Subscribe($"{Module}.{Name}.WaterOff", WaterOffAction);
            OP.Subscribe($"{Module}.{Name}.ChuckVacuumOn", ChuckVacuumOnAction);
            OP.Subscribe($"{Module}.{Name}.ChuckVacuumOff", ChuckVacuumOffAction);
            OP.Subscribe($"{Module}.{Name}.N2On", N2OnAction);
            OP.Subscribe($"{Module}.{Name}.N2Off", N2OffAction);
            OP.Subscribe($"{Module}.{Name}.LiftUpOn", LiftUpOnAction);
            OP.Subscribe($"{Module}.{Name}.LiftUpOff", LiftUpOffAction);
            OP.Subscribe($"{Module}.{Name}.ChuckATMOn", ChuckATMOnAction);
            OP.Subscribe($"{Module}.{Name}.ChuckATMOff", ChuckATMOffAction);
            OP.Subscribe($"{Module}.{Name}.FlipperIn", FlipperInAction);
            OP.Subscribe($"{Module}.{Name}.FlipperOut", FlipperOutAction);

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

        /// 更新变量数值
        /// </summary>
        /// <param name="variable"></param>
        /// <param name="value"></param>
        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);

        }
        /// <summary>
        /// 更新Wafer Presence
        /// </summary>
        private void UpdateWaferPresence(string variable,object value)
        {
            if (variable == WAFER_PRESENCE&&value is double)
            {
                UpdateWaferPresence((double)value);
            }
        }
        /// <summary>
        /// 更新Wafer Presence
        /// </summary>
        /// <param name="waferPresence"></param>
        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
        /// <summary>
        /// DisabledAction
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        private bool DisabledOperation(string cmd, object[] args)
        {
            string currentOperation = "Disabled";
            SRDEntity srdEntity = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(Module);
            if (srdEntity == null || _srdPersistentValue == null) return false;
            if (_srdPersistentValue.OperatingMode != "Disabled") srdEntity.EnterInit();
            SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation);
            return true;
        }
        /// <summary>
        /// ManualAction
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        private bool ManualOperation(string cmd, object[] args)
        {
            string currentOperation = "Manual";
            SRDEntity srdEntity = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(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;
        }
        /// <summary>
        /// AutoAction
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        private bool AutoOperation(string cmd, object[] args)
        {
            string currentOperation = "Auto";
            SRDEntity srdEntity = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(Module);
            if (srdEntity == null || _srdPersistentValue == null) return false;
            if (_srdPersistentValue.OperatingMode != "Auto") srdEntity.EnterInit();
            SRDPersistentManager.Instance.UpdateOperationModeValue(Module,currentOperation);
            return true;
        }
        /// <summary>
        /// EngineeringModeAction
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        private bool EngineeringModeOperation(string cmd, object[] args)
        {
            string currentRecipeOperation = "Engineering";
            SRDPersistentManager.Instance.UpdateRecipeOperationModeValue(Module, currentRecipeOperation);
            return true;
        }
        /// <summary>
        /// ProductionAction
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        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 
        /// <summary>
        /// Door Close操作
        /// </summary>
        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;
            }
        }
        /// <summary>
        /// Door Open操作
        /// </summary>
        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 N2 On
        /// <summary>
        /// N2 On
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool N2OnAction(string cmd, object[] args)
        {
            return N2On();
        }
        /// <summary>
        /// N2 Off
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool N2OffAction(string cmd, object[] args)
        {
            return N2Off();
        }
        /// <summary>
        /// Exhaust On(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool N2On()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{N2_ON}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }

        /// <summary>
        /// Exhaust On(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool N2Off()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{N2_ON}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion

        #region Flipper      
        /// <summary>
        /// FlipperIn
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool FlipperInAction(string cmd, object[] args)
        {
            int waferSize = (int)args[0];
            if (!JudgeRunningState(SrdCommonOperation.FlippersIn))
            {
                _currentOperation = SrdCommonOperation.FlippersIn;
                _status = _flipperRoutine.Start(true, waferSize);
                return _status == RState.Running;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// FlipperOut
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool FlipperOutAction(string cmd, object[] args)
        {
            int waferSize = (int)args[0];
            if (!JudgeRunningState(SrdCommonOperation.FlippersOut))
            {
                _currentOperation = SrdCommonOperation.FlippersOut;
                _status = _flipperRoutine.Start(false, waferSize);
                return _status == RState.Running;
            }
            else
            {
                return false;
            }
        }
        #endregion
        #region Water
        /// <summary>
        /// Water On操作
        /// </summary>
        public bool WaterOnAction(string cmd, object[] args)
        {
            return WaterOn();
        }
        /// <summary>
        /// water Off操作
        /// </summary>
        public bool WaterOffAction(string cmd, object[] args)
        {
            return WaterOff();
        }
        /// <summary>
        /// Water On(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool WaterOn()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ON}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// <summary>
        /// Water Off(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool WaterOff()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ON}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion

        #region Chuck Vacuum 
        /// <summary>
        /// Chuck Vacuum操作
        /// </summary>
        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;
            }
        }
        /// <summary>
        /// chuck Vacuum Off操作
        /// </summary>
        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 LiftUp
        /// <summary>
        /// Lift Up On
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool LiftUpOnAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(SrdCommonOperation.LiftUpOn))
            {
                _currentOperation = SrdCommonOperation.LiftUpOn;
                _status = _liftUpRoutine.Start(true);
                return _status == RState.Running;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Lift Up Off
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool LiftUpOffAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(SrdCommonOperation.LiftUpOff))
            {
                _currentOperation = SrdCommonOperation.LiftUpOff;
                _status = _liftUpRoutine.Start(false);
                return _status == RState.Running;
            }
            else
            {
                return false;
            }
        }       
        #endregion

        #region ChuckATM
        /// <summary>
        /// Chuck ATM On
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool ChuckATMOnAction(string cmd, object[] args)
        {
            return ChuckATM(true);
        }
        /// <summary>
        /// Chuck ATM Off
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool ChuckATMOffAction(string cmd, object[] args)
        {
            return ChuckATM(false);
        }
        private bool ChuckATM(bool value)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{CHUCK_ATM_ON}");
            return IOModuleManager.Instance.WriteIoValue(ioName, value);
        }
        /// <summary>
        /// Chuck ATM Routine
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool ChuckATMAction(string cmd, object[] args)
        {
            if (!JudgeRunningState(SrdCommonOperation.ChuckATMClick))
            {
                _currentOperation = SrdCommonOperation.ChuckATMClick;
                _status = _chuckATMRoutine.Start();
                return _status == RState.Running;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region Water Above 
        /// <summary>
        /// Water Above On操作
        /// </summary>
        public bool WaterAboveOnAction(string cmd, object[] args)
        {
            return WaterAboveOn();
        }
        /// <summary>
        /// water above Off操作
        /// </summary>
        public bool WaterAboveOffAction(string cmd, object[] args)
        {
            return WaterAboveOff();
        }
        /// <summary>
        /// Water Above On(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool WaterAboveOn()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ABOVE}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// <summary>
        /// Water Above Off(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool WaterAboveOff()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_ABOVE}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion

        #region Water Below 
        /// <summary>
        /// Water Below On操作
        /// </summary>
        public bool WaterBelowOnAction(string cmd, object[] args)
        {
            return WaterBelowOn();
        }
        /// <summary>
        /// water Below Off操作
        /// </summary>
        public bool WaterBelowOffAction(string cmd, object[] args)
        {
            return WaterBelowOff();
        }
        /// <summary>
        /// Water Below On(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool WaterBelowOn()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_BELOW}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        /// <summary>
        /// Water Below Off(不确认信号)
        /// </summary>
        /// <returns></returns>
        public bool WaterBelowOff()
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WATER_BELOW}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion
        /// <summary>
        /// Update IsWaferPresence 标志位
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool UpdateIsWaferPresenceAction(string cmd, object[] args)
        {
            _isWaferPresence = (bool)args[0];
            return true; 
        }

        /// <summary>
        /// 判定运行状态
        /// </summary>
        /// <returns></returns>
        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;
        }

        /// <summary>
        /// ErrorOperation
        /// </summary>
        public void EnterErrorOperation()
        {
            //关闭风扇
            if (CommonData.N2On)
            {
                bool result = N2OffAction("", null);
                if (!result)
                {
                    LOG.WriteLog(eEvent.ERR_SRD, Module, "EnterError: N2 Off is failed");
                }
            }
            //关闭WaterAbove
            if (CommonData.WaterOn)
            {
                bool result = WaterOff();
                if (!result)
                {
                    LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Off is failed");
                }
            }
            
            //停电机
            JetAxisBase _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
            if (_rotationAxis != null && _rotationAxis.IsRun) _rotationAxis.StopPositionOperation();

        }
        #endregion
        /// <summary>
        /// Rotation InterLock
        /// </summary>
        /// <returns></returns>
        public bool RotationInterLock()
        {
            if (!CommonData.DoorClosed)
            {
                LOG.WriteLog(eEvent.ERR_SRD, Module, "Door is not closed. Rotation can not position");
                return false;
            }
            //Check Flippers
            if (CommonData.FlippersIn150 || CommonData.FlippersIn200) //|| _srdCommon.CommonData.FlippersIn100
            {
                LOG.WriteLog(eEvent.ERR_SRD, Module, "FlippersIn is on. Rotation can not position");
                return false;
            }
            if (!CommonData.Flipper1Out150Status || !CommonData.Flipper2Out150Status || !CommonData.Flipper3Out150Status
                || !CommonData.Flipper1Out200Status || !CommonData.Flipper2Out200Status || !CommonData.Flipper3Out200Status)
            //|| !_srdCommon.CommonData.Flipper1Out100Status || !_srdCommon.CommonData.Flipper2Out100Status || !_srdCommon.CommonData.Flipper3Out100Status
            {
                LOG.WriteLog(eEvent.ERR_SRD, Module, "Flippers are at In position. Rotation can not position");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 定时器
        /// </summary>
        /// <returns></returns>
        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<TotalSRDDevice>("SRD");
            }
            if (_totalSRDDevice != null)
            {
                CommonData.FluidContainment = _totalSRDDevice.FluidContainment;
                CommonData.WaterPressure = _totalSRDDevice.WaterPressure;
            }
            return true;
        }
        /// <summary>
        /// 获取当前操作对应的Routine
        /// </summary>
        /// <param name="currentOperation"></param>
        /// <returns></returns>
        private IRoutine GetCurrentRoutine(SrdCommonOperation currentOperation)
        {
            switch (currentOperation)
            {
                case SrdCommonOperation.DoorClose:
                case SrdCommonOperation.DoorOpen:
                    return _doorCloseRoutine;
                case SrdCommonOperation.ChuckVacuumOn:
                case SrdCommonOperation.ChuckVacuumOff:
                    return _chuckVacuumRoutine;
                case SrdCommonOperation.LiftUpOn:
                case SrdCommonOperation.LiftUpOff:
                    return _liftUpRoutine;
                case SrdCommonOperation.FlippersIn:
                case SrdCommonOperation.FlippersOut:
                    return _flipperRoutine;
                case SrdCommonOperation.ChuckATMClick:
                    return _chuckATMRoutine;
                default:
                    return null;
            }
        }
        /// <summary>
        /// 检验Routine状态
        /// </summary>
        /// <param name="routine"></param>
        /// <param name="currentOperation"></param>
        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();
            }
        }
        /// <summary>
        /// 结束操作
        /// </summary>
        private void EndOperation()
        {
            _status = RState.End;
            _currentOperation = SrdCommonOperation.None;
        }

        #region 设备接口
        /// <summary>
        /// 监控
        /// </summary>
        public void Monitor()
        {

        }

        public void Reset()
        {
        }

        public void Terminate()
        {
        }
        #endregion
    }
}