Explorar el Código

1.根据tps提供sequence 添加控压功能
2.根据tps提供Sequence添加TM Home Step功能

# Conflicts:
# Venus/Venus_RT/Config/TM/DeviceModelVenus_MF.xml
# Venus/Venus_RT/Devices/TM/JetTM.cs

lixiang hace 2 años
padre
commit
76a22f462f
Se han modificado 30 ficheros con 1102 adiciones y 141 borrados
  1. 14 0
      Venus/Framework/Common/Fsm/Entity.cs
  2. 2 0
      Venus/Framework/Common/Fsm/IStateMachine.cs
  3. 19 5
      Venus/Framework/Common/Fsm/StateMachine.cs
  4. 9 1
      Venus/Venus_Core/Recipe.cs
  5. 1 0
      Venus/Venus_Core/RtState.cs
  6. 6 1
      Venus/Venus_Core/VenusDevice.cs
  7. 1 1
      Venus/Venus_MainPages/ViewModels/OverVenusViewModel.cs
  8. 71 30
      Venus/Venus_MainPages/ViewModels/RecipeViewModel.cs
  9. 152 41
      Venus/Venus_MainPages/ViewModels/TMOperationViewModel.cs
  10. 29 24
      Venus/Venus_MainPages/Views/TMOperationView.xaml
  11. 2 1
      Venus/Venus_RT/Config/System.sccfg
  12. BIN
      Venus/Venus_RT/Config/TM/DeviceModelVenus_MF.xml
  13. 4 8
      Venus/Venus_RT/Config/TM/TMInterlock.xml
  14. 132 3
      Venus/Venus_RT/Devices/TM/JetTM.cs
  15. 3 1
      Venus/Venus_RT/Modules/LLs/LLEntity.cs
  16. 6 2
      Venus/Venus_RT/Modules/PMs/ProcessDefine.cs
  17. 112 0
      Venus/Venus_RT/Modules/TM/MFControlPressureRoutine.cs
  18. 97 9
      Venus/Venus_RT/Modules/TM/MFHomeRoutine.cs
  19. 1 1
      Venus/Venus_RT/Modules/TM/MFPumpRoutine.cs
  20. 85 10
      Venus/Venus_RT/Modules/TM/TMEntity.cs
  21. 1 0
      Venus/Venus_RT/Venus_RT.csproj
  22. 1 1
      Venus/Venus_Setup/Venus_RT.iss
  23. 1 1
      Venus/Venus_Simulator/Instances/SimulatorSystem.cs
  24. 35 0
      Venus/Venus_Themes/Converters/IsLastItemConverter.cs
  25. 54 0
      Venus/Venus_Themes/Converters/IsProgressedConverter.cs
  26. 102 0
      Venus/Venus_Themes/CustomControls/StepBar.cs
  27. 46 0
      Venus/Venus_Themes/CustomControls/StepBarItem.cs
  28. 111 0
      Venus/Venus_Themes/Themes/Generic.xaml
  29. 4 0
      Venus/Venus_Themes/Venus_Themes.csproj
  30. 1 1
      Venus/Venus_UI/Views/ShellView.xaml.cs

+ 14 - 0
Venus/Framework/Common/Fsm/Entity.cs

@@ -92,6 +92,12 @@ namespace Aitex.Core.RT.Fsm
                 fsm.AnyStateTransition(msg, func, next);
         }
 
+        protected void AnyStateTransition(int msg, FsmFunc func, int next, FsmFunc monitorFunc)
+        {
+            if (fsm != null)
+                fsm.AnyStateTransition(msg, func, next,monitorFunc);
+        }
+
         protected void AnyStateTransition<T, V>(V msg, FsmFunc func, T next)
         {
             Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
@@ -101,7 +107,15 @@ namespace Aitex.Core.RT.Fsm
             AnyStateTransition(_msg, func, _next);
 
         }
+        protected void AnyStateTransition<T, V>(V msg, FsmFunc func, T next, FsmFunc monitorFunc)
+        {
+            Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
 
+            int _next = Convert.ToInt32(next);
+            int _msg = Convert.ToInt32(msg);
+            AnyStateTransition(_msg, func, _next,  monitorFunc);
+
+        }
         protected void EnterExitTransition<T, V>(T state, FsmFunc enter, Nullable<V> msg, FsmFunc exit) where V : struct
         {
             Debug.Assert(typeof(T).IsEnum && ((msg == null) || typeof(V).IsEnum));

+ 2 - 0
Venus/Framework/Common/Fsm/IStateMachine.cs

@@ -26,6 +26,8 @@ namespace Aitex.Core.RT.Fsm
 
         void Transition(int state, int msg, FsmFunc func, int next);
         void AnyStateTransition(int msg, FsmFunc func, int next);
+        void AnyStateTransition(int msg, FsmFunc func, int next, FsmFunc monitorFunc);
+
         void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit);
 
         void PostMsg(int msg, object[] args);

+ 19 - 5
Venus/Framework/Common/Fsm/StateMachine.cs

@@ -7,6 +7,7 @@ using System.Collections.Concurrent;
 
 using Aitex.Core.RT.Log;
 using Aitex.Core.Utilities;
+using System.Linq;
 
 namespace Aitex.Core.RT.Fsm
 {
@@ -73,7 +74,7 @@ namespace Aitex.Core.RT.Fsm
         /// 状态进入/退出迁移表  状态,进入函数,进入消息,退出函数, 
         /// </summary>
         private Dictionary<int, Dictionary<int, Tuple<FsmFunc, int>>> transition;
-        private Dictionary<int, Tuple<FsmFunc, int>> anyStateTransition;
+        private Dictionary<int, Tuple<FsmFunc, int,FsmFunc>> anyStateTransition;
         private Dictionary<int, Tuple<FsmFunc, int, FsmFunc>> enterExitTransition;
 
         private Dictionary<int, string> _stringState = new Dictionary<int, string>();
@@ -82,6 +83,7 @@ namespace Aitex.Core.RT.Fsm
         private KeyValuePair<int, object[]> _msgInProcess = new KeyValuePair<int, object[]>((int)FSM_MSG.TIMER, null);
 
         private long _msgCounter = 0;
+        Dictionary<int, FsmFunc> fsmFuncs = new Dictionary<int, FsmFunc>();
 
         public StateMachine(string name, int initState = (int)FSM_STATE.UNDEFINE, int interval = 100)
         {
@@ -95,7 +97,7 @@ namespace Aitex.Core.RT.Fsm
             _msgQueue = new BlockingCollection<KeyValuePair<int, object[]>>();
 
             transition = new Dictionary<int, Dictionary<int, Tuple<FsmFunc, int>>>();
-            anyStateTransition = new Dictionary<int, Tuple<FsmFunc, int>>();
+            anyStateTransition = new Dictionary<int, Tuple<FsmFunc, int,FsmFunc>>();
             enterExitTransition = new Dictionary<int, Tuple<FsmFunc, int, FsmFunc>>();
 
             EnumLoop<FSM_STATE>.ForEach((item) =>
@@ -142,9 +144,13 @@ namespace Aitex.Core.RT.Fsm
                     }
 
                     //Loop AnyState迁移表
-
+                    
                     if (anyStateTransition.ContainsKey(_msgInProcess.Key))
                     {
+                        if (anyStateTransition[_msgInProcess.Key].Item3 != null && !fsmFuncs.Keys.Contains(_msgInProcess.Key))
+                        {
+                            fsmFuncs.Add(_msgInProcess.Key,anyStateTransition[_msgInProcess.Key].Item3);
+                        }
                         if (anyStateTransition[_msgInProcess.Key].Item1 != null)
                         {
                             if (anyStateTransition[_msgInProcess.Key].Item1(_msgInProcess.Value))  //need ChangeState
@@ -181,6 +187,11 @@ namespace Aitex.Core.RT.Fsm
                         continue;
                     }
 
+                    foreach (var func in fsmFuncs.Values)
+                    {
+                        func.Invoke(null);
+                    }
+
                     if (!transition.ContainsKey(State))
                     {
                         if (_msgInProcess.Key != (int)FSM_MSG.TIMER)
@@ -318,9 +329,12 @@ namespace Aitex.Core.RT.Fsm
 
         public void AnyStateTransition(int msg, FsmFunc func, int next)
         {
-            anyStateTransition[msg] = new Tuple<FsmFunc, int>(func, next);
+            anyStateTransition[msg] = new Tuple<FsmFunc, int,FsmFunc>(func, next,null);
+        }
+        public void AnyStateTransition(int msg, FsmFunc func, int next, FsmFunc monitorFunc)
+        {
+            anyStateTransition[msg] = new Tuple<FsmFunc, int,FsmFunc>(func, next,monitorFunc);
         }
-
         public void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit)
         {
             enterExitTransition[state] = new Tuple<FsmFunc, int, FsmFunc>(enter, msg, exit);

+ 9 - 1
Venus/Venus_Core/Recipe.cs

@@ -102,12 +102,19 @@ namespace Venus_Core
             get { return m_CreateTime;}
             set { m_CreateTime = value; InvokePropertyChanged("CreateTime"); }
         }
+        private string m_EditTime;
+        [IsOnlyRead]
+        public string EditTime
+        {
+            get { return m_EditTime; }
+            set { m_EditTime = value; InvokePropertyChanged("EditTime"); }
+        }
         private string m_LastModifiedBy;
         [IsOnlyRead]
         public string LastModifiedBy
         {
             get {  return m_LastModifiedBy;}
-            set { m_LastModifiedBy = value; InvokePropertyChanged("CreateTime"); }
+            set { m_LastModifiedBy = value; InvokePropertyChanged("LastModifiedBy"); }
         }
         private string m_Barcode;
         public string Barcode
@@ -569,6 +576,7 @@ namespace Venus_Core
             Recipe recipe = new Recipe();
             recipe.Header = new RecipeHead();
             recipe.Header.CreateTime = DateTime.Now.ToString();
+            recipe.Header.EditTime = DateTime.Now.ToString();
             recipe.Header.Type = recipeType;
             recipe.Header.Name = recipeName;
             recipe.Header.LastModifiedBy = "Admin";

+ 1 - 0
Venus/Venus_Core/RtState.cs

@@ -124,6 +124,7 @@ namespace Venus_Core
         Retracting,
         Swapping,
         Gotoing,
+        ControllingPressure
     }
     public enum LLState
     {

+ 6 - 1
Venus/Venus_Core/VenusDevice.cs

@@ -337,7 +337,12 @@
 
         JobTmRecovered,
 
-        Cycle
+        Cycle,
+        Online,
+        Offline,
+        ControlPressure,
+        AbortControlPressure
+
     }
 
     public enum MovementPosition

+ 1 - 1
Venus/Venus_MainPages/ViewModels/OverVenusViewModel.cs

@@ -1439,7 +1439,7 @@ namespace Venus_MainPages.ViewModels
         }
         private  IEnumerable<string> GetFilesNames(string path)
         {
-            return Directory.GetFiles(path, "*.rcp")
+            return Directory.GetFiles(path, "*.rcp")?
       .Select(Path.GetFileNameWithoutExtension);
         }
         void timer_Tick(object sender, EventArgs e)

+ 71 - 30
Venus/Venus_MainPages/ViewModels/RecipeViewModel.cs

@@ -213,10 +213,10 @@ namespace Venus_MainPages.ViewModels
                 UpdateRecipeFileList();
                 treeViewRcpList.SelectedItemChanged += TreeViewRcpList_SelectedItemChanged;
 
-                DispatcherTimer timer = new DispatcherTimer();
-                timer.Interval = TimeSpan.FromSeconds(1);
-                timer.Tick += Timer_Tick; ;
-                timer.Start();
+                //DispatcherTimer timer = new DispatcherTimer();
+                //timer.Interval = TimeSpan.FromSeconds(1);
+                //timer.Tick += Timer_Tick; ;
+                //timer.Start();
 
                 for (int i = 0; i < 5; i++)
                 {
@@ -241,10 +241,10 @@ namespace Venus_MainPages.ViewModels
             }
         }
 
-        private void Timer_Tick(object sender, EventArgs e)
-        {
+        //private void Timer_Tick(object sender, EventArgs e)
+        //{
             
-        }
+        //}
 
         TreeViewFileItem selectedItem;
         private void TreeViewRcpList_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
@@ -623,9 +623,7 @@ namespace Venus_MainPages.ViewModels
         {
             var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
             int insertIndex = Convert.ToInt32(t.Text);
-            
-            //RecipeStep recipeStep;
-            //OnAddStep(insertIndex);
+
             if (copyIndex == -1)
             {
                 var recipeStep = new RecipeStep();
@@ -673,36 +671,79 @@ namespace Venus_MainPages.ViewModels
         }
         private void MenuItemRightInsert_Click(object sender, RoutedEventArgs e)
         {
+            //var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
+            //int insertIndex = Convert.ToInt32(t.Text);
+            ////OnAddStep(insertIndex + 1);
+            //var recipeStep = new RecipeStep();
+            //switch (currentChamber)
+            //{
+            //    case JetChamber.Venus:
+            //    case JetChamber.Kepler2300:
+            //        recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
+            //        recipeStep.LstUnit.Add(new TCPUnit());
+            //        recipeStep.LstUnit.Add(new BiasUnit());
+            //        recipeStep.LstUnit.Add(new GasControlUnit());
+            //        recipeStep.LstUnit.Add(new ESCHVUnit());
+            //        recipeStep.LstUnit.Add(new ProcessKitUnit());
+            //        break;
+
+            //    case JetChamber.Kepler2200A:
+            //        recipeStep.LstUnit.Add(new Kepler2200GasControlUnit());
+
+            //        recipeStep.LstUnit.Add(new HeaterUnit());
+            //        recipeStep.LstUnit.Add(new Kepler2200RFUnit());
+
+
+
+
+
+            //        break;
+            //}
+            //CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
+            //for (int i=0;i< CurrentRecipe.Steps.Count;i++)
+            //{
+            //    CurrentRecipe.Steps[i].StepNo = i + 1;
+            //}
+            //LoadRecipe(CurrentRecipe);
             var t = ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as TextBox;
             int insertIndex = Convert.ToInt32(t.Text);
-            //OnAddStep(insertIndex + 1);
-            var recipeStep = new RecipeStep();
-            switch (currentChamber)
-            {
-                case JetChamber.Venus:
-                case JetChamber.Kepler2300:
-                    recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
-                    recipeStep.LstUnit.Add(new TCPUnit());
-                    recipeStep.LstUnit.Add(new BiasUnit());
-                    recipeStep.LstUnit.Add(new GasControlUnit());
-                    recipeStep.LstUnit.Add(new ESCHVUnit());
-                    recipeStep.LstUnit.Add(new ProcessKitUnit());
-                    break;
 
-                case JetChamber.Kepler2200A:
-                    recipeStep.LstUnit.Add(new Kepler2200GasControlUnit());
+            if (copyIndex == -1)
+            {
+                var recipeStep = new RecipeStep();
+                switch (currentChamber)
+                {
+                    case JetChamber.Venus:
+                    case JetChamber.Kepler2300:
+                        recipeStep.LstUnit.Add(new PressureByPressureModeUnit());
+                        recipeStep.LstUnit.Add(new TCPUnit());
+                        recipeStep.LstUnit.Add(new BiasUnit());
+                        recipeStep.LstUnit.Add(new GasControlUnit());
+                        recipeStep.LstUnit.Add(new ESCHVUnit());
+                        recipeStep.LstUnit.Add(new ProcessKitUnit());
+                        break;
 
-                    recipeStep.LstUnit.Add(new HeaterUnit());
-                    recipeStep.LstUnit.Add(new Kepler2200RFUnit());
+                    case JetChamber.Kepler2200A:
+                        recipeStep.LstUnit.Add(new Kepler2200GasControlUnit());
 
+                        recipeStep.LstUnit.Add(new HeaterUnit());
+                        recipeStep.LstUnit.Add(new Kepler2200RFUnit());
 
+                        break;
+                }
 
+                CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
+            }
+            else
+            {
+                var t1 = JsonConvert.SerializeObject(CurrentRecipe);
+                var recipeStep = Recipe.Load(t1).Steps[copyIndex - 1];
 
+                CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
 
-                    break;
             }
-            CurrentRecipe.Steps.Insert(insertIndex, recipeStep);
-            for (int i=0;i< CurrentRecipe.Steps.Count;i++)
+
+            for (int i = 0; i < CurrentRecipe.Steps.Count; i++)
             {
                 CurrentRecipe.Steps[i].StepNo = i + 1;
             }

+ 152 - 41
Venus/Venus_MainPages/ViewModels/TMOperationViewModel.cs

@@ -1,15 +1,18 @@
 using Aitex.Core.Common.DeviceData;
 using Aitex.Core.UI.Control;
 using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.Equipment;
 using MECF.Framework.Common.OperationCenter;
 using Prism.Commands;
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Windows.Threading;
 using Venus_Core;
 using Venus_MainPages.Unity;
+using Venus_MainPages.Views;
 using Venus_Themes.CustomControls;
 using Venus_Themes.Unity;
 
@@ -18,14 +21,19 @@ namespace Venus_MainPages.ViewModels
     public class TMOperationViewModel : BindableBase
     {
         #region 私有字段
-        private bool m_TMIsOFFline;
-        private bool m_LLIsOFFline;
+        private TMOperationView m_TMOperationView;
+        private bool m_IsOFFline=true;
 
-        private bool m_PMADoorIsOpen;
-        private bool m_PMBDoorIsOpen;
-        private bool m_PMCDoorIsOpen;
-        private bool m_PMDDoorIsOpen;
-        private bool m_LLADoorIsOpen;
+        private bool m_TMIsOFFline = true;
+
+
+
+
+        //private bool m_PMADoorIsOpen;
+        //private bool m_PMBDoorIsOpen;
+        //private bool m_PMCDoorIsOpen;
+        //private bool m_PMDDoorIsOpen;
+        //private bool m_LLADoorIsOpen;
 
 
         private bool m_PMAIsInstalled;
@@ -56,8 +64,17 @@ namespace Venus_MainPages.ViewModels
         private List<string> m_RtDataKeys=new List<string> ();
 
         private int m_TMOutChamberPressure;
+        private int m_TMOutChamberFlow;
+
         private int m_TMChamberPressureSetPoint;
+        private int m_TMChamberFlowSetPoint;
+        private ObservableCollection<string> m_HomeAllSteps = new ObservableCollection<string>();
+        private int m_StepProcess;
+        private bool m_TMIsHoming;
+
+        #endregion
 
+        #region 属性
         public bool TMValveN2IsOpen
         {
             get { return m_TMValveN2IsOpen; }
@@ -133,30 +150,63 @@ namespace Venus_MainPages.ViewModels
             get { return m_TMChamberPressureSetPoint; }
             set { SetProperty(ref m_TMChamberPressureSetPoint, value); }
         }
-        
-        #endregion
-
-        #region 属性
-        public bool TMIsOFFline
+        public int TMChamberFlowSetPoint
         {
-            get { return m_TMIsOFFline; }
-            set { SetProperty(ref m_TMIsOFFline, value); }
-        }
-        public bool LLIsOFFline
-        {
-            get { return m_LLIsOFFline; }
-            set { SetProperty(ref m_LLIsOFFline, value); }
+            get { return m_TMChamberFlowSetPoint; }
+            set { SetProperty(ref m_TMChamberFlowSetPoint, value); }
         }
-        public bool PMADoorIsOpen
+        public bool IsOFFline
         {
-            get { return m_PMADoorIsOpen; }
-            set { SetProperty(ref m_PMADoorIsOpen, value); }
+            get { return m_IsOFFline; }
+            set
+            {
+                SetProperty(ref m_IsOFFline, value);
+            }
         }
-        public bool LLADoorIsOpen
+        public bool TMIsOFFline
         {
-            get { return m_LLADoorIsOpen; }
-            set { SetProperty(ref m_LLADoorIsOpen, value); }
+            get { return m_TMIsOFFline; }
+            set 
+            {
+                if (m_TMIsOFFline == true && value == false)
+                {
+                    InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.ControlPressure}");
+
+                }
+                if (m_TMIsOFFline == false && value == true)
+                {
+                    InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.AbortControlPressure}");
+
+                }
+                SetProperty(ref m_TMIsOFFline, value);
+            }
         }
+      
+        //public bool PMADoorIsOpen
+        //{
+        //    get { return m_PMADoorIsOpen; }
+        //    set { SetProperty(ref m_PMADoorIsOpen, value); }
+        //}
+        //public bool PMBDoorIsOpen
+        //{
+        //    get { return m_PMBDoorIsOpen; }
+        //    set { SetProperty(ref m_PMBDoorIsOpen, value); }
+        //}
+        //public bool PMCDoorIsOpen
+        //{
+        //    get { return m_PMCDoorIsOpen; }
+        //    set { SetProperty(ref m_PMCDoorIsOpen, value); }
+        //}
+        //public bool PMDDoorIsOpen
+        //{
+        //    get { return m_PMDDoorIsOpen; }
+        //    set { SetProperty(ref m_PMDDoorIsOpen, value); }
+        //}
+        //public bool LLADoorIsOpen
+        //{
+        //    get { return m_LLADoorIsOpen; }
+        //    set { SetProperty(ref m_LLADoorIsOpen, value); }
+        //}
         public Dictionary<string, object> RtDataValues
         {
             get { return m_RtDataValues; }
@@ -192,23 +242,52 @@ namespace Venus_MainPages.ViewModels
             get { return m_LLBIsInstalled; }
             set { SetProperty(ref m_LLBIsInstalled, value); }
         }
+        public int TMOutChamberFlow
+        {
+            get { return m_TMOutChamberFlow; }
+            set
+            {
+                if (value != m_TMOutChamberFlow)
+                {
+                    InvokeClient.Instance.Service.DoOperation($"TM.SetChamberFlow", value);
+                }
+                SetProperty(ref m_TMOutChamberFlow, value);
+            }
+        }
+
         public int TMOutChamberPressure
         {
             get { return m_TMOutChamberPressure; }
             set 
             {
-                if (value != m_TMOutChamberPressure)
-                {
-                    InvokeClient.Instance.Service.DoOperation($"TM.SetChamberPressure",value);
-                }
+                //if (value != m_TMOutChamberPressure)
+                //{
+                //    InvokeClient.Instance.Service.DoOperation($"TM.SetChamberPressure",value);
+                //}
                 SetProperty(ref m_TMOutChamberPressure, value);
             }
         }
-        
+        public ObservableCollection<string> HomeAllSteps
+        {
+            get { return m_HomeAllSteps; }
+            set{SetProperty(ref m_HomeAllSteps, value);}
+        }
+        public int StepProcess
+        {
+            get { return m_StepProcess; }
+            set { SetProperty(ref m_StepProcess, value); }
+        }
+        public bool TMIsHoming
+        {
+            get { return m_TMIsHoming; }
+            set { SetProperty(ref m_TMIsHoming, value); }
+        }
         #endregion
 
         #region 命令
-
+        private DelegateCommand<object> _LoadCommand;
+        public DelegateCommand<object> LoadCommand =>
+            _LoadCommand ?? (_LoadCommand = new DelegateCommand<object>(OnLoad));
 
         private DelegateCommand _HomeCommand;
         public DelegateCommand HomeCommand =>
@@ -271,7 +350,14 @@ namespace Venus_MainPages.ViewModels
         private DelegateCommand _SetTMChamberPressureCommand;
         public DelegateCommand SetTMChamberPressureCommand =>
             _SetTMChamberPressureCommand ?? (_SetTMChamberPressureCommand = new DelegateCommand(OnSetTMChamberPressure));
-        
+
+        private DelegateCommand _OnlineCommand;
+        public DelegateCommand OnlineCommand =>
+            _OnlineCommand ?? (_OnlineCommand = new DelegateCommand(OnOnline));
+
+        private DelegateCommand _OfflineCommand;
+        public DelegateCommand OfflineCommand =>
+            _OfflineCommand ?? (_OfflineCommand = new DelegateCommand(OnOffline));
 
         #endregion
 
@@ -298,9 +384,11 @@ namespace Venus_MainPages.ViewModels
             UIEvents.LLTDoorRaiseChangedEvent += UIEvents_LLTDoorRaiseChangedEvent;
 
             UIEvents.LLEDoorRaiseChangedEvent += UIEvents_LLEDoorRaiseChangedEvent;
-
-
-
+            HomeAllSteps.Add("Lid");
+            HomeAllSteps.Add("Robot");
+            HomeAllSteps.Add("Slit Door");
+            HomeAllSteps.Add("Pump");
+            HomeAllSteps.Add("ATM Switch");
 
         }
 
@@ -308,7 +396,10 @@ namespace Venus_MainPages.ViewModels
         #endregion
 
         #region 命令方法
-
+        private void OnLoad(object tmOperationView)
+        {
+           m_TMOperationView = (TMOperationView)tmOperationView;
+        }
 
         private void OnHome()
         {
@@ -382,15 +473,23 @@ namespace Venus_MainPages.ViewModels
         {
             //InvokeClient.Instance.Service.DoOperation($"TM.SetChamberPressure", TMChamberPressureSetPoint);
             //TMOutChamberPressure = TMChamberPressureSetPoint;
-            InvokeClient.Instance.Service.DoOperation("System.SetConfig","TM.ChamberPressure", TMChamberPressureSetPoint.ToString());
+            ////InvokeClient.Instance.Service.DoOperation("System.SetConfig", "TM.ControlPressureSetPoint", TMChamberPressureSetPoint.ToString());
         }
-      
+        private void OnOnline()
+        {
+            InvokeClient.Instance.Service.DoOperation($"{m_ModuleCheckedName}.{RtOperation.Online}");
+        }
+        private void OnOffline()
+        {
+            InvokeClient.Instance.Service.DoOperation($"{m_ModuleCheckedName}.{RtOperation.Offline}");
+        }
+
         #endregion
 
         #region 私有方法
         void timer_Tick(object sender, EventArgs e)
         {
-            TMOutChamberPressure = (int)QueryDataClient.Instance.Service.GetConfig("TM.ChamberPressure");
+            TMOutChamberPressure = (int)QueryDataClient.Instance.Service.GetConfig("TM.ControlPressureSetPoint");
 
 
             RtDataValues = QueryDataClient.Instance.Service.PollData(m_RtDataKeys);
@@ -414,6 +513,14 @@ namespace Venus_MainPages.ViewModels
             LLBFastPumpValveIsOpen = CommonFunction.GetValue<bool>(RtDataValues, "TM.LLBFastPumpValve.IsOpen");
             LLBPurgeValveIsOpen = CommonFunction.GetValue<bool>(RtDataValues, "TM.LLBPurgeValve.IsOpen");
             LLBVentValveIsOpen = CommonFunction.GetValue<bool>(RtDataValues, "TM.LLBVentValve.IsOpen");
+            IsOFFline= !CommonFunction.GetValue<bool>(RtDataValues, $"{m_ModuleCheckedName}.IsOnline");
+            TMIsOFFline= !CommonFunction.GetValue<bool>(RtDataValues, $"TM.IsOnline");
+            TMIsHoming= (TMState)(Enum.Parse(typeof(TMState), RtDataValues[$"TM.FsmState"].ToString()))== TMState.Initializing;
+            if (m_TMOperationView != null)
+            {
+                m_TMOperationView.stepBar.Progress= CommonFunction.GetValue<int>(RtDataValues, "TM.Home.StepNo");
+
+            }
         }
         private void addDataKeys()
         {
@@ -459,9 +566,13 @@ namespace Venus_MainPages.ViewModels
             m_RtDataKeys.Add("TM.LLBESlitDoor.IsClosed");
             m_RtDataKeys.Add("TM.N2PressureSwitch.Value");
             m_RtDataKeys.Add("TM.TMPressureCtrl.TMChamberSetPoint");
+            m_RtDataKeys.Add("LLA.IsOnline");
+            m_RtDataKeys.Add("LLB.IsOnline");
+            m_RtDataKeys.Add("TM.IsOnline");
+            m_RtDataKeys.Add("TM.FsmState");
+            m_RtDataKeys.Add("TM.Home.StepNo");
 
-
-
+            
         }
         private void UIEvents_PMDoorRaiseChangedEvent(DoorPara obj)
         {

+ 29 - 24
Venus/Venus_MainPages/Views/TMOperationView.xaml

@@ -13,7 +13,12 @@
              xmlns:converters2="clr-namespace:Venus_MainPages.Converters"
              xmlns:unity="clr-namespace:Venus_MainPages.Unity"
              mc:Ignorable="d" 
-             d:DesignHeight="450" d:DesignWidth="1900">
+             d:DesignHeight="450" d:DesignWidth="1900" Name="tmOp">
+    <i:Interaction.Triggers>
+        <i:EventTrigger EventName="Loaded">
+            <i:InvokeCommandAction Command="{Binding LoadCommand}" CommandParameter="{Binding ElementName=tmOp}"/>
+        </i:EventTrigger>
+    </i:Interaction.Triggers>
     <UserControl.Resources>
         <converters:BoolToBool   x:Key="BoolToBool"/>
         <converters:BoolToColor  x:Key="boolToColor"/>
@@ -27,8 +32,8 @@
 
     </UserControl.Resources>
     <Canvas>
-        
 
+        <customControls:StepBar x:Name="stepBar" Width="1000" Margin="100,11,0,0"  ItemsSource="{Binding HomeAllSteps}" Progress="{Binding RtDataValues[TM.Home.StepNo]}" Visibility="{Binding TMIsHoming,Converter={StaticResource bool2VisibilityConverter}}"/>
         <Canvas>
             <userControls:FlowPipe   Height="8"  Width="180" Canvas.Left="80" Canvas.Top="50" IsFlowing="{Binding TMValveN2IsOpen}"/>
             <Image    Width="40" Height="25" Canvas.Top="42" Canvas.Left="40" Source="Pack://application:,,,/Venus_Themes;Component/Resources/Arrow.png" Stretch="Uniform"/>
@@ -239,20 +244,20 @@
                 </userControls:Pump.ContextMenu>
             </userControls:Pump>
 
-            <customControls:CommonValveControl Status="{Binding TMValveN2IsOpen,Mode=TwoWay}"  ValveOrientation="Horizontal" Height="20" Width="20"  Canvas.Left="160" Canvas.Top="44"  Tag="TMValveN2" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding TMFastVentValveIsOpen,Mode=TwoWay}"  ValveOrientation="Horizontal" Height="20" Width="20"  Canvas.Left="440" Canvas.Top="204"  Tag="TMVentValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding LLAVentValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="245.5" Canvas.Top="360"  Tag="LLAVentValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding LLAPurgeValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="307" Canvas.Top="360"  Tag="LLAPurgeValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
+            <customControls:CommonValveControl Status="{Binding TMValveN2IsOpen,Mode=TwoWay}"  ValveOrientation="Horizontal" Height="20" Width="20"  Canvas.Left="160" Canvas.Top="44"  Tag="TMValveN2" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding TMFastVentValveIsOpen,Mode=TwoWay}"  ValveOrientation="Horizontal" Height="20" Width="20"  Canvas.Left="440" Canvas.Top="204"  Tag="TMVentValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding LLAVentValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="245.5" Canvas.Top="360"  Tag="LLAVentValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding LLAPurgeValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="307" Canvas.Top="360"  Tag="LLAPurgeValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
 
-            <customControls:CommonValveControl Status="{Binding LLBVentValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="1058" Canvas.Top="350"   Tag="LLBVentValve"  Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding LLBPurgeValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="992" Canvas.Top="350"  Tag="LLBPurgeValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
+            <customControls:CommonValveControl Status="{Binding LLBVentValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="1058" Canvas.Top="350"   Tag="LLBVentValve"  Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding LLBPurgeValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="992" Canvas.Top="350"  Tag="LLBPurgeValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
 
-            <customControls:CommonValveControl Status="{Binding TMSoftPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="603" Canvas.Top="570"  Tag="TMSoftPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding TMFastPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="683" Canvas.Top="570"  Tag="TMFastPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding LLASoftPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="453" Canvas.Top="650"  Tag="LLASoftPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding LLAFastPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="533" Canvas.Top="650"  Tag="LLAFastPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding LLBSoftPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="753" Canvas.Top="650"  Tag="LLBSoftPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
-            <customControls:CommonValveControl Status="{Binding LLBFastPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="833" Canvas.Top="650"  Tag="LLBFastPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="True"/>
+            <customControls:CommonValveControl Status="{Binding TMSoftPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="603" Canvas.Top="570"  Tag="TMSoftPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding TMFastPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="683" Canvas.Top="570"  Tag="TMFastPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding LLASoftPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="453" Canvas.Top="650"  Tag="LLASoftPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding LLAFastPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="533" Canvas.Top="650"  Tag="LLAFastPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding LLBSoftPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="753" Canvas.Top="650"  Tag="LLBSoftPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
+            <customControls:CommonValveControl Status="{Binding LLBFastPumpValveIsOpen,Mode=TwoWay}"  ValveOrientation="Vertical"   Height="20" Width="20"  Canvas.Left="833" Canvas.Top="650"  Tag="LLBFastPumpValve" Command="{Binding ControlValveCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" IsCanEdit="{Binding TMIsOFFline}"/>
 
 
             <userControls:Pipe2    Canvas.Left="1072"  Canvas.Top="445" HorizontalAlignment="Left" VerticalAlignment="Top" RotateTransformValue="90" />
@@ -292,7 +297,7 @@
 
 
 
-            <TextBlock  FontSize="15" Canvas.Top="20" Canvas.Left="162" Text="V1"/>
+            <TextBlock  FontSize="15" Canvas.Top="70" Canvas.Left="162" Text="V1"/>
             <TextBlock  FontSize="15" Canvas.Top="180" Canvas.Left="420" Text="Fast Vent"/>
             <TextBlock  FontSize="15" Canvas.Top="310" Canvas.Left="420" Text="Soft Vent"/>
 
@@ -545,22 +550,22 @@
                     </Grid.ColumnDefinitions>
                     <TextBlock Text="Purge Count"   Padding="30,10,0,0" Background="#D0D8E8"/>
                     <TextBlock Text="All Count"        Grid.Column="2"  Padding="40,10,0,5" Background="#D0D8E8"/>
-                    <customControls:PathButton Content="Purge"  Width="110" Margin="0,3,0,3" Height="28" VerticalAlignment="Center"  Grid.Column="4" Command="{Binding PurgeCommand}"  IsEnabled="{Binding Path=TMIsOFFline}"/>
+                    <customControls:PathButton Content="Purge"  Width="110" Margin="0,3,0,3" Height="28" VerticalAlignment="Center"  Grid.Column="4" Command="{Binding PurgeCommand}"  IsEnabled="{Binding Path=IsOFFline}"/>
 
                     <StackPanel Grid.Row="1" Grid.ColumnSpan="5" Orientation="Horizontal" HorizontalAlignment="Center" Height="35">
-                        <customControls:PathButton Content="Home"              Width="110" Height="28" Margin="0,0,5,0"   Command="{Binding HomeCommand}" IsEnabled="{Binding Path=TMIsOFFline}"/>
-                        <customControls:PathButton Content="Vent"              Width="110" Height="28" Margin="0 0 5 0"  IsEnabled="{Binding Path=TMIsOFFline}" Command="{Binding VentCommand}"/>
-                        <customControls:PathButton Content="Pump"              Width="110" Height="28" Margin="0 0 0 0"  IsEnabled="{Binding Path=TMIsOFFline}" Command="{Binding PumpCommand}"/>
+                        <customControls:PathButton Content="Home"              Width="110" Height="28" Margin="0,0,5,0"   Command="{Binding HomeCommand}" IsEnabled="{Binding Path=IsOFFline}"/>
+                        <customControls:PathButton Content="Vent"              Width="110" Height="28" Margin="0 0 5 0"  IsEnabled="{Binding Path=IsOFFline}" Command="{Binding VentCommand}"/>
+                        <customControls:PathButton Content="Pump"              Width="110" Height="28" Margin="0 0 0 0"  IsEnabled="{Binding Path=IsOFFline}" Command="{Binding PumpCommand}"/>
                         <!--<customControls:PathButton Content="Check Load"        Width="114" Height="28" Margin="5,0,0,0" Visibility="{Binding ElementName=tmRadioButton,Path=IsChecked,Converter={StaticResource bool2VisibilityConverter}}" IsEnabled="{Binding Path=TMIsOFFline}"/>-->
-                        <customControls:PathButton Content="Control Pressure"              Width="150" Height="28" Margin="5 0 0 0"  IsEnabled="{Binding Path=TMIsOFFline}" Command="{Binding SetTMChamberPressureCommand}" Visibility="{Binding ElementName=tmRadioButton,Path=IsChecked,Converter={StaticResource bool2VisibilityConverter}}"/>
-                        <TextBox Text="{Binding TMChamberPressureSetPoint,UpdateSourceTrigger=PropertyChanged}" Width="60" Height="28" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Visibility="{Binding ElementName=tmRadioButton,Path=IsChecked,Converter={StaticResource bool2VisibilityConverter}}"/>
-                        <customControls:PathButton Content="Abort"             Width="110"  Height="28" Margin="5,0,5,0" Command="{Binding AbortCommand}" IsEnabled="{Binding Path=TMIsOFFline}"/>
+                        <!--<customControls:PathButton Content="Control Pressure"              Width="160" Height="28" Margin="5 0 0 0"  IsEnabled="{Binding Path=TMIsOFFline}" Command="{Binding SetTMChamberPressureCommand}" Visibility="{Binding ElementName=tmRadioButton,Path=IsChecked,Converter={StaticResource bool2VisibilityConverter}}"/>-->
+                        <!--<TextBox Text="{Binding TMChamberPressureSetPoint,UpdateSourceTrigger=PropertyChanged}" Width="60" Height="28" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Visibility="{Binding ElementName=tmRadioButton,Path=IsChecked,Converter={StaticResource bool2VisibilityConverter}}"/>-->
+                        <customControls:PathButton Content="Abort"             Width="110"  Height="28" Margin="5,0,5,0" Command="{Binding AbortCommand}" IsEnabled="{Binding Path=IsOFFline}"/>
 
                     </StackPanel>
 
                     <StackPanel Grid.Row="2" Grid.ColumnSpan="5" Orientation="Horizontal" HorizontalAlignment="Center" Height="35">
-                        <RadioButton Content="Online"  Grid.Row="2" Grid.Column="2"  Width="80" Height="28" Margin="0 0 5 0" Style="{StaticResource Button_RadioButton}" IsChecked="{Binding TMIsOFFline,Converter={StaticResource BoolToBool},Mode=TwoWay}"/>
-                        <RadioButton Content="Offline" Grid.Row="2" Grid.Column="3"  Width="80" Height="28" Margin="5 0 0 0" Style="{StaticResource Button_RadioButton}" IsChecked="{Binding TMIsOFFline,Mode=TwoWay}"/>
+                        <RadioButton Content="Online"  Grid.Row="2" Grid.Column="2"  Width="80" Height="28" Margin="0 0 5 0" Style="{StaticResource Button_RadioButton}" IsChecked="{Binding IsOFFline,Converter={StaticResource BoolToBool},Mode=OneWay}" Command="{Binding OnlineCommand}"/>
+                        <RadioButton Content="Offline" Grid.Row="2" Grid.Column="3"  Width="80" Height="28" Margin="5 0 0 0" Style="{StaticResource Button_RadioButton}" IsChecked="{Binding IsOFFline,Mode=OneWay}" Command="{Binding OfflineCommand}"/>
                     </StackPanel>
 
                 </Grid>

+ 2 - 1
Venus/Venus_RT/Config/System.sccfg

@@ -141,7 +141,8 @@
 		<config default="60" name="ExtendTimeout" nameView="Extend Timeout" description="" max="300" min="0" paramter="" tag="" unit="s" type="Integer" />
 		<config default="60" name="RetractTimeout" nameView="Retract Timeout" description="" max="300" min="0" paramter="" tag="" unit="s" type="Integer" />
 		<config default="180" name="SwapTimeout" nameView="Swap Timeout" description="" max="300" min="0" paramter="" tag="" unit="s" type="Integer" />
-		<config default="1000" name="ChamberPressure" nameView="Chamber Pressure" description="TM Chamber 控压" max="10000" min="0" paramter="" tag="" unit="s" type="Integer" />
+		<config default="100" name="ControlPressureCheckPoint" nameView="Control Pressure CheckPoint" description="TM Chamber 控压 检测值" max="300" min="0" paramter="" tag="" unit="mTorr" type="Integer" />
+		<config default="90" name="ControlPressureSetPoint"   nameView="Control Pressure SetPoint"   description="TM Chamber 控压 设定值" max="200" min="0" paramter="" tag="" unit="mTorr" type="Integer" />
 		<configs name="TM_MFC1" nameView="MFC1" >
 			<config default="true" name="Enable" nameView="Enable" description="Enable gas 1 or not" tag="" unit="" type="Bool" />
 			<config default="O2" name="GasName" nameView="Gas Name" description="Name of NO.1 gas stick" tag="" unit="" type="String" />

BIN
Venus/Venus_RT/Config/TM/DeviceModelVenus_MF.xml


+ 4 - 8
Venus/Venus_RT/Config/TM/TMInterlock.xml

@@ -18,8 +18,7 @@
     <Limit di="DI_LLB_E_Slit_Door_close_Position"			value="true" tip="LLB In Slit Door close Position"		tip.zh-CN="" tip.en-US="DI-28" />
     <Limit di="DI_LLB_T_Slit_Door_close_Position"			value="true" tip="LLB Out Slit Door close Position"		tip.zh-CN="" tip.en-US="DI-30" />    
     <Limit di="DI_LLB_Lid_Door_Closed"			value="true" tip="LLB Lid Door Closed"		tip.zh-CN="" tip.en-US="DI-31" />
-    <Limit do="DO_Purge_Valve_TM"	value="false" tip="Purge Valve TM"			tip.zh-CN="" tip.en-US="D0-03" />
-    <Limit do="DO_Vent_Valve_TM"				value="false" tip="Soft Vent Valve TM"					tip.zh-CN="" tip.en-US="DO-04" />
+   
   </Action>
   
   <Action do="DO_Fast_Pumping_Valve_TM"					value="true" tip="Fast Pumping Valve TM"	tip.zh-CN="" tip.en-US="DO-02" >
@@ -31,24 +30,21 @@
     <Limit di="DI_LLB_E_Slit_Door_close_Position"			value="true" tip="LLB In Slit Door close Position"		tip.zh-CN="" tip.en-US="DI-28" />
     <Limit di="DI_LLB_T_Slit_Door_close_Position"			value="true" tip="LLB Out Slit Door close Position"		tip.zh-CN="" tip.en-US="DI-30" />
     <Limit di="DI_LLB_Lid_Door_Closed"			value="true" tip="LLB Lid Door Closed"		tip.zh-CN="" tip.en-US="DI-31" />
-    <Limit do="DO_Purge_Valve_TM"	value="false" tip="Purge Valve TM"			tip.zh-CN="" tip.en-US="D0-03" />
-    <Limit do="DO_Vent_Valve_TM"				value="false" tip="Soft Vent Valve TM"					tip.zh-CN="" tip.en-US="DO-04" />
+   
   </Action>
 
   <Action do="DO_Purge_Valve_TM"					value="true" tip="Purge Valve TM"	tip.zh-CN="" tip.en-US="DO-03" >
     <Limit di="DI_TM_CHB_Door_Closed"	value="true" tip="TM CHB Lid Door Closed"			tip.zh-CN="" tip.en-US="DI-17" />
     <Limit di="DI_CDA_Pressure_Switch"			value="true" tip="CDA Pressure Switch"		tip.zh-CN="" tip.en-US="DI-19" />
     <Limit di="DI_N2_Pressure_Switch"			value="true" tip="N2 Pressure Switch"		tip.zh-CN="" tip.en-US="DI-21" />
-    <Limit do="DO_Soft_Pumping_Valve_TM"			value="false" tip="Soft Pumping Valve TM"		tip.zh-CN="" tip.en-US="DO-01" />
-    <Limit do="DO_Fast_Pumping_Valve_TM"			value="false" tip="Fast Pumping Valve TM"		tip.zh-CN="" tip.en-US="DO-02" />
+    
   </Action>
 
   <Action do="DO_Vent_Valve_TM"					value="true" tip="Soft Vent Valve TM"	tip.zh-CN="" tip.en-US="DO-04" >
     <Limit di="DI_TM_CHB_Door_Closed"	value="true" tip="TM CHB Lid Door Closed"			tip.zh-CN="" tip.en-US="DI-17" />
     <Limit di="DI_CDA_Pressure_Switch"			value="true" tip="CDA Pressure Switch"		tip.zh-CN="" tip.en-US="DI-19" />
     <Limit di="DI_N2_Pressure_Switch"			value="true" tip="N2 Pressure Switch"		tip.zh-CN="" tip.en-US="DI-21" />
-    <Limit do="DO_Soft_Pumping_Valve_TM"			value="false" tip="Soft Pumping Valve TM"		tip.zh-CN="" tip.en-US="DO-01" />
-    <Limit do="DO_Fast_Pumping_Valve_TM"			value="false" tip="Fast Pumping Valve TM"		tip.zh-CN="" tip.en-US="DO-02" />
+   
   </Action>
 
   <Action do="DO_Soft_Pumping_Valve_LLA"					value="true" tip="Soft Pumping Valve LLA"	tip.zh-CN="" tip.en-US="DO-06" >

+ 132 - 3
Venus/Venus_RT/Devices/TM/JetTM.cs

@@ -21,6 +21,7 @@ using Aitex.Core.RT.OperationCenter;
 using MECF.Framework.Common.SubstrateTrackings;
 
 using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
+using IoMfc = Venus_RT.Devices.IODevices.IoMfc;
 
 namespace Venus_RT.Devices
 {
@@ -96,6 +97,11 @@ namespace Venus_RT.Devices
         private readonly IoSwitch _PMBWaferSizeCheck;
         private readonly IoSwitch _PMCWaferSizeCheck;
         private readonly IoSwitch _PMDWaferSizeCheck;
+        private readonly IoSwitch _PressureMode_Switch;
+
+
+        private readonly IoMfc _TMMfc;
+
 
         private readonly PumpBase _TMPump;
         private readonly PumpBase _LLPump;
@@ -155,8 +161,77 @@ namespace Venus_RT.Devices
 
         public  bool? TMPumpIsRunning => _TMPump?.IsRunning;
         public  bool? LLPumpIsRunning => _LLPump?.IsRunning;
-
-
+        private string _allInstalledModules { get { return SC.GetStringValue("System.InstalledModules").ToString(); } }
+        public bool PMASlitDoorClosed
+        {
+            get
+            {
+                if (_allInstalledModules.Contains("PMA"))
+                {
+                    return DATA.Poll<bool>("PMA", "IsSlitDoorClosed");
+                }
+                else
+                {
+                    return true;
+                }
+            }
+        }
+        public bool PMBSlitDoorClosed
+        {
+            get
+            {
+                if (_allInstalledModules.Contains("PMB"))
+                {
+                    return DATA.Poll<bool>("PMB", "IsSlitDoorClosed");
+                }
+                else
+                {
+                    return true;
+                }
+            }
+        }
+        public bool PMCSlitDoorClosed
+        {
+            get
+            {
+                if (_allInstalledModules.Contains("PMC"))
+                {
+                    return DATA.Poll<bool>("PMC", "IsSlitDoorClosed");
+                }
+                else
+                {
+                    return true;
+                }
+            }
+        }
+        public bool PMDSlitDoorClosed
+        {
+            get
+            {
+                if (_allInstalledModules.Contains("PMD"))
+                {
+                    return DATA.Poll<bool>("PMD", "IsSlitDoorClosed");
+                }
+                else
+                {
+                    return true;
+                }
+            }
+        }
+        public bool AllPMSlitDoorClosed
+        {
+            get 
+            {
+                if (PMASlitDoorClosed == true && PMBSlitDoorClosed == true && PMCSlitDoorClosed == true && PMDSlitDoorClosed == true)
+                {
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        }
         public JetTM() : base("TM")
         {
             _TMLid  = DEVICE.GetDevice<IoLid>($"TM.{VenusDevice.TMLid}");
@@ -230,7 +305,9 @@ namespace Venus_RT.Devices
             _PMBWaferSizeCheck = DEVICE.GetDevice<IoSwitch>($"TM.{VenusDevice.PMBWaferSizeCheckSwitch}");
             _PMCWaferSizeCheck = DEVICE.GetDevice<IoSwitch>($"TM.{VenusDevice.PMCWaferSizeCheckSwitch}");
             _PMDWaferSizeCheck = DEVICE.GetDevice<IoSwitch>($"TM.{VenusDevice.PMDWaferSizeCheckSwitch}");
+            _PressureMode_Switch = DEVICE.GetDevice<IoSwitch>("TM.PressureModeSwitch");
 
+            _TMMfc = DEVICE.GetDevice<IoMfc>($"{Module}.TM_MFC1");
 
             _presureCtrl = DEVICE.GetDevice<IoTMPressureCtrl>($"TM.{VenusDevice.TMPressureCtrl}");
 
@@ -278,7 +355,11 @@ namespace Venus_RT.Devices
                 _presureCtrl.SetTMPressure((int)(args[0]));
                 return true;
             });
-
+            OP.Subscribe("TM.SetChamberFlow", (cmd, args) =>
+            {
+                _TMMfc.SetPoint = (int)(args[0]);
+                return true;
+            });
             _isATMMode = SC.GetValue<bool>("System.IsATMMode");
             _TMVacAtmMode.TurnValve(_isATMMode, out string _);
 
@@ -638,7 +719,55 @@ namespace Venus_RT.Devices
         //    _TMPump.SetPumpOnOff(ison);
         //    return true;
         //}
+        public void SwitchTMPressureMode(bool isPressureMode)
+        {
+            if (isPressureMode==true)
+            {
+                _PressureMode_Switch.TurnOn();
+
+            }
+            else
+            { 
+                _PressureMode_Switch.TurnOff();
 
+            }
+        }
+        public void SetTMPressure(int pressureValue)
+        {
+            _presureCtrl.SetTMPressure(pressureValue);
+        }
+        public void SetTMFlow(int flowValue)
+        {
+            _TMMfc.SetPoint = (flowValue);
+        }
+
+        public bool CloseAllSlitDoor()
+        {
+            _LLATSlitDoor.SetCylinder(false, out _);
+            _LLBTSlitDoor.SetCylinder(false, out _);
+            if (_allInstalledModules.Contains("PMA"))
+            {
+                OP.DoOperation("PMA.SetSlitDoor", false);
+            }
+            if (_allInstalledModules.Contains("PMB"))
+            {
+                OP.DoOperation("PMB.SetSlitDoor", false);
+            }
+            if (_allInstalledModules.Contains("PMC"))
+            {
+                OP.DoOperation("PMC.SetSlitDoor", false);
+            }
+            if (_allInstalledModules.Contains("PMD"))
+            {
+                OP.DoOperation("PMD.SetSlitDoor", false);
+            }
+            return true;
+        }
+        public bool TurnTMPump(bool ison)
+        {
+            _TMPump.SetPumpOnOff(ison);
+            return true;
+        }
 
     }
 }

+ 3 - 1
Venus/Venus_RT/Modules/LLs/LLEntity.cs

@@ -121,12 +121,14 @@ namespace Venus_RT.Modules
             OP.Subscribe($"{Module}.{RtOperation.Purge}", (cmd, args) => CheckToPostMessage((int)MSG.Purge));
             OP.Subscribe($"{Module}.{RtOperation.Abort}", (cmd, args) => CheckToPostMessage((int)MSG.Abort));
             OP.Subscribe($"{Module}.{RtOperation.LeakCheck}", (cmd, args) => CheckToPostMessage((int)MSG.LeakCheck));
-
+            OP.Subscribe($"{Module}.{RtOperation.Online}", (cmd, args) => CheckToPostMessage((int)MSG.Online));
+            OP.Subscribe($"{Module}.{RtOperation.Offline}", (cmd, args) => CheckToPostMessage((int)MSG.Offline));
 
 
             DATA.Subscribe($"{Module}.FsmState", () => (((STATE)fsm.State).ToString()));
             DATA.Subscribe($"{Module}.FsmPrevState", () => (((PMState)fsm.PrevState).ToString()));
             DATA.Subscribe($"{Module}.FsmLastMessage", () => (((MSG)fsm.LastMsg).ToString()));
+            DATA.Subscribe($"{Module}.IsOnline", () => IsOnline);
             return true;
         }
         private void InitFsmMap()

+ 6 - 2
Venus/Venus_RT/Modules/PMs/ProcessDefine.cs

@@ -109,9 +109,13 @@ namespace Venus_RT.Modules.PMs
                     return RState.End;
                 }
             }
-            else if (ProcessUnit.PressureUnitMode == PressureUnitMode.Valve)
+            else if (ProcessUnit.PressureUnitMode == PressureUnitMode.Valve )
             {
-                return RState.End;
+                if (step.Type == StepType.Stable &&  Chamber.GetPVPosition() == ProcessUnit.StartValue)
+                {
+                    return RState.End;
+                }
+               
             }
                
 

+ 112 - 0
Venus/Venus_RT/Modules/TM/MFControlPressureRoutine.cs

@@ -0,0 +1,112 @@
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using MECF.Framework.Common.Equipment;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Venus_Core;
+using Venus_RT.Devices;
+using Venus_RT.Modules.PMs;
+
+namespace Venus_RT.Modules.TM
+{
+   
+    class MFControlPressureRoutine : ModuleRoutineBase, IRoutine
+    {
+        private enum ControlPressureStep
+        {
+            PumpDown,
+            Delay1s,
+            StartControlPressure,
+            End
+        }
+
+        private readonly JetTM _JetTM;
+        private readonly MFPumpRoutine _pumpDownRoutine;
+        private int _controlPressureCheckPoint = 100;
+        private int _controlPressureSetPoint = 90;
+        private int  _controlFlowSetPoint = 90;
+
+        public MFControlPressureRoutine(JetTM jetTM, MFPumpRoutine pumpDownRoutine) : base(ModuleName.TM)
+        {
+            _JetTM = jetTM;
+            _pumpDownRoutine = pumpDownRoutine;
+        }
+        public RState Start(params object[] objs)
+        {
+            _controlPressureCheckPoint= SC.GetValue<int>($"TM.ControlPressureCheckPoint");
+            _controlPressureSetPoint= SC.GetValue<int>($"TM.ControlPressureSetPoint");
+            _controlFlowSetPoint= SC.GetValue<int>($"TM.TM_MFC1.DefaultSetPoint");
+            return Runner.Start(Module, Name);
+        }
+
+        public RState Monitor()
+        {
+
+            Runner.Run((int)ControlPressureStep.PumpDown,              PumpingDown,          StopPumpDone)
+                .Delay((int)ControlPressureStep.Delay1s,               _delay_1s)
+                .Run((int)ControlPressureStep.StartControlPressure,    StartControlPressure)
+
+                .End((int)ControlPressureStep.End,                     End);
+            return Runner.Status;
+        }
+
+        private bool PumpingDown()
+        {
+            return _pumpDownRoutine.Start() == RState.Running;
+
+        }
+
+        private bool StopPumpDone()
+        {
+            if (_JetTM.TMPressure <= _controlPressureCheckPoint)
+            {
+                _JetTM.TurnSoftPumpValve(ModuleName.TM, false);
+                _JetTM.TurnFastPumpValve(ModuleName.TM, false);
+                _JetTM.TurnFastPumpValve(ModuleName.TM,true);
+                return true;
+            }
+            else
+            {
+                _pumpDownRoutine.Monitor();
+                return false;
+            }
+        }
+
+        private bool StartControlPressure()
+        {
+            _JetTM.TurnN2Valve(true);
+            _JetTM.TurnPurgeValve(ModuleName.TM, true);
+            if (_JetTM.AllPMSlitDoorClosed)
+            {
+                _JetTM.SwitchTMPressureMode(true);             
+                _JetTM.SetTMPressure(_controlPressureSetPoint);
+            }
+            else
+            {
+                _JetTM.SwitchTMPressureMode(false);
+                _JetTM.SetTMFlow(_controlFlowSetPoint);
+            }
+            return true;
+        }
+
+
+
+        private bool End()
+        {
+
+            return true;
+        }
+        public void Abort()
+        {
+            _JetTM.TurnFastPumpValve(ModuleName.TM, false);
+            _JetTM.TurnN2Valve(false);
+            _JetTM.TurnPurgeValve(ModuleName.TM, false);
+            _JetTM.SetTMPressure(0);
+            _JetTM.SetTMFlow(0);
+
+        }
+    }
+}

+ 97 - 9
Venus/Venus_RT/Modules/TM/MFHomeRoutine.cs

@@ -5,6 +5,7 @@ using MECF.Framework.Common.Routine;
 using MECF.Framework.Common.Equipment;
 using Venus_Core;
 using Aitex.Core.RT.Log;
+using Venus_RT.Modules.PMs;
 
 namespace Venus_RT.Modules.TM
 {
@@ -13,45 +14,132 @@ namespace Venus_RT.Modules.TM
         private enum HomeStep
         {
             kHoming,
+            kRobot,
+            kSlitDoor,
+            kPump,
+            kATMSwitch,
             kEnd,
         }
 
-        private int _homingTimeout = 30000;
+        private int _robotHomingTimeout = 120*1000;
+        private int _slitDoorHomingTimeout = 20 * 1000;
+        private int _pumpHomingTimeout = 120 * 1000;
+        private int _pumpDownHomingTimeout = 600 * 1000;
+
+
+
         private readonly JetTM _JetTM;
         private readonly ITransferRobot _robot;
-        public MFHomeRoutine(JetTM jetTM, ITransferRobot robot) : base(ModuleName.TM)
+        private readonly MFPumpRoutine _pumpDownRoutine;
+
+        public int currentStepNo;
+        public MFHomeRoutine(JetTM jetTM, ITransferRobot robot, MFPumpRoutine pumpDownRoutine) : base(ModuleName.TM)
         {
             _JetTM = jetTM;
             _robot = robot;
+            _pumpDownRoutine= pumpDownRoutine;
             Name = "TM Home";
         }
 
         public RState Start(params object[] objs)
         {
+            currentStepNo = 0;
+            if (!_JetTM.CheckLidClosed(Module))
+            {
+                Stop($"TM Lid Not Closed");
+                return RState.Failed;
+            }
             Reset();
-            _homingTimeout = SC.GetValue<int>($"{Module}.HomeTimeout") * 1000;
-
+            _robotHomingTimeout = SC.GetValue<int>($"{Module}.HomeTimeout") * 1000;
+           
             return Runner.Start(Module, Name);
         }
 
         public RState Monitor()
         {
-            Runner.Run((int)HomeStep.kHoming,   HomeTM,     CheckHomeReady,     _homingTimeout)
-                .End((int)HomeStep.kEnd,        NullFun,    _delay_50ms);
+            Runner.Run((int)HomeStep.kRobot,      HomeRobot,     CheckRobotReady,       _robotHomingTimeout)
+                  .Run((int)HomeStep.kSlitDoor,   HomeSlitDoor,  CheckSlitDoorReady,    _slitDoorHomingTimeout)
+                  .Run((int)HomeStep.kPump,       HomePump,      CheckPumpReady,        _pumpHomingTimeout)
+                  .Run((int)HomeStep.kATMSwitch,  HomePumpDown,  CheckATMSwitchReady,   _pumpDownHomingTimeout)
+
+
+                  .End((int)HomeStep.kEnd,      NullFun,    _delay_50ms);
 
             return Runner.Status;
         }
 
-        private bool HomeTM()
+        private bool HomeRobot()
         {
+            currentStepNo = 1;
+            if (_robot.Status == RState.End)
+            {
+                return true;
+            }
             return _robot.Home();
         }
 
-        private bool CheckHomeReady()
-        {     
+        private bool CheckRobotReady()
+        {
             return _robot.Status == RState.End;
         }
+        private bool HomeSlitDoor()
+        {
+            currentStepNo = 2;
+          return  _JetTM.CloseAllSlitDoor();
+        }
+
+        private bool CheckSlitDoorReady()
+        {
+            if (_JetTM.AllPMSlitDoorClosed && _JetTM.IsLLASlitDoorClosed && _JetTM.IsLLBSlitDoorClosed)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        private bool HomePump()
+        {
+            currentStepNo = 3;
+            if ((bool)_JetTM.TMPumpIsRunning)
+            {
+                return true;
+            }
+            return _JetTM.TurnTMPump(true);
+        }
 
+        private bool CheckPumpReady()
+        {
+            if ((bool)_JetTM.TMPumpIsRunning)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        private bool HomePumpDown()
+        {
+            currentStepNo = 4;
+            return _pumpDownRoutine.Start() == RState.Running;
+        }
+
+        private bool CheckATMSwitchReady()
+        {
+            if (_JetTM.IsTMVac)
+            {
+                _JetTM.TurnSoftPumpValve(ModuleName.TM, false);
+                _JetTM.TurnFastPumpValve(ModuleName.TM, false);
+                return true;
+            }
+            else
+            {
+                _pumpDownRoutine.Monitor();
+                return false;
+            }
+        }
         public void Abort()
         {
         }

+ 1 - 1
Venus/Venus_RT/Modules/TM/MFPumpRoutine.cs

@@ -47,7 +47,7 @@ namespace Venus_RT.Modules.TM
         public RState Monitor()
         {
             Runner.Wait((int)PumpStep.kWaitPeerModule,  WaitPeerModule)
-                .Run((int)PumpStep.kSoftPump,           OpenSoftPump,                       () => { return _JetTM.GetModulePressure(Module) < _pumpCrossingPressure; }, _pumpingTimeout)
+                .Run((int)PumpStep.kSoftPump,           OpenSoftPump,                       () => { return _JetTM.TMPressure < _pumpCrossingPressure; }, _pumpingTimeout)
                 .Run((int)PumpStep.kFastPump,           SwitchFastPump,                     IsPressureReady,                                                            _pumpingTimeout)
                 .End((int)PumpStep.kClosePumpValves,    ClosePumpValves,                    _delay_50ms);
 

+ 85 - 10
Venus/Venus_RT/Modules/TM/TMEntity.cs

@@ -14,6 +14,10 @@ using Aitex.Core.RT.OperationCenter;
 using MECF.Framework.Common.Schedulers;
 using MECF.Framework.Common.CommonData;
 using Aitex.Core.RT.Device;
+using System.Timers;
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.Backend;
+using System.Windows.Controls;
 
 namespace Venus_RT.Modules
 {
@@ -42,6 +46,7 @@ namespace Venus_RT.Modules
             Retracting,   
             Swapping,
             Gotoing,
+            ControllingPressure
         }
 
         public enum MSG
@@ -66,10 +71,13 @@ namespace Venus_RT.Modules
             Extend,
             Retract,
             TMCycle,
+            ControlPressure,
             Error,
             Abort,
+            AbortControlPressure
         }
 
+        
         public bool IsIdle
         {
             get { return fsm.State == (int)STATE.Idle; }
@@ -100,6 +108,9 @@ namespace Venus_RT.Modules
 
         public double TMPressure { get { return _tm.TMPressure; } }
 
+       
+
+
         private readonly JetTM _tm;
         private readonly ITransferRobot _robot;
 
@@ -119,14 +130,14 @@ namespace Venus_RT.Modules
         private readonly MFPMRetractRoutine _pmRetractRoutine;
         private readonly MFPMExtendRoutine  _pmExtendRoutine;
 
-
+        private readonly MFControlPressureRoutine _tmControlPressureRoutine;
+        //private readonly Timer controlPressureTimer;
         public TMEntity()
         {
             //_tm                 = Singleton<JetTM>.Instance;
             _tm                 = DEVICE.GetDevice<JetTM>("TM");
             _robot              = new SIASUNRobot();
 
-            _homeRoutine    = new MFHomeRoutine(_tm, _robot);
             _pickRoutine    = new MFPickRoutine(_tm, _robot);
             _placeRoutine   = new MFPlaceRoutine(_tm, _robot);
             _swapRoutine    = new MFSwapRoutine(_tm, _robot);
@@ -136,18 +147,27 @@ namespace Venus_RT.Modules
             _pmSwapRoutine  = new MFPMSwapRoutine(_tm, _robot);
 
             _pumpingRoutine     = new MFPumpRoutine(_tm, ModuleName.TM);
-            _ventingRoutine     = new MFVentRoutine(_tm, ModuleName.TM);
+
+            _homeRoutine = new MFHomeRoutine(_tm, _robot, _pumpingRoutine);
+
+            _ventingRoutine = new MFVentRoutine(_tm, ModuleName.TM);
             _leakCheckRoutine   = new MFLeakCheckRoutine(_tm, ModuleName.TM);
             _purgeRoutine       = new MFPurgeRoutine(_tm, ModuleName.TM);
 
             _pmRetractRoutine = new MFPMRetractRoutine(_tm, _robot);
             _pmExtendRoutine  = new MFPMExtendRoutine(_tm, _robot);
 
+            _tmControlPressureRoutine = new MFControlPressureRoutine(_tm, _pumpingRoutine);
+
             WaferManager.Instance.SubscribeLocation(ModuleName.TMRobot, 2);
 
             InitFsmMap();
+            //controlPressureTimer = new Timer(50);
+            //controlPressureTimer.Elapsed += ControlPressureTimer_Elapsed;
         }
 
+      
+
         protected override bool Init()
         {
             OP.Subscribe("TM.Home", (cmd, args) => CheckToPostMessage((int)MSG.Home));
@@ -168,8 +188,10 @@ namespace Venus_RT.Modules
             OP.Subscribe($"TM.{RtOperation.Purge}", (cmd, args) => CheckToPostMessage((int)MSG.Purge));
             OP.Subscribe($"TM.{RtOperation.Abort}", (cmd, args) => CheckToPostMessage((int)MSG.Abort));
 
-            
-
+            OP.Subscribe($"TM.{RtOperation.Online}", (cmd, args) => CheckToPostMessage((int)MSG.Online));
+            OP.Subscribe($"TM.{RtOperation.Offline}", (cmd, args) => CheckToPostMessage((int)MSG.Offline));
+            OP.Subscribe($"TM.{RtOperation.ControlPressure}", (cmd, args) => CheckToPostMessage((int)MSG.ControlPressure));
+            OP.Subscribe($"TM.{RtOperation.AbortControlPressure}", (cmd, args) => CheckToPostMessage((int)MSG.AbortControlPressure));
 
 
 
@@ -184,6 +206,9 @@ namespace Venus_RT.Modules
             DATA.Subscribe("TM.RobotMoveAction.BladeTarget", () => _robot.TMRobotMoveInfo.BladeTarget);
             DATA.Subscribe("TM.RobotMoveAction.RobotAction", () => _robot.TMRobotMoveInfo.Action.ToString());
 
+            DATA.Subscribe("TM.IsOnline", () => IsOnline);
+            DATA.Subscribe("TM.Home.StepNo", () => _homeRoutine.currentStepNo);
+
             return true;
         }
 
@@ -191,13 +216,14 @@ namespace Venus_RT.Modules
         {
             fsm = new StateMachine<TMEntity>("TM", (int)STATE.Init, 50);
 
-            //AnyStateTransition(FSM_MSG.TIMER,   fnMonitor,      FSM_STATE.SAME);
+            //AnyStateTransition(FSM_MSG.TIMER,   fnMonitor,      FSM_STATE.SAME); 
 
 
-            AnyStateTransition(MSG.Error,       fnError,        STATE.Error);
-            AnyStateTransition(MSG.Online,      fnOnline,       FSM_STATE.SAME);
-            AnyStateTransition(MSG.Offline,     fnOffline,      FSM_STATE.SAME);
-            AnyStateTransition(MSG.Home,        fnHome,         STATE.Initializing);
+            AnyStateTransition(MSG.Error,           fnError,               STATE.Error);
+            AnyStateTransition(MSG.Online,          fnOnline,              FSM_STATE.SAME);
+            AnyStateTransition(MSG.Offline,         fnOffline,             FSM_STATE.SAME);
+            AnyStateTransition(MSG.Home,            fnHome,                STATE.Initializing);
+
 
             // Home
             Transition(STATE.Initializing,      FSM_MSG.TIMER,      fnHoming,           STATE.Idle);
@@ -268,6 +294,12 @@ namespace Venus_RT.Modules
 
             //Transition(RtState.Init, MSG.TMCycle, FsmStartTMCycle, RtState.TMCycle);
             //Transition(RtState.TMCycle, FSM_MSG.TIMER, FsmMonitorTMCycle, RtState.Idle);
+            //Extend
+
+            //Control Pressure
+            AnyStateTransition(MSG.ControlPressure,      FnStartControlPressure, FSM_STATE.SAME, ControlPressureTimer_Elapsed);
+            //Transition(STATE.ControllingPressure,        FSM_MSG.TIMER,               FnControlPressure,          STATE.Idle);
+            AnyStateTransition(MSG.AbortControlPressure, FnAbortControlPressure, FSM_STATE.SAME);
 
 
             Running = true;
@@ -287,11 +319,14 @@ namespace Venus_RT.Modules
 
         private bool fnOnline(object[] param)
         {
+            //controlPressureTimer.Start();
+            IsOnline = true;
             return true;
         }
 
         private bool fnOffline(object[] param)
         {
+            //controlPressureTimer.Stop();
             IsOnline = false;
             return true;
         }
@@ -592,6 +627,46 @@ namespace Venus_RT.Modules
             _pmExtendRoutine.Abort();
             return true;
         }
+        private bool FnStartControlPressure(object[] param)
+        {
+            return _tmControlPressureRoutine.Start(param) == RState.Running;
+        }
+        private bool ControlPressureTimer_Elapsed(object[] param)
+        {
+            if (IsOnline == true)
+            {
+                RState ret = _tmControlPressureRoutine.Monitor();
+                
+                if (ret == RState.End)
+                {
+                    if (_tm.PMASlitDoorClosed == false || _tm.PMBSlitDoorClosed == false || _tm.PMCSlitDoorClosed == false || _tm.PMDSlitDoorClosed == false)
+                    {
+                        _tm.SwitchTMPressureMode(true);
+                    }
+                    else
+                    { 
+                        _tm.SwitchTMPressureMode(false);
+                    }
+                }
+            }
+            
+            return true;
+        }
+        private bool FnControlPressure(object[] param)
+        {
+            RState ret = _tmControlPressureRoutine.Monitor();
+            if (ret == RState.Failed)
+            {
+                PostMsg(MSG.Error);
+                return false;
+            }
+            return ret == RState.End;
+        }
+        private bool FnAbortControlPressure(object[] param)
+        {
+            _tmControlPressureRoutine.Abort();
+            return true;
+        }
         public bool Check(int msg, out string reason, params object[] args)
         {
             reason = "";

+ 1 - 0
Venus/Venus_RT/Venus_RT.csproj

@@ -236,6 +236,7 @@
     <Compile Include="Modules\Schedulers\SchedulerTMRobot.cs" />
     <Compile Include="Modules\Schedulers\TransferModule.cs" />
     <Compile Include="Modules\TMCycle.cs" />
+    <Compile Include="Modules\TM\MFControlPressureRoutine.cs" />
     <Compile Include="Modules\TM\MFHomeRoutine.cs" />
     <Compile Include="Modules\TM\MFLeakCheckRoutine.cs" />
     <Compile Include="Modules\TM\MFPickRoutine.cs" />

+ 1 - 1
Venus/Venus_Setup/Venus_RT.iss

@@ -33,7 +33,7 @@ Name: "chinesesimp"; MessagesFile: "compiler:Default.isl"
 
 
 [Files]
-Source: "..\Venus_RT\bin\Release\*";Excludes:"Config,Recipes,Logs,LeakCheck,Objects,PartialPressureResult,VATPerformanceResult"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs
+Source: "..\Venus_RT\bin\Release\*";Excludes:"Config,Recipes,Logs,Objects,PartialPressureResult,VATPerformanceResult"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs
 Source: "..\Venus_RT\bin\Release\Config\*"; Excludes:"*.data,*.bak";DestDir: "{app}\Config";  Flags: recursesubdirs
 
 

+ 1 - 1
Venus/Venus_Simulator/Instances/SimulatorSystem.cs

@@ -412,7 +412,7 @@ namespace Venus_Simulator.Instances
             SetAiValue($"{mod}.AI_Second", DateTime.Now.Second);
 
 
-            SetAiValue($"{mod}.AI_TM_CHB_Pressure", 5000);
+            SetAiValue($"{mod}.AI_TM_CHB_Pressure", 760000);
             SetAiValue($"{mod}.AI_TM_Foreline_Pressure", 5001);
             SetAiValue($"{mod}.AI_LLA_CHB_Pressure", 5002);
             SetAiValue($"{mod}.AI_LLA_LLB_Foreline_Pressure", 5003);

+ 35 - 0
Venus/Venus_Themes/Converters/IsLastItemConverter.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace Venus_Themes.Converters
+{
+    public class IsLastItemConverter : IMultiValueConverter
+    {
+        #region IValueConverter 成员
+
+        public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            ContentControl contentPresenter = value[0] as ContentControl;
+            ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(contentPresenter);
+
+            bool flag = false;
+            if (itemsControl != null)
+            {
+                int index = itemsControl.ItemContainerGenerator.IndexFromContainer(contentPresenter);
+                flag = (index == (itemsControl.Items.Count - 1));
+            }
+
+            return flag;
+        }
+        public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            return null;
+        }
+        #endregion
+    }
+}

+ 54 - 0
Venus/Venus_Themes/Converters/IsProgressedConverter.cs

@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace Venus_Themes.Converters
+{
+    public enum EnumCompare
+    {
+        None,
+        Less,
+        Equal,
+        Large
+    }
+
+    public class IsProgressedConverter : IMultiValueConverter
+    {
+        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            if ((values[0] is ContentControl && values[1] is int) == false)
+            {
+                return EnumCompare.None;
+            }
+
+            ContentControl contentControl = values[0] as ContentControl;
+            int progress = (int)values[1];
+            ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(contentControl);
+
+            if (itemsControl == null)
+            {
+                return EnumCompare.None;
+            }
+
+            int index = itemsControl.ItemContainerGenerator.IndexFromContainer(contentControl);
+
+            if (index < progress)
+            {
+                return EnumCompare.Less;
+            }
+            else if (index == progress)
+            {
+                return EnumCompare.Equal;
+            }
+            return EnumCompare.Large;
+        }
+        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
+        {
+            throw new NotSupportedException();
+        }
+    }
+}

+ 102 - 0
Venus/Venus_Themes/CustomControls/StepBar.cs

@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows;
+
+namespace Venus_Themes.CustomControls
+{
+    public class StepBar : ItemsControl
+    {
+        #region Private属性
+
+        #endregion
+
+        #region 依赖属性定义
+        public int Progress
+        {
+            get { return (int)GetValue(ProgressProperty); }
+            set { SetValue(ProgressProperty, value); }
+        }
+
+        public static readonly DependencyProperty ProgressProperty =
+            DependencyProperty.Register("Progress", typeof(int), typeof(StepBar), new PropertyMetadata(0, OnProgressChangedCallback, OnProgressCoerceValueCallback));
+
+        private static object OnProgressCoerceValueCallback(DependencyObject d, object baseValue)
+        {
+            //不让Progress超出边界
+            StepBar stepBar = d as StepBar;
+            int newValue = Convert.ToInt32(baseValue);
+            if (newValue < 0)
+            {
+                return 0;
+            }
+            else if (newValue >= stepBar.Items.Count)
+            {
+                return stepBar.Items.Count - 1;
+            }
+            return newValue;
+        }
+
+        private static void OnProgressChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+
+        }
+
+
+        #endregion
+
+        #region 依赖属性set get
+
+        #endregion
+
+        #region Constructors
+        static StepBar()
+        {
+            DefaultStyleKeyProperty.OverrideMetadata(typeof(StepBar), new FrameworkPropertyMetadata(typeof(StepBar)));
+        }
+        #endregion
+
+        #region Override方法
+        protected override DependencyObject GetContainerForItemOverride()
+        {
+            return new StepBarItem();
+        }
+
+        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
+        {
+            //设置Item的显示数字
+            StepBarItem stepBarItem = element as StepBarItem;
+            ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(stepBarItem);
+            int index = itemsControl.ItemContainerGenerator.IndexFromContainer(stepBarItem);
+            stepBarItem.Number = Convert.ToString(++index);
+            base.PrepareContainerForItemOverride(element, item);
+        }
+
+        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
+        {
+            base.OnItemsChanged(e);
+
+            //ItemsControl数量变化时,重新设置各个Item的显示的数字
+            for (int i = 0; i < this.Items.Count; i++)
+            {
+                StepBarItem stepBarItem = this.ItemContainerGenerator.ContainerFromIndex(i) as StepBarItem;
+                if (stepBarItem != null)
+                {
+                    int temp = i;
+                    stepBarItem.Number = Convert.ToString(++temp);
+                }
+            }
+            //进度重新回到第一个
+            this.Progress = 0;
+        }
+        #endregion
+
+        #region Private方法
+
+        #endregion
+    }
+}

+ 46 - 0
Venus/Venus_Themes/CustomControls/StepBarItem.cs

@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows;
+
+namespace Venus_Themes.CustomControls
+{
+    public class StepBarItem : ContentControl
+    {
+        #region Private属性
+
+        #endregion
+
+        #region 依赖属性定义
+        public string Number
+        {
+            get { return (string)GetValue(NumberProperty); }
+            set { SetValue(NumberProperty, value); }
+        }
+
+        public static readonly DependencyProperty NumberProperty =
+            DependencyProperty.Register("Number", typeof(string), typeof(StepBarItem));
+        #endregion
+
+        #region 依赖属性set get
+
+        #endregion
+
+        #region Constructors
+        static StepBarItem()
+        {
+            DefaultStyleKeyProperty.OverrideMetadata(typeof(StepBarItem), new FrameworkPropertyMetadata(typeof(StepBarItem)));
+        }
+        #endregion
+
+        #region Override方法
+        #endregion
+
+        #region Private方法
+
+        #endregion
+    }
+}

+ 111 - 0
Venus/Venus_Themes/Themes/Generic.xaml

@@ -7,6 +7,8 @@
 
     <converters:BoolToDirection x:Key="boolToDirection"/>
     <converters:BoolToBool x:Key="BoolToBool"/>
+    <converters:IsLastItemConverter x:Key="IsLastItemConverter"/>
+    <converters:IsProgressedConverter x:Key="IsProgressedConverter"/>
 
     <SolidColorBrush x:Key="robotBorderBrush" Color="#030303" />
     <LinearGradientBrush x:Key="RobotBrush" StartPoint="0,0" EndPoint="1,0">
@@ -1121,4 +1123,113 @@
             </Setter.Value>
         </Setter>
     </Style>
+
+    <Style TargetType="{x:Type customControls:StepBarItem}">
+        <Setter Property="FontWeight" Value="Bold" />
+        <Setter Property="FontSize" Value="14" />
+        <Setter Property="FontFamily" Value="宋体" />
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="{x:Type customControls:StepBarItem}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="auto" />
+                            <ColumnDefinition Width="*" />
+                        </Grid.ColumnDefinitions>
+                        <StackPanel Orientation="Horizontal">
+                            <Grid Margin="0,0,10,0">
+                                <Border x:Name="Bd" BorderBrush="#CCCCCC" Width="25" Height="25" CornerRadius="100" 
+                                        BorderThickness="1" SnapsToDevicePixels="True" UseLayoutRounding="True">
+                                </Border>
+                                <TextBlock x:Name="Number" Text="{TemplateBinding Number}"
+                                           HorizontalAlignment="Center" VerticalAlignment="Center" />
+                                <Path x:Name="path" Data="{StaticResource Icon_Gou}" Stretch="Uniform" Width="12" Fill="#3399FF" Visibility="Collapsed" />
+                            </Grid>
+                            <ContentPresenter VerticalAlignment="Center" />
+
+                        </StackPanel>
+                        <Border x:Name="Line" Grid.Column="1" BorderBrush="#E3E8EE" BorderThickness="0,1,0,0" 
+                                VerticalAlignment="Center" Margin="10,0"
+                                SnapsToDevicePixels="True" UseLayoutRounding="True" />
+                    </Grid>
+                    <ControlTemplate.Triggers>
+                        <DataTrigger Value="True">
+                            <DataTrigger.Binding>
+                                <MultiBinding Converter="{StaticResource IsLastItemConverter}">
+                                    <Binding RelativeSource="{RelativeSource Self}" />
+                                    <Binding RelativeSource="{RelativeSource AncestorType={x:Type customControls:StepBar}}" Path="Items.Count"/>
+                                </MultiBinding>
+                            </DataTrigger.Binding>
+                            <Setter TargetName="Line" Property="Visibility" Value="Collapsed" />
+                        </DataTrigger>
+                        <DataTrigger Value="False">
+                            <DataTrigger.Binding>
+                                <MultiBinding Converter="{StaticResource IsLastItemConverter}">
+                                    <Binding RelativeSource="{RelativeSource Self}" />
+                                    <Binding RelativeSource="{RelativeSource AncestorType={x:Type customControls:StepBar}}" Path="Items.Count"/>
+                                </MultiBinding>
+                            </DataTrigger.Binding>
+                            <Setter TargetName="Line" Property="Visibility" Value="Visible" />
+                        </DataTrigger>
+                        <DataTrigger Value="Less">
+                            <DataTrigger.Binding>
+                                <MultiBinding Converter="{StaticResource IsProgressedConverter}">
+                                    <Binding RelativeSource="{RelativeSource Self}" />
+                                    <Binding RelativeSource="{RelativeSource AncestorType={x:Type customControls:StepBar}}" Path="Progress"/>
+                                </MultiBinding>
+                            </DataTrigger.Binding>
+                            <Setter TargetName="Bd" Property="Background" Value="#003399FF" />
+                            <Setter TargetName="Bd" Property="BorderBrush" Value="#3399FF" />
+                            <Setter TargetName="Number" Property="Visibility" Value="Collapsed" />
+                            <Setter TargetName="Line" Property="BorderBrush" Value="#3399FF" />
+                            <Setter TargetName="path" Property="Visibility" Value="Visible" />
+                            <Setter Property="Foreground" Value="#999999" />
+                        </DataTrigger>
+                        <DataTrigger Value="Equal">
+                            <DataTrigger.Binding>
+                                <MultiBinding Converter="{StaticResource IsProgressedConverter}">
+                                    <Binding RelativeSource="{RelativeSource Self}" />
+                                    <Binding RelativeSource="{RelativeSource AncestorType={x:Type customControls:StepBar}}" Path="Progress"/>
+                                </MultiBinding>
+                            </DataTrigger.Binding>
+                            <Setter TargetName="Bd" Property="Background" Value="#3399FF" />
+                            <Setter TargetName="Bd" Property="BorderBrush" Value="#3399FF" />
+                            <Setter TargetName="Number" Property="Visibility" Value="Visible" />
+                            <Setter TargetName="Number" Property="Foreground" Value="#FFFFFF" />
+                            <Setter TargetName="path" Property="Visibility" Value="Collapsed" />
+                            <Setter Property="Foreground" Value="#666666" />
+                        </DataTrigger>
+                        <DataTrigger Value="Large">
+                            <DataTrigger.Binding>
+                                <MultiBinding Converter="{StaticResource IsProgressedConverter}">
+                                    <Binding RelativeSource="{RelativeSource Self}" />
+                                    <Binding RelativeSource="{RelativeSource AncestorType={x:Type customControls:StepBar}}" Path="Progress"/>
+                                </MultiBinding>
+                            </DataTrigger.Binding>
+                            <Setter Property="Foreground" Value="#999999" />
+                        </DataTrigger>
+                    </ControlTemplate.Triggers>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style TargetType="{x:Type customControls:StepBar}">
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="{x:Type customControls:StepBar}">
+                    <Border>
+                        <ItemsPresenter />
+                    </Border>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+        <Setter Property="ItemsPanel">
+            <Setter.Value>
+                <ItemsPanelTemplate>
+                    <UniformGrid IsItemsHost="True" Rows="1" />
+                </ItemsPanelTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
 </ResourceDictionary>

+ 4 - 0
Venus/Venus_Themes/Venus_Themes.csproj

@@ -83,6 +83,8 @@
     <Compile Include="Converters\IntToBoolConverter.cs" />
     <Compile Include="Converters\IntToBoolConverter2.cs" />
     <Compile Include="Converters\IntToIsEnableConverter.cs" />
+    <Compile Include="Converters\IsLastItemConverter.cs" />
+    <Compile Include="Converters\IsProgressedConverter.cs" />
     <Compile Include="Converters\Null2Bool.cs" />
     <Compile Include="Converters\String2Double.cs" />
     <Compile Include="Converters\StringToColorConverter.cs" />
@@ -97,6 +99,8 @@
     <Compile Include="CustomControls\CustomRobot.cs" />
     <Compile Include="CustomControls\MultiComboBox.cs" />
     <Compile Include="CustomControls\PathButton.cs" />
+    <Compile Include="CustomControls\StepBar.cs" />
+    <Compile Include="CustomControls\StepBarItem.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Themes\Attach\BorderElement.cs" />
     <Compile Include="Themes\Attach\ElementBackground.cs" />

+ 1 - 1
Venus/Venus_UI/Views/ShellView.xaml.cs

@@ -77,7 +77,7 @@ namespace Venus_UI.Views
                     continue;
                 }
                 string[] allModules = QueryDataClient.Instance.Service.GetConfig($"System.InstalledModules").ToString().Split(',');
-                if (VenusMenu[i].Id == "PMA" || VenusMenu[i].Id == "PMB" || VenusMenu[i].Id == "PMC" || VenusMenu[i].Id == "PMD")
+                if (VenusMenu[i].Id == "PMA" || VenusMenu[i].Id == "PMB" || VenusMenu[i].Id == "PMC" || VenusMenu[i].Id == "PMD" || VenusMenu[i].Id == "TM")
                 {
                     if (!allModules.Contains(VenusMenu[i].Id))
                     {