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 System.Linq; using System.Text; using System.Threading.Tasks; using SicModules.PMs.Utilities; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.DBCore; namespace SicModules.PMs.Routines { public class PMMfcRorRoutine : PMBaseRoutine { private enum RoutineStep { TimeDelay1, TimeDelay2, TimeDelay3, TimeDelay4, TimeDelay5, TimeDelay6, TimeDelay7, TimeDelay8, TimeDelay9, SetEPV2_1, SetEPV2_2, 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, SetMfcFlow_1, SetMfcFlow_2, SetPressure1, SetPressure2, SetPressure3, SetPressure4, SetMaintainPressure1, SetMaintainPressure2, CalStandardMfc, CalTestMfc, CalBasePressure1, CalBasePressure2, } private ModuleName moduleName; private PMModule _pmModule; private MfcRorData _mfcData; private Stopwatch _swTimer = new Stopwatch(); //摩尔气体常数 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 _flag; private string _startTime; private string _endTime; public PMMfcRorRoutine(ModuleName module, PMModule pm) : base(module, pm) { moduleName = module; _pmModule = pm; Name = "MfcRor"; _IoThrottle = DEVICE.GetDevice($"{Module}.TV"); } public override Result Start(params object[] objs) { Reset(); _mfcData = (MfcRorData)objs[0]; _pressureMaxDiff = SC.GetValue($"PM.{Module}.ThrottlePressureMaxDiff"); _throttleTimeout = SC.GetValue($"PM.{Module}.ThrottlePressureTimeout"); _startTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff"); _swTimer.Restart(); Notify($"Start {_mfcData.Name} ROR"); return Result.RUN; } public override Result Monitor() { try { //CheckRoutineTimeOut(); CalBasePressure((int)RoutineStep.CalBasePressure1); if (_flag) { //打开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 SetThrottlePressureAndWaitSetPoint((int)RoutineStep.SetTV_1, _IoThrottle, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); //等待腔体压力Pump到设定值 WaitChamberPressDownTo((int)RoutineStep.WaitTV_1, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); } //关闭蝶阀,再关闭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流量 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流量 SetMfcFlow((int)RoutineStep.SetMfcFlow_2, _mfcData.Name, 0, 3); CalBasePressure((int)RoutineStep.CalBasePressure2); if (_flag) { //打开EPV2 SetIoValueByGroup((int)RoutineStep.SetEPV2_2, IoGroupName.EPV2, true, _IoValueTimeout); //设置蝶阀Enable SetThrottleEnableAndWait((int)RoutineStep.SetTVEnable_2, _IoThrottle, 5); //设置蝶阀为压力模式 SetThrottleToPressModeAndWait((int)RoutineStep.SetTVPressMode_2, _IoThrottle, 5); //伺服压力设定值到0mbar SetThrottlePressureAndWaitSetPoint((int)RoutineStep.SetTV_2, _IoThrottle, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); //等待腔体压力Pump到设定值 WaitChamberPressDownTo((int)RoutineStep.WaitTV_2, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); } //计算 if(_mfcData.IsStandardMfc) { CalStandardMfc((int)RoutineStep.CalStandardMfc); } else { CalTestMfc((int)RoutineStep.CalTestMfc); } } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } _swTimer.Stop(); return Result.DONE; } private void CalBasePressure(int id) { Tuple ret = Execute(id, () => { _flag = _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 ret = Execute(id, () => { if (_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference > 0) { _mfcData.Volume = 100000 * (_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); _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\") 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}')"); List cmdList = new List() { sql }; if(DB.ExcuteTransAction(cmdList)) { 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! 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 ret = Execute(id, () => { if (_mfcData.SetFlow != 0) { _mfcData.ActualFlow = ((_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference) / (0.01 * (_mfcData.Interval / 60.0))) * (_mfcData.Volume / 100000.0 / (R * _mfcData.Temperature)) * Vm; _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.IsOverStandard = _mfcData.Deviation > 3; _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\",\"IsOverStandard\") 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.IsOverStandard}')"); List cmdList = new List() { sql }; if (DB.ExcuteTransAction(cmdList)) { 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()); } } //设定压力 private void SetRorPressure(int id,int index) { Tuple 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; } break; } 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 ret = Execute(id, () => { switch (index) { case 1: { _mfcData.MaintainPressure1 = _pmModule.GetChamberPressure(); } break; case 2: { _mfcData.MaintainPressure2 = _pmModule.GetChamberPressure(); _mfcData.MaintainPressureDifference = _mfcData.MaintainPressure2 - _mfcData.MaintainPressure1; } break; } 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()); // } // } //} } }