Pārlūkot izejas kodu

ELK需求177:bufferPurge功能优化

huangping 2 nedēļas atpakaļ
vecāks
revīzija
b2f0c7d993

+ 1 - 0
FrameworkLocal/Common/Common.csproj

@@ -244,6 +244,7 @@
     <Compile Include="CommonData\FileNodeItem.cs" />
     <Compile Include="CommonData\HistoryDataItem.cs" />
     <Compile Include="CommonData\NotifiableData.cs" />
+    <Compile Include="CommonData\PurgeParameter.cs" />
     <Compile Include="CommonData\RecipeHistory.cs" />
     <Compile Include="CommonData\RobotMoveInfo.cs" />
     <Compile Include="CommonData\SorterDefines\DeviceState.cs" />

+ 100 - 0
FrameworkLocal/Common/CommonData/PurgeParameter.cs

@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MECF.Framework.Common.CommonData
+{
+    public class PurgeParameter : NotifyPropertyBase
+    {
+        public string Name { get; set; }
+        private float _speed;
+
+        public float Speed
+        {
+            get { return _speed; }
+            set
+            {
+                if (_speed != value)
+                {
+                    _speed = value;
+                    RaisePropertyChanged();
+                }
+            }
+        }
+        private string _timeString;
+
+        public string TimeString
+        {
+            get { return _timeString; }
+            set
+            {
+                if (_timeString != value)
+                {
+                    _timeString = value;
+                    RaisePropertyChanged();
+                    var t = value.Split(':');                  
+                    if (t.Length > 0 && t.Length <= 3)
+                    {
+                        _time = 0;
+                        for (int i = 0; i < t.Length; i++)//时分秒格式
+                        {
+                            _time += (int)(float.Parse(t[i]) * Math.Pow(60, 2 - i));
+                        }
+                    }
+                }
+            }
+        }
+
+        private int _time;
+
+        public int Time => _time;
+
+        private bool _isOpen;
+
+        public bool IsOpen
+        {
+            get { return _isOpen; }
+            set
+            {
+                if (_isOpen != value)
+                {
+                    _isOpen = value;
+                    RaisePropertyChanged();
+                }
+            }
+        }
+        private bool _isClose;
+
+        public bool IsClose
+        {
+            get { return _isClose; }
+            set
+            {
+                if (_isClose != value)
+                {
+                    _isClose = value;
+                    RaisePropertyChanged();
+                }
+            }
+        }
+    }
+    public class NotifyPropertyBase : INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        public void RaisePropertyChanged([CallerMemberName] string propertyName = "")
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+        public void Set<T>(ref T fied, T value, [CallerMemberName] string propertyName = "")
+        {
+            if (EqualityComparer<T>.Default.Equals(fied, value)) return;
+            fied = value;
+            RaisePropertyChanged(propertyName);
+        }
+    }
+}

+ 1 - 0
FrameworkLocal/Common/OperationCenter/IInvokeService.cs

@@ -32,6 +32,7 @@ namespace MECF.Framework.Common.OperationCenter
     [ServiceKnownType(typeof(ManualTransferTask[]))]
     [ServiceKnownType(typeof(Dictionary<string, Dictionary<string, EventItem>>))]
     [ServiceKnownType(typeof(RecipeHistory))]
+    [ServiceKnownType(typeof(List<PurgeParameter>))]
     public interface IInvokeService
     {
         [OperationContract]

+ 9 - 0
Furnace/FurnaceRT/Config/System.sccfg

@@ -10227,4 +10227,13 @@
 
 		</configs>
 	</configs>
+
+	<configs name="BufferPurge"  visible="false">
+		<config default="false" name="IsEnable" description="whether the BufferPurge Function is Available" max="" min="" paramter="" tag="" unit="" type="Bool" />
+		<config default="Purge1" name="NameList" description="Purge NameList" max="" min="" paramter="" tag="" unit="" type="String" />
+		<config default="Open;Close" name="Operation" description="Purge Operation Items" max="" min="" paramter="" tag="" unit="" type="String" />
+		<config default="Time;Condition" name="FinishCondition" description="Purge Finish Condition" max="" min="" paramter="" tag="" unit="" type="String" />
+		<!-- 操作顺序:名称,挡位,时间/条件,命令-->
+		<config default="Purge1,0,Time(10),Open" name="OperationOrder" description="BufferPurge excute order" max="" min="" paramter="" tag="" unit="" type="String" />
+	</configs>
 </root>

+ 55 - 0
Furnace/FurnaceRT/Equipments/PMs/PMModule.cs

@@ -37,6 +37,7 @@ using MECF.Framework.Common.CommonData.SorterDefines;
 using MECF.Framework.Common.Utilities;
 using System.Windows.Documents;
 using MECF.Framework.Common.CommonData.EnumData;
+using MECF.Framework.Common.CommonData;
 
 namespace FurnaceRT.Equipments.PMs
 {
@@ -188,6 +189,7 @@ namespace FurnaceRT.Equipments.PMs
 
         private Stopwatch _processTimer = new Stopwatch();
 
+
         public List<IoValve> ValveLists = new List<IoValve>();
         public List<IoFlowMeter> FlowmeterLists = new List<IoFlowMeter>();
 
@@ -258,6 +260,35 @@ namespace FurnaceRT.Equipments.PMs
 
             Singleton<EventManager>.Instance.OnAlarmEvent += Instance_OnAlarmEvent;
             ToolType = SC.GetStringValue("System.SetUp.ToolType");
+            #region bufferpurge重启下发
+            var isEnable = SC.GetValue<bool>("BufferPurge.IsEnable");
+            if (isEnable)
+            {
+               var sequence= SC.GetStringValue("BufferPurge.OperationOrder")?.Split(';');
+                string[] names = SC.GetStringValue("BufferPurge.NameList")?.Split(';');
+                if (sequence?.Length > 0&&names?.Length>0)
+                {
+                    List<PurgeParameter> purge = new List<PurgeParameter>();
+                    foreach (string p in sequence)
+                    {
+                        if (string.IsNullOrWhiteSpace(p)) continue;//Purge1,0,Time(10),Open;
+                        var step = p.Trim().Split(',');
+                        if (step.Length == 4)
+                        {
+                            if (string.IsNullOrEmpty(step[0])) continue;//name
+                            if (names.Contains(step[0]))
+                            {
+                                var index = step[2].IndexOf('(') + 1;
+                                int.TryParse(step[2].Substring(index, step[2].Length - index - 1), out int time);//仅考虑时间
+                                purge.Add(
+                                new PurgeParameter() { Name = step[0], TimeString = $"{time / 3600:00}:{time % 3600 / 60:00}:{time % 60:00}", IsClose = step[3].ToLower() == "close", IsOpen = step[3].ToLower() == "open" });
+                            }
+                        }
+                    }
+                    SetBufferPurge(purge);
+                }
+            }
+            #endregion
             return base.Initialize();
         }
         private void Instance_OnAlarmEvent(EventItem item)
@@ -743,8 +774,32 @@ namespace FurnaceRT.Equipments.PMs
                 SetSIREFEnable(param);
                 return true;
             });
+            OP.Subscribe($"{Name}.SetBufferPurge", (out string reason, int time, object[] param) =>
+            {
+                reason = string.Empty;
+                if (param.Length > 0 && param[0] is List<PurgeParameter> purge)
+                {
+                   reason= SetBufferPurge(purge);
+                   if (!string.IsNullOrEmpty(reason)) return false;
+                    SC.SetItemValue("BufferPurge.OperationOrder", $"{purge[0].Name},{purge[0].Speed},Time({purge[0].Time}),{(purge[0].IsOpen ? "Open" : (purge[0].IsClose?"Close":""))}");
+                }
+                return true;
+            });
             InitOtherOP();
         }
+        private string SetBufferPurge(List<PurgeParameter> purge)
+        {
+            string reason = string.Empty;
+            if (TrigBufferPurgeTime == null || TrigBufferN2PurageEN == null) { reason = "TrigBufferPurgeTime/TrigBufferN2PurageEN is null"; }
+            if (purge[0].IsOpen || purge[0].IsClose)
+            {
+                if (TrigBufferPurgeTime.SetAOTrigger(purge[0].Time, out reason))
+                {
+                    TrigBufferN2PurageEN.SetTrigger(purge[0].IsOpen, out reason);
+                }
+            }
+            return reason;
+        }
         public void SetTemperatureDetail()
         {
 

+ 2 - 0
Furnace/FurnaceRT/Equipments/PMs/PMModuleDevice.cs

@@ -1626,6 +1626,8 @@ namespace FurnaceRT.Equipments.PMs
         public IoTrigger TrigN2PurgeLAO2CheckSV { get; set; }
         [Tag("TrigN2PurgeFOUPO2CheckSV")]
         public IoTrigger TrigN2PurgeFOUPO2CheckSV { get; set; }
+        [Tag("TrigBufferN2PurageEN")]
+        public IoTrigger TrigBufferN2PurageEN { get; set; }
         #endregion
         #region IoHeaterBand
         [Tag("CapHeater")]

+ 2 - 2
Furnace/FurnaceRT/Equipments/PMs/PMModuleInterlock.cs

@@ -35,7 +35,7 @@ namespace FurnaceRT.Equipments.PMs
         private int _vac3PumpTimeS = 120;
         private int _foolProofTime = 5;   
         private DeviceTimer _plcFoolProofTime = null;
-        private RD_TRIG _trigPLCConnected = null; 
+        private RD_TRIG _trigPLCConnected = null;
       
 
         private void InitInterlock()
@@ -265,7 +265,7 @@ namespace FurnaceRT.Equipments.PMs
                 if (_plcFoolProofTime.IsTimeout())
                 {
                     _plcFoolProofTime.Stop();
-                    SensorPLCConnectedAlarm.Set($"Connected Status keep {_trigPLCConnected.CLK} out of {_foolProofTime}s");
+                    SensorPLCConnectedAlarm?.Set($"Connected Status keep {_trigPLCConnected.CLK} out of {_foolProofTime}s");
                 }
             }
         }

+ 53 - 0
Furnace/FurnaceUI/Views/Maintenances/BufferRobotView.xaml

@@ -160,6 +160,59 @@
                     </StackPanel>
                 </Border>
             </Grid>
+            <Grid Margin="500,10,0,0" Height="314" Visibility="{Binding PurgeVisibilty}">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="24"/>
+                    <RowDefinition Height="*"/>
+                    <RowDefinition Height="35"/>
+                </Grid.RowDefinitions>
+                <Label Style="{DynamicResource Table_TitleStyle}"  Grid.Row="0" Grid.ColumnSpan="4" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
+                    <Label.Content>
+                        <TextBlock Text="Buffer Purge" Foreground="White"></TextBlock>
+                    </Label.Content>
+                </Label>
+                <DataGrid ItemsSource="{Binding PurgeParameters}" AutoGenerateColumns="False" CanUserSortColumns="False" CanUserAddRows="False" Grid.Row="1" VerticalScrollBarVisibility="Auto" 
+                          MinRowHeight="40">
+                    <DataGrid.Columns>
+                        <DataGridTextColumn Header="Name" Width="150" Binding="{Binding Name,Mode=TwoWay}" ElementStyle="{StaticResource TextBlock_GridTitle}" IsReadOnly="True"/>
+                        <DataGridTextColumn Header="Level" Width="150"   IsReadOnly="True" Visibility="Hidden"/>
+                        <DataGridTemplateColumn Header="Duration" Width="150">
+                            <DataGridTemplateColumn.CellTemplate>
+                                <DataTemplate>
+                                    <Button Content="{Binding TimeString,Mode=TwoWay}">
+                                        <i:Interaction.Triggers>
+                                            <i:EventTrigger EventName="Click">
+                                                <cal:ActionMessage MethodName="TimeEdit">
+                                                    <cal:Parameter Value="{Binding}"></cal:Parameter>
+                                                </cal:ActionMessage>
+                                            </i:EventTrigger>
+                                        </i:Interaction.Triggers>
+                                    </Button>
+                                </DataTemplate>
+                            </DataGridTemplateColumn.CellTemplate>
+                        </DataGridTemplateColumn>
+                        <DataGridTemplateColumn Header="Operation" Width="160">
+                            <DataGridTemplateColumn.CellTemplate>
+                                <DataTemplate>
+                                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
+                                        <RadioButton Content="Open" IsChecked="{Binding IsOpen,UpdateSourceTrigger=PropertyChanged}"  Margin="5,0,0,0" Width="70"/>
+                                        <RadioButton Content="Close" IsChecked="{Binding IsClose,UpdateSourceTrigger=PropertyChanged}"  Margin="5,0,0,0" Width="70"/>
+                                    </StackPanel>
+                                </DataTemplate>
+                            </DataGridTemplateColumn.CellTemplate>
+                        </DataGridTemplateColumn>
+                    </DataGrid.Columns>
+                </DataGrid>
+                <Border BorderBrush="{DynamicResource Table_BD}" BorderThickness="1,0,1,1" Background="{DynamicResource Table_BG_Content}" Grid.Row="2">
+                    <Button Content="Set" HorizontalAlignment="Right" Width="92" Margin="10,0,20,0" >
+                        <i:Interaction.Triggers>
+                            <i:EventTrigger EventName="Click">
+                                <cal:ActionMessage MethodName="SetBufferPurge"/>
+                            </i:EventTrigger>
+                        </i:Interaction.Triggers>
+                    </Button>
+                </Border>
+            </Grid>
         </Canvas>
     </Grid>
 </UserControl>

+ 77 - 1
Furnace/FurnaceUI/Views/Maintenances/BufferRobotViewModel.cs

@@ -13,6 +13,10 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Windows.Controls;
 using OpenSEMI.ClientBase;
+using MECF.Framework.UI.Client.CenterViews.Editors.Recipe;
+using System.Collections.ObjectModel;
+using System.Windows;
+using MECF.Framework.Common.CommonData;
 
 
 namespace FurnaceUI.Views.Maintenances
@@ -61,6 +65,19 @@ namespace FurnaceUI.Views.Maintenances
                 NotifyOfPropertyChange(nameof(SelectedTargetPosition));
             }
         }
+        public ObservableCollection<PurgeParameter> PurgeParameters { get; set; }
+        private Visibility _purgeVisibilty;
+
+        public Visibility PurgeVisibilty
+        {
+            get { return _purgeVisibilty; }
+            set 
+            { 
+                _purgeVisibilty = value;
+                NotifyOfPropertyChange(nameof(PurgeVisibilty));
+            }
+        }
+
         private BufferRobotView _view;
         protected override void OnViewLoaded(object view)
         {
@@ -68,7 +85,40 @@ namespace FurnaceUI.Views.Maintenances
             _view = view as BufferRobotView;
             
             BufferAxisLimitSpeed = (double)QueryDataClient.Instance.Service.GetConfig($"BufferServo.BufferAxisLimitSpeed");
-
+           
+        }
+        protected override void OnActivate()
+        {
+            #region BufferPurge
+            var isEnable = (bool)QueryDataClient.Instance.Service.GetConfig("BufferPurge.IsEnable");
+            PurgeVisibilty = isEnable ? Visibility.Visible : Visibility.Collapsed;
+            if (isEnable)
+            {
+                List<string> keys = new List<string> { "BufferPurge.NameList", "BufferPurge.Operation", "BufferPurge.FinishCondition", "BufferPurge.OperationOrder" };
+                var dic = QueryDataClient.Instance.Service.PollConfig(keys);
+                string[] names = $"{dic["BufferPurge.NameList"]}".Split(';');
+                string[] operation = $"{dic["BufferPurge.Operation"]}".Split(';');
+                string[] sequence = $"{dic["BufferPurge.OperationOrder"]}".Split(';');
+                PurgeParameters = new ObservableCollection<PurgeParameter>();
+                foreach (string p in sequence)
+                {
+                    if (string.IsNullOrWhiteSpace(p)) continue;//Purge1,0,Time(10),Open;
+                    var step = p.Trim().Split(',');
+                    if (step.Length == 4)
+                    {
+                        if (string.IsNullOrEmpty(step[0])) continue;//name
+                        if (names.Contains(step[0]))
+                        {
+                            var index = step[2].IndexOf('(') + 1;
+                            int.TryParse(step[2].Substring(index, step[2].Length - index - 1), out int time);//仅考虑时间
+                            PurgeParameters.Add(
+                            new PurgeParameter() { Name = step[0], TimeString = $"{time / 3600:00}:{time % 3600 / 60:00}:{time % 60:00}", IsClose = step[3].ToLower() == "close", IsOpen = step[3].ToLower() == "open" });
+                        }
+                    }
+                }
+            }
+            #endregion
+            base.OnActivate();
         }
         private void InitData()
         {
@@ -161,5 +211,31 @@ namespace FurnaceUI.Views.Maintenances
         {
             InvokeClient.Instance.Service.DoOperation($"{target}.ServoResetAlarm");
         }
+
+        public void TimeEdit(PurgeParameter purge)
+        {
+            RecipeStepTimeViewModel recipeStepTimeViewModel = new RecipeStepTimeViewModel("ControlTime");
+            recipeStepTimeViewModel.SelectTime =purge.TimeString;
+            recipeStepTimeViewModel.SelectValueTime = purge.TimeString;
+            (IoC.Get<IWindowManager>() as WindowManager)?.ShowDialogWithTitle(recipeStepTimeViewModel, null, "Control Time Set");
+            if (recipeStepTimeViewModel.IsSave)
+            {
+                purge.TimeString = recipeStepTimeViewModel.SelectValueTime;
+            }
+        }
+        public void SetBufferPurge()
+        {
+            if (PurgeParameters?.Count > 0&&PurgeParameters.Any(r=>r.IsClose||r.IsOpen))
+            {
+                if(DialogBox.Confirm("Do you want to operating BufferPurge?"))
+                {
+                    InvokeClient.Instance.Service.DoOperation("PM1.SetBufferPurge", PurgeParameters.ToList());      
+                }
+            }
+            else
+            {
+                DialogBox.ShowWarning("No Parameter to Set!");
+            }
+        }
     }
 }