Sfoglia il codice sorgente

优化漏气检测算法,给TM界面添加 1.删除/添加wafer 2.PM/LL自动隐藏功能

lixiang 1 anno fa
parent
commit
2d424f4cab

+ 23 - 7
Venus/Framework/Common/CommonData/MoveItem.cs

@@ -1,23 +1,35 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Runtime.Serialization;
 using System.Text;
 using System.Threading.Tasks;
+using Aitex.Core.Common.DeviceData;
 using Aitex.Sorter.Common;
 using MECF.Framework.Common.Equipment;
 
 namespace MECF.Framework.Common.Schedulers
 {
+    [DataContract]
+    [Serializable]
     //helper class
-    public class MoveItem
+    public class MoveItem :  IDeviceData
     {
-        public ModuleName SourceModule;
-        public int SourceSlot;
-        public ModuleName DestinationModule;
-        public int DestinationSlot;
-        public Hand RobotHand;
 
-        
+    
+
+        [DataMember]
+        public ModuleName SourceModule { get; set; }
+        [DataMember]
+        public int SourceSlot { get; set; }
+        [DataMember]
+        public ModuleName DestinationModule { get; set; }
+        [DataMember]
+        public int DestinationSlot { get; set; }
+        [DataMember]
+        public Hand RobotHand { get; set; }
+
+
 
         public MoveItem(ModuleName sourceModule, int sourceSlot, ModuleName destinationModule, int destinationSlot, Hand robotHand)
         {
@@ -28,5 +40,9 @@ namespace MECF.Framework.Common.Schedulers
             this.RobotHand = robotHand;
 
         }
+        public void Update(IDeviceData data)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 4 - 1
Venus/Framework/Common/DataCenter/IQueryDataService.cs

@@ -13,6 +13,7 @@ using Aitex.Sorter.Common;
 using MECF.Framework.Common.CommonData;
 using MECF.Framework.Common.Equipment;
 using MECF.Framework.Common.IOCore;
+using MECF.Framework.Common.Schedulers;
 using MECF.Framework.Common.SubstrateTrackings;
 using VenusCommon;
 
@@ -96,7 +97,9 @@ namespace MECF.Framework.Common.DataCenter
 	[ServiceKnownType(typeof(List<string>))]
 	[ServiceKnownType(typeof(SerializableDictionary<string, bool>))]
 	[ServiceKnownType(typeof(SerializableDictionary<string, string>))]
-    public interface IQueryDataService
+	[ServiceKnownType(typeof(MoveItem))]
+
+	public interface IQueryDataService
 	{
 		[OperationContract]
 		object GetData(string key);

+ 2 - 0
Venus/Framework/Common/OperationCenter/IInvokeService.cs

@@ -5,6 +5,7 @@ using Aitex.Core.Util;
 using Aitex.Sorter.Common;
 using MECF.Framework.Common.Device.Bases;
 using MECF.Framework.Common.Equipment;
+using MECF.Framework.Common.Schedulers;
 
 namespace MECF.Framework.Common.OperationCenter
 {
@@ -22,6 +23,7 @@ namespace MECF.Framework.Common.OperationCenter
     [ServiceKnownType(typeof(string[]))]
     [ServiceKnownType(typeof(Dictionary<string, object>))]
     [ServiceKnownType(typeof(WaferSize))]
+    [ServiceKnownType(typeof(Queue<MoveItem>))]
     public interface IInvokeService
     {
         [OperationContract]

+ 24 - 14
Venus/RecipeEditorControl/ViewModel/RecipeEditorControlViewModel.cs

@@ -68,11 +68,11 @@ namespace Aitex.UI.RecipeEditor
             }           
         }
 
-
-       /// <summary>
-       /// 选中recipe,显示界面
-       /// </summary>
-       /// <param name="recipe"></param>
+        int index = 0;
+        /// <summary>
+        /// 选中recipe,显示界面
+        /// </summary>
+        /// <param name="recipe"></param>
         public void LoadRecipe(Recipe recipe)
         {
             GridStackPanel.Children.Clear();
@@ -89,7 +89,7 @@ namespace Aitex.UI.RecipeEditor
             GridOptions.SetShowBorder(grid, true);
             GridOptions.SetLineBrush(grid, Brushes.Black);
             GridOptions.SetLineThickness(grid, 1);
-
+            index = 0;
             recipe.Steps.ToList().ForEach(x =>
             {
                  RecipeStepToGridColumn(x,grid);
@@ -184,14 +184,19 @@ namespace Aitex.UI.RecipeEditor
             ColumnDefinition col2 = new ColumnDefinition();//Value
             grid.ColumnDefinitions.Add(col2);
 
+            
             foreach (PropertyInfo propertyInfo in recipeType.GetProperties())
             {
                 string propertyInfoName = propertyInfo.Name;
                 string propertyTypeName = propertyInfo.PropertyType.Name;
                 if (propertyInfoName != "LstUnit")
                 {
-                    RowDefinition row1 = new RowDefinition();
-                    grid.RowDefinitions.Add(row1);
+                    if (index == 0)
+                    {
+                        RowDefinition row1 = new RowDefinition();
+                        grid.RowDefinitions.Add(row1);
+                    }
+                    
 
                     Binding binding = new Binding()
                     {
@@ -241,10 +246,10 @@ namespace Aitex.UI.RecipeEditor
                             grid.Children.Add(comboBox);
                             Grid.SetRow(comboBox, i);
                             Grid.SetColumn(comboBox, grid.ColumnDefinitions.Count - 1);
-                            if (propertyInfo.Name == "PressureUnitMode")
-                            {
-                                comboBox.SelectionChanged += ComboBox_SelectionChanged;
-                            }
+                            //if (propertyInfo.Name == "PressureUnitMode")
+                            //{
+                            //    comboBox.SelectionChanged += ComboBox_SelectionChanged;
+                            //}
                             break;
                     }
 
@@ -292,8 +297,11 @@ namespace Aitex.UI.RecipeEditor
                         Mode = BindingMode.TwoWay,        // 绑定模式  
                         UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged    //触发器
                     };
-                    RowDefinition row1 = new RowDefinition();
-                    grid.RowDefinitions.Add(row1);
+                    if (index == 0)
+                    {
+                        RowDefinition row1 = new RowDefinition();
+                        grid.RowDefinitions.Add(row1);
+                    }
                     var item = propertyInfo.PropertyType.Name;
                     if (propertyInfo.Name == "UnitName")
                     {
@@ -368,6 +376,8 @@ namespace Aitex.UI.RecipeEditor
                 ints.Add(unitType.GetProperties().Length);
                 k++;
             });
+            index++;
+
             //return new ValueTuple<Grid, List<int>>(grid, ints);
         }
         /// <summary>

+ 18 - 0
Venus/Venus_Core/GlobalEvents.cs

@@ -0,0 +1,18 @@
+using OpenSEMI.Ctrlib.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Venus_Core
+{
+    public static class VenusGlobalEvents 
+    {
+        public static event Action<Slot> SlotRightClickChangedEvent;
+        public static void OnSlotRightClickChanged(Slot slot)
+        {
+            SlotRightClickChangedEvent?.Invoke(slot);
+        }
+    }
+}

+ 4 - 0
Venus/Venus_Core/Venus_Core.csproj

@@ -36,6 +36,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\ThirdParty\Newtonsoft.Json.dll</HintPath>
     </Reference>
+    <Reference Include="OpenSEMI.Ctrlib">
+      <HintPath>..\ThirdParty\OpenSEMI.Ctrlib.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Runtime.Serialization" />
@@ -52,6 +55,7 @@
     <Compile Include="DeviceName.cs" />
     <Compile Include="EventDefine.cs" />
     <Compile Include="FADefine.cs" />
+    <Compile Include="GlobalEvents.cs" />
     <Compile Include="InvokeName.cs" />
     <Compile Include="PartialPressureResult.cs" />
     <Compile Include="PMLeakCheckResult.cs" />

+ 13 - 0
Venus/Venus_MainPages/Unity/CommonFunction.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Venus_MainPages.Unity
+{
+    internal static class CommonFunction
+    {
+        //internal T 
+    }
+}

+ 230 - 0
Venus/Venus_MainPages/Unity/ContextMenuManager.cs

@@ -0,0 +1,230 @@
+using Aitex.Core.Common;
+using Caliburn.Micro;
+using MECF.Framework.Common.OperationCenter;
+using OpenSEMI.Ctrlib.Controls;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Venus_MainPages.Unity
+{
+    public class MenuElement
+    {
+        public string Name { get; set; }
+        public string Invoke { get; set; }
+        public bool IsSeparator { get; set; }
+    }
+
+    public class ContextMenuManager
+    {
+        public bool ShowAligner { get; set; }
+        public bool ShowCooling { get; set; }
+
+        public ContextMenuManager()
+        {
+            _slotMenus = InitMenus(_SlotMenuElements);
+            _carrierMenus = InitMenus(_carrierMenuElements);
+
+            ShowAligner = true;
+            ShowCooling = true;
+        }
+
+        #region single Instance
+        private static ContextMenuManager m_Instance = null;
+        public static ContextMenuManager Instance
+        {
+            get
+            {
+                if (m_Instance == null)
+                {
+                    m_Instance = new ContextMenuManager();
+                }
+                return m_Instance;
+            }
+        }
+        #endregion
+
+        #region Slot Menus
+
+        private ContextMenu _slotMenus;
+        public ContextMenu SlotMenus
+        {
+            get { return _slotMenus; }
+        }
+
+        private readonly List<MenuElement> _SlotMenuElements = new List<MenuElement>() {
+            new MenuElement(){ Name="Create Wafer", Invoke="CreateWafer"},
+            new MenuElement(){ Name="Delete Wafer", Invoke="DeleteWafer"},
+            //new MenuElement(){ Name="-", IsSeparator = true},
+            //new MenuElement(){ Name="Return Wafer", Invoke="ReturnWafer"}
+        };
+
+        public void OnContextMenuClick(object sender, RoutedEventArgs args)
+        {
+            try
+            {
+                MenuItem m_menu = sender as MenuItem;
+                Slot CurrentSlot = ContextMenuService.GetPlacementTarget(LogicalTreeHelper.GetParent(m_menu)) as Slot;
+                if (CurrentSlot == null)
+                    return;
+
+                MenuElement ele = m_menu.Tag as MenuElement;
+
+             
+                InvokeClient.Instance.Service.DoOperation(ele.Invoke, CurrentSlot.ModuleID, CurrentSlot.SlotID);
+            }
+            catch (Exception ex)
+            {
+                //LOG.Write(ex);
+            }
+        }
+
+        private ContextMenu InitMenus(List<MenuElement> menus)
+        {
+            ContextMenu cm = new ContextMenu();
+
+            foreach (MenuElement element in menus)
+            {
+                if (element.IsSeparator)
+                {
+                    cm.Items.Add(new Separator());
+                }
+                else
+                {
+                    MenuItem m_item = new MenuItem();
+                    m_item.Header = element.Name;
+                    m_item.Tag = element;
+                    m_item.Click += new RoutedEventHandler(OnContextMenuClick);
+                    m_item.IsEnabled = true;
+                    cm.Items.Add(m_item);
+                }
+
+            }
+            return cm;
+        }
+
+        public bool IsAutoMode { get; set; }
+
+        public bool EnableAuto
+        {
+            get { return !IsAutoMode; }
+        }
+
+        public ContextMenu GetSlotMenus(Slot slot)
+        {           
+            if (slot != null)
+            {
+                MenuItem createWafer = _slotMenus.Items.GetItemAt(0) as MenuItem;
+                MenuItem deleteWafer = _slotMenus.Items.GetItemAt(1) as MenuItem;
+                //MenuItem returnWafer = _slotMenus.Items.GetItemAt(3) as MenuItem;
+
+                createWafer.IsEnabled = ((WaferStatus)slot.WaferStatus == WaferStatus.Empty ? true : false) && EnableAuto;
+                //createWafer.IsChecked= ((WaferStatus)slot.WaferStatus == WaferStatus.Empty ? false : true) && EnableAuto;
+                deleteWafer.IsEnabled = ((WaferStatus)slot.WaferStatus == WaferStatus.Empty ? false : true) && EnableAuto;
+                //deleteWafer.IsChecked = ((WaferStatus)slot.WaferStatus == WaferStatus.Empty ? true : false) && EnableAuto;
+
+                //returnWafer.IsEnabled = (WaferStatus)slot.WaferStatus != WaferStatus.Empty && !slot.ModuleID.StartsWith("LP");
+            }
+            return _slotMenus;
+        }
+
+        public void ReturnWafer(string menu, Slot p_from)
+        {
+            //try
+            //{
+            //    if (p_from == null || !p_from.IsValidSlot())
+            //        return;
+
+            //    //DialogButton btns = DialogButton.Transfer | DialogButton.Cancel;       
+            //    string info = " from " + p_from.ModuleID + " slot " + (p_from.SlotID + 1).ToString();
+            //    string message = "Are you sure to return the wafer: \n" + info;
+            //    //DialogButton m_dResult = DialogBox.ShowDialog(btns, DialogType.CONFIRM, message);
+
+            //    bool displayAlignerCondition = p_from.ModuleID == "LP1" || p_from.ModuleID == "LP2" || p_from.ModuleID == "LP3" || p_from.ModuleID == "EfemRobot"
+            //        || p_from.ModuleID == "LLA" || p_from.ModuleID == "LLB" || p_from.ModuleID == "LLC" || p_from.ModuleID == "LLD" || p_from.ModuleID == "Buffer";
+
+            //    displayAlignerCondition = displayAlignerCondition && (p_from.ModuleID != "Aligner");
+
+            //    bool displayPassCoolingCondition = (p_from.ModuleID.Contains("PM") || p_from.ModuleID == "TMRobot");
+
+            //    WindowManager wm = new WindowManager();
+            //    WaferTransferDialogViewModel _transferVM = new WaferTransferDialogViewModel(message, displayAlignerCondition, displayPassCoolingCondition);
+            //    _transferVM.AlignerVisibility = ShowAligner ? Visibility.Visible : Visibility.Hidden;
+            //    _transferVM.CoolingVisibility = ShowCooling ? Visibility.Visible : Visibility.Hidden;
+            //    bool? bret = wm.ShowDialogWithNoStyle(_transferVM);
+            //    if ((bool)bret)
+            //    {
+            //        //get and use transfer conditions
+            //        WaferTransferCondition conditions = _transferVM.DialogResult;
+
+            //        InvokeClient.Instance.Service.DoOperation(menu, p_from.ModuleID, p_from.SlotID,
+            //            conditions.IsPassCooling, conditions.CoolingTime);
+            //    }
+
+            //    p_from.ClearDragDropStatus();
+            //}
+            //catch (Exception ex)
+            //{
+            //    LOG.Write(ex);
+            //}
+        }
+
+        #endregion
+
+
+
+        #region Carrier menus
+
+        private ContextMenu _carrierMenus;
+        public ContextMenu CarrierMenus
+        {
+            get { return _carrierMenus; }
+        }
+
+        private readonly List<MenuElement> _carrierMenuElements = new List<MenuElement>() {
+            new MenuElement(){ Name="Create Carrier", Invoke="System.CreateCarrier"},
+            new MenuElement(){ Name="Delete Carrier", Invoke="System.DeleteCarrier"},
+
+        };
+
+        public void OnCarrierContextMenuClick(object sender, RoutedEventArgs args)
+        {
+            //try
+            //{
+            //    MenuItem menuItem = sender as MenuItem;
+            //    CarrierContentControl locateCarrier = ContextMenuService.GetPlacementTarget(LogicalTreeHelper.GetParent(menuItem)) as CarrierContentControl;
+            //    if (locateCarrier == null)
+            //        return;
+
+            //    MenuElement ele = menuItem.Tag as MenuElement;
+
+            //    InvokeClient.Instance.Service.DoOperation(ele.Invoke, locateCarrier.ModuleID, locateCarrier.CarrierID);
+            //}
+            //catch (Exception ex)
+            //{
+            //    LOG.Write(ex);
+            //}
+        }
+
+
+        //public ContextMenu GetCarrierMenus(CarrierContentControl carrier)
+        //{
+        //    if (carrier != null)
+        //    {
+        //        MenuItem createCarrier = _carrierMenus.Items.GetItemAt(0) as MenuItem;
+        //        MenuItem deleteWafer = _carrierMenus.Items.GetItemAt(1) as MenuItem;
+
+        //        createCarrier.IsEnabled = (WaferStatus)carrier.WaferStatus == WaferStatus.Empty ? true : false;
+        //        deleteWafer.IsEnabled = (WaferStatus)carrier.WaferStatus == WaferStatus.Empty ? false : true;
+        //    }
+        //    return _carrierMenus;
+        //}
+
+        #endregion
+
+    }
+}

+ 2 - 0
Venus/Venus_MainPages/Venus_MainPages.csproj

@@ -123,7 +123,9 @@
     <Compile Include="PMS\UiRecipeManager.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="RTData.cs" />
+    <Compile Include="Unity\CommonFunction.cs" />
     <Compile Include="Unity\ConfigValueTemplateSelector.cs" />
+    <Compile Include="Unity\ContextMenuManager.cs" />
     <Compile Include="Unity\FileNode.cs" />
     <Compile Include="Unity\FolderOrFileTemplateSelector.cs" />
     <Compile Include="Unity\GlobalEvents.cs" />

+ 4 - 5
Venus/Venus_MainPages/ViewModels/GasLeakCheckViewModel.cs

@@ -368,12 +368,11 @@ namespace Venus_MainPages.ViewModels
                         stringBuilder.Append(',');
                     }
                 }
-                if (stringBuilder.Length > 1)
+                if (stringBuilder.Length > 0)
                 {
                     stringBuilder.Remove(stringBuilder.Length - 1, 1);
-                    InvokeClient.Instance.Service.DoOperation($"{ModuleName}.GasLeakCheck", VentTime, CheckTime, LeakRateUpperLimit, stringBuilder.ToString(), GasIsCheck[0], LeakCheckMode[LeakCheckModeSelectedIndex]);
-                }
-               
+                }           
+                InvokeClient.Instance.Service.DoOperation($"{ModuleName}.GasLeakCheck", VentTime, CheckTime, LeakRateUpperLimit, stringBuilder.ToString(), GasIsCheck[0], LeakCheckMode[LeakCheckModeSelectedIndex]);
             }
         }
         private void OnAbort()
@@ -410,7 +409,7 @@ namespace Venus_MainPages.ViewModels
         void timer_Tick(object sender, EventArgs e)
         {
             RtDataValues = QueryDataClient.Instance.Service.PollData(m_RtDataKeys);
-            PVN21ValveIsOpen = (bool)RtDataValues[$"{ModuleName}.ValvePVN21.IsOpen"];
+            N2ValveIsOpen = (bool)RtDataValues[$"{ModuleName}.ValveN2.IsOpen"];
             GasFinalValveIsOpen = (bool)RtDataValues[$"{ModuleName}.ValveGasFinal.IsOpen"];
             PV11ValveIsOpen = (bool)RtDataValues[$"{ModuleName}.ValvePV11.IsOpen"];
             PV12ValveIsOpen = (bool)RtDataValues[$"{ModuleName}.ValvePV12.IsOpen"];

+ 30 - 22
Venus/Venus_MainPages/ViewModels/OverViewModel.cs

@@ -112,8 +112,8 @@ namespace Venus_MainPages.ViewModels
 
 
 
-        private List<string> m_RtConfigKeys;
-        private Dictionary<string, object> m_RtConfigValues;
+        //private List<string> m_RtConfigKeys;
+        //private Dictionary<string, object> m_RtConfigValues;
 
         private List<string> m_RtDataKeys;
         private Dictionary<string, object> m_RtDataValues;
@@ -549,11 +549,11 @@ namespace Venus_MainPages.ViewModels
             get { return m_PMCurrentState; }
             set { SetProperty(ref m_PMCurrentState, value); }
         }
-        public Dictionary<string, object> RtConfigValues
-        {
-            get { return m_RtConfigValues; }
-            set { SetProperty(ref m_RtConfigValues, value); }
-        }
+        //public Dictionary<string, object> RtConfigValues
+        //{
+        //    get { return m_RtConfigValues; }
+        //    set { SetProperty(ref m_RtConfigValues, value); }
+        //}
 
         #region 阀
         public bool GasFinalValveIsOpen
@@ -974,13 +974,13 @@ namespace Venus_MainPages.ViewModels
         public OverViewModel()
         {
             //RTData.init();
-            m_RtConfigKeys = new List<string>();
+            //m_RtConfigKeys = new List<string>();
             m_RtDataKeys = new List<string>();
 
             m_IsATM = true;
 
             ModuleName = "PMA";
-            addConfigKeys();
+            //addConfigKeys();
             addDataKeys();
 
             DispatcherTimer timer = new DispatcherTimer();
@@ -1151,17 +1151,21 @@ namespace Venus_MainPages.ViewModels
                 InvokeClient.Instance.Service.DoOperation($"{ModuleName}.StopPump");
                 return;
             }
-            string BasePressureSetPoint= RtConfigValues[$"{ModuleName}.Pump.PumpBasePressure"].ToString(); ;
+            //string BasePressureSetPoint= RtConfigValues[$"{ModuleName}.Pump.PumpBasePressure"].ToString(); ;
             //{
             //    get { return RtConfigValues[$"{ModuleName}.Pump.PumpBasePressure"].ToString(); }
             //}
 
-            string PumpLimitSetPoint= RtConfigValues[$"{ModuleName}.Pump.PumpTimeLimit"].ToString();
-        //{
-        //    get { return RtConfigValues[$"{ModuleName}.Pump.PumpTimeLimit"].ToString(); }
-        //}
-        // 设置底压
-        double basePressure = string.IsNullOrEmpty(BasePressureSetPoint) ? 0 : Convert.ToDouble(BasePressureSetPoint);
+            //string PumpLimitSetPoint= RtConfigValues[$"{ModuleName}.Pump.PumpTimeLimit"].ToString();
+            //{
+            //    get { return RtConfigValues[$"{ModuleName}.Pump.PumpTimeLimit"].ToString(); }
+            //}
+
+            string BasePressureSetPoint = QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.Pump.PumpBasePressure").ToString();
+
+            string PumpLimitSetPoint= QueryDataClient.Instance.Service.GetConfig($"{ModuleName}.Pump.PumpTimeLimit").ToString();
+            // 设置底压
+            double basePressure = string.IsNullOrEmpty(BasePressureSetPoint) ? 0 : Convert.ToDouble(BasePressureSetPoint);
 
             if (basePressure <= 0.01 || basePressure >= 1000)
             {
@@ -1388,9 +1392,13 @@ namespace Venus_MainPages.ViewModels
         #region 私有方法
         void timer_Tick(object sender, EventArgs e)
         {
-            RtConfigValues = QueryDataClient.Instance.Service.PollConfig(m_RtConfigKeys);
+            //RtConfigValues = QueryDataClient.Instance.Service.PollConfig(m_RtConfigKeys);
             RtDataValues = QueryDataClient.Instance.Service.PollData(m_RtDataKeys);
 
+            if (RtDataValues.Count == 0)
+            {
+                return;
+            }
 
             var N2SetPoint =Convert.ToInt32( QueryDataClient.Instance.Service.GetConfig("System.TurboN2FlowSetPoint"));
             InvokeClient.Instance.Service.DoOperation($"{ModuleName}.MfcN2.SetPoint", N2SetPoint);
@@ -1514,11 +1522,11 @@ namespace Venus_MainPages.ViewModels
         }
 
 
-        private void addConfigKeys()
-        {
-            m_RtConfigKeys.Add($"{ModuleName}.Pump.PumpBasePressure");
-            m_RtConfigKeys.Add($"{ModuleName}.Pump.PumpTimeLimit");
-        }
+        //private void addConfigKeys()
+        //{
+        //    m_RtConfigKeys.Add($"{ModuleName}.Pump.PumpBasePressure");
+        //    m_RtConfigKeys.Add($"{ModuleName}.Pump.PumpTimeLimit");
+        //}
         private void addDataKeys()
         {
             m_RtDataKeys.Add($"{ModuleName}.MfcGas1");

+ 106 - 14
Venus/Venus_MainPages/ViewModels/TMViewModel.cs

@@ -3,6 +3,7 @@ using MECF.Framework.Common.CommonData;
 using MECF.Framework.Common.DataCenter;
 using MECF.Framework.Common.Equipment;
 using MECF.Framework.Common.OperationCenter;
+using MECF.Framework.Common.Schedulers;
 using OpenSEMI.ClientBase;
 using Prism.Commands;
 using Prism.Mvvm;
@@ -12,6 +13,8 @@ using System.Collections.ObjectModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
 using System.Windows.Threading;
 using Venus_Core;
 using Venus_MainPages.Unity;
@@ -19,6 +22,7 @@ using Venus_Themes.CustomControls;
 
 namespace Venus_MainPages.ViewModels
 {
+    
     public enum TMModule
     {
         PMA, PMB, PMC, PMD, LLA, LLB
@@ -84,7 +88,16 @@ namespace Venus_MainPages.ViewModels
         private string m_RobotTarget;
 
         private string m_RobotArm;
-  
+
+        private bool m_PMAIsInstalled;
+        private bool m_PMBIsInstalled;
+        private bool m_PMCIsInstalled;
+        private bool m_PMDIsInstalled;
+        private bool m_LLAIsInstalled;
+        private bool m_LLBIsInstalled;
+
+
+
 
         #endregion
 
@@ -465,7 +478,36 @@ namespace Venus_MainPages.ViewModels
             get { return m_RtDataValues; }
             set { SetProperty(ref m_RtDataValues, value); }
         }
-
+        public bool PMAIsInstalled
+        {
+            get { return m_PMAIsInstalled; }
+            set { SetProperty(ref m_PMAIsInstalled, value); }
+        }
+        public bool PMBIsInstalled
+        {
+            get { return m_PMBIsInstalled; }
+            set { SetProperty(ref m_PMBIsInstalled, value); }
+        }
+        public bool PMCIsInstalled
+        {
+            get { return m_PMCIsInstalled; }
+            set { SetProperty(ref m_PMCIsInstalled, value); }
+        }
+        public bool PMDIsInstalled
+        {
+            get { return m_PMDIsInstalled; }
+            set { SetProperty(ref m_PMDIsInstalled, value); }
+        }
+        public bool LLAIsInstalled
+        {
+            get { return m_LLAIsInstalled; }
+            set { SetProperty(ref m_LLAIsInstalled, value); }
+        }
+        public bool LLBIsInstalled
+        {
+            get { return m_LLBIsInstalled; }
+            set { SetProperty(ref m_LLBIsInstalled, value); }
+        }
         #endregion
 
         #region 命令
@@ -516,11 +558,20 @@ namespace Venus_MainPages.ViewModels
         public DelegateCommand AbortCommand =>
             _AbortCommand ?? (_AbortCommand = new DelegateCommand(OnAbort));
 
+       
+
         #endregion
 
         #region 构造函数
         public TMViewModel()
         {
+            string[] allModules = QueryDataClient.Instance.Service.GetConfig($"System.InstalledModules").ToString().Split(',');
+            PMAIsInstalled = allModules.Contains("PMA");
+            PMBIsInstalled = allModules.Contains("PMB");
+            PMCIsInstalled = allModules.Contains("PMC");
+            PMDIsInstalled = allModules.Contains("PMD");
+            LLAIsInstalled = allModules.Contains("LLA");
+            LLBIsInstalled = allModules.Contains("LLB");
 
             addDataKeys();
 
@@ -535,19 +586,56 @@ namespace Venus_MainPages.ViewModels
             RetractSoltItemsSource.Add(1);
             //Robot1TAction = WaferRobotTAction.PMA;
             //Robot2TAction = WaferRobotTAction.PMD;
+            VenusGlobalEvents.SlotRightClickChangedEvent += Instance_SlotRightClickChangedEvent;
 
 
         }
 
+        private void Instance_SlotRightClickChangedEvent(OpenSEMI.Ctrlib.Controls.Slot slot)
+        {
+            if (slot!=null)
+            {
+                ContextMenu cm = ContextMenuManager.Instance.GetSlotMenus(slot);
+                if (cm != null)
+                {
+                    slot.ContextMenu = cm;
+                }
+
+                return;
+            }
+        }
+
         private void Timer_Tick(object sender, EventArgs e)
         {
-            LLAModuleInfo = ModuleManager.ModuleInfos["LLA"];
-            LLBModuleInfo = ModuleManager.ModuleInfos["LLB"];
+            if (LLAIsInstalled == true)
+            {
+                LLAModuleInfo = ModuleManager.ModuleInfos["LLA"];
+            }
+            if (LLBIsInstalled == true)
+            {
+                LLBModuleInfo = ModuleManager.ModuleInfos["LLB"];
+            }
 
             //LLBWafer = ModuleManager.ModuleInfos["LLB"].WaferManager.Wafers[0];
             //LLAWafer = ModuleManager.ModuleInfos["LLA"].WaferManager.Wafers[3];
+            if (PMAIsInstalled == true)
+            {
+                PMAWafer = ModuleManager.ModuleInfos["PMA"].WaferManager.Wafers[0];
+            }
+            if (PMBIsInstalled == true)
+            {
+                PMBWafer = ModuleManager.ModuleInfos["PMB"].WaferManager.Wafers[0];
+            }
+            if (PMCIsInstalled == true)
+            {
+                PMCWafer = ModuleManager.ModuleInfos["PMC"].WaferManager.Wafers[0];
+            }
+            if (PMDIsInstalled == true)
+            {
+                PMDWafer = ModuleManager.ModuleInfos["PMD"].WaferManager.Wafers[0];
+            }
+
 
-            PMAWafer = ModuleManager.ModuleInfos["PMA"].WaferManager.Wafers[0];
             BladeAWafer = ModuleManager.ModuleInfos["TM"].WaferManager.Wafers[0];
             BladeBWafer = ModuleManager.ModuleInfos["TM"].WaferManager.Wafers[1];
 
@@ -708,33 +796,37 @@ namespace Venus_MainPages.ViewModels
         }
         private  void OnPick()
         {
+            Queue<MoveItem> moveItems = new Queue<MoveItem>();
+           
             var moduleName= (ModuleName)Enum.Parse(typeof(ModuleName), PickSelectedModule.ToString(), true);
             var selectedHand= (Hand)Enum.Parse(typeof(Hand), PickSelectedBlade.ToString(), true);
+            MoveItem moveItem = new MoveItem(moduleName, PickSoltItemsSource[PickSoltSelectedIndex] - 1, 0, 0, selectedHand);
+            moveItems.Enqueue(moveItem);
             if ((int)PickSelectedModule > 3)
-            {
-                InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.LLPick}", moduleName, PickSoltItemsSource[PickSoltSelectedIndex] - 1, selectedHand);
-
+            {           
+                InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.LLPick}", moveItems);
             }
             else
-            { 
-            InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.PMPick}", moduleName, PickSoltItemsSource[PickSoltSelectedIndex] - 1, selectedHand);
-
+            {
+                InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.PMPick}", moveItems);
             }
         }
         private  void OnPlace()
         {
+            Queue<MoveItem> moveItems = new Queue<MoveItem>();
             var moduleName = (ModuleName)Enum.Parse(typeof(ModuleName), PlaceSelectedModule.ToString(), true);
 
             var selectedHand = (Hand)Enum.Parse(typeof(Hand), PlaceSelectedBlade.ToString(), true);
+            MoveItem moveItem = new MoveItem(0,0,moduleName, PickSoltItemsSource[PickSoltSelectedIndex] - 1, selectedHand);
+            moveItems.Enqueue(moveItem);
             if ((int)PlaceSelectedModule > 3)
             {
-                InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.LLPlace}", moduleName, PlaceSoltItemsSource[PlaceSoltSelectedIndex]-1, selectedHand);
+                InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.LLPlace}", moveItems);
 
             }
             else
             {
-                InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.PMPlace}", moduleName, PlaceSoltItemsSource[PlaceSoltSelectedIndex] - 1, selectedHand);
-
+                InvokeClient.Instance.Service.DoOperation($"TM.{RtOperation.PMPlace}", moveItems);
             }
         }
         private void OnHome()

+ 4 - 4
Venus/Venus_MainPages/Views/PlatformView.xaml

@@ -23,18 +23,18 @@
                        
                         />-->
         <Image Canvas.Left="200" Canvas.Top="500"  Width="150" Height="150" Source="Pack://application:,,,/Venus_Themes;Component/Resources/LoadLock.png">
-            <Image.ContextMenu>
+            <!--<Image.ContextMenu>
                 <ContextMenu Visibility="{Binding WaferIsVisibility,Converter={StaticResource VisibilityToReverse}}">
                     <MenuItem Header="新建晶圆" Command="{Binding NewWaferCommand}"/>
                 </ContextMenu>
-            </Image.ContextMenu>
+            </Image.ContextMenu>-->
         </Image>
         <ctrls:WaferCtrl  Canvas.Left="242" Canvas.Top="542"  WaferData="{Binding PMAWafer}">
-            <ctrls:WaferCtrl.ContextMenu>
+            <!--<ctrls:WaferCtrl.ContextMenu>
                 <ContextMenu >
                     <MenuItem Header="删除晶圆" Command="{Binding DeleteWaferCommand}" />
                 </ContextMenu>
-            </ctrls:WaferCtrl.ContextMenu>
+            </ctrls:WaferCtrl.ContextMenu>-->
         </ctrls:WaferCtrl>
 
         <!--<Ellipse Stroke="White"  Width="80" Height="80" Canvas.Left="235" Canvas.Top="536" Visibility="{Binding PMAWaferIsVisibility}">

+ 7 - 6
Venus/Venus_MainPages/Views/TMView.xaml

@@ -450,18 +450,19 @@
             <Viewbox Width="350" Height="600" Stretch="Fill" >
                 <Canvas Canvas.Top="100" Width="450" Height="800">
                     <userControls:MainTM Width="300" Height="250" Canvas.Left="380" Canvas.Top="90"/>
+                    
                     <customControls:WaferRobotControl OriginT="PMA"    Canvas.Left="410" Canvas.Top="76"   Width="200" Height="300"   x:Name="robot"  RobotTAction="{Binding Robot1TAction}" RobotXAction="{Binding Robot1XAction}" RobotWafer="{Binding BladeAWafer}"/>
                     <customControls:WaferRobotControl OriginT="PMD"   Canvas.Left="410" Canvas.Top="76"   Width="200" Height="300"   x:Name="robot2" RobotTAction="{Binding Robot2TAction}" RobotXAction="{Binding Robot2XAction}"  RobotWafer="{Binding BladeBWafer}"/>
 
 
-                    <userControls:LoadLockLeft  Width="150" Height="150" Canvas.Top="310" Canvas.Left="358"  DoorIsOpen="{Binding RtDataValues[TM.LLATSlitDoor.IsClosed],Converter={StaticResource BoolToBool}}"/>
-                    <userControls:LoadLockRight Width="150" Height="150" Canvas.Top="309" Canvas.Left="519"  DoorIsOpen="{Binding RtDataValues[TM.LLBTSlitDoor.IsClosed],Converter={StaticResource BoolToBool}}"/>
+                    <userControls:LoadLockLeft  Width="150" Height="150" Canvas.Top="310" Canvas.Left="358"  DoorIsOpen="{Binding RtDataValues[TM.LLATSlitDoor.IsClosed],Converter={StaticResource BoolToBool}}" Visibility="{Binding LLAIsInstalled,Converter={StaticResource bool2VisibilityConverter}}"/>
+                    <userControls:LoadLockRight Width="150" Height="150" Canvas.Top="309" Canvas.Left="519"  DoorIsOpen="{Binding RtDataValues[TM.LLBTSlitDoor.IsClosed],Converter={StaticResource BoolToBool}}" Visibility="{Binding LLBIsInstalled,Converter={StaticResource bool2VisibilityConverter}}"/>
 
 
-                    <userControls:TMChamber x:Name="PMA" Canvas.Top="302"  Canvas.Left="233" Width="140" Height="140" RotateTransformValue="-90"  DoorIsOpen="{Binding RtDataValues[PMA.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMAWafer}"/>
-                    <userControls:TMChamber x:Name="PMB" Canvas.Top="28"   Canvas.Left="315" Width="140" Height="140" RotateTransformValue="-28"  DoorIsOpen="{Binding RtDataValues[PMB.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMBWafer}"/>
-                    <userControls:TMChamber x:Name="PMC" Canvas.Top="-38"  Canvas.Left="588" Width="140" Height="140" RotateTransformValue="30"   DoorIsOpen="{Binding RtDataValues[PMC.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMCWafer}"/>
-                    <userControls:TMChamber x:Name="PMD" Canvas.Top="160"  Canvas.Left="788" Width="140" Height="140" RotateTransformValue="90"   DoorIsOpen="{Binding RtDataValues[PMD.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMDWafer}"/>
+                    <userControls:TMChamber x:Name="PMA" Canvas.Top="302"  Canvas.Left="233" Width="140" Height="140" RotateTransformValue="-90"  DoorIsOpen="{Binding RtDataValues[PMA.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMAWafer}" Visibility="{Binding PMAIsInstalled,Converter={StaticResource bool2VisibilityConverter}}"/>
+                    <userControls:TMChamber x:Name="PMB" Canvas.Top="28"   Canvas.Left="315" Width="140" Height="140" RotateTransformValue="-28"  DoorIsOpen="{Binding RtDataValues[PMB.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMBWafer}" Visibility="{Binding PMBIsInstalled,Converter={StaticResource bool2VisibilityConverter}}"/>
+                    <userControls:TMChamber x:Name="PMC" Canvas.Top="-38"  Canvas.Left="588" Width="140" Height="140" RotateTransformValue="30"   DoorIsOpen="{Binding RtDataValues[PMC.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMCWafer}" Visibility="{Binding PMCIsInstalled,Converter={StaticResource bool2VisibilityConverter}}"/>
+                    <userControls:TMChamber x:Name="PMD" Canvas.Top="160"  Canvas.Left="788" Width="140" Height="140" RotateTransformValue="90"   DoorIsOpen="{Binding RtDataValues[PMD.IsSlitDoorClosed],Converter={StaticResource BoolToBool}}" RobotWafer="{Binding PMDWafer}" Visibility="{Binding PMDIsInstalled,Converter={StaticResource bool2VisibilityConverter}}"/>
                 </Canvas>
             </Viewbox>
         </Canvas>

+ 1 - 1
Venus/Venus_RT/Devices/IODevices/IoGasStick.cs

@@ -10,7 +10,7 @@ namespace Venus_RT.Devices
     class IoGasStick : BaseDevice, IDevice
     {
         private readonly IoValve _DownValve;
-        private readonly MfcBase1 _mfc;
+        public readonly MfcBase1 _mfc;
 
         // Properties
         //

+ 1 - 1
Venus/Venus_RT/Devices/JetPM.cs

@@ -97,7 +97,7 @@ namespace Venus_RT.Devices
 
         private readonly IoPressureControl _pressureController;
 
-        private readonly IoGasStick[] _gasLines;
+        public readonly IoGasStick[] _gasLines;
         private readonly IoGasStick _gasLineN2;
         private readonly IoBacksideHe _backsideHe;
 

+ 3 - 1
Venus/Venus_RT/Modules/PMs/GasBoxLeakCheckRoutine.cs

@@ -115,7 +115,9 @@ namespace Venus_RT.Modules.PMs
         {
             foreach(var num in _gasLineNums)
             {
-                _chamber.FlowGas(num-1, _GasFlow);
+                //var str = _chamber._gasLines[num-1]._mfc.Scale
+                //var _GasFlow = Convert.ToDouble(SC.GetStringValue($"PMA.MfcGas{num}.MfcN2Scale"));
+                _chamber.FlowGas(num-1, _chamber._gasLines[num - 1]._mfc.Scale);
             }
             _chamber.OpenValve(ValveType.PV11, true);
             _chamber.OpenValve(ValveType.PV21, true);

+ 2 - 1
Venus/Venus_RT/Modules/PMs/PMLeakCheckRoutine.cs

@@ -6,6 +6,7 @@ using System.Diagnostics;
 using Venus_Core;
 using System;
 using Venus_Unity;
+using MECF.Framework.Common.DBCore;
 
 namespace Venus_RT.Modules.PMs
 {
@@ -135,7 +136,7 @@ namespace Venus_RT.Modules.PMs
                 Stop($"PM Leakcheck失败, 腔体漏率 [{LeakRate}] mt/min, 高于 [{_leakRate}] mt/min");
                 pMLeakCheckResult.Result = "Fail";
             }
-
+            LeakCheckDataRecorder.Add(_leakcheckHoldTime, (int)_startPressure, (int)_endPressure, LeakRate, pMLeakCheckResult.Result, "ChamberOnly");
             _chamber.OpenValve(ValveType.GasFinal, true);
             _chamber.TurnPendulumValve(true);
             pMLeakCheckResult.LeakCheckTime = (int)_routineTimer.ElapsedMilliseconds / 1000;

File diff suppressed because it is too large
+ 8 - 5
Venus/Venus_Themes/Themes/Generic.xaml


+ 3 - 2
Venus/Venus_Themes/UserControls/TMChamber.xaml

@@ -75,9 +75,10 @@
 
                 </Rectangle>
                 <Viewbox Width="120" Height="120"  Canvas.Left="40" Canvas.Top="40">
-                    <ctrl:Slot  ViewType="Top" WaferStatus="{Binding WaferStatus}" SlotID="{Binding SlotID}" ModuleID="{Binding ModuleID}" SourceName="{Binding SourceName}" 
+                    <!--<ctrl:Slot  ViewType="Top" WaferStatus="{Binding WaferStatus}" SlotID="{Binding SlotID}" ModuleID="{Binding ModuleID}" SourceName="{Binding SourceName}" 
                        DataContext="{Binding ElementName=tmChamber, Path=RobotWafer}"  HorizontalAlignment="Center" VerticalAlignment="Center">
-                    </ctrl:Slot>
+                    </ctrl:Slot>-->
+                    <local:WaferCtrl WaferData="{Binding ElementName=tmChamber, Path=RobotWafer}"/>
                 </Viewbox>
                
             </Canvas>

+ 3 - 1
Venus/Venus_Themes/UserControls/WaferCtrl.xaml

@@ -9,7 +9,9 @@
              xmlns:ctrl="http://OpenSEMI.Ctrlib.com/presentation">
     <Grid RenderTransformOrigin="0.5,0.5">
         <ctrl:Slot ViewType="Top" WaferStatus="{Binding WaferStatus}" SlotID="{Binding SlotID}" ModuleID="{Binding ModuleID}" SourceName="{Binding SourceName}" 
-                       DataContext="{Binding WaferData,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"  HorizontalAlignment="Center" VerticalAlignment="Center">
+                       DataContext="{Binding WaferData,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"  HorizontalAlignment="Center" VerticalAlignment="Center"  SlotMouseButtonDown="Slot_SlotMouseButtonDown">
+ 
         </ctrl:Slot>
+        
     </Grid>
 </UserControl>

+ 8 - 0
Venus/Venus_Themes/UserControls/WaferCtrl.xaml.cs

@@ -1,5 +1,6 @@
 
 using OpenSEMI.ClientBase;
+using OpenSEMI.Ctrlib.Controls;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -14,6 +15,7 @@ using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;
+using Venus_Core;
 
 namespace Venus_Themes.UserControls
 {
@@ -34,5 +36,11 @@ namespace Venus_Themes.UserControls
 
         public static readonly DependencyProperty WaferDataProperty =
             DependencyProperty.Register("WaferData", typeof(WaferInfo), typeof(WaferCtrl), new PropertyMetadata(null));
+
+
+        private void Slot_SlotMouseButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            VenusGlobalEvents.OnSlotRightClickChanged(sender as Slot);
+        }
     }
 }

+ 10 - 0
Venus/Venus_Themes/Venus_Themes.csproj

@@ -31,6 +31,10 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Caliburn.Micro, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\jet.svn\jet.plasma\trunk\MetisMars\ThirdParty\dlls\Caliburn.Micro.dll</HintPath>
+    </Reference>
     <Reference Include="OpenSEMI.ClientBase">
       <HintPath>..\ThirdParty\selfbuild\OpenSEMI.ClientBase.dll</HintPath>
     </Reference>
@@ -404,5 +408,11 @@
     <Content Include="Themes\Images\pms\vaporPipe.png" />
     <Content Include="Themes\Images\pms\Virgo_D.ico" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Venus_Core\Venus_Core.csproj">
+      <Project>{e40639dd-94a7-4ecd-8137-11496bd0bfa3}</Project>
+      <Name>Venus_Core</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>