Przeglądaj źródła

add vpwmain persistent

chenzk 15 godzin temu
rodzic
commit
fe78b81136

+ 8 - 0
Framework/Common/CommonData/Vpw/VpwMainCommonData.cs

@@ -33,6 +33,8 @@ namespace MECF.Framework.Common.CommonData.Vpw
         
         public bool BoosterPumpEnable { get { return _boosterPumpEnable; } set { _boosterPumpEnable = value;InvokePropertyChanged(nameof(BoosterPumpEnable)); } }
 
+
+
         /// <summary>
         /// pump状态内容
         /// </summary>
@@ -58,6 +60,11 @@ namespace MECF.Framework.Common.CommonData.Vpw
         /// Pump pressure数据
         /// </summary>
         public CommonLimitData BoosterPumpPressureData { get { return _boosterPumpPressureData; } set { _boosterPumpPressureData = value; InvokePropertyChanged(nameof(BoosterPumpPressureData)); } }
+        ///<summary>
+        /// 数据是否初始化
+        /// </summary>
+        public bool IsDataInitialized { get { return _isDataInitialized; } set { _isDataInitialized = value; InvokePropertyChanged(nameof(IsDataInitialized)); } }
+
 
 
         public bool DiwEnable { get { return _diwEnable; } set { _diwEnable = value;InvokePropertyChanged(nameof(DiwEnable)); } }
@@ -108,6 +115,7 @@ namespace MECF.Framework.Common.CommonData.Vpw
         private bool _degasAdjust;
         private bool _degasPurge;
         private bool _degasPumpEnable;
+        private bool _isDataInitialized;
         private double _degasPumpPressure;
         #endregion
     }

+ 12 - 10
Framework/Common/DataCenter/IQueryDataService.cs

@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Data;
-using System.ServiceModel;
-using Aitex.Core.Common;
+using Aitex.Core.Common;
 using Aitex.Core.Common.DeviceData;
 using Aitex.Core.RT.Event;
 using Aitex.Core.UI.ControlDataContext;
@@ -25,6 +19,7 @@ using MECF.Framework.Common.CommonData.Reservoir;
 using MECF.Framework.Common.CommonData.SRD;
 using MECF.Framework.Common.CommonData.TemperatureControl;
 using MECF.Framework.Common.CommonData.Transporter;
+using MECF.Framework.Common.CommonData.Vpw;
 using MECF.Framework.Common.ControlDataContext;
 using MECF.Framework.Common.DBCore;
 using MECF.Framework.Common.Device.LinMot;
@@ -42,14 +37,20 @@ using MECF.Framework.Common.Persistent.Reservoirs;
 using MECF.Framework.Common.Persistent.Rinse;
 using MECF.Framework.Common.Persistent.SRD;
 using MECF.Framework.Common.Persistent.Temperature;
+using MECF.Framework.Common.Persistent.VpwMain;
+using MECF.Framework.Common.ProcessCell;
+using MECF.Framework.Common.RecipeCenter;
 using MECF.Framework.Common.Schedulers;
 using MECF.Framework.Common.SubstrateTrackings;
 using MECF.Framework.Common.ToolLayout;
 using PunkHPX8_Core;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Data;
+using System.ServiceModel;
 using VenusCommon;
-using MECF.Framework.Common.RecipeCenter;
-using MECF.Framework.Common.ProcessCell;
-using MECF.Framework.Common.CommonData.Vpw;
 
 namespace MECF.Framework.Common.DataCenter
 {
@@ -167,6 +168,7 @@ namespace MECF.Framework.Common.DataCenter
 	[ServiceKnownType(typeof(PrewetPumpData))]
     [ServiceKnownType(typeof(VpwMainCommonData))]
     [ServiceKnownType(typeof(VpwCellCommonData))]
+    [ServiceKnownType(typeof(VpwMainPersistentValue))]
     [ServiceKnownType(typeof(PrewetPersistentValue))]
     [ServiceKnownType(typeof(SafetyData))]
     [ServiceKnownType(typeof(RinseData))]

+ 2 - 1
PunkHPX8_MainPages/ViewModels/VPWMainViewModel.cs

@@ -23,7 +23,7 @@ namespace PunkHPX8_MainPages.ViewModels
     public class VPWMainViewModel : BindableBase
     {
         #region 常量
-        private const string COMMONDATA = "CommonData1";
+        private const string COMMONDATA = "CommonData";
         private const string VPW = "vpw";
         private const string PERSISTENT_VALUE = "PersistentValue";
         #endregion
@@ -211,6 +211,7 @@ namespace PunkHPX8_MainPages.ViewModels
                 if (_rtDataValueDic != null)
                 {
                     VpwMainCommonData = CommonFunction.GetValue<VpwMainCommonData>(_rtDataValueDic, $"{Module}.{COMMONDATA}");
+                    VpwMainPersistent = CommonFunction.GetValue<VpwMainPersistentValue>(_rtDataValueDic, $"{Module}.{PERSISTENT_VALUE}");
                 }
             }
         }

+ 12 - 5
PunkHPX8_MainPages/Views/VPWMainView.xaml

@@ -52,7 +52,8 @@
         </Grid>
         <Grid Grid.Row="3" Grid.Column="0">
             <UserControls:VPWMainStateControl  Margin="5,20,0,0" ModuleName="{Binding Module}"
-                                               ChamberClose="{Binding VpwMainCommonData.ChamberClose}"
+                                               ChamberClose="{Binding VpwMainCommonData.ChamberClosed}"
+                                               ChamberOpen="{Binding VpwMainCommonData.ChamberOpened}"
                                                FluidInContainment="{Binding VpwMainCommonData.LeakDetected}"
                                                DIWInletValveOpen="{Binding VpwMainCommonData.DiwEnable}"
                                                WaterPressure="{Binding VpwMainCommonData.DiwPressure}"
@@ -91,18 +92,24 @@
 
 
         <Grid Grid.Row="1" Grid.Column="3" Margin="25,0,0,0">
-            <UserControls:OperatingModeControl Margin="0,50,0,0"></UserControls:OperatingModeControl>
+            <UserControls:OperatingModeControl Margin="0,50,0,0" ModuleName="{Binding Module}"
+                                              OperationModeValue="{Binding VpwMainPersistent.OperatingMode}"
+                                              IsManual="{Binding IsManualOperationMode,Mode=TwoWay}"
+                                               ></UserControls:OperatingModeControl>
         </Grid>
 
         <Grid Grid.Row="2" Grid.Column="3" Margin="25,0,0,0">
-            <UserControls:RecipeModeControl Margin="5,40,35,10"></UserControls:RecipeModeControl>
+            <UserControls:RecipeModeControl Margin="5,40,35,10"
+                                            ModuleName="{Binding Module}"
+                                            RecipeModeValue="{Binding VpwMainPersistent.RecipeOperatingMode}"
+                                            ></UserControls:RecipeModeControl>
         </Grid>
 
         <Grid Grid.Row="0" Grid.Column="3" Grid.RowSpan="2">
-            <Button Margin="0,0,0,140" IsEnabled="{Binding IsAutoEnabled}" Style="{StaticResource SysBtnStyle}" Height="30" Width="120" HorizontalAlignment="Center" Content="Initialize" Command="{Binding InitializeCommand}" />
+            <Button Margin="0,0,0,140" IsEnabled="True" Style="{StaticResource SysBtnStyle}" Height="30" Width="120" HorizontalAlignment="Center" Content="Initialize" Command="{Binding InitializeCommand}" />
         </Grid>
         <Grid Grid.Row="2" Grid.Column="3" Grid.RowSpan="2">
-            <Button Margin="0,0,0,80" IsEnabled="{Binding IsAutoEnabled}" Style="{StaticResource SysBtnStyle}" Height="30" Width="120" HorizontalAlignment="Center" Content="Home" Command="{Binding HomeCommand}" />
+            <Button Margin="0,0,0,80" IsEnabled="True" Style="{StaticResource SysBtnStyle}" Height="30" Width="120" HorizontalAlignment="Center" Content="Home" Command="{Binding HomeCommand}" />
         </Grid>
 
         <Label Grid.Row="1" Grid.Column="3" Margin="0,10,0,0" Content="Operating Mode"  FontSize="15" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Top" HorizontalAlignment="Center"></Label>

+ 1 - 1
PunkHPX8_RT/Config/Devices/Beckhoffcfg - plctask.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <BeckhoffCfg>
-	<Controller Name="MASTER" IPAddress="192.168.0.200.1.1" PortAddress="851">
+	<Controller Name="MASTER" IPAddress="10.4.6.75.1.1" PortAddress="851">
 
 		<!-- Need to have at least one input and one output before Axis stuff -->
 

+ 140 - 8
PunkHPX8_RT/Devices/VpwMain/VpwMainDevice.cs

@@ -10,6 +10,8 @@ using MECF.Framework.Common.CommonData.Vpw;
 using MECF.Framework.Common.IOCore;
 using MECF.Framework.Common.Persistent.Prewet;
 using MECF.Framework.Common.Persistent.VpwMain;
+using PunkHPX8_RT.Modules;
+using PunkHPX8_RT.Modules.VpwMain;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -22,8 +24,8 @@ namespace PunkHPX8_RT.Devices.VpwMain
     public class VpwMainDevice : BaseDevice, IDevice
     {
         #region 常量 
-        private const string COMMON_DATA = "CommonData1";
-        private const string PERSISTENT_VALUE = "CommonData";
+        private const string COMMON_DATA = "CommonData";
+        private const string PERSISTENT_VALUE = "PersistentValue";
         private const string CHAMBER_CLOSED = "ChamberClosed";
         private const string CHAMBER_OPENED = "ChamberOpened";
         private const string CHAMBER_CLOSE = "ChamberClose";
@@ -60,7 +62,7 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// <summary>
         /// 持久性数值
         /// </summary>
-        private VpwMainPersistentValue _persistentValue;
+        private VpwMainPersistentValue _vpwMainPersistentValue;
         /// <summary>
         /// 上一次Booster泵速
         /// </summary>
@@ -69,6 +71,8 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// 定时器任务
         /// </summary>
         private PeriodicJob _periodicJob;
+        
+        private bool _isDataInitialized;
         #endregion
 
         #region 属性
@@ -104,10 +108,10 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// </summary>
         private void InitializeParameter()
         {
-            _persistentValue = VpwMainPersistentManager.Instance.GetPersistentValue(Module);
-            if (_persistentValue != null)
+            _vpwMainPersistentValue = VpwMainPersistentManager.Instance.GetPersistentValue(Module);
+            if (_vpwMainPersistentValue != null)
             {
-                _lastBoosterPumpSpeed = _persistentValue.Speed;
+                _lastBoosterPumpSpeed = _vpwMainPersistentValue.Speed;
             }
             else
             {
@@ -127,7 +131,7 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// </summary>
         private void SubscribeData()
         {
-            DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => null, SubscriptionAttribute.FLAG.IgnoreSaveDB);
+            DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _vpwMainPersistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
             DATA.Subscribe($"{Module}.{COMMON_DATA}", () => CommonData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
         }
         /// <summary>
@@ -143,6 +147,7 @@ namespace PunkHPX8_RT.Devices.VpwMain
             IoSubscribeUpdateVariable(BOOSTER_PUMP_CURRENT);
             IoSubscribeUpdateVariable(DEGAS_PURGE);
             IoSubscribeUpdateVariable(DEGAS_ADJUST);
+            IoSubscribeUpdateVariable(DEGAS_PUMP_PRESSURE);
             IoSubscribeUpdateVariable(DEGAS_PUMP_ENABLE);
             IoSubscribeUpdateVariable(DIW_ENABLE);
             IoSubscribeUpdateVariable(DIW_PROCESS);
@@ -173,6 +178,11 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// <param name="value"></param>
         private void UpdateVariableValue(string variable, object value)
         {
+            if (!_commonData.IsDataInitialized)
+            {
+                _commonData.IsDataInitialized = true;
+                _commonData.BoosterPumpModel = "Manual";
+            }
             PropertyInfo property = _commonData.GetType().GetProperty(variable);
             if (property != null)
             {
@@ -226,6 +236,13 @@ namespace PunkHPX8_RT.Devices.VpwMain
             
             OP.Subscribe($"{Module}.BoosterPumpSpeedAuto", (cmd, para) => { return BoosterPumpSpeedAutoOperation(); });
             OP.Subscribe($"{Module}.BoosterPumpSpeedManual", (cmd, para) => { return BoosterPumpSpeedManualOperation(); });
+
+            OP.Subscribe($"{Module}.DisabledAction", DisabledOperation);
+            OP.Subscribe($"{Module}.ManualAction", ManualOperation);
+            OP.Subscribe($"{Module}.AutoAction", AutoOperation);
+            OP.Subscribe($"{Module}.EngineeringModeAction", EngineeringModeOperation);
+            OP.Subscribe($"{Module}.ProductionModeAction", ProductionModeOperation);
+
         }
         #endregion
 
@@ -387,7 +404,7 @@ namespace PunkHPX8_RT.Devices.VpwMain
             bool result = BoosterPumpSpeed(speed);
             if (result)
             {
-                _persistentValue.Speed = speed;
+                _vpwMainPersistentValue.Speed = speed;
                 _lastBoosterPumpSpeed = speed;
                 PrewetPersistentManager.Instance.UpdatePersistentValue(Module);
             }
@@ -440,6 +457,121 @@ namespace PunkHPX8_RT.Devices.VpwMain
             _commonData.BoosterPumpStatusContent = $"{_commonData.BoosterPumpModel}: {statusContent}";
             return true;
         }
+
+        /// <summary>
+        /// DisabledAction
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool DisabledOperation(string cmd, object[] args)
+        {
+            string currentOperation = "Disabled";
+            VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(Module);
+            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)
+            {
+                string preOperation = _vpwMainPersistentValue.OperatingMode;
+                if (vpwMainEntity.IsBusy)
+                {
+                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Disabled mode");
+                    return false;
+                }
+
+                vpwMainEntity.EnterInit();
+
+                _vpwMainPersistentValue.OperatingMode = currentOperation;
+
+                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
+            }
+            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
+            return true;
+        }
+        /// <summary>
+        /// ManualAction
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool ManualOperation(string cmd, object[] args)
+        {
+            string currentOperation = "Manual";
+            VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(Module);
+            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)
+            {
+                string preOperation = _vpwMainPersistentValue.OperatingMode;
+                if (vpwMainEntity.IsBusy)
+                {
+                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Manual mode");
+                    return false;
+                }
+                vpwMainEntity.EnterInit();
+                _vpwMainPersistentValue.OperatingMode = currentOperation;
+
+                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
+            }
+            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
+            return true;
+        }
+        /// <summary>
+        /// AutoAction
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool AutoOperation(string cmd, object[] args)
+        {
+            string currentOperation = "Auto";
+            VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(Module);
+            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)
+            {
+                string preOperation = _vpwMainPersistentValue.OperatingMode;
+                if (vpwMainEntity.IsBusy)
+                {
+                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Auto mode");
+                    return false;
+                }
+                vpwMainEntity.EnterInit();
+                _vpwMainPersistentValue.OperatingMode = currentOperation;
+
+                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
+            }
+
+            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
+            return true;
+        }
+        /// <summary>
+        /// EngineeringModeAction
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool EngineeringModeOperation(string cmd, object[] args)
+        {
+            string currentRecipeOperation = "Engineering";
+            if (_vpwMainPersistentValue != null)
+            {
+                _vpwMainPersistentValue.RecipeOperatingMode = currentRecipeOperation;
+            }
+            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
+            return true;
+        }
+        /// <summary>
+        /// ProductionAction
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool ProductionModeOperation(string cmd, object[] args)
+        {
+            string currentRecipeOperation = "Production";
+            if (_vpwMainPersistentValue != null)
+            {
+                _vpwMainPersistentValue.RecipeOperatingMode = currentRecipeOperation;
+            }
+            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
+            return true;
+        }
+
         #endregion
 
         /// <summary>

+ 14 - 0
PunkHPX8_RT/Modules/VpwMain/VpwMainEntity.cs

@@ -1,5 +1,7 @@
 using Aitex.Core.RT.Fsm;
+using Aitex.Core.RT.Log;
 using MECF.Framework.Common.Equipment;
+using PunkHPX8_Core;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -88,6 +90,18 @@ namespace PunkHPX8_RT.Modules.VpwMain
             return false;
         }
 
+        /// <summary>
+        /// EnterInit
+        /// </summary>
+        public void EnterInit()
+        {
+            //if ((VpwMainState)fsm.State != PrewetState.Idle) return;
+            //else
+            //{
+            //    CheckToPostMessage<PrewetState, PrewetMsg>(eEvent.ERR_PREWET, Module.ToString(), (int)PrewetMsg.Init);
+            //}
+        }
+
         public int Invoke(string function, params object[] args)
         {
             switch (function)

+ 0 - 1
PunkHPX8_RT/PunkHPX8_RT.csproj

@@ -242,7 +242,6 @@
     <Compile Include="Devices\SRD\SRDDeviceTimer.cs" />
     <Compile Include="Devices\SRD\TotalSRDDevice.cs" />
     <Compile Include="Devices\VpwCell\VpwCellDevice.cs" />
-    <Compile Include="Devices\VpwCell\VpwCellDeviceTimer.cs" />
     <Compile Include="Devices\VpwCell\VpwRotationAxisInterLock.cs" />
     <Compile Include="Devices\VpwMain\VpwMainDevice.cs" />
     <Compile Include="Modules\EFEM\CycleRobotCycleNewRoutine.cs" />

+ 7 - 0
PunkHPX8_Themes/PunkHPX8_Themes.csproj

@@ -483,6 +483,9 @@
     <Compile Include="UserControls\VPWBoosterPumpControl.xaml.cs">
       <DependentUpon>VPWBoosterPumpControl.xaml</DependentUpon>
     </Compile>
+    <Compile Include="UserControls\VPWCellStatusControl.xaml.cs">
+      <DependentUpon>VPWCellStatusControl.xaml</DependentUpon>
+    </Compile>
     <Compile Include="UserControls\VPWDegasControl.xaml.cs">
       <DependentUpon>VPWDegasControl.xaml</DependentUpon>
     </Compile>
@@ -1047,6 +1050,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="UserControls\VPWCellStatusControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="UserControls\VPWDegasControl.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 113 - 0
PunkHPX8_Themes/UserControls/VPWCellStatusControl.xaml

@@ -0,0 +1,113 @@
+<UserControl x:Class="PunkHPX8_Themes.UserControls.VPWCellStatusControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:converters="clr-namespace:PunkHPX8_Themes.Converters"
+             xmlns:UserControls="clr-namespace:PunkHPX8_Themes.UserControls"
+             xmlns:Control="clr-namespace:MECF.Framework.UI.Core.Control;assembly=MECF.Framework.UI.Core"
+             xmlns:local="clr-namespace:PunkHPX8_Themes.UserControls"
+             mc:Ignorable="d" x:Name="self"
+             d:DesignHeight="310" d:DesignWidth="420">
+    <UserControl.Resources>
+        <converters:BoolToYellowColor x:Key="boolToYellowColor"></converters:BoolToYellowColor>
+        <converters:BoolToColor x:Key="boolToColor"></converters:BoolToColor>
+        <converters:BoolToColor2 x:Key="boolToColor2"></converters:BoolToColor2>
+        <converters:BoolToColor6 x:Key="boolToColor6"></converters:BoolToColor6>
+        <converters:BoolToBool x:Key="boolToBool"></converters:BoolToBool>
+    </UserControl.Resources>
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="40"/>
+            <RowDefinition Height="40"/>
+            <RowDefinition Height="40"/>
+            <RowDefinition Height="40"/>
+            <RowDefinition Height="40"/>
+            <RowDefinition Height="40"/>
+            <RowDefinition Height="40"/>
+            <RowDefinition/>
+        </Grid.RowDefinitions>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="180"/>
+            <ColumnDefinition Width="30"/>
+            <ColumnDefinition Width="80"/>
+            <ColumnDefinition Width="80"/>
+            <ColumnDefinition Width="30"/>
+            <ColumnDefinition Width="60"/>
+            <ColumnDefinition/>
+        </Grid.ColumnDefinitions>
+        <Grid Grid.Row="0" Grid.Column="0">
+            <Label Content="Machine State" FontSize="15" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
+        </Grid>
+        <Grid Grid.Row="1" Grid.Column="0">
+            <Label Content="Wafer Size" FontSize="15" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
+        </Grid>
+        <Grid Grid.Row="2" Grid.Column="0">
+            <Label Content="Water Pressure" FontSize="15" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
+        </Grid>
+        <Grid Grid.Row="3" Grid.Column="0">
+            <Label Content="Pressure Target" FontSize="15" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
+        </Grid>
+        <Grid Grid.Row="5" Grid.Column="0">
+            <Label Content="Rotation" FontSize="15" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
+        </Grid>
+        <Grid Grid.Row="4" Grid.Column="0">
+            <Label Content="Chamber" FontSize="15" FontWeight="Bold" VerticalContentAlignment="Center" HorizontalContentAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
+        </Grid>
+        <Border Grid.Row="1" Grid.Column="1"  Grid.ColumnSpan="2" Margin="5,5,5,5" Background="Black" Width="50" VerticalAlignment="Center" HorizontalAlignment="Left">
+            <TextBlock  Text="{Binding ElementName=self,Path=WaferSize}" Foreground="Lime" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left"/>
+        </Border>
+        <Border Grid.Row="1" Grid.Column="2"  Grid.ColumnSpan="2" Margin="32,5,5,5" Background="Black" Height="22" Width="50" VerticalAlignment="Center" HorizontalAlignment="Left">
+            <TextBlock  Text="mm" Foreground="Lime" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left"/>
+        </Border>
+
+        <Grid Grid.Row="5" Grid.Column="2" >
+            <Button Style="{StaticResource SysBtnStyle}" Margin="0,0,0,0" Grid.Column="1" Height="25" Width="60" HorizontalAlignment="Center" Content="Start" Click="RotationStart_Click"></Button>
+        </Grid>
+        <Grid Grid.Row="5" Grid.Column="3" >
+            <Button Style="{StaticResource SysBtnStyle}" Margin="0,0,0,0" Grid.Column="1" Height="25" Width="60" HorizontalAlignment="Center" Content="Stop" Click="RotationStop_Click"></Button>
+        </Grid>
+
+        <Control:NumbericTextBox Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="15" FontWeight="Bold" Height="22" Width="50" Margin="5,0,5,0"
+                Value="{Binding ElementName=self,Path=InputRotationSpeed,Mode=TwoWay}"  
+                IsEnabled="True"/>
+        <TextBlock Grid.Row="6" Background="White"   Grid.Column="2" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center"  FontSize="15" FontWeight="Bold" Height="22" Width="40" Margin="-35,0,30,0" Text="rpm"/>
+
+        <Control:NumbericTextBox Grid.Row="6" Grid.Column="3" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="15" FontWeight="Bold" Height="22" Width="50" Margin="-7,0,5,0"
+          Value="{Binding ElementName=self,Path=InputRotationTime,Mode=TwoWay}"  
+          IsEnabled="True"/>
+        <TextBlock Grid.Row="6" Background="White"   Grid.Column="4" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center"  FontSize="15" FontWeight="Bold" Height="22" Width="40" Margin="-65,0,50,0" Text="sec"/>
+
+
+        <Grid Grid.Row="4" Grid.Column="1">
+            <Ellipse Grid.Column="1" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="Silver"
+    Fill="{Binding ChamberOpen, Converter={StaticResource boolToColor}, ElementName=self}"/>
+        </Grid>
+        <Grid Grid.Row="4" Grid.Column="2" >
+            <Button Style="{StaticResource SysBtnStyle}" Margin="0,0,0,0" Grid.Column="1" Height="25" Width="60" HorizontalAlignment="Center" Content="Open" Click="ChamberOpen_Click"></Button>
+        </Grid>
+        <Grid Grid.Row="4" Grid.Column="3" >
+            <Button Style="{StaticResource SysBtnStyle}" Margin="0,0,0,0" Grid.Column="1" Height="25" Width="60" HorizontalAlignment="Center" Content="Close" Click="ChamberClose_Click"></Button>
+        </Grid>
+        <Grid Grid.Row="4" Grid.Column="4">
+            <Ellipse Grid.Column="1" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="Silver"
+Fill="{Binding ChamberClose, Converter={StaticResource boolToColor}, ElementName=self}"/>
+        </Grid>
+
+        <Border Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="4" Margin="5,5,5,5" Background="Black">
+            <TextBlock  Text="{Binding ElementName=self,Path=MachineState}" Foreground="Lime" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left"/>
+        </Border>
+        <Border Grid.Row="2" Grid.Column="1"  Grid.ColumnSpan="2" Margin="5,5,5,5" Background="Black" Width="50" VerticalAlignment="Center" HorizontalAlignment="Left">
+            <TextBlock  Text="{Binding ElementName=self,Path=WaterPressure}" Foreground="Lime" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left"/>
+        </Border>
+        <Border Grid.Row="2" Grid.Column="2"  Grid.ColumnSpan="2" Margin="32,5,5,5" Background="Black" Height="22" Width="50" VerticalAlignment="Center" HorizontalAlignment="Left">
+            <TextBlock  Text="Psi" Foreground="Lime" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left"/>
+        </Border>
+        <Border Grid.Row="3" Grid.Column="1"  Grid.ColumnSpan="2" Margin="5,5,5,5" Background="Black" Width="50" VerticalAlignment="Center" HorizontalAlignment="Left">
+            <TextBlock  Text="{Binding ElementName=self,Path=PressureTarget}" Foreground="Lime" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left"/>
+        </Border>
+        <Border Grid.Row="3" Grid.Column="2"  Grid.ColumnSpan="2" Margin="32,5,5,5" Background="Black" Height="22" Width="50" VerticalAlignment="Center" HorizontalAlignment="Left">
+            <TextBlock  Text="Psi" Foreground="Lime" FontSize="16" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Left"/>
+        </Border>
+    </Grid>
+</UserControl>

+ 201 - 0
PunkHPX8_Themes/UserControls/VPWCellStatusControl.xaml.cs

@@ -0,0 +1,201 @@
+using MECF.Framework.Common.OperationCenter;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace PunkHPX8_Themes.UserControls
+{
+    /// <summary>
+    /// VPWCellStatusControl.xaml 的交互逻辑
+    /// </summary>
+    public partial class VPWCellStatusControl : UserControl
+    {
+        public VPWCellStatusControl()
+        {
+            InitializeComponent();
+        }
+
+        public static readonly DependencyProperty ModuleNameProperty = DependencyProperty.Register(
+         "ModuleName", typeof(string), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// 模块名称
+        /// </summary>
+        public string ModuleName
+        {
+            get
+            {
+                return (string)this.GetValue(ModuleNameProperty);
+            }
+            set
+            {
+                this.SetValue(ModuleNameProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty MachineStateProperty = DependencyProperty.Register(
+            "MachineState", typeof(string), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// MachineState
+        /// </summary>
+        public string MachineState
+        {
+            get
+            {
+                return (string)this.GetValue(MachineStateProperty);
+            }
+            set
+            {
+                this.SetValue(MachineStateProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty WaterPressureProperty = DependencyProperty.Register(
+            "WaterPressure", typeof(double), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// WaterPressure
+        /// </summary>
+        public double WaterPressure
+        {
+            get
+            {
+                return (double)this.GetValue(WaterPressureProperty);
+            }
+            set
+            {
+                this.SetValue(WaterPressureProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty PressureTargetProperty = DependencyProperty.Register(
+            "PressureTarget", typeof(double), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// PressureTarget
+        /// </summary>
+        public double PressureTarget
+        {
+            get
+            {
+                return (double)this.GetValue(PressureTargetProperty);
+            }
+            set
+            {
+                this.SetValue(PressureTargetProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty ChamberOpenProperty = DependencyProperty.Register(
+           "ChamberOpen", typeof(bool), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// ChamberOpen
+        /// </summary>
+        public bool ChamberOpen
+        {
+            get
+            {
+                return (bool)this.GetValue(ChamberOpenProperty);
+            }
+            set
+            {
+                this.SetValue(ChamberOpenProperty, value);
+            }
+        }
+        public static readonly DependencyProperty ChamberCloseProperty = DependencyProperty.Register(
+    "ChamberClose", typeof(bool), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// ChamberClose
+        /// </summary>
+        public bool ChamberClose
+        {
+            get
+            {
+                return (bool)this.GetValue(ChamberCloseProperty);
+            }
+            set
+            {
+                this.SetValue(ChamberCloseProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty InputRotationSpeedProperty = DependencyProperty.Register(
+            "InputRotationSpeed", typeof(double), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// InputRotationSpeed
+        /// </summary>
+        public double InputRotationSpeed
+        {
+            get
+            {
+                return (double)this.GetValue(InputRotationSpeedProperty);
+            }
+            set
+            {
+                this.SetValue(InputRotationSpeedProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty InputRotationTimeProperty = DependencyProperty.Register(
+           "InputRotationTime", typeof(double), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// InputRotationTime
+        /// </summary>
+        public double InputRotationTime
+        {
+            get
+            {
+                return (double)this.GetValue(InputRotationTimeProperty);
+            }
+            set
+            {
+                this.SetValue(InputRotationTimeProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty WaferSizeProperty = DependencyProperty.Register(
+    "WaferSize", typeof(int), typeof(VPWCellStatusControl), new FrameworkPropertyMetadata(200, FrameworkPropertyMetadataOptions.AffectsRender));
+        /// <summary>
+        /// WaferSize
+        /// </summary>
+        public int WaferSize
+        {
+            get
+            {
+                return (int)this.GetValue(WaferSizeProperty);
+            }
+            set
+            {
+                this.SetValue(WaferSizeProperty, value);
+            }
+        }
+
+        private void ChamberOpen_Click(object sender, RoutedEventArgs e)
+        {
+            InvokeClient.Instance.Service.DoOperation($"{ModuleName}.ChamberUp");
+        }
+
+        private void ChamberClose_Click(object sender, RoutedEventArgs e)
+        {
+            InvokeClient.Instance.Service.DoOperation($"{ModuleName}.ChamberDown");
+        }
+
+        private void RotationStart_Click(object sender, RoutedEventArgs e)
+        {
+
+        }
+
+        private void RotationStop_Click(object sender, RoutedEventArgs e)
+        {
+
+        }
+    }
+}

+ 1 - 1
PunkHPX8_Themes/UserControls/VPWMainStateControl.xaml

@@ -74,7 +74,7 @@
 
         <Grid Grid.Row="5" Grid.Column="1">
             <Ellipse Grid.Column="1" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="Silver"
-    Fill="{Binding ChamberClose, Converter={StaticResource boolToColor2}, ElementName=self}"/>
+    Fill="{Binding ChamberOpen, Converter={StaticResource boolToColor}, ElementName=self}"/>
         </Grid>
         <Grid Grid.Row="5" Grid.Column="2" >
             <Button Style="{StaticResource SysBtnStyle}" Margin="0,0,0,0" Grid.Column="1" Height="25" Width="60" HorizontalAlignment="Center" Content="Open" Click="ChamberOpen_Click"></Button>

+ 1 - 4
PunkHPX8_Themes/UserControls/VPWMainVacuumPumpControl.xaml

@@ -95,13 +95,10 @@
                         <Ellipse Grid.Column="1" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="Silver"
        Fill="{Binding PumpSpeedControlEnable, Converter={StaticResource boolToColor2}, ElementName=self}"/>
                     </Grid>
-
-
-
                     <Control:NumbericTextBox Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="15" FontWeight="Bold" Height="22" Width="50" Margin="5,0,5,0"
                         Value="{Binding ElementName=self,Path=InputPumpSpeed,Mode=TwoWay}"  
                         KeyOperation="{Binding ElementName=self,Path=KeyDownCommand}"
-                        IsEnabled="{Binding PumpSpeedControlEnable}"/>
+                        IsEnabled="{Binding PumpSpeedControlEnable,ElementName=self}"/>
                     <TextBlock Grid.Row="3" Background="White"   Grid.Column="2" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center"  FontSize="15" FontWeight="Bold" Height="22" Width="50" Margin="5,0,50,0" Text="V"/>
 
                     <Border Grid.Row="4" Grid.Column="1"  Grid.ColumnSpan="2" Margin="5,5,5,5" Background="Black" Width="50" VerticalAlignment="Center" HorizontalAlignment="Left">

+ 9 - 1
PunkHPX8_Themes/UserControls/VPWMainVacuumPumpControl.xaml.cs

@@ -153,7 +153,15 @@ namespace PunkHPX8_Themes.UserControls
             {
                 if (short.TryParse(param[1].ToString(), out short paramValue))
                 {
-                     InvokeClient.Instance.Service.DoOperation($"{ModuleName}.VacuumPumpSpeed", paramValue);  
+                    if (paramValue < 0 || paramValue > 10)
+                    {
+                        MessageBox.Show("qualified values 0 ~ 10", "Invalid Speed Input", MessageBoxButton.OK, MessageBoxImage.Error);
+                    }
+                    else
+                    {
+                        InvokeClient.Instance.Service.DoOperation($"{ModuleName}.VacuumPumpSpeed", paramValue);
+                    }
+                        
                 }
             }
         }