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.Alarm;
using MECF.Framework.Common.Algorithm;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.CommonData.Prewet;
using MECF.Framework.Common.CommonData.Vpw;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.IOCore;
using MECF.Framework.Common.Persistent.Prewet;
using MECF.Framework.Common.Persistent.VpwMain;
using MECF.Framework.Common.ToolLayout;
using PunkHPX8_Core;
using PunkHPX8_RT.Devices.VpwCell;
using PunkHPX8_RT.Modules;
using PunkHPX8_RT.Modules.VpwCelMain;
using PunkHPX8_RT.Modules.VpwMain;
using SecsGem.Core.ItemModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Animation;
namespace PunkHPX8_RT.Devices.VpwMain
{
    public class VpwMainDevice : BaseDevice, IDevice
    {
        #region 常量 
        private const string COMMON_DATA = "CommonData";
        private const string PERSISTENT_VALUE = "PersistentValue";
        private const string CHAMBER_CLOSED = "ChamberClosed";
        private const string CHAMBER_OPENED = "ChamberOpened";
        private const string CHAMBER_CLOSE = "ChamberClose";
        private const string LEAK_DETECTED = "LeakDetected";
        private const string VACUUM_PUMP_PRESSURE = "VacuumPumpPressure";
        private const string VACUUM_PUMP_POWER = "VacuumPumpPower";
        private const string VACUUM_PUMP_ENABLE = "VacuumPumpEnable";
        private const string VACUUM_PUMP_SPEED_ENABLE = "VacuumPumpSpeedEnable";
        private const string VACUUM_PUMP_SPEED = "VacuumPumpSpeed";
        private const string BOOSTER_PUMP_SPEED = "BoosterPumpSpeed";
        private const string BOOSTER_PUMP_CURRENT = "BoosterPumpCurrent";
        private const string BOOSTER_PUMP_ENABLE = "BoosterPumpEnable";
        private const string BOOSTER_PUMP_STATUS = "BoosterPumpStatus";
        private const string DIW_ENABLE = "DiwEnable";
        private const string DIW_PROCESS = "DiwProcess";
        private const string DIW_DEGAS = "DiwDegas";
        private const string DIW_TOTAL_FLOW = "DiwTotalFlow";
        private const string DIW_PRESSURE = "DiwPressure";
        private const string DEGAS_ADJUST = "DegasAdjust";
        private const string DEGAS_PURGE = "DegasPurge";
        private const string DEGAS_PUMP_ENABLE = "DegasPumpEnable";
        private const string DEGAS_PUMP_PRESSURE = "DegasPumpPressure";
        #endregion
        private enum VPWOperation
        {
            None,
            PumpEnable,
            PumpDisable,
            HomeAllRotation
        }
        #region 内部变量
        /// 
        /// 变量是否初始化字典
        /// 
        private Dictionary _variableInitializeDic = new Dictionary();
        /// 
        /// 数据
        /// 
        private VpwMainCommonData _commonData=new VpwMainCommonData();
        /// 
        /// 持久性数值
        /// 
        private VpwMainPersistentValue _vpwMainPersistentValue;
        /// 
        /// Pump Enable routine
        /// 
        private BoosterPumpEnableRoutine _boosterPumpEnableRoutine;
        /// 
        /// Pump Disable routine
        /// 
        private BoosterPumpDisableRoutine _boosterPumpDisableRoutine;
        /// 
        /// 上一次Booster泵速
        /// 
        private short _lastBoosterPumpSpeed = 0;
        /// 
        /// 定时器任务
        /// 
        private PeriodicJob _periodicJob;
        /// 
        /// 是否数据完成初台化
        /// 
        private bool _isDataInitialized;
        /// 
        /// pdi控制中的p
        /// 
        private double _pumpKp;
        /// 
        /// pdi控制中的i
        /// 
        private double _pumpKi;
        /// 
        /// pdi控制中的d
        /// 
        private double _pumpKd;
        /// 
        /// flow pdi控制中的p
        /// 
        private double _pumpFlowKp;
        /// 
        /// flow pdi控制中的i
        /// 
        private double _pumpFlowKi;
        /// 
        /// flow pdi控制中的d
        /// 
        private double _pumpFlowKd;
        /// 
        /// Boost pump调速的目标类型
        /// 
        private VPWBoostPumpTarget _boosterBoostPumpTarget;
        /// 
        /// Boost pump目标流量
        /// 
        private double _boosterTargetFlow;
        /// 
        /// Cell Flow数值
        /// 
        private double _cellFlow;
        /// 
        /// 操作当前状态
        /// 
        private RState _status;
        /// 
        /// 当前操作
        /// 
        private VPWOperation _currentOperation;
        /// 
        /// 启动自动调泵速
        /// 
        private bool _isStartAutoSpeed;
        /// 
        /// Home 电机
        /// 
        private VpwSimpleHomeRoutine _simpleHomeRoutine;
        /// 
        /// 总流量计时器
        /// 
        private Stopwatch _totalFlowWatch = new Stopwatch();
        /// 
        /// 总流量上升沿
        /// 
        private R_TRIG _totalFlowTrig = new R_TRIG();
        /// 
        /// 检测到total flow 低于设定条件的时间
        /// 
        private DateTime _totalFlowAbnormalDetectTime;
        /// 
        /// 检测到cell flow 满足设定条件的时间
        /// 
        private bool _totalFlowAbnormal;
        #endregion
        #region 属性
        /// 
        /// 数据
        /// 
        public VpwMainCommonData CommonData { get { return _commonData; } }
        /// 
        /// Boost Pump目标类型
        /// 
        public VPWBoostPumpTarget VPWBoostPumpTarget { set { _boosterBoostPumpTarget = value; } }
        /// 
        /// Booster目标流量
        /// 
        public double BoostTargetFlow { set { _boosterTargetFlow = value; } }
        /// 
        /// Cell Flow
        /// 
        public double CellFlow { set { _cellFlow = value; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public VpwMainDevice(string moduleName) : base(moduleName, moduleName, moduleName, moduleName)
        {
        }
        #region 初始化
        /// 
        /// 初始化
        /// 
        /// 
        public bool Initialize()
        {
            InitializeParameter();
            InitializeRoutine();
            SubscribeData();
            SubscribeValueAction();
            InitializeOperation();
            return true;
        }
        /// 
        /// 初始化参数
        /// 
        private void InitializeParameter()
        {
            _vpwMainPersistentValue = VpwMainPersistentManager.Instance.GetPersistentValue(Module);
            if (_vpwMainPersistentValue != null)
            {
                _lastBoosterPumpSpeed = _vpwMainPersistentValue.Speed;
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "Persistent Value Object is not exist");
            }
            _commonData.BoosterPumpPressureData = new MECF.Framework.Common.CommonData.CommonLimitData();
        }
        /// 
        /// 初始化Routine
        /// 
        private void InitializeRoutine()
        {
            _boosterPumpEnableRoutine = new BoosterPumpEnableRoutine(Module, this);
            _boosterPumpDisableRoutine = new BoosterPumpDisableRoutine(Module, this);
            _simpleHomeRoutine = new VpwSimpleHomeRoutine(Module.ToString());
        }
        /// 
        /// 订阅
        /// 
        private void SubscribeData()
        {
            DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _vpwMainPersistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.{COMMON_DATA}", () => CommonData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.DiwEnable", () => CommonData.DiwEnable, SubscriptionAttribute.FLAG.IgnoreSaveDB);
        }
        /// 
        /// 订阅数据
        /// 
        private void SubscribeValueAction()
        {
            IoSubscribeUpdateVariable(CHAMBER_CLOSED);
            IoSubscribeUpdateVariable(CHAMBER_OPENED);
            IoSubscribeUpdateVariable(BOOSTER_PUMP_STATUS);
            IoSubscribeUpdateVariable(BOOSTER_PUMP_SPEED);
            IoSubscribeUpdateVariable(BOOSTER_PUMP_ENABLE);
            IoSubscribeUpdateVariable(BOOSTER_PUMP_CURRENT);
            IoSubscribeUpdateVariable(DEGAS_PURGE);
            IoSubscribeUpdateVariable(DEGAS_ADJUST);
            IoSubscribeUpdateVariable(DEGAS_PUMP_PRESSURE);
            IoSubscribeUpdateVariable(DEGAS_PUMP_ENABLE);
            IoSubscribeUpdateVariable(DIW_ENABLE);
            IoSubscribeUpdateVariable(DIW_PROCESS);
            IoSubscribeUpdateVariable(DIW_PRESSURE);
            IoSubscribeUpdateVariable(DIW_DEGAS);
            IoSubscribeUpdateVariable(DIW_TOTAL_FLOW);
            IoSubscribeUpdateVariable(VACUUM_PUMP_ENABLE);
            IoSubscribeUpdateVariable(VACUUM_PUMP_POWER);
            IoSubscribeUpdateVariable(VACUUM_PUMP_PRESSURE);
            IoSubscribeUpdateVariable(VACUUM_PUMP_SPEED);
            IoSubscribeUpdateVariable(VACUUM_PUMP_SPEED_ENABLE);
            IoSubscribeUpdateVariable(LEAK_DETECTED);
        }
        /// 
        /// 初始化变量
        /// 
        /// 
        private void IoSubscribeUpdateVariable(string variable)
        {
             _variableInitializeDic[variable] = false;
            IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue);
        }
        /// 
        /// 更新变量数值
        /// 
        /// 
        /// 
        private void UpdateVariableValue(string variable, object value)
        {
            if (!_commonData.IsDataInitialized)
            {
                _commonData.IsDataInitialized = true;
                _commonData.BoosterPumpModel = "Manual";
            }
            PropertyInfo property = _commonData.GetType().GetProperty(variable);
            if (property != null)
            {
                property.SetValue(_commonData, value);
            }
            if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable])
            {
                _variableInitializeDic[variable] = true;
            }
            switch (variable)
            {
                case BOOSTER_PUMP_STATUS:
                    string statusContent = _commonData.BoosterPumpStatus ? "On" : "Off";
                    _commonData.BoosterPumpStatusContent = $"{_commonData.BoosterPumpModel}: {statusContent}";
                    break;
                case DIW_PRESSURE:
                    if (double.TryParse(value.ToString(), out var pressure))
                    {
                        _commonData.BoosterPumpPressureData.Value = pressure;
                    }
                    break;
            }
        }
        /// 
        /// 初始化OP
        /// 
        private void InitializeOperation()
        {
            OP.Subscribe($"{Module}.VacuumPumpPowerOn", (cmd,para)=> { return VacuumPumpPowerOn(); });
            OP.Subscribe($"{Module}.VacuumPumpPowerOff", (cmd, para) => { return VacuumPumpPowerOff(); });
            OP.Subscribe($"{Module}.VacuumPumpEnable", (cmd, para) => { return VacuumPumpEnable(); });
            OP.Subscribe($"{Module}.VacuumPumpDisable", (cmd, para) => { return VacuumPumpDisable(); });
            OP.Subscribe($"{Module}.VacuumPumpSpeedEnable", (cmd, para) => { return VacuumSpeedEnable(); });
            OP.Subscribe($"{Module}.VacuumPumpSpeedDisable", (cmd, para) => { return VacuumSpeedDisable(); });
            OP.Subscribe($"{Module}.VacuumPumpSpeed", (cmd, para) => { return WriteVacuumSpeedOperation(cmd, para); });
            OP.Subscribe($"{Module}.DegasPumpEnable", (cmd, para) => { return DegasPumpEnable(); });
            OP.Subscribe($"{Module}.DegasPumpDisable", (cmd, para) => { return DegasPumpDisable(); });
            OP.Subscribe($"{Module}.DegasAdjustOn", (cmd, para) => { return DegasAdjustOn(); });
            OP.Subscribe($"{Module}.DegasAdjustOff", (cmd, para) => { return DegasAdjustOff(); });
            OP.Subscribe($"{Module}.DegasPurgeOn", (cmd, para) => { return N2PurgeValveOn(); });
            OP.Subscribe($"{Module}.DegasPurgeOff", (cmd, para) => { return N2PurgeValveOff(); });
            OP.Subscribe($"{Module}.DiwDegasValveOn", (cmd, para) => { return DiwDegasValveOn(); });
            OP.Subscribe($"{Module}.DiwDegasValveOff", (cmd, para) => { return DiwDegasValveOff(); });
            OP.Subscribe($"{Module}.DiwEnable", (cmd, para) => { return DiwEnable(); });
            OP.Subscribe($"{Module}.DiwDisable", (cmd, para) => { return DiwDisable(); });
            OP.Subscribe($"{Module}.DiwProcessOn", (cmd, para) => { return DiwProcessOn(); });
            OP.Subscribe($"{Module}.DiwProcessOff", (cmd, para) => { return DiwProcessOff(); });
            OP.Subscribe($"{Module}.BoosterPumpEnable", BoosterPumpEnableOperation);
            OP.Subscribe($"{Module}.BoosterPumpDisable", BoosterPumpDisableOperation);
            OP.Subscribe($"{Module}.BoosterPumpSpeed", BoosterPumpSpeedKeyDownOperation);
            OP.Subscribe($"{Module}.ChamberUp", (cmd, para) => { return ChamberUp(); });
            OP.Subscribe($"{Module}.ChamberDown", (cmd, para) => { return ChamberDown(); });
            
            OP.Subscribe($"{Module}.BoosterPumpSpeedAuto", (cmd, para) => { return BoosterPumpSpeedAutoOperation(); });
            OP.Subscribe($"{Module}.BoosterPumpSpeedManual", (cmd, para) => { return BoosterPumpSpeedManualOperation(); });
            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}.HomeAllRotation", HomeAllRotation);
        }
        #endregion
        #region Action
        #region HomeAllRotation
        public bool HomeAllRotation(string cmd, object[] param)
        {
            if (_status == RState.Running)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot home all rotation");
                return false;
            }
            _status = _simpleHomeRoutine.Start();
            _currentOperation = VPWOperation.HomeAllRotation;
            return _status == RState.Running;
        }
        #endregion
        #region Vacum Pump
        /// 
        /// Pump Power On
        /// 
        /// 
        public bool VacuumPumpPowerOn()
        {
            return WriteVariableValue(VACUUM_PUMP_POWER, true);
        }
        /// 
        /// Pump Power Off
        /// 
        /// 
        public bool VacuumPumpPowerOff()
        {
            return WriteVariableValue(VACUUM_PUMP_POWER, false);
        }
        /// 
        /// Pump Enable
        /// 
        /// 
        public bool VacuumPumpEnable()
        {
            return WriteVariableValue(VACUUM_PUMP_ENABLE, true);
        }
        /// 
        /// Pump Disable
        /// 
        /// 
        public bool VacuumPumpDisable()
        {
            return WriteVariableValue(VACUUM_PUMP_ENABLE, false);
        }
        /// 
        /// Speed Enable
        /// 
        /// 
        public bool VacuumSpeedEnable()
        {
            return WriteVariableValue(VACUUM_PUMP_SPEED_ENABLE, true);
        }
        /// 
        /// Speed disable
        /// 
        /// 
        public bool VacuumSpeedDisable()
        {
            return WriteVariableValue(VACUUM_PUMP_SPEED_ENABLE, false);
        }
        /// 
        /// 写入Vacuum速度
        /// 
        /// 
        /// 
        private bool WriteVacuumSpeedOperation(string cmd, object[] param)
        {
            if (short.TryParse(param[0].ToString(), out var speed))
            {
                return WriteVariableValue(VACUUM_PUMP_SPEED, speed);
            }
            else
            {
                LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"Write VacuumSpeed {param[0]} is not short");
                return false;
            }
        }
        /// 
        /// 写入速度
        /// 
        /// 
        /// 
        public bool WriteVacuumSpeed(short speed)
        {
            return WriteVariableValue(VACUUM_PUMP_SPEED, speed);
        }
        #endregion
        #region Degas Pump
        /// 
        /// Degas Pump Enable
        /// 
        /// 
        public bool DegasPumpEnable()
        {
            return WriteVariableValue(DEGAS_PUMP_ENABLE, true);
        }
        /// 
        /// Degas Pump disable
        /// 
        /// 
        public bool DegasPumpDisable()
        {
            return WriteVariableValue(DEGAS_PUMP_ENABLE, false);
        }
        /// 
        /// Degas Adjust On
        /// 
        /// 
        public bool DegasAdjustOn()
        {
            return WriteVariableValue(DEGAS_ADJUST, true);
        }
        /// 
        /// Degas Adjust Off
        /// 
        /// 
        public bool DegasAdjustOff()
        {
            return WriteVariableValue(DEGAS_ADJUST, false);
        }
        #endregion
        #region Booster Pump
        /// 
        /// Pump Enable操作
        /// 
        /// 
        /// 
        /// 
        public bool BoosterPumpEnableOperation(string cmd, object[] param)
        {
            if (_status == RState.Running)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump enable");
                return false;
            }
            _status = _boosterPumpEnableRoutine.Start();
            _currentOperation = VPWOperation.PumpEnable;
            return _status == RState.Running;
        }
        ///  
        /// pump disable 操作
        /// 
        /// 
        /// 
        /// 
        public bool BoosterPumpDisableOperation(string cmd, object[] param)
        {
            if (_status == RState.Running)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump disable");
                return false;
            }
            _status = _boosterPumpDisableRoutine.Start();
            _currentOperation = VPWOperation.PumpDisable;
            return _status == RState.Running;
            //return PumpDisable();
        }
        /// 
        /// Booster Pump enable
        /// 
        /// 
        public bool BoosterPumpEnable()
        {
            return WriteVariableValue(BOOSTER_PUMP_ENABLE, true);
        }
        /// 
        /// Booster Pump Disable
        /// 
        /// 
        public bool BoosterPumpDisable()
        {
            return WriteVariableValue(BOOSTER_PUMP_ENABLE, false);
        }
        /// 
        /// 写入Booster泵速
        /// 
        /// 
        /// 
        public bool BoosterPumpSpeed(short speed=0)
        {
            return WriteVariableValue(BOOSTER_PUMP_SPEED, speed == 0 ? _lastBoosterPumpSpeed : speed);
        }
        /// Booster Pump Speed回车操作
        /// 
        /// 
        /// 
        /// 
        private bool BoosterPumpSpeedKeyDownOperation(string cmd, object[] param)
        {
            if (_commonData.BoosterPumpSpeedAuto)
            {
                LOG.WriteLog(eEvent.ERR_PREWET, Module, "Pump speed is auto,cannot change speed");
                return false;
            }
            short speed = (short)param[0];
            bool result = BoosterPumpSpeed(speed);
            if (result)
            {
                _vpwMainPersistentValue.Speed = speed;
                _lastBoosterPumpSpeed = speed;
                VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
            }
            return true;
        }
        /// 
        /// Pump Speed手动模式
        /// 
        /// 
        /// 
        /// 
        private bool BoosterPumpSpeedManualOperation()
        {
            _commonData.BoosterPumpSpeedAuto = false;
            _commonData.BoosterPumpModel = "Manual";
            string statusContent = _commonData.BoosterPumpStatus ? "On" : "Off";
            _commonData.BoosterPumpStatusContent = $"{_commonData.BoosterPumpModel}: {statusContent}";
            return true;
        }
        /// 
        /// Pump Speed自动模式
        /// 
        /// 
        /// 
        /// 
        private bool BoosterPumpSpeedAutoOperation()
        {
            _commonData.BoosterPumpSpeedAuto = true;
            _commonData.BoosterPumpModel = "Auto";
            string statusContent = _commonData.BoosterPumpStatus ? "On" : "Off";
            _commonData.BoosterPumpStatusContent = $"{_commonData.BoosterPumpModel}: {statusContent}";
            return true;
        }
        #endregion
        #region Chamber
        /// 
        /// 上升
        /// 
        /// 
        public bool ChamberUp()
        {
            return WriteVariableValue(CHAMBER_CLOSE, true);
        }
        /// 
        /// 下降
        /// 
        /// 
        public bool ChamberDown()
        {
            return WriteVariableValue(CHAMBER_CLOSE, false);
        }
        #endregion
        #region Mode switch
        /// 
        /// DisabledAction
        /// 
        /// 
        /// 
        /// 
        private bool DisabledOperation(string cmd, object[] args)
        {
            string currentOperation = "Disabled";
            VpwMainEntity vpwMainEntity = Singleton.Instance.GetModule(Module);
            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)
            {
                string preOperation = _vpwMainPersistentValue.OperatingMode;
                if (vpwMainEntity.IsBusy)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Disabled mode");
                    return false;
                }
                vpwMainEntity.EnterInit();
                _vpwMainPersistentValue.OperatingMode = currentOperation;
                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
            }
            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// ManualAction
        /// 
        /// 
        /// 
        /// 
        private bool ManualOperation(string cmd, object[] args)
        {
            string currentOperation = "Manual";
            VpwMainEntity vpwMainEntity = Singleton.Instance.GetModule(Module);
            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)
            {
                string preOperation = _vpwMainPersistentValue.OperatingMode;
                if (vpwMainEntity.IsBusy)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Manual mode");
                    return false;
                }
                vpwMainEntity.EnterInit();
                _vpwMainPersistentValue.OperatingMode = currentOperation;
                _boosterBoostPumpTarget = VPWBoostPumpTarget.Pressure;
                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
            }
            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// AutoAction
        /// 
        /// 
        /// 
        /// 
        private bool AutoOperation(string cmd, object[] args)
        {
            string currentOperation = "Auto";
            VpwMainEntity vpwMainEntity = Singleton.Instance.GetModule(Module);
            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)
            {
                string preOperation = _vpwMainPersistentValue.OperatingMode;
                if (vpwMainEntity.IsBusy)
                {
                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Auto mode");
                    return false;
                }
                vpwMainEntity.EnterInit();
                _vpwMainPersistentValue.OperatingMode = currentOperation;
                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
            }
            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// EngineeringModeAction
        /// 
        /// 
        /// 
        /// 
        private bool EngineeringModeOperation(string cmd, object[] args)
        {
            string currentRecipeOperation = "Engineering";
            if (_vpwMainPersistentValue != null)
            {
                _vpwMainPersistentValue.RecipeOperatingMode = currentRecipeOperation;
            }
            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        /// 
        /// ProductionAction
        /// 
        /// 
        /// 
        /// 
        private bool ProductionModeOperation(string cmd, object[] args)
        {
            string currentRecipeOperation = "Production";
            if (_vpwMainPersistentValue != null)
            {
                _vpwMainPersistentValue.RecipeOperatingMode = currentRecipeOperation;
            }
            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
            return true;
        }
        #endregion
        #region DIW
        /// 
        /// DIW Enable
        /// 
        /// 
        public bool DiwEnable()
        {
            return WriteVariableValue(DIW_ENABLE, true);
        }
        /// 
        /// DIW Disable
        /// 
        /// 
        public bool DiwDisable()
        {
            return WriteVariableValue(DIW_ENABLE, false);
        }
        /// 
        /// DIW Process On
        /// 
        /// 
        public bool DiwProcessOn()
        {
            return WriteVariableValue(DIW_PROCESS, true);
        }
        /// 
        /// DIW Process On
        /// 
        /// 
        public bool DiwProcessOff()
        {
            return WriteVariableValue(DIW_PROCESS, false);
        }
        /// 
        /// DIW Degas Valve On
        /// 
        /// 
        public bool DiwDegasValveOn()
        {
            return WriteVariableValue(DIW_DEGAS, true);
        }
        /// 
        /// DIW Degas Valve Off
        /// 
        /// 
        public bool DiwDegasValveOff()
        {
            return WriteVariableValue(DIW_DEGAS, false);
        }
        #endregion
        #region N2Purge
        /// 
        /// 打开N2 Purge
        /// 
        /// 
        public bool N2PurgeValveOn()
        {
            return WriteVariableValue(DEGAS_PURGE, true);
        }
        /// 
        /// 关闭N2 Purge
        /// 
        /// 
        public bool N2PurgeValveOff()
        {
            return WriteVariableValue(DEGAS_PURGE, false);
        }
        #endregion
        /// 
        /// 写变量
        /// 
        /// 
        /// 
        /// 
        private bool WriteVariableValue(string variable, object value)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{variable}");
            return IOModuleManager.Instance.WriteIoValue(ioName, value);
        }
        #endregion
        /// 
        /// 定时器
        /// 
        /// 
        public bool OnTimer()
        {
            _commonData.BoosterPumpPressureData.MinError = SC.GetValue($"VPWMain.PumpPressure.Error_Min");
            _commonData.BoosterPumpPressureData.MinWarning = SC.GetValue($"VPWMain.PumpPressure.Warning_Min");
            _commonData.BoosterPumpPressureData.MaxError = SC.GetValue($"VPWMain.PumpPressure.Error_Max");
            _commonData.BoosterPumpPressureData.MaxWarning = SC.GetValue($"VPWMain.PumpPressure.Warning_Max");
            _commonData.PressureTarget = SC.GetValue($"VPWMain.PressureTarget");
            if (_status == RState.Running)
            {
                IRoutine routine = GetCurrentRoutine();
                if (routine != null)
                {
                    RState rsState = routine.Monitor();
                    if (rsState == RState.Failed || rsState == RState.Timeout)
                    {
                        _status = RState.Failed;
                        _currentOperation = VPWOperation.None;
                        LOG.WriteLog(eEvent.ERR_VPWMAIN, Module.ToString(), $"{_currentOperation} error");
                        _isStartAutoSpeed = false;
                    }
                    else if (rsState == RState.End)
                    {
                        if (_currentOperation == VPWOperation.PumpEnable)
                        {
                            _isStartAutoSpeed = true;
                        }
                        else if (_currentOperation == VPWOperation.PumpDisable)
                        {
                            _isStartAutoSpeed = false;
                        }
                        _status = RState.End;
                        _currentOperation = VPWOperation.None;
                    }
                }
            }
            if (_isStartAutoSpeed)
            {
                AdjustPumpSpeed();
            }
            MonitorTotalFlow();
            BoosterPumpMonitor();
            WaterPressureMonitor();
            return true;
        }
        //Speed Auto模式同时pump enbled,对water pressure 上下限进行监控
        private void WaterPressureMonitor()
        {
            if (_commonData.BoosterPumpSpeedAuto && _commonData.BoosterPumpEnable)
            {
                if(_commonData.DiwPressure > _commonData.BoosterPumpPressureData.MaxError)
                {
                    LOG.WriteLog(eEvent.ERR_VPW, Module, $"water pressure {_commonData.DiwPressure} is large than Error_max {_commonData.BoosterPumpPressureData.MaxError},Booster Pump Closed!");
                    BoosterPumpDisable();
                }
                else if (_commonData.DiwPressure > _commonData.BoosterPumpPressureData.MaxWarning)
                {
                    if(!AlarmListManager.Instance.IsContainDataWarn(Module, "WaterPressure"))
                    {
                        AlarmListManager.Instance.AddWarn(Module, "WaterPressure", $"water pressure {_commonData.DiwPressure} is large than Warning_max {_commonData.BoosterPumpPressureData.MaxWarning}");
                        LOG.WriteLog(eEvent.WARN_VPW, Module, $"water pressure {_commonData.DiwPressure} is large than Warning_max {_commonData.BoosterPumpPressureData.MaxWarning}");
                    } 
                }
                else if (_commonData.DiwPressure < _commonData.BoosterPumpPressureData.MinError)
                {
                    LOG.WriteLog(eEvent.ERR_VPW, Module, $"water pressure {_commonData.DiwPressure} is lower than Error_min {_commonData.BoosterPumpPressureData.MinError},Booster Pump Closed!");
                    BoosterPumpDisable();
                }
                else if (_commonData.DiwPressure < _commonData.BoosterPumpPressureData.MinWarning)
                {
                    if (!AlarmListManager.Instance.IsContainDataWarn(Module, "WaterPressure"))
                    {
                        AlarmListManager.Instance.AddWarn(Module, "WaterPressure", $"water pressure {_commonData.DiwPressure} is large than Warning_min {_commonData.BoosterPumpPressureData.MinWarning}");
                        LOG.WriteLog(eEvent.WARN_VPW, Module, $"water pressure {_commonData.DiwPressure} is lower than Warning_min {_commonData.BoosterPumpPressureData.MinWarning}");
                    }
                }
            }
        }
        //total flow不满足条件过一段时间自动关闭增压泵
        private void BoosterPumpMonitor()
        {
            double totalFlowStartLimit = SC.GetValue("VPWMain.Plumbing.TotalFlowStartLowLimit");
            int flowFaultHoldOffTime = SC.GetValue($"VPWMain.Plumbing.FlowFaultHoldoffTime");
            if (_commonData.DiwTotalFlow < totalFlowStartLimit)
            {
                if (!_totalFlowAbnormal)
                {
                    _totalFlowAbnormal = true;
                    _totalFlowAbnormalDetectTime = DateTime.Now;
                }
                if ((DateTime.Now - _totalFlowAbnormalDetectTime).TotalSeconds > flowFaultHoldOffTime && _commonData.BoosterPumpEnable)
                {
                    LOG.WriteLog(eEvent.WARN_VPW, Module, $"total flow is lower than start limit more than {flowFaultHoldOffTime} min,Booster Pump Closed!");
                    BoosterPumpDisable();
                    _totalFlowAbnormalDetectTime = DateTime.Now;
                }
            }
            else
            {
                _totalFlowAbnormal = false;
            }
        }
        /// 
        /// 调速
        /// 
        public void AdjustPumpSpeed()
        {
            //Speed Auto模式同时pump enbled,根据kdi调整泵速
            if (_commonData.BoosterPumpSpeedAuto && _commonData.BoosterPumpEnable)
            {
                _pumpKp = SC.GetValue($"VPWMain.PumpKp");
                _pumpKd = SC.GetValue($"VPWMain.PumpKd");
                _pumpKi = SC.GetValue($"VPWMain.PumpKi");
                double limit = SC.GetValue("VPWMain.PrewetTargetLimit");
                double downLimit = SC.GetValue("VPWMain.PrewetDownTargetLimit");
                double minSpeedDelta = SC.GetValue("VPWMain.MinSpeedDelta");
                short speed = 0;
                if (_boosterBoostPumpTarget == VPWBoostPumpTarget.Pressure)
                {
                    speed= PdiAlgorithm.Instance.CalculateSpeed(_pumpKp, _pumpKi, _pumpKd, _commonData.PressureTarget,
                    _commonData.BoosterPumpPressureData.Value, _lastBoosterPumpSpeed, limit, downLimit, minSpeedDelta);
                }
                else
                {
                    speed= PdiAlgorithm.Instance.CalculateSpeed(_pumpFlowKp, _pumpFlowKi, _pumpFlowKd, _boosterTargetFlow,
                    _cellFlow, _lastBoosterPumpSpeed, limit, downLimit, minSpeedDelta);
                }
                //short speed = PdiAlgorithm.Instance.CalculateSpeed(PrewetPumpData.PressureTarget, PrewetPumpData.PumpPressureData.Value,
                //    _lastPumpSpeed, limit, downLimit);
                if (Math.Abs(speed - _lastBoosterPumpSpeed) >= 1)
                {
                    _lastBoosterPumpSpeed = speed;
                    BoosterPumpSpeed(speed);
                }
            }
        }
        /// 
        /// 当前Routine;
        /// 
        /// 
        private IRoutine GetCurrentRoutine()
        {
            switch (_currentOperation)
            {
                case VPWOperation.PumpEnable:
                    return _boosterPumpEnableRoutine;
                case VPWOperation.PumpDisable:
                    return _boosterPumpDisableRoutine;
                case VPWOperation.HomeAllRotation:
                    return _simpleHomeRoutine;
                default:
                    return null;
            }
        }
        /// 
        /// 监控总流量 
        /// 
        private void MonitorTotalFlow()
        {
            double totalFlow = _commonData.DiwTotalFlow;
            double totalFlowStartLimit = SC.GetValue("VPWMain.Plumbing.TotalFlowStartLowLimit");
            int dripValveOpenIdlePeriod = SC.GetValue("VPWMain.DripValveOpenIdlePeriod")*60*1000;
            if (dripValveOpenIdlePeriod == 0)
            {
                return;
            }
            if (totalFlow < totalFlowStartLimit&&_totalFlowWatch.IsRunning)
            {
                LOG.WriteLog(eEvent.INFO_VPW, Module, $"total flow is less then start limit");
                _totalFlowWatch.Stop();
                return;
            }
            _totalFlowTrig.CLK = totalFlow >= totalFlowStartLimit;
            if (_totalFlowTrig.Q)
            {
                LOG.WriteLog(eEvent.INFO_VPW, Module, $"total flow is over start limit");
                _totalFlowWatch.Start();
            }
            if (_totalFlowWatch.ElapsedMilliseconds >= dripValveOpenIdlePeriod)
            {
                LOG.WriteLog(eEvent.INFO_VPW, Module, $"the time of total flow is over DripValveOpenIdlePeriod");
                List vpwCellDevices = new List();
                VpwMainItem vpwMainItem = VpwMainItemManager.Instance.GetItem(ModuleName.VPWMain1.ToString());
                if (vpwMainItem == null || vpwMainItem.VpwCells == null)
                {
                    return;
                }
                foreach (var item in vpwMainItem.VpwCells)
                {
                    VpwCellDevice cellDevice = DEVICE.GetDevice(item.ModuleName);
                    vpwCellDevices.Add(cellDevice);
                }
                _totalFlowWatch.Reset();
                foreach (var item in vpwCellDevices)
                {
                    VpwCellEntity vpwCellEntity = Singleton.Instance.GetModule(item.Module);
                    if (vpwCellEntity == null || vpwCellEntity.IsDisable)
                    {
                        continue;
                    }
                    if (item.CommonData.FlowDrip)
                    {
                        continue;
                    }
                    item.FlowDripOn();
                    LOG.WriteLog(eEvent.INFO_VPW, Module, $"{item.Module} open drip valve after DripValveOpenIdlePeriod");
                }
            }
        }
        /// 
        /// 监控
        /// 
        public void Monitor()
        {
        }
        public void Reset()
        {
        }
        public void Terminate()
        {
        }
    }
}