using Aitex.Core.RT.Device.Devices;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Equipment;
using SicModules.PMs.Routines.Base;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Aitex.Core.RT.DBCore;
using Aitex.Core.Common.DeviceData;
using Aitex.Common.Util;
using Aitex.Core.RT.Log;
using System.Xml;
using System.Collections.ObjectModel;
using MECF.Framework.Common.DBCore;
using System.Data;
using System.Reflection;
using System.Linq;

namespace SicModules.PMs.Routines
{
    public class MfcRorAction
    {
        public string Name { get; set; }

        public string Value { get; set; }
    }

    public class PMMfcRorRoutine : PMBaseRoutine
    {
        private enum RoutineStep
        {
            TimeDelay1,
            TimeDelay2,
            TimeDelay3,
            TimeDelay4,
            TimeDelay5,
            TimeDelay6,
            TimeDelay7,
            TimeDelay8,
            TimeDelay9,
            TimeDelay10,

            SetFinalValve_1,
            SetFinalValve_2,
            SetV111,
            SetJValve,

            SetEPV2_1,
            SetEPV2_2,
            SetEPV2_3,
            SetTVEnable_1,
            SetTVEnable_2,
            SetTVPressMode_1,
            SetTVPressMode_2,
            SetTV_1,
            SetTV_2,
            WaitTV_1,
            WaitTV_2,
            SetM2toM40,
            SetTVCloseMode_1,
            SetTVCloseMode_2,
            CloseTV_1,
            CloseTV_2,
            PreSetMfcFlow,
            SetMfcFlow_1,
            SetMfcFlow_2,
            SetMfcFlow_3,
            PostSetMfcFlow,

            SetPressure1,
            SetPressure2,
            SetPressure3,
            SetPressure4,

            SetMaintainPressure1,
            SetMaintainPressure2,

            CalStandardMfc,
            CalTestMfc,

            CalBasePressure1,
            CalBasePressure2,

            SetMFCMode_1,
            SetMFCMode_2,
            SetMFCMode_3,

            SetPCMode_1,
            SetPCMode_2,
            SetPCMode_3,

            StartLoop,
            EndLoop,

            CheckOutMfc,
        }

        private ModuleName moduleName;

        private PMModule _pmModule;

        private int _loopCount;

        private MfcRorData _mfcData;

        private ObservableCollection<MfcRorData> _mfcDataArray = new ObservableCollection<MfcRorData>();

        private Stopwatch _swTimer = new Stopwatch();

        //Mfc Name列表
        public List<string> MfcNameList { get; set; } = new List<string>();

        //标准Mfc
        public MfcRorData StandardMfcRorData { get; set; }

        public List<MfcRorData> MfcRorList { get; set; } = new List<MfcRorData>();

        //摩尔气体常数
        private const double R = 8.314;

        //气体摩尔体积
        private const double Vm = 22.414;

        private IoThrottleValve2 _IoThrottle;

        private int _IoValueTimeout = 10;

        private double _pressureMaxDiff;

        private int _throttleTimeout;

        private double _ventBasePressure;

        private double _pumpBasePressure;

        private bool _flag1;

        private bool _flag2;

        private string _startTime;

        private string _endTime;

        private string _mfcRorConfigPath = PathManager.GetCfgDir() + @"PM\MfcRor\MfcRor.xml";

        private Dictionary<string, double> _mfcFlowList = new Dictionary<string, double>(); 

        private Dictionary<string, List<MfcRorAction>> _preActionList = new Dictionary<string, List<MfcRorAction>>();

        private Dictionary<string, List<MfcRorAction>> _postActionList = new Dictionary<string, List<MfcRorAction>>();

        public PMMfcRorRoutine(ModuleName module, PMModule pm) : base(module, pm)
        {
            moduleName = module;
            _pmModule = pm;
            Name = "MfcRor";

            _IoThrottle = DEVICE.GetDevice<IoThrottleValve2>($"{Module}.TV");

            InitializeXml();

            InitializeMfcRorList();

            InitStandardMfc();
        }

        private void InitializeXml()
        {
            string reason = string.Empty;
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(_mfcRorConfigPath);
                XmlNode xmlNode = xmlDocument.SelectSingleNode("Items");

                foreach (XmlNode childNode in xmlNode.ChildNodes)
                {
                    if (childNode.NodeType == XmlNodeType.Comment || !(childNode is XmlElement xmlElement))
                    {
                        continue;
                    }

                    if (xmlElement.Name != "Item")
                    {
                        if (xmlElement.NodeType != XmlNodeType.Comment)
                        {
                            reason += "mfcRor config file contains no comments content, " + xmlElement.InnerXml;
                        }
                        continue;
                    }

                    if (!xmlElement.HasAttribute("Name"))
                    {
                        reason += "action node has no [Name] attribute \r\n";
                        continue;
                    }

                    string name = xmlElement.GetAttribute("Name");

                    //Flow
                    XmlNode xmlNodeFlow = childNode.SelectSingleNode("Flow");
                    if (xmlNodeFlow != null)
                    {
                        _mfcFlowList[name] = double.Parse(xmlNodeFlow.InnerText);
                    }

                    //PreAction
                    List<MfcRorAction> preActionList = new List<MfcRorAction>();

                    XmlNode xmlNode1 = childNode.SelectSingleNode("PreAction");

                    foreach (XmlElement childNode1 in xmlNode1.ChildNodes)
                    {
                        if (childNode1.Name != "Action")
                        {
                            if (childNode1.NodeType != XmlNodeType.Comment)
                            {
                                LOG.Error("MfcRor config file contains no comments content, " + childNode1.InnerXml);
                            }
                            continue;
                        }

                        if (!childNode1.HasAttribute("Name") || !childNode1.HasAttribute("Value"))
                        {
                            reason += "MfcRor node lack of Name or Value attribute \r\n";
                            continue;
                        }

                        string actionName = childNode1.GetAttribute("Name");
                        string value = childNode1.GetAttribute("Value");

                        preActionList.Add(new MfcRorAction() { Name = actionName, Value = value });
                    }

                    _preActionList[name] = preActionList;

                    //PostAction
                    List<MfcRorAction> postActionList = new List<MfcRorAction>();

                    XmlNode xmlNode2 = childNode.SelectSingleNode("PostAction");

                    foreach (XmlElement childNode2 in xmlNode2.ChildNodes)
                    {
                        if (childNode2.Name != "Action")
                        {
                            if (childNode2.NodeType != XmlNodeType.Comment)
                            {
                                LOG.Error("MfcRor config file contains no comments content, " + childNode2.InnerXml);
                            }
                            continue;
                        }

                        if (!childNode2.HasAttribute("Name") || !childNode2.HasAttribute("Value"))
                        {
                            reason += "MfcRor node lack of Name or Value attribute \r\n";
                            continue;
                        }

                        string actionName = childNode2.GetAttribute("Name");
                        string value = childNode2.GetAttribute("Value");

                        postActionList.Add(new MfcRorAction() { Name = actionName, Value = value });
                    }

                    _postActionList[name] = postActionList;
                }
            }
            catch (Exception ex)
            {
                LOG.Error(ex.Message, ex);
            }
        }

        private void InitializeMfcRorList()
        {
            //初始化所有MFC
            foreach (var item in _preActionList)
            {
                MfcNameList.Add(item.Key);
                MfcRorList.Add(new MfcRorData() { Name = item.Key });
            }

            QueryMfcRorListData();
        }

        private void QueryMfcRorListData()
        {
            try
            {
                string cmd = $"select * from pm_mfcror where module = '{Module}' order by \"endtime\" ASC";
                var dt = DB.ExecuteDataSet(cmd);
                if (dt is null || dt.Tables[0].Rows.Count == 0)
                    return;

                for (int i = 0; i < dt.Tables[0].Rows.Count; i++)
                {
                    if (dt.Tables[0].Rows[i].ItemArray.Length != 0)
                    {
                        //if(bool.Parse(dt.Tables[0].Rows[i]["isstandardMfc"].ToString()))
                        //{
                        //    continue;
                        //}

                        MfcRorList.ForEach(t =>
                        {
                            if (t.Name == dt.Tables[0].Rows[i]["name"].ToString())
                            {
                                t.StartTime = Convert.ToDateTime(dt.Tables[0].Rows[i]["starttime"].ToString());
                                t.EndTime = Convert.ToDateTime(dt.Tables[0].Rows[i]["endtime"].ToString());
                                t.Module = dt.Tables[0].Rows[i]["module"].ToString();
                                t.Pressure1 = double.Parse(dt.Tables[0].Rows[i]["pressure1"].ToString());
                                t.Pressure2 = double.Parse(dt.Tables[0].Rows[i]["pressure2"].ToString());
                                t.Pressure3 = double.Parse(dt.Tables[0].Rows[i]["pressure3"].ToString());
                                t.Pressure4 = double.Parse(dt.Tables[0].Rows[i]["pressure4"].ToString());
                                t.ActualFlow = double.Parse(dt.Tables[0].Rows[i]["actualflow"].ToString());
                                t.SetFlow = double.Parse(dt.Tables[0].Rows[i]["setflow"].ToString());
                                t.Temperature = double.Parse(dt.Tables[0].Rows[i]["temperature"].ToString());
                                t.Interval = double.Parse(dt.Tables[0].Rows[i]["interval"].ToString());
                                t.IsStandardMfc = bool.Parse(dt.Tables[0].Rows[i]["isstandardMfc"].ToString());
                                t.MaintainPressure1 = double.Parse(dt.Tables[0].Rows[i]["maintainpressure1"].ToString());
                                t.MaintainPressure2 = double.Parse(dt.Tables[0].Rows[i]["maintainpressure2"].ToString());
                                t.MaintainPressureDifference = double.Parse(dt.Tables[0].Rows[i]["maintainpressuredifference"].ToString());
                                t.Volume = double.Parse(dt.Tables[0].Rows[i]["volume"].ToString());
                                t.MeanDifferencePressure = double.Parse(dt.Tables[0].Rows[i]["meandifferencepressure"].ToString());
                                t.BasePressure = double.Parse(dt.Tables[0].Rows[i]["basepressure"].ToString());
                                t.Deviation = double.Parse(dt.Tables[0].Rows[i]["deviation"].ToString());
                                t.Result = dt.Tables[0].Rows[i]["result"].ToString();
                            }
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                LOG.Error(ex.Message, ex);
            }
        }

        public void InitStandardMfc()
        {
            try
            {
                string sql = $"select * from \"pm_mfcror\" where \"module\" = '{Module}' and \"isstandardmfc\" = 't' order by \"endtime\" DESC";

                DataTable dbData = DataQuery.Query(sql);

                if (dbData.Rows.Count != 0)
                {
                    StandardMfcRorData = TableToListModel<MfcRorData>(dbData).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                LOG.Error(ex.Message, ex);
            }
        }

        public void ClearMfcRorData()
        {
            MfcRorList.Clear();
            foreach (var item in _preActionList)
            {
                MfcRorList.Add(new MfcRorData() { Name = item.Key });
            }

            //DB.ExcuteTransAction(new List<string> { $"delete from pm_mfcror where \"module\" = '{Module}'" });
        }

        public List<T> TableToListModel<T>(DataTable dt) where T : new()
        {
            // 定义集合    
            List<T> ts = new List<T>();

            // 获得此模型的类型   
            Type type = typeof(T);
            string tempName = "";

            foreach (DataRow dr in dt.Rows)
            {
                T t = new T();
                // 获得此模型的公共属性      
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    tempName = pi.Name;  // 检查DataTable是否包含此列    

                    if (dt.Columns.Contains(tempName))
                    {
                        // 判断此属性是否有Setter      
                        if (!pi.CanWrite) continue;

                        object value = dr[tempName];
                        if (value != DBNull.Value)
                            pi.SetValue(t, value, null);
                    }
                }
                ts.Add(t);
            }
            return ts;
        }

        public override Result Start(params object[] objs)
        {
            Reset();

            _loopCount = objs.Length;

            _mfcDataArray.Clear();

            for (int i = 0; i < objs.Length; i++)
            {
                _mfcDataArray.Add((MfcRorData)objs[i]);
            }

            _pressureMaxDiff = SC.GetValue<double>($"PM.{Module}.ThrottlePressureMaxDiff");
            _throttleTimeout = SC.GetValue<int>($"PM.{Module}.ThrottlePressureTimeout");

            _flag1 = _pmModule.GetChamberPressure() > _mfcDataArray[0].BasePressure;

            _startTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff");
            _swTimer.Restart();

            return Result.RUN;
        }

        public override Result Monitor()
        {
            try
            {
                //循环开始
                Loop((int)RoutineStep.StartLoop, _loopCount);

                CheckOutMfc((int)RoutineStep.CheckOutMfc);

                //设置MFC和PC的模式
                SetMfcModeToNormalByGroup((int)RoutineStep.SetMFCMode_1, MfcGroupName.All);
                SetPcModeToNormal((int)RoutineStep.SetPCMode_1, _lstPcList);

                //检查是否退出
                if (_pmModule.GetChamberPressure() > 980)
                {
                    //设置对应的MFC流量为0
                    SetMfcFlow((int)RoutineStep.SetMfcFlow_3, _mfcData.Name, 0, 3);

                    //设置MFC和PC的模式
                    SetMfcModeToNormalByGroup((int)RoutineStep.SetMFCMode_3, MfcGroupName.All);
                    SetPcModeToNormal((int)RoutineStep.SetPCMode_3, _lstPcList);

                    TimeDelay((int)RoutineStep.TimeDelay10, 3);

                    EV.PostWarningLog(Module, "Chamber Pressure above 980mbar,Mfc Ror Routine Abort!");

                    throw (new RoutineFaildException());
                }

                if (_flag1)
                {
                    //打开EPV2
                    SetIoValueByGroup((int)RoutineStep.SetEPV2_1, IoGroupName.EPV2, true, _IoValueTimeout);

                    //设置蝶阀Enable
                    SetThrottleEnableAndWait((int)RoutineStep.SetTVEnable_1, _IoThrottle, 5);

                    //设置蝶阀为压力模式
                    SetThrottleToPressModeAndWait((int)RoutineStep.SetTVPressMode_1, _IoThrottle, 5);

                    //伺服压力设定值到0mbar
                    SetThrottleToTargetAndNoWait((int)RoutineStep.SetTV_1, _IoThrottle, _pumpBasePressure);

                    //等待腔体压力Pump到设定值
                    WaitChamberPressDownTo((int)RoutineStep.WaitTV_1, _pumpBasePressure, _throttleTimeout);
                }

                //关闭Final Valve
                SetIoValueByGroup((int)RoutineStep.SetFinalValve_1, IoGroupName.Final1, false, _IoValueTimeout);
                SetIoValueByGroup((int)RoutineStep.SetFinalValve_2, IoGroupName.Final2, false, _IoValueTimeout);
                SetIoValueByGroup((int)RoutineStep.SetV111, IoGroupName.V111, false, _IoValueTimeout);

                //关闭J阀组
                SetIoValueByGroup((int)RoutineStep.SetJValve, IoGroupName.J, false, _IoValueTimeout);

                //关闭蝶阀,再关闭EPV2
                SetThrottleToCloseMode((int)RoutineStep.SetTVCloseMode_1, _IoThrottle, 8);
                SetThrottleDisable((int)RoutineStep.CloseTV_1, _IoThrottle, 8);
                TimeDelay((int)RoutineStep.TimeDelay1, 1);
                SetIoValueByGroup((int)RoutineStep.SetEPV2_2, IoGroupName.EPV2, false, _IoValueTimeout);
                TimeDelay((int)RoutineStep.TimeDelay2, 3);

                if (_mfcData.IsStandardMfc)
                {
                    //记录第一次保压值
                    TimeDelay((int)RoutineStep.TimeDelay3, _mfcData.Interval);
                    SetRorMaintainPressure((int)RoutineStep.SetMaintainPressure1, 1);

                    //记录第二次保压值
                    TimeDelay((int)RoutineStep.TimeDelay4, _mfcData.Interval);
                    SetRorMaintainPressure((int)RoutineStep.SetMaintainPressure2, 2);
                }

                //设定MFC流量前执行动作
                PreSetMfcFlow((int)RoutineStep.PreSetMfcFlow);

                //设定MFC流量
                SetMfcFlow((int)RoutineStep.SetMfcFlow_1, _mfcData.Name, _mfcData.SetFlow, 3);
                TimeDelay((int)RoutineStep.TimeDelay5, 3);

                //记录第一次压力值
                TimeDelay((int)RoutineStep.TimeDelay6, _mfcData.Interval);
                SetRorPressure((int)RoutineStep.SetPressure1, 1);

                //记录第二次压力值
                TimeDelay((int)RoutineStep.TimeDelay7, _mfcData.Interval);
                SetRorPressure((int)RoutineStep.SetPressure2, 2);

                //记录第三次压力值
                TimeDelay((int)RoutineStep.TimeDelay8, _mfcData.Interval);
                SetRorPressure((int)RoutineStep.SetPressure3, 3);

                //记录第四次压力值
                TimeDelay((int)RoutineStep.TimeDelay9, _mfcData.Interval);
                SetRorPressure((int)RoutineStep.SetPressure4, 4);

                //设置MFC和PC的模式
                SetMfcModeToNormalByGroup((int)RoutineStep.SetMFCMode_2, MfcGroupName.All);
                SetPcModeToNormal((int)RoutineStep.SetPCMode_2, _lstPcList);

                //设定MFC流量后执行动作
                PostSetMfcFlow((int)RoutineStep.PostSetMfcFlow);

                CalBasePressure((int)RoutineStep.CalBasePressure2);
                if (_flag2)
                {
                    //打开EPV2
                    SetIoValueByGroup((int)RoutineStep.SetEPV2_3, IoGroupName.EPV2, true, _IoValueTimeout);

                    //设置蝶阀Enable
                    SetThrottleEnableAndWait((int)RoutineStep.SetTVEnable_2, _IoThrottle, 5);

                    //设置蝶阀为压力模式
                    SetThrottleToPressModeAndWait((int)RoutineStep.SetTVPressMode_2, _IoThrottle, 5);

                    //伺服压力设定值到0mbar
                    SetThrottleToTargetAndNoWait((int)RoutineStep.SetTV_2, _IoThrottle, _pumpBasePressure);

                    //等待腔体压力Pump到设定值
                    WaitChamberPressDownTo((int)RoutineStep.WaitTV_2, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout);
                }

                //计算
                if (_mfcData.IsStandardMfc)
                {
                    CalStandardMfc((int)RoutineStep.CalStandardMfc);
                }
                else
                {
                    CalTestMfc((int)RoutineStep.CalTestMfc);
                }

                EndLoop((int)RoutineStep.EndLoop);
            }
            catch (RoutineBreakException)
            {
                return Result.RUN;
            }
            catch (RoutineFaildException)
            {
                return Result.FAIL;
            }

            _swTimer.Stop();

            return Result.DONE;
        }

        protected void CheckOutMfc(int id)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                _mfcData = _mfcDataArray[0];
                //测试流量设置为配置文件中的流量值
                _mfcData.SetFlow = _mfcFlowList[_mfcData.Name];
                _mfcDataArray.RemoveAt(0);

                Notify($"Start {_mfcData.Name} ROR");

                return true;
            });

            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        //设定保压压力
        private void SetRorMaintainPressure(int id, int index)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                switch (index)
                {
                    case 1:
                        {
                            _mfcData.MaintainPressure1 = _pmModule.GetChamberPressure();
                        }
                        break;

                    case 2:
                        {
                            _mfcData.MaintainPressure2 = _pmModule.GetChamberPressure();

                            _mfcData.MaintainPressureDifference = _mfcData.MaintainPressure2 - _mfcData.MaintainPressure1;
                            _mfcData.MaintainPressureDifference = Math.Round(_mfcData.MaintainPressureDifference, 2);
                        }
                        break;
                }

                return true;
            });
            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        //设定压力
        private void SetRorPressure(int id, int index)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                switch (index)
                {
                    case 1:
                        {
                            _mfcData.Pressure1 = _pmModule.GetChamberPressure();
                        }
                        break;

                    case 2:
                        {
                            _mfcData.Pressure2 = _pmModule.GetChamberPressure();
                        }
                        break;

                    case 3:
                        {
                            _mfcData.Pressure3 = _pmModule.GetChamberPressure();
                        }
                        break;

                    case 4:
                        {
                            _mfcData.Pressure4 = _pmModule.GetChamberPressure();

                            _mfcData.MeanDifferencePressure = (_mfcData.Pressure4 - _mfcData.Pressure1) / 3.0;
                            _mfcData.MeanDifferencePressure = Math.Round(_mfcData.MeanDifferencePressure, 2);
                        }
                        break;
                }

                return true;
            });
            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        protected void PreSetMfcFlow(int id)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                if (!_preActionList.ContainsKey(_mfcData.Name))
                {
                    return false;
                }

                foreach (MfcRorAction action in _preActionList[_mfcData.Name])
                {
                    if (action.Name.Contains("Mfc"))
                    {
                        SetMfc(action.Name, action.Value);
                    }
                    else if (action.Name.Contains("V"))
                    {
                        SetValve(action.Name, action.Value);
                    }
                    else if (action.Name.Contains("Pressure"))
                    {
                        SetPC(action.Name, action.Value);
                    }
                }

                return true;
            });

            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        protected void PostSetMfcFlow(int id)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                if (!_postActionList.ContainsKey(_mfcData.Name))
                {
                    return false;
                }

                foreach (MfcRorAction action in _postActionList[_mfcData.Name])
                {
                    if (action.Name.Contains("Mfc"))
                    {
                        SetMfc(action.Name, action.Value);
                    }
                    else if (action.Name.Contains("V"))
                    {
                        SetValve(action.Name, action.Value);
                    }
                    else if (action.Name.Contains("Pressure"))
                    {
                        SetPC(action.Name, action.Value);
                    }
                }

                return true;
            });

            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        private bool SetValve(string valveName, string value)
        {
            IoValve valve = DEVICE.GetDevice<IoValve>($"{Module}.{valveName}");

            if (valve == null)
            {
                EV.PostAlarmLog(Module, $"{valveName} is null");

                return false;
            }

            bool isOpen = value == "Open";

            if (valve.TurnValve(isOpen, out string reason))
            {
                EV.PostInfoLog(Module, $"{valveName} Set {value} Succeed , {reason}");
                return true;
            }
            else
            {
                EV.PostAlarmLog(Module, $"{valveName} Set {value} Failed");
                return false;
            }
        }

        private bool SetPC(string pcName, string value)
        {
            IoPressure pc = DEVICE.GetDevice<IoPressure>($"{Module}.{pcName}");

            if (pc == null)
            {
                EV.PostAlarmLog(Module, $"{pcName} is null");

                return false;
            }

            string reason;

            if (value == "Open")
            {
                if (pc.SetPcMode(PcCtrlMode.Open, out reason))
                {
                    EV.PostInfoLog(Module, $"{pcName} Set {value} Succeed");
                    return true;
                }
            }
            else if (value == "Close")
            {
                if (pc.SetPcMode(PcCtrlMode.Close, out reason))
                {
                    EV.PostInfoLog(Module, $"{pcName} Set {value} Succeed");
                    return true;
                }
            }
            else if (value == "Default")
            {
                pc.Ramp(pc.DefaultValue, 3000);

                EV.PostInfoLog(Module, $"{pcName} Set {value} Succeed");

                return true;
            }

            EV.PostAlarmLog(Module, $"{pcName} Set  {value} Failed");

            return false;
        }

        private bool SetMfc(string mfcName, string value)
        {
            IoMFC mfc = DEVICE.GetDevice<IoMFC>($"{Module}.{mfcName}");

            if (mfc == null)
            {
                EV.PostAlarmLog(Module, $"{mfcName} is null");

                return false;
            }

            string reason;

            if (value == "Open")
            {
                if (mfc.SetMfcMode(MfcCtrlMode.Open, out reason))
                {
                    EV.PostInfoLog(Module, $"{mfcName} Set {value} Succeed");
                    return true;
                }
            }
            else if (value == "Close")
            {
                if (mfc.SetMfcMode(MfcCtrlMode.Close, out reason))
                {
                    EV.PostInfoLog(Module, $"{mfcName} Set {value} Succeed");
                    return true;
                }
            }
            else if (value == "Default")
            {
                mfc.SetToDefaultByRamp(3000);

                return true;
            }
            else
            {
                if (double.TryParse(value, out double dValue))
                {
                    mfc.Ramp(dValue, 3000, out reason);

                    return true;
                }
            }

            EV.PostAlarmLog(Module, $"{mfcName} Set {value} Failed");

            return false;
        }

        private void CalBasePressure(int id)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                _flag2 = _pmModule.GetChamberPressure() > _mfcData.BasePressure;

                return true;
            });
            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        //计算标准MFC,求得反应腔压力
        private void CalStandardMfc(int id)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                if (_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference > 0)
                {
                    _mfcData.Volume = 1000000 * (_mfcData.SetFlow * 0.001 / Vm * R * _mfcData.Temperature) /
                  ((_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference) / (_mfcData.Interval / 60.0) / 0.01);

                    //保留2位小数
                    _mfcData.Volume = Math.Round(_mfcData.Volume, 2);
                    _mfcData.Result = "OK";

                    _endTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");

                    //数据保存至数据库
                    string sql = string.Format($"insert into \"pm_mfcror\"(\"starttime\",\"endtime\",\"name\",\"module\",\"scale\",\"pressure1\",\"pressure2\",\"pressure3\",\"pressure4\",\"actualflow\",\"setflow\",\"temperature\",\"interval\",\"isstandardmfc\",\"maintainpressure1\",\"maintainpressure2\",\"maintainpressuredifference\",\"volume\",\"meandifferencepressure\",\"basepressure\",\"deviation\",\"result\") values('{_startTime}','{_endTime}','{_mfcData.Name}','{_mfcData.Module}','{_mfcData.Scale}','{_mfcData.Pressure1}','{_mfcData.Pressure2}','{_mfcData.Pressure3}','{_mfcData.Pressure4}','{_mfcData.ActualFlow}','{_mfcData.SetFlow}','{_mfcData.Temperature}','{_mfcData.Interval}','{_mfcData.IsStandardMfc}','{_mfcData.MaintainPressure1}','{_mfcData.MaintainPressure2}','{_mfcData.MaintainPressureDifference}','{_mfcData.Volume}','{_mfcData.MeanDifferencePressure}','{_mfcData.BasePressure}','{_mfcData.Deviation}','{_mfcData.Result}')");

                    List<string> cmdList = new List<string>() { sql };
                    if (DB.ExcuteTransAction(cmdList))
                    {
                        //设置基准MFC
                        StandardMfcRorData = _mfcData;

                        MfcRorList.ForEach(mfc =>
                        {
                            if (mfc.Name == _mfcData.Name)
                            {
                                mfc.Update(_mfcData);
                            }
                        });

                        Notify($"{_mfcData.Name} ROR Finished! Chamber Volume is {_mfcData.Volume};Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
                    }
                    else
                    {
                        EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
                    }
                }
                else
                {
                    EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! MeanDifferencePressure Less Than MaintainPressureDifference !Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
                }

                return true;
            });
            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        //计算测试MFC,求得实际流量
        private void CalTestMfc(int id)
        {
            Tuple<bool, Result> ret = Execute(id, () =>
            {
                if (_mfcData.SetFlow != 0)
                {
                    _mfcData.ActualFlow = ((_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference) / (0.01 * (_mfcData.Interval / 60.0))) * (_mfcData.Volume / 1000000.0 / (R * _mfcData.Temperature)) * Vm * 1000;

                    _mfcData.Deviation = (_mfcData.ActualFlow / _mfcData.SetFlow - 1) * 100;
                    //保留2位小数
                    _mfcData.Deviation = Math.Round(_mfcData.Deviation, 2);
                    _mfcData.Volume = Math.Round(_mfcData.Volume, 2);

                    //大于3%的MFC为超标
                    _mfcData.Result = Math.Abs(_mfcData.Deviation) <= 3 ? "OK" : "NG";

                    _endTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");

                    //数据保存至数据库
                    string sql = string.Format($"insert into \"pm_mfcror\"(\"starttime\",\"endtime\",\"name\",\"module\",\"scale\",\"pressure1\",\"pressure2\",\"pressure3\",\"pressure4\",\"actualflow\",\"setflow\",\"temperature\",\"interval\",\"isstandardmfc\",\"maintainpressure1\",\"maintainpressure2\",\"maintainpressuredifference\",\"volume\",\"meandifferencepressure\",\"basepressure\",\"deviation\",\"result\") values('{_startTime}','{_endTime}','{_mfcData.Name}','{_mfcData.Module}','{_mfcData.Scale}','{_mfcData.Pressure1}','{_mfcData.Pressure2}','{_mfcData.Pressure3}','{_mfcData.Pressure4}','{_mfcData.ActualFlow}','{_mfcData.SetFlow}','{_mfcData.Temperature}','{_mfcData.Interval}','{_mfcData.IsStandardMfc}','{_mfcData.MaintainPressure1}','{_mfcData.MaintainPressure2}','{_mfcData.MaintainPressureDifference}','{_mfcData.Volume}','{_mfcData.MeanDifferencePressure}','{_mfcData.BasePressure}','{_mfcData.Deviation}','{_mfcData.Result}')");

                    List<string> cmdList = new List<string>() { sql };
                    if (DB.ExcuteTransAction(cmdList))
                    {
                        MfcRorList.ForEach(mfc =>
                        {
                            if (mfc.Name == _mfcData.Name)
                            {
                                mfc.Update(_mfcData);
                            }
                        });

                        if (_mfcData.ActualFlow < 1)
                        {
                            EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed!腔体平均压差为{_mfcData.MeanDifferencePressure}," +
                                $"压差为{_mfcData.MaintainPressureDifference},时间间隔为{_mfcData.Interval},腔体体积为{_mfcData.Volume}," +
                                $"设定温度为{_mfcData.Temperature}");
                        }
                        else
                        {
                            Notify($"{_mfcData.Name} ROR Finished! {_mfcData.Name} Deviation is {_mfcData.Deviation}%;Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
                        }
                    }
                    else
                    {
                        EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
                    }
                }
                else
                {
                    EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
                }

                return true;
            });
            if (ret.Item1)
            {
                if (ret.Item2 == Result.FAIL)
                {
                    throw (new RoutineFaildException());
                }
                else
                    throw (new RoutineBreakException());
            }
        }

        public override void Abort()
        {
            base.Abort();
        }

        //private void CheckRoutineTimeOut()
        //{
        //    if (_routineTimeOut > 10)
        //    {
        //        if ((int)(_swTimer.ElapsedMilliseconds / 1000) > _routineTimeOut)
        //        {
        //            EV.PostAlarmLog(Module,$"Routine TimeOut! over {_routineTimeOut} s");
        //            throw (new RoutineFaildException());
        //        }
        //    }
        //}
    }
}
