| 
					
				 | 
			
			
				@@ -25,6 +25,7 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private R_TRIG _trigN2DownRD = new R_TRIG();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private R_TRIG _trigN2AirUpRD = new R_TRIG();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private R_TRIG _trigN2AirDownRD = new R_TRIG();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private R_TRIG _trigN2AirDownTwoRD = new R_TRIG();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private R_TRIG _trigSelectN2PurgeModeD = new R_TRIG();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private Dictionary<string, Tuple<R_TRIG, List<Tuple<IDevice, string>>>> _n2PurgeSequenceAction;
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -33,7 +34,9 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private N2PurgeModeEnum _N2PurgeMode = N2PurgeModeEnum.Auto;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private double _n2PurgeData = 20;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private double _n2ToAirData = 185000;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private double _stabilityTime = 30;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private double _manualPhase2StabilityTime = 60;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private double _manualPhase4StabilityTime = 60;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private Dictionary<string, Stopwatch> _allTimeDict = new Dictionary<string, Stopwatch>();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private void InitN2PurgeData()
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -49,7 +52,8 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _n2PurgeData = SC.ContainsItem($"System.N2PurgeData") ? SC.GetValue<double>("System.N2PurgeData") : 20;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _n2ToAirData = SC.ContainsItem($"System.N2PurgeData") ? SC.GetValue<double>("System.N2ToAirData") : 185000;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            _stabilityTime = SC.ContainsItem($"System.StabilityTime") ? SC.GetValue<double>("System.StabilityTime") : 30;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _manualPhase2StabilityTime = SC.ContainsItem($"PM1.N2Purge.Manual_phase2.StabilityTime") ? SC.GetValue<double>("PM1.N2Purge.Manual_phase2.StabilityTime") : 60;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _manualPhase4StabilityTime = SC.ContainsItem($"PM1.N2Purge.Manual_phase4.StabilityTime") ? SC.GetValue<double>("PM1.N2Purge.Manual_phase4.StabilityTime") : 60;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _n2PurgeSequenceAction = ExtractionMethods.GetN2PurgeSequenceAction();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _n2PurgeSequenceStatus = new Dictionary<string, Func<bool>>()
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -65,6 +69,7 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {N2PurgeModeEnum.Manual_phase2.ToString(),()=>  GetN2PurgePhase2()},
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {N2PurgeModeEnum.Manual_phase3.ToString(),()=>  GetN2PurgePhase3() },
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {N2PurgeModeEnum.Manual_phase4.ToString(),()=>  GetN2PurgePhase4() },
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                {N2PurgeModeEnum.Manual_phase5.ToString(),()=>  GetN2PurgePhase5() },
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             };
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _allTimeDict = new Dictionary<string, Stopwatch>()
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -72,7 +77,8 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {N2PurgeModeEnum.Manual_phase1.ToString(),new Stopwatch() },
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {N2PurgeModeEnum.Manual_phase2.ToString(),new Stopwatch()},
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {N2PurgeModeEnum.Manual_phase3.ToString(),new Stopwatch()},
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {N2PurgeModeEnum.Manual_phase4.ToString(),new Stopwatch() }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                {N2PurgeModeEnum.Manual_phase4.ToString(),new Stopwatch() },
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                {N2PurgeModeEnum.Manual_phase5.ToString(),new Stopwatch() }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             };
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _rTrigDict = new Dictionary<string, R_TRIG>();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -101,12 +107,13 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 case N2PurgeModeEnum.N2PurgeMode:
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     ProcessPhase(_trigN2UpRD, N2PurgeModeEnum.Manual_phase1.ToString());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ProcessPhase(_trigN2DownRD, N2PurgeModeEnum.Manual_phase2.ToString());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ProcessPhase(_trigN2DownRD, N2PurgeModeEnum.Manual_phase2.ToString(), true, (int)(_manualPhase2StabilityTime * 1000));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 case N2PurgeModeEnum.ATMMode:
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     ProcessPhase(_trigN2AirDownRD, N2PurgeModeEnum.Manual_phase3.ToString());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ProcessPhase(_trigN2AirUpRD, N2PurgeModeEnum.Manual_phase4.ToString());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ProcessPhase(_trigN2AirUpRD, N2PurgeModeEnum.Manual_phase4.ToString(), true, (int)(_manualPhase4StabilityTime * 1000));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ProcessPhase(_trigN2AirDownTwoRD, N2PurgeModeEnum.Manual_phase5.ToString());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     break;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -134,9 +141,9 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private void ProcessPhase(R_TRIG r_TRIG, string modeKey)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private void ProcessPhase(R_TRIG r_TRIG, string modeKey, bool needCheck = false, int time = 0)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r_TRIG.CLK = _n2PurgeSequenceStatus[modeKey].Invoke();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            r_TRIG.CLK = needCheck ? (CheckConditionInTime(modeKey, time, () => _n2PurgeSequenceStatus[modeKey].Invoke())) : _n2PurgeSequenceStatus[modeKey].Invoke();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (r_TRIG.Q)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 LOG.Info($"N2PurgeMode Trigger {modeKey}!,O2:{GetO2Density()},time:{_allTimeDict[modeKey].ElapsedMilliseconds}");
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -266,15 +273,15 @@ namespace FurnaceRT.Equipments.PMs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private bool GetN2PurgePhase3()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return GetLADoorOpenStatus();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return GetO2Density() < _n2ToAirData && GetLADoorOpenStatus();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private bool GetN2PurgePhase5()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return GetO2Density() >= _n2ToAirData && GetLADoorOpenStatus();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return GetO2Density() >= _n2ToAirData && !GetLADoorOpenStatus();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private bool GetN2PurgePhase4()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return GetO2Density() >= _n2ToAirData;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return GetO2Density() >= _n2ToAirData && GetLADoorOpenStatus();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private bool GetN2PurgeAIRTo20PPMStatus()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 |