瀏覽代碼

revise reservoir UI, add start job PMCounter Check

chenzk 1 周之前
父節點
當前提交
5f835c9295

+ 16 - 16
CyberX8_MainPages/ViewModels/PMCounterViewModel.cs

@@ -248,22 +248,22 @@ namespace CyberX8_MainPages.ViewModels
                             MetalUsage metalUsage = CommonFunction.GetValue<MetalUsage>(tmpMetalUsage, $"{strMetals[i]}.MetalUsage");
                             if (metalUsage != null)
                             {
-                                double metalTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalAmpHoursWarningLimit"));
-                                double metalTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalAmpHoursFaultLimit"));
-                                double anodeATotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalAmpHoursWarningLimit"));
-                                double anodeATotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalAmpHoursFaultLimit"));
-                                double anodeBTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalAmpHoursWarningLimit"));
-                                double anodeBTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalAmpHoursFaultLimit"));
-                                double membraneATotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneATotalAmpHoursWarningLimit"));
-                                double membraneATotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneATotalAmpHoursFaultLimit"));
-                                double membraneBTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneBTotalAmpHoursWarningLimit"));
-                                double membraneBTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneBTotalAmpHoursFaultLimit"));
-                                int metalTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalWafersWarningLimit"));
-                                int metalTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalWafersFaultLimit"));
-                                int anodeATotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalWafersWarningLimit"));
-                                int anodeATotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalWafersFaultLimit"));
-                                int anodeBTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalWafersWarningLimit"));
-                                int anodeBTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalWafersFaultLimit"));
+                                double metalTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MetalTotalAmpHoursWarningLimit"));
+                                double metalTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MetalTotalAmpHoursFaultLimit"));
+                                double anodeATotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeATotalAmpHoursWarningLimit"));
+                                double anodeATotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeATotalAmpHoursFaultLimit"));
+                                double anodeBTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeBTotalAmpHoursWarningLimit"));
+                                double anodeBTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeBTotalAmpHoursFaultLimit"));
+                                double membraneATotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MembraneATotalAmpHoursWarningLimit"));
+                                double membraneATotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MembraneATotalAmpHoursFaultLimit"));
+                                double membraneBTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MembraneBTotalAmpHoursWarningLimit"));
+                                double membraneBTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MembraneBTotalAmpHoursFaultLimit"));
+                                int metalTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MetalTotalWafersWarningLimit"));
+                                int metalTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.MetalTotalWafersFaultLimit"));
+                                int anodeATotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeATotalWafersWarningLimit"));
+                                int anodeATotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeATotalWafersFaultLimit"));
+                                int anodeBTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeBTotalWafersWarningLimit"));
+                                int anodeBTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig($"Metal.{strMetals[i]}.AnodeBTotalWafersFaultLimit"));
                                 ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Total Usage(AHr)", Value = $"{metalUsage.TotalUsage}", FaultLimit = $"{metalTotalAmpHoursFaultLimit}", WarningLimit = $"{metalTotalAmpHoursWarningLimit}" });
                                 ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Anode A Usage(AHr)", Value = $"{metalUsage.AnodeAUsage}", FaultLimit = $"{anodeATotalAmpHoursFaultLimit}", WarningLimit = $"{anodeATotalAmpHoursWarningLimit}" });
                                 ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Anode B Usage(AHr)", Value = $"{metalUsage.AnodeBUsage}", FaultLimit = $"{anodeBTotalAmpHoursFaultLimit}", WarningLimit = $"{anodeBTotalAmpHoursWarningLimit}" });

+ 45 - 40
CyberX8_MainPages/Views/StandardHotReservoirsView.xaml

@@ -76,12 +76,12 @@
                 </Grid>
 
                 <Canvas Grid.Row="2" Grid.Column="1" Grid.RowSpan="3" Margin="-110 0 0 0">
-                    <Viewbox Stretch="Fill" Height="650" Width="480">
-                        <Image Width="440" Height="450" Source="pack://application:,,,/CyberX8_Themes;component/Themes/Images/parts/Clamp1.png"></Image>
+                    <Viewbox Stretch="Fill" Height="620" Width="480">
+                        <Image Width="440" Height="250" Source="pack://application:,,,/CyberX8_Themes;component/Themes/Images/parts/Clamp1.png"></Image>
                     </Viewbox>
-                    <Rectangle x:Name="ErrorRectangle" Fill="Red" Height="450" Width="440" VerticalAlignment="Center" Opacity="0.5" Panel.ZIndex="3"
-Visibility="{Binding IsError,Converter={StaticResource boolToVisibility2}}" Canvas.Left="20" Canvas.Top="105" HorizontalAlignment="Center"/>
-                    <userControls:Clamp MouseLeftButtonUp="ClickJumpMetalCommand" IsShowSignal="False" LabelValue="{Binding CellModuleNameCollection[0],Converter={StaticResource stringToString}}" Width="85" Height="508" Canvas.Top="-103" Canvas.Left="312" HorizontalAlignment="Center" VerticalAlignment="Top"/>
+                    <Rectangle x:Name="ErrorRectangle" Fill="Red" Height="441" Width="241" VerticalAlignment="Top" Opacity="0.5" Panel.ZIndex="3"
+Visibility="{Binding IsError,Converter={StaticResource boolToVisibility2}}" Canvas.Left="120" Canvas.Top="100" HorizontalAlignment="Center"/>
+                    <userControls:Clamp MouseLeftButtonUp="ClickJumpMetalCommand" IsShowSignal="False" LabelValue="{Binding CellModuleNameCollection[0],Converter={StaticResource stringToString}}" Width="86" Height="508" Canvas.Top="-90" Canvas.Left="197" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                 </Canvas>
                 <GroupBox Grid.Row="1" Grid.Column="2" Grid.RowSpan="4" Header="Recipe Settings"  BorderBrush="DarkGray" Padding="5" Margin="0,10,0,0" Height="510" VerticalAlignment="Top">
                     <Grid>
@@ -471,14 +471,14 @@ Visibility="{Binding IsError,Converter={StaticResource boolToVisibility2}}" Canv
             </Grid>
         </StackPanel>
         <Canvas Canvas.Left="210">
-            <ctrls:Pipe2    Canvas.Left="465"  Canvas.Top="220" RotateTransformValue="-180" HorizontalAlignment="Center" VerticalAlignment="Top" />
+            <ctrls:Pipe2    Canvas.Left="336"  Canvas.Top="206" RotateTransformValue="-180" HorizontalAlignment="Left" VerticalAlignment="Center" />
             <!--Cell2 Clamp-->
-            <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].WaferHolderClamp}" Height="8"  Width="30"  Canvas.Left="460"  Canvas.Top="212" RotateTransformValue="0" HorizontalAlignment="Center" VerticalAlignment="Top" />
-            <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].WaferHolderClamp}" Height="8"  Width="40"  Canvas.Left="460"  Canvas.Top="170" RotateTransformValue="90" HorizontalAlignment="Left" VerticalAlignment="Center" />
+            <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].WaferHolderClamp}" Height="8"  Width="30"  Canvas.Left="331"  Canvas.Top="198" RotateTransformValue="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
+            <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].WaferHolderClamp}" Height="8"  Width="40"  Canvas.Left="331"  Canvas.Top="156" RotateTransformValue="90" HorizontalAlignment="Left" VerticalAlignment="Center" />
             <customControls:CommonValveControl Status="{Binding MetalDataCollection[0].WaferHolderClamp}" IsEnabled="{Binding IsEnabled}"
-                                       Height="20" Width="20"  Canvas.Left="446"  Canvas.Top="182" ValveOrientation="Vertical"
-                                       ContextMenu="{StaticResource Cell0ClampValve}" IsCanEdit="True" Tag="26"/>
-            <TextBlock FontSize="14" Width="50" Canvas.Top="183" Canvas.Left="411" HorizontalAlignment="Left" VerticalAlignment="Center" Text="Clamp" RenderTransformOrigin="0.5,0.5">
+                                       Height="20" Width="20"  Canvas.Left="317"  Canvas.Top="168" ValveOrientation="Vertical"
+                                       ContextMenu="{StaticResource Cell0ClampValve}" IsCanEdit="True" Tag="26" HorizontalAlignment="Left" VerticalAlignment="Center"/>
+            <TextBlock FontSize="14" Width="50" Canvas.Top="169" Canvas.Left="282" HorizontalAlignment="Left" VerticalAlignment="Center" Text="Clamp" RenderTransformOrigin="0.5,0.5">
                 <TextBlock.RenderTransform>
                     <TransformGroup>
                         <ScaleTransform/>
@@ -550,59 +550,64 @@ Visibility="{Binding IsError,Converter={StaticResource boolToVisibility2}}" Canv
             <Button Grid.Row="1" Grid.Column ="2" IsEnabled="{Binding IsAutoEnabled}" Style="{StaticResource SysBtnStyle}" Command="{Binding ResPowerOnCommand}" Margin="0,0,0,0" Height="20" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center"  Content="ON"></Button>
             <Button Grid.Row="1" Grid.Column ="3" IsEnabled="{Binding IsAutoEnabled}" Style="{StaticResource SysBtnStyle}" Command="{Binding ResPowerOffCommand}" Margin="0,0,0,0" Height="20" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center"  Content="OFF"></Button>
         </Grid>
-        <ctrls:TextboxWithLabel TextBoxValue="{Binding MetalDataCollection[0].CellFlow,StringFormat=\{0:F1\} L/min}" Canvas.Top="533" Canvas.Left="613" LabelValue="Flow"  TextBoxColor="White" HorizontalAlignment="Center"  VerticalAlignment="Center"/>
-        <TextBlock FontSize="14" Width="70" Canvas.Top="406" Canvas.Left="102" HorizontalAlignment="Left" VerticalAlignment="Center" Text="DI Replen" RenderTransformOrigin="0.5,0.5"></TextBlock>
-        <TextBlock FontSize="14" Width="72" Canvas.Top="625" Canvas.Left="702" HorizontalAlignment="Left" VerticalAlignment="Top" Text="Circulation" RenderTransformOrigin="0.5,0.5"></TextBlock>
+        <ctrls:TextboxWithLabel TextBoxValue="{Binding MetalDataCollection[0].CellFlow,StringFormat=\{0:F1\} L/min}" Canvas.Top="445" Canvas.Left="125" LabelValue="Flow"  TextBoxColor="White" HorizontalAlignment="Center"  VerticalAlignment="Top"/>
+        <TextBlock FontSize="14" Width="70" Canvas.Top="396" Canvas.Left="102" HorizontalAlignment="Center" VerticalAlignment="Top" Text="DI Replen" RenderTransformOrigin="0.5,0.5"></TextBlock>
+        <TextBlock FontSize="14" Width="72" Canvas.Top="664" Canvas.Left="587" HorizontalAlignment="Left" VerticalAlignment="Top" Text="Circulation" RenderTransformOrigin="0.5,0.5"></TextBlock>
 
         <!--DIReplen pipe-->
-        <ctrls:FlowPipe IsFlowing="{Binding ReservoirData.DiReplen}" Height="8"  Width="281"  Canvas.Left="93"  Canvas.Top="431" RotateTransformValue="0" HorizontalAlignment="Center" VerticalAlignment="Top" />
+        <ctrls:FlowPipe IsFlowing="{Binding ReservoirData.DiReplen}" Height="8"  Width="390"  Canvas.Left="93"  Canvas.Top="421" RotateTransformValue="0" HorizontalAlignment="Center" VerticalAlignment="Top" />
         <!--Bypass flow pipe-->
-        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" Height="8"  Width="507"  Canvas.Left="94"  Canvas.Top="688" RotateTransformValue="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
+        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" Height="8"  Width="500"  Canvas.Left="88"  Canvas.Top="627" RotateTransformValue="0" HorizontalAlignment="Center" VerticalAlignment="Top" />
         <!--HED Flow pipe-->
-        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" Height="8"  Width="281"  Canvas.Left="93"  Canvas.Top="488" RotateTransformValue="0" HorizontalAlignment="Center" VerticalAlignment="Top" Loaded="FlowPipe_Loaded" />
-        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" IsReverse="True" Height="8"  Width="194"  Canvas.Left="90"  Canvas.Top="493" RotateTransformValue="90" HorizontalAlignment="Center" VerticalAlignment="Top" />
+        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" IsReverse="True" Height="8"  Width="390"  Canvas.Left="93"  Canvas.Top="488" RotateTransformValue="0" HorizontalAlignment="Center" VerticalAlignment="Top" Loaded="FlowPipe_Loaded" />
+        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" IsReverse="False" Height="8"  Width="130"  Canvas.Left="90"  Canvas.Top="493" RotateTransformValue="90" HorizontalAlignment="Center" VerticalAlignment="Top" />
 
         <!--Cell2 pump Flow pipe-->
-        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" Height="8"  Width="93"  Canvas.Left="602"  Canvas.Top="685" RotateTransformValue="-90" HorizontalAlignment="Center" VerticalAlignment="Top" />
-        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" Height="8"  Width="106"  Canvas.Left="613"  Canvas.Top="582" RotateTransformValue="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
         <!--Cell2 CellFlow pipe-->
-        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].Circulation}" Height="8"  Width="38"  Canvas.Left="721"  Canvas.Top="584" RotateTransformValue="-90" HorizontalAlignment="Center" VerticalAlignment="Top" />
+        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].Circulation}" Height="8"  Width="65"  Canvas.Left="606"  Canvas.Top="623" RotateTransformValue="-90" HorizontalAlignment="Left" VerticalAlignment="Top" />
         <!--Cell2 CellBypass pipe-->
-        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].Circulation,Converter={StaticResource boolToBool}}" Height="8"  Width="32"  Canvas.Left="721"  Canvas.Top="626" RotateTransformValue="-90" HorizontalAlignment="Center" VerticalAlignment="Top" IsReverse="True"/>
-        <userControls:Fan Width="45" Height="45" Canvas.Top="563" Canvas.Left="703" HorizontalAlignment="Left" VerticalAlignment="Center" 
+        <ctrls:FlowPipe IsFlowing="{Binding MetalDataCollection[0].Circulation,Converter={StaticResource boolToBool}}" Height="8"  Width="32"  Canvas.Left="606"  Canvas.Top="665" RotateTransformValue="-90" HorizontalAlignment="Left" VerticalAlignment="Top" IsReverse="True"/>
+        <userControls:Fan Width="45" Height="45" Canvas.Top="607" Canvas.Left="588" HorizontalAlignment="Center" VerticalAlignment="Top" 
                   ContextMenu="{StaticResource Cell0CirculationValve}"/>
 
-       
+
         <ctrls:Pipe2    Canvas.Left="82"  Canvas.Top="501" RotateTransformValue="-90" HorizontalAlignment="Center" VerticalAlignment="Top" />
-        <ctrls:Pipe2    Canvas.Left="95"  Canvas.Top="696" RotateTransformValue="-180" HorizontalAlignment="Center" VerticalAlignment="Top" />
-        <ctrls:Pipe2    Canvas.Left="610"  Canvas.Top="683" RotateTransformValue="90" HorizontalAlignment="Center" VerticalAlignment="Top" />
+        <ctrls:Pipe2    Canvas.Left="95"  Canvas.Top="635" RotateTransformValue="-180" HorizontalAlignment="Left" VerticalAlignment="Center" />
 
-        <customControls:CommonValveControl ValveOrientation="Horizontal" Height="20" Width="20"  Canvas.Left="125"  Canvas.Top="425" 
+        <customControls:CommonValveControl ValveOrientation="Horizontal" Height="20" Width="20"  Canvas.Left="125"  Canvas.Top="415" 
                                            ContextMenu="{StaticResource DIReplenValve}" Status="{Binding ReservoirData.DiReplen,Mode=TwoWay}" IsEnabled="{Binding IsEnabled}"
-                                           IsCanEdit="True" Tag="26" HorizontalAlignment="Left" VerticalAlignment="Center" 
+                                           IsCanEdit="True" Tag="26" HorizontalAlignment="Center" VerticalAlignment="Top" 
                                            />
 
 
         <Canvas Canvas.Left="250">
-            <ctrls:Pipe2    Canvas.Left="352"  Canvas.Top="595" RotateTransformValue="-90" HorizontalAlignment="Center" VerticalAlignment="Top" />
-            <userControls:PrewetTankControl Width="40" Height="70" Canvas.Top="581" Canvas.Left="384" HorizontalAlignment="Left" VerticalAlignment="Center"></userControls:PrewetTankControl>
-            <Rectangle Width="18" Height="38" Canvas.Left="395" Canvas.Top="608" HorizontalAlignment="Left" VerticalAlignment="Center" 
+            <userControls:PrewetTankControl Width="40" Height="70" Canvas.Top="487" Canvas.Left="-75" HorizontalAlignment="Left" VerticalAlignment="Top"></userControls:PrewetTankControl>
+            <Rectangle Width="18" Height="38" Canvas.Left="-64" Canvas.Top="514" HorizontalAlignment="Left" VerticalAlignment="Top" 
                        Visibility="{Binding MetalDataCollection[0].CellPump,Converter={StaticResource boolToVisibility2}}" Fill="Lime"/>
             <userControls:Pump1 IsEnabled="{Binding IsEnabled}" Name="pump2" ModuleName="{Binding CellModuleNameCollection[0]}" IsOpenPump="{Binding MetalDataCollection[0].CellPump,Mode=TwoWay}" 
                                  Visibility="{Binding CellModuleSignalPump[0],Converter={StaticResource boolToVisibility2}}"
-                                RotateTransformValue="-90" Height="60" Width="60"  Canvas.Left="304"  Canvas.Top="597" Tag="26" HorizontalAlignment="Left" VerticalAlignment="Center" />
+                                RotateTransformValue="270" Height="60" Width="60"  Canvas.Left="20"  Canvas.Top="439" Tag="26" HorizontalAlignment="Center" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" >
+                <userControls:Pump1.RenderTransform>
+                    <TransformGroup>
+                        <ScaleTransform/>
+                        <SkewTransform/>
+                        <RotateTransform Angle="90.186"/>
+                        <TranslateTransform/>
+                    </TransformGroup>
+                </userControls:Pump1.RenderTransform>
+            </userControls:Pump1>
             <userControls:ReservoirPump IsEnabled="{Binding IsEnabled}" ModuleName="{Binding Module}" PumpType="RegulatPump" IsOpenPump="{Binding ReservoirData.RegulatePumpSignalIn}" 
-                                        Visibility="{Binding IsRegulatePump,Converter={StaticResource boolToVisibility2}}" Height="60" Width="60" Canvas.Top="640" Tag="26" HorizontalAlignment="Left" VerticalAlignment="Top" />
-            <TextBlock FontSize="14" Width="120" Canvas.Top="620" Canvas.Left="-10" HorizontalAlignment="Center" VerticalAlignment="Top" Text="Reservoir Pump" RenderTransformOrigin="0.5,0.5"
+                                        Visibility="{Binding IsRegulatePump,Converter={StaticResource boolToVisibility2}}" Height="60" Width="60" Canvas.Top="439" Tag="26" HorizontalAlignment="Left" VerticalAlignment="Top" Canvas.Left="20" />
+            <TextBlock FontSize="14" Width="120" Canvas.Top="504" Canvas.Left="-10" HorizontalAlignment="Center" VerticalAlignment="Top" Text="Reservoir Pump" RenderTransformOrigin="0.5,0.5"
                        Visibility="{Binding IsRegulatePump,Converter={StaticResource boolToVisibility2}}"></TextBlock>
-            <TextBlock FontSize="14" Width="70" Canvas.Top="579" Canvas.Left="271" HorizontalAlignment="Center" VerticalAlignment="Top" Text="Cell Pump" RenderTransformOrigin="0.5,0.5"
+            <TextBlock FontSize="14" Width="70" Canvas.Top="504" Canvas.Left="15" HorizontalAlignment="Left" VerticalAlignment="Top" Text="Cell Pump" RenderTransformOrigin="0.5,0.5"
                        Visibility="{Binding CellModuleSignalPump[0],Converter={StaticResource boolToVisibility2}}"></TextBlock>
-            <Canvas Width="40" Height="20" Canvas.Left="350" Canvas.Top="615" HorizontalAlignment="Center" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" >
+            <Canvas Width="40" Height="20" Canvas.Left="-35" Canvas.Top="471" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" >
                 <Canvas.RenderTransform>
                     <TransformGroup>
                         <ScaleTransform/>
                         <SkewTransform/>
-                        <RotateTransform Angle="90"/>
+                        <RotateTransform Angle="-0.588"/>
                         <TranslateTransform/>
                     </TransformGroup>
                 </Canvas.RenderTransform>
@@ -610,7 +615,7 @@ Visibility="{Binding IsError,Converter={StaticResource boolToVisibility2}}" Canv
                 <Polygon Width="10" Points="0,10 20,0 20,20" Fill="Black" StrokeThickness="1" HorizontalAlignment="Left" VerticalAlignment="Center"></Polygon>
                 <Polygon Points="0,0 30,0 30,4 0,4" Fill="Black" StrokeThickness="1" Canvas.Left="10" Canvas.Top="8" HorizontalAlignment="Left" VerticalAlignment="Center"></Polygon>
             </Canvas>
-            <Canvas Width="40" Height="20" Canvas.Left="10" Canvas.Top="700" HorizontalAlignment="Center" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" >
+            <Canvas Width="40" Height="20" Canvas.Left="-134" Canvas.Top="630" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" >
                 <Canvas.RenderTransform>
                     <TransformGroup>
                         <ScaleTransform/>
@@ -624,8 +629,8 @@ Visibility="{Binding IsError,Converter={StaticResource boolToVisibility2}}" Canv
                 <Polygon Points="0,0 30,0 30,4 0,4" Fill="Black" StrokeThickness="1" Canvas.Left="10" Canvas.Top="8" HorizontalAlignment="Left" VerticalAlignment="Center"></Polygon>
             </Canvas>
         </Canvas>
-        <Canvas Width="150" Height="100" Canvas.Left="10" Canvas.Top="506" HorizontalAlignment="Center" VerticalAlignment="Top">
-            <userControls:TempControl MouseLeftButtonUp="ClickJumpTCCommand"  HorizontalAlignment="Center" Canvas.Top="18" VerticalAlignment="Top" 
+        <Canvas Width="150" Height="100" Canvas.Left="175" Canvas.Top="582" HorizontalAlignment="Left" VerticalAlignment="Top">
+            <userControls:TempControl MouseLeftButtonUp="ClickJumpTCCommand"  HorizontalAlignment="Left" VerticalAlignment="Top" 
                                       TempValue="{Binding TemperatureControlData.ReserviorTemperature}" ModuleName="{Binding TemperatureControlData.Name}"
                                       Status="{Binding TemperatureControlData.Status}" DisableStatus="{Binding TCEnableStatus}"/>
         </Canvas>

+ 1 - 26
CyberX8_RT/Devices/Reservoir/StandardHotReservoirDevice.cs

@@ -1939,31 +1939,6 @@ namespace CyberX8_RT.Devices.Reservoir
                 AlarmListManager.Instance.AddWarn(Module,
                    $"MembraneUsage", $"{Module} usage:{reservoirUsage.MembranceUsage} is over MembraneTotalAmpHoursWarningLimit:{membraneTotalAmpHoursWarningLimit}");
             }
-            //ANBathTotalAmpHoursCheck
-            //double anBathTotalAmpHoursWarningLimit = 0;
-            //if (SC.ContainsItem($"Reservoir.{Module}.ANBathTotalAmpHoursWarningLimit"))
-            //{
-            //    anBathTotalAmpHoursWarningLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.ANBathTotalAmpHoursWarningLimit");
-            //}
-            //double anBathTotalAmpHoursFaultLimit = 0;
-            //if (SC.ContainsItem($"Reservoir.{Module}.ANBathTotalAmpHoursFaultLimit"))
-            //{
-            //    anBathTotalAmpHoursFaultLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.ANBathTotalAmpHoursFaultLimit");
-            //}
-            //if (reservoirUsage.AnodeUsage > anBathTotalAmpHoursFaultLimit && anBathTotalAmpHoursFaultLimit != 0)
-            //{
-            //    LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} Anolyte Bath Usage(AHr):{reservoirUsage.AnodeUsage} is over config item ANBathTotalAmpHoursFaultLimit:{anBathTotalAmpHoursFaultLimit}");
-            //    reservoirEntity.PostMsg(ReservoirMsg.Error);
-            //    AlarmListManager.Instance.AddDataError(Module,
-            //        $"AnodeUsage", $"{Module} usage:{reservoirUsage.AnodeUsage} is over ANBathTotalAmpHoursFaultLimit:{anBathTotalAmpHoursFaultLimit}");
-            //}
-            //else if (reservoirUsage.AnodeUsage > anBathTotalAmpHoursWarningLimit && anBathTotalAmpHoursWarningLimit != 0)
-            //{
-            //    LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Anolyte Bath Usage(AHr):{reservoirUsage.AnodeUsage} is over config item ANBathTotalAmpHoursWarningLimit:{anBathTotalAmpHoursWarningLimit}");
-            //    AlarmListManager.Instance.AddWarn(Module,
-            //        $"AnodeUsage", $"{Module} usage:{reservoirUsage.AnodeUsage} is over ANBathTotalAmpHoursWarningLimit:{anBathTotalAmpHoursWarningLimit}");
-            //}
-            //BathTotalAmpHoursCheck
             double bathTotalAmpHoursWarningLimit = 0;
             if (SC.ContainsItem($"Reservoir.{Module}.BathTotalAmpHoursWarningLimit"))
             {
@@ -2007,7 +1982,7 @@ namespace CyberX8_RT.Devices.Reservoir
             }
             else if (reservoirUsage.BathUsageDays > bathTotalDaysWarningLimit && bathTotalDaysWarningLimit != 0)
             {
-                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Bath Usage(Days):{reservoirUsage.BathUsage} is over config item BathTotalDaysWarningLimit:{bathTotalDaysWarningLimit}");
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Bath Usage(Days):{reservoirUsage.BathUsageDays} is over config item BathTotalDaysWarningLimit:{bathTotalDaysWarningLimit}");
                 AlarmListManager.Instance.AddWarn(Module,
                     $"BathUsageDays", $"{Module} usage:{reservoirUsage.BathUsageDays} is over BathTotalDaysWarningLimit:{bathTotalDaysWarningLimit}");
             }

+ 329 - 1
CyberX8_RT/Modules/RouteManager.cs

@@ -40,6 +40,8 @@ using MECF.Framework.Common.Alarm;
 using System.Diagnostics;
 using MECF.Framework.Common.WaferHolder;
 using CyberX8_RT.Schedulers;
+using MECF.Framework.Common.ProcessCell;
+using System.Reflection;
 
 namespace CyberX8_RT.Modules
 {
@@ -968,9 +970,38 @@ namespace CyberX8_RT.Modules
 
         private bool FsmStartJob(object[] objs)
         {
+            bool result = CheckPMCounter();
+            if (!result)
+            {
+                return false;
+            }
             return _jobCycle.StartJob((string)objs[0],out string reason);
         }
-
+        /// <summary>
+        /// 检查PM counter
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckPMCounter()
+        {
+            bool result = false;
+            foreach (string item in ReservoirItemManager.Instance.InstalledModules)
+            {
+                result = ReservoirUsageMonitor(item);
+                if (!result)
+                {
+                    return false;
+                }
+            }
+            foreach (string item in MetalItemManager.Instance.InstalledModules)
+            {
+                result = MetalUsageMointor(item);
+                if (!result)
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
         private bool FsmPauseJob(object[] objs)
         {
             return _jobCycle.PauseJob((string)objs[0],out string reason);
@@ -1070,5 +1101,302 @@ namespace CyberX8_RT.Modules
         {
             return _modultTypeEntitiesDic.ContainsKey(type) ? _modultTypeEntitiesDic[type] : new List<IModuleEntity>();
         }
+
+        /// <summary>
+        /// 监控PM Counter Reservoir Usage
+        /// </summary>
+        public bool ReservoirUsageMonitor(string Module)
+        {
+            ReservoirUsage reservoirUsage = ReservoirUsageManager.Instance.GetReservoirUsage(Module);
+            ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(Module);
+            if (reservoirUsage == null || reservoirEntity == null) return true;
+            //reservoirTotalAmpHours Check
+            double reservoirTotalAmpHoursWarningLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.ReservoirTotalAmpHoursWarningLimit"))
+            {
+                reservoirTotalAmpHoursWarningLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.ReservoirTotalAmpHoursWarningLimit");
+            }
+            double reservoirTotalAmpHoursFaultLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.ReservoirTotalAmpHoursFaultLimit"))
+            {
+                reservoirTotalAmpHoursFaultLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.ReservoirTotalAmpHoursFaultLimit");
+            }
+            if (reservoirUsage.TotalUsage > reservoirTotalAmpHoursFaultLimit && reservoirTotalAmpHoursFaultLimit != 0)
+            {
+                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} Total Usage(AHr):{reservoirUsage.TotalUsage} is over config item ReservoirTotalAmpHoursFaultLimit:{reservoirTotalAmpHoursFaultLimit}");
+                return false;
+            }
+            else if (reservoirUsage.TotalUsage > reservoirTotalAmpHoursWarningLimit && reservoirTotalAmpHoursWarningLimit != 0)
+            {
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Total Usage(AHr):{reservoirUsage.TotalUsage} is over config item ReservoirTotalAmpHoursWarningLimit:{reservoirTotalAmpHoursWarningLimit}");
+            }
+            //MembraneTotalAmpHoursCheck
+            double membraneTotalAmpHoursWarningLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.MembraneTotalAmpHoursWarningLimit"))
+            {
+                membraneTotalAmpHoursWarningLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.MembraneTotalAmpHoursWarningLimit");
+            }
+            double membraneTotalAmpHoursFaultLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.MembraneTotalAmpHoursFaultLimit"))
+            {
+                membraneTotalAmpHoursFaultLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.MembraneTotalAmpHoursFaultLimit");
+            }
+            if (reservoirUsage.MembranceUsage > membraneTotalAmpHoursFaultLimit && membraneTotalAmpHoursFaultLimit != 0)
+            {
+                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} Membrane Usage(AHr):{reservoirUsage.MembranceUsage} is over config item MembraneTotalAmpHoursFaultLimit:{membraneTotalAmpHoursFaultLimit}");
+                return false;
+            }
+            else if (reservoirUsage.MembranceUsage > membraneTotalAmpHoursWarningLimit && membraneTotalAmpHoursWarningLimit != 0)
+            {
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Membrane Usage(AHr):{reservoirUsage.MembranceUsage} is over config item MembraneTotalAmpHoursWarningLimit:{membraneTotalAmpHoursWarningLimit}");
+            }
+            double bathTotalAmpHoursWarningLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.BathTotalAmpHoursWarningLimit"))
+            {
+                bathTotalAmpHoursWarningLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.BathTotalAmpHoursWarningLimit");
+            }
+            double bathTotalAmpHoursFaultLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.BathTotalAmpHoursFaultLimit"))
+            {
+                bathTotalAmpHoursFaultLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.BathTotalAmpHoursFaultLimit");
+            }
+            if (reservoirUsage.BathUsage > bathTotalAmpHoursFaultLimit && bathTotalAmpHoursFaultLimit != 0)
+            {
+                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} Bath Usage(AHr):{reservoirUsage.BathUsage} is over config item BathTotalAmpHoursFaultLimit:{bathTotalAmpHoursFaultLimit}");
+                return false;
+            }
+            else if (reservoirUsage.BathUsage > bathTotalAmpHoursWarningLimit && bathTotalAmpHoursWarningLimit != 0)
+            {
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Bath Usage(AHr):{reservoirUsage.BathUsage} is over config item BathTotalAmpHoursWarningLimit:{bathTotalAmpHoursWarningLimit}");
+            }
+            //BathTotalDaysCheck
+            int bathTotalDaysWarningLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.BathTotalDaysWarningLimit"))
+            {
+                bathTotalDaysWarningLimit = SC.GetValue<int>($"Reservoir.{Module}.BathTotalDaysWarningLimit");
+            }
+            int bathTotalDaysFaultLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.BathTotalDaysFaultLimit"))
+            {
+                bathTotalDaysFaultLimit = SC.GetValue<int>($"Reservoir.{Module}.BathTotalDaysFaultLimit");
+            }
+            if (reservoirUsage.BathUsageDays > bathTotalDaysFaultLimit && bathTotalDaysFaultLimit != 0)
+            {
+                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} Bath Usage(Days):{reservoirUsage.BathUsageDays} is over config item BathTotalDaysFaultLimit:{bathTotalDaysFaultLimit}");
+                return false;
+            }
+            else if (reservoirUsage.BathUsageDays > bathTotalDaysWarningLimit && bathTotalDaysWarningLimit != 0)
+            {
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Bath Usage(Days):{reservoirUsage.BathUsageDays} is over config item BathTotalDaysWarningLimit:{bathTotalDaysWarningLimit}");
+            }
+            //ReservoirTotalWafersCheck
+            int reservoirTotalWafersWarningLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.ReservoirTotalWafersWarningLimit"))
+            {
+                reservoirTotalWafersWarningLimit = SC.GetValue<int>($"Reservoir.{Module}.ReservoirTotalWafersWarningLimit");
+            }
+            int reservoirTotalWafersFaultLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.ReservoirTotalWafersFaultLimit"))
+            {
+                reservoirTotalWafersFaultLimit = SC.GetValue<int>($"Reservoir.{Module}.ReservoirTotalWafersFaultLimit");
+            }
+            if (reservoirUsage.TotalWafers > reservoirTotalWafersFaultLimit && reservoirTotalWafersFaultLimit != 0)
+            {
+                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} Total Wafers:{reservoirUsage.TotalWafers} is over config item ReservoirTotalWafersFaultLimit:{reservoirTotalWafersFaultLimit}");
+                return false;
+            }
+            else if (reservoirUsage.TotalWafers > reservoirTotalWafersWarningLimit && reservoirTotalWafersWarningLimit != 0)
+            {
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} Total Wafers:{reservoirUsage.TotalWafers} is over config item ReservoirTotalWafersWarningLimit:{reservoirTotalWafersWarningLimit}");
+            }
+            //CMMAnodeTotalAmpHoursCheck
+            double cmmAnodeTotalAmpHoursWarningLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.CMMAnodeTotalAmpHoursWarningLimit"))
+            {
+                cmmAnodeTotalAmpHoursWarningLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.CMMAnodeTotalAmpHoursWarningLimit");
+            }
+            double cmmAnodeTotalAmpHoursFaultLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.CMMAnodeTotalAmpHoursFaultLimit"))
+            {
+                cmmAnodeTotalAmpHoursFaultLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.CMMAnodeTotalAmpHoursFaultLimit");
+            }
+            if (reservoirUsage.CMMAnodeUsage > cmmAnodeTotalAmpHoursFaultLimit && cmmAnodeTotalAmpHoursFaultLimit != 0)
+            {
+                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} CMM Anode Usage(AHr):{reservoirUsage.CMMAnodeUsage} is over config item CMMAnodeTotalAmpHoursFaultLimit:{cmmAnodeTotalAmpHoursFaultLimit}");
+                return false;
+            }
+            else if (reservoirUsage.CMMAnodeUsage > cmmAnodeTotalAmpHoursWarningLimit && cmmAnodeTotalAmpHoursWarningLimit != 0)
+            {
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} CMM Anode Usage(AHr):{reservoirUsage.CMMAnodeUsage} is over config item CMMAnodeTotalAmpHoursWarningLimit:{cmmAnodeTotalAmpHoursWarningLimit}");
+            }
+            //CMMCathodeTotalAmpHoursCheck
+            double cmmCathodeTotalAmpHoursWarningLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.CMMCathodeTotalAmpHoursWarningLimit"))
+            {
+                cmmCathodeTotalAmpHoursWarningLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.CMMCathodeTotalAmpHoursWarningLimit");
+            }
+            double cmmCathodeTotalAmpHoursFaultLimit = 0;
+            if (SC.ContainsItem($"Reservoir.{Module}.CMMCathodeTotalAmpHoursFaultLimit"))
+            {
+                cmmCathodeTotalAmpHoursFaultLimit = (double)SC.GetValue<double>($"Reservoir.{Module}.CMMCathodeTotalAmpHoursFaultLimit");
+            }
+            if (reservoirUsage.CMMMembranceUsage > cmmCathodeTotalAmpHoursFaultLimit && cmmCathodeTotalAmpHoursFaultLimit != 0)
+            {
+                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, $"{Module} CMM Cathode Usage(AHr):{reservoirUsage.CMMMembranceUsage} is over config item CMMCathodeTotalAmpHoursFaultLimit:{cmmCathodeTotalAmpHoursFaultLimit}");
+                return false;
+            }
+            else if (reservoirUsage.CMMMembranceUsage > cmmCathodeTotalAmpHoursWarningLimit && cmmCathodeTotalAmpHoursWarningLimit != 0)
+            {
+                LOG.WriteLog(eEvent.WARN_RESERVOIR, Module, $"{Module} CMM Cathode Usage(AHr):{reservoirUsage.CMMMembranceUsage} is over config item CMMCathodeTotalAmpHoursWarningLimit:{cmmCathodeTotalAmpHoursWarningLimit}");
+            }
+            return true;
+        }
+        /// <summary>
+        /// 监控 PM Counter Metal用量
+        /// </summary>
+        private bool MetalUsageMointor(string Module)
+        {
+            MetalUsage metalUsage = MetalUsageManager.Instance.GetMetalUsage(Module);
+            if (metalUsage != null)
+            {
+                //TotalAUsage
+                if (metalUsage.TotalUsage > SC.GetValue<double>($"Metal.{Module}.MetalTotalAmpHoursWarningLimit") && SC.GetValue<double>($"Metal.{Module}.MetalTotalAmpHoursWarningLimit") != 0 && SC.GetValue<double>($"Metal.{Module}.MetalTotalAmpHoursFaultLimit") != 0)
+                {
+                    if (metalUsage.TotalUsage > SC.GetValue<double>($"Metal.{Module}.MetalTotalAmpHoursFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), $"{Module} usage:{metalUsage.TotalUsage} is exceed MetalTotalAmpHoursFaultLimit:{SC.GetValue<double>($"Metal.{Module}.MetalTotalAmpHoursFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module.ToString(), $"{Module} usage:{metalUsage.TotalUsage} is exceed MetalTotalAmpHoursWarningLimit:{SC.GetValue<double>($"Metal.{Module}.MetalTotalAmpHoursWarningLimit")}");
+                    }
+                }
+                //AnodeAUsage
+                if (metalUsage.AnodeAUsage > SC.GetValue<double>($"Metal.{Module}.AnodeATotalAmpHoursWarningLimit") && SC.GetValue<double>($"Metal.{Module}.AnodeATotalAmpHoursWarningLimit") != 0 && SC.GetValue<double>($"Metal.{Module}.AnodeATotalAmpHoursFaultLimit") != 0)
+                {
+                    if (metalUsage.AnodeAUsage > SC.GetValue<double>($"Metal.{Module}.AnodeATotalAmpHoursFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), $"{Module} usage:{metalUsage.AnodeAUsage} is exceed AnodeATotalAmpHoursFaultLimit:{SC.GetValue<double>($"Metal.{Module}.AnodeATotalAmpHoursFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.AnodeAUsage} is exceed AnodeATotalAmpHoursWarningLimit:{SC.GetValue<double>($"Metal.{Module}.AnodeATotalAmpHoursWarningLimit")}");
+                    }
+                }
+                //AnodeBUsage
+                if (metalUsage.AnodeBUsage > SC.GetValue<double>($"Metal.{Module}.AnodeBTotalAmpHoursWarningLimit") && SC.GetValue<double>($"Metal.{Module}.AnodeBTotalAmpHoursWarningLimit") != 0 && SC.GetValue<double>($"Metal.{Module}.AnodeBTotalAmpHoursFaultLimit") != 0)
+                {
+                    if (metalUsage.AnodeBUsage > SC.GetValue<double>($"Metal.{Module}.AnodeBTotalAmpHoursFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.AnodeBUsage} is exceed AnodeBTotalAmpHoursFaultLimit:{SC.GetValue<double>($"Metal.{Module}.AnodeBTotalAmpHoursFaultLimit")}");
+                        return false ;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.AnodeBUsage} is exceed AnodeBTotalAmpHoursWarningLimit:{SC.GetValue<double>($"Metal.{Module}.AnodeBTotalAmpHoursWarningLimit")}");
+                    }
+                }
+
+                //MembraneAUsage
+                if (metalUsage.MembranceAUsage > SC.GetValue<double>($"Metal.{Module}.MembraneATotalAmpHoursWarningLimit") && SC.GetValue<double>($"Metal.{Module}.MembraneATotalAmpHoursWarningLimit") != 0 && SC.GetValue<double>($"Metal.{Module}.MembraneATotalAmpHoursFaultLimit") != 0)
+                {
+                    if (metalUsage.MembranceAUsage > SC.GetValue<double>($"Metal.{Module}.MembraneATotalAmpHoursFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.MembranceAUsage} is exceed MembraneATotalAmpHoursFaultLimit:{SC.GetValue<double>($"Metal.{Module}.MembraneATotalAmpHoursFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.MembranceAUsage} is exceed MembraneATotalAmpHoursWarningLimit:{SC.GetValue<double>($"Metal.{Module}.MembraneATotalAmpHoursWarningLimit")}");
+                    }
+                }
+
+                //MembraneBUsage
+                if (metalUsage.MembranceBUsage > SC.GetValue<double>($"Metal.{Module}.MembraneBTotalAmpHoursWarningLimit") && SC.GetValue<double>($"Metal.{Module}.MembraneBTotalAmpHoursWarningLimit") != 0 && SC.GetValue<double>($"Metal.{Module}.MembraneBTotalAmpHoursFaultLimit") != 0)
+                {
+                    if (metalUsage.MembranceBUsage > SC.GetValue<double>($"Metal.{Module}.MembraneBTotalAmpHoursFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.MembranceBUsage} is exceed MembraneBTotalAmpHoursFaultLimit:{SC.GetValue<double>($"Metal.{Module}.MembraneBTotalAmpHoursFaultLimit")}");
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.MembranceBUsage} is exceed MembraneBTotalAmpHoursWarningLimit:{SC.GetValue<double>($"Metal.{Module}.MembraneBTotalAmpHoursWarningLimit")}");
+                    }
+                }
+
+                //TotalWafer
+                if (metalUsage.TotalWafers > SC.GetValue<int>($"Metal.{Module}.MetalTotalWafersWarningLimit") && SC.GetValue<int>($"Metal.{Module}.MetalTotalWafersWarningLimit") != 0 && SC.GetValue<int>($"Metal.{Module}.MetalTotalWafersFaultLimit") != 0)
+                {
+                    if (metalUsage.TotalWafers > SC.GetValue<int>($"Metal.{Module}.MetalTotalWafersFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.TotalWafers} is exceed MetalTotalWafersFaultLimit:{SC.GetValue<int>($"Metal.{Module}.MetalTotalWafersFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.TotalWafers} is exceed MetalTotalWafersWarningLimit:{SC.GetValue<int>($"Metal.{Module}.MetalTotalWafersWarningLimit")}");
+                    }
+                }
+
+                //AnodeAWafer
+                if (metalUsage.AnodeAWafers > SC.GetValue<int>($"Metal.{Module}.AnodeATotalWafersWarningLimit") && SC.GetValue<int>($"Metal.{Module}.AnodeATotalWafersWarningLimit") != 0 && SC.GetValue<int>($"Metal.{Module}.AnodeATotalWafersFaultLimit") != 0)
+                {
+                    if (metalUsage.AnodeAWafers > SC.GetValue<int>($"Metal.{Module}.AnodeATotalWafersFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.AnodeAWafers} is exceed AnodeATotalWafersFaultLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeATotalWafersFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.AnodeAWafers} is exceed AnodeATotalWafersWarningLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeATotalWafersWarningLimit")}");
+                    }
+                }
+
+                //AnodeBWafer
+                if (metalUsage.AnodeBWafers > SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersWarningLimit") && SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersWarningLimit") != 0 && SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersFaultLimit") != 0)
+                {
+                    if (metalUsage.AnodeBWafers > SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.AnodeBWafers} is exceed AnodeBTotalWafersFaultLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.AnodeBWafers} is exceed AnodeBTotalWafersWarningLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeBTotalWafersWarningLimit")}");
+                    }
+                }
+
+                //AnodeAbathUsage
+                if (metalUsage.AnodeABathUsage > SC.GetValue<int>($"Metal.{Module}.AnodeABathTotalUsageDaysWarningLimit") && SC.GetValue<int>($"Metal.{Module}.AnodeABathTotalUsageDaysWarningLimit") != 0 && SC.GetValue<int>($"Metal.{Module}.AnodeABathTotalUsageDaysFaultLimit") != 0)
+                {
+                    if (metalUsage.AnodeABathUsage > SC.GetValue<int>($"Metal.{Module}.AnodeABathTotalUsageDaysFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.AnodeABathUsage} is exceed AnodeABathTotalUsageDaysFaultLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeABathTotalUsageDaysFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.AnodeABathUsage} is exceed AnodeABathTotalUsageDaysWarningLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeABathTotalUsageDaysWarningLimit")}");
+                    }
+                }
+
+                //AnodeBbathUsage
+                if (metalUsage.AnodeBBathUsage > SC.GetValue<int>($"Metal.{Module}.AnodeBBathTotalUsageDaysWarningLimit") && SC.GetValue<int>($"Metal.{Module}.AnodeBBathTotalUsageDaysWarningLimit") != 0 && SC.GetValue<int>($"Metal.{Module}.AnodeBBathTotalUsageDaysFaultLimit") != 0)
+                {
+                    if (metalUsage.AnodeBBathUsage > SC.GetValue<int>($"Metal.{Module}.AnodeBBathTotalUsageDaysFaultLimit"))
+                    {
+                        LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} usage:{metalUsage.AnodeBBathUsage} is exceed AnodeBBathTotalUsageDaysFaultLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeBBathTotalUsageDaysFaultLimit")}");
+                        return false;
+                    }
+                    else
+                    {
+                        LOG.WriteLog(eEvent.WARN_METAL, Module, $"{Module} usage:{metalUsage.AnodeBBathUsage} is exceed AnodeBBathTotalUsageDaysWarningLimit:{SC.GetValue<int>($"Metal.{Module}.AnodeBBathTotalUsageDaysWarningLimit")}");
+                    }
+                }
+            }
+            return true;
+        }
     }
 }

+ 1 - 1
CyberX8_Themes/UserControls/Pump1.xaml

@@ -30,7 +30,7 @@
                                 <DoubleAnimation Storyboard.TargetProperty=
                                                  "RenderTransform.Children[0].Angle"
                                  Duration="0:0:1" BeginTime="0:0:0" 
-                                 From="0" To="360" />
+                                 From="0" To="-360" />
                             </Storyboard>
                         </BeginStoryboard>
                     </DataTrigger.EnterActions>

+ 36 - 36
CyberX8_UI/Config/UIMenu.json

@@ -55,23 +55,23 @@
 				"IsShow": "true",
 				"MenuItem": [
 					{
-						"Id": "Reservoir4",
-						"ModuleName": "Reservoir4",
-						"Name": "Reservoir4",
+						"Id": "Reservoir1",
+						"ModuleName": "Reservoir1",
+						"Name": "Reservoir1",
 						"IsShow": "true",
 						"MultiItem": [
 							{
-								"Id": "Reservoir4",
-								"ModuleName": "Reservoir4",
-								"Name": "Reservoir4",
+								"Id": "Reservoir1",
+								"ModuleName": "Reservoir1",
+								"Name": "Reservoir1",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "StandardHotReservoirsView"
 							},
 							{
-								"Id": "PMCounter4",
-								"ModuleName": "Reservoir4",
-								"Name": "Res4PMCt",
+								"Id": "PMCounter1",
+								"ModuleName": "Reservoir1",
+								"Name": "Res1PMCt",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "PMCounterView"
@@ -79,23 +79,23 @@
 						]
 					},
 					{
-						"Id": "Reservoir3",
-						"ModuleName": "Reservoir3",
-						"Name": "Reservoir3",
+						"Id": "Reservoir2",
+						"ModuleName": "Reservoir2",
+						"Name": "Reservoir2",
 						"IsShow": "true",
 						"MultiItem": [
 							{
-								"Id": "Reservoir3",
-								"ModuleName": "Reservoir3",
-								"Name": "Reservoir3",
+								"Id": "Reservoir2",
+								"ModuleName": "Reservoir2",
+								"Name": "Reservoir2",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "StandardHotReservoirsView"
 							},
 							{
-								"Id": "PMCounter3",
-								"ModuleName": "Reservoir3",
-								"Name": "Res3PMCt",
+								"Id": "PMCounter2",
+								"ModuleName": "Reservoir2",
+								"Name": "Res2PMCt",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "PMCounterView"
@@ -103,23 +103,23 @@
 						]
 					},
 					{
-						"Id": "Reservoir2",
-						"ModuleName": "Reservoir2",
-						"Name": "Reservoir2",
+						"Id": "Reservoir3",
+						"ModuleName": "Reservoir3",
+						"Name": "Reservoir3",
 						"IsShow": "true",
 						"MultiItem": [
 							{
-								"Id": "Reservoir2",
-								"ModuleName": "Reservoir2",
-								"Name": "Reservoir2",
+								"Id": "Reservoir3",
+								"ModuleName": "Reservoir3",
+								"Name": "Reservoir3",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "StandardHotReservoirsView"
 							},
 							{
-								"Id": "PMCounter2",
-								"ModuleName": "Reservoir2",
-								"Name": "Res2PMCt",
+								"Id": "PMCounter3",
+								"ModuleName": "Reservoir3",
+								"Name": "Res3PMCt",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "PMCounterView"
@@ -127,23 +127,23 @@
 						]
 					},
 					{
-						"Id": "Reservoir1",
-						"ModuleName": "Reservoir1",
-						"Name": "Reservoir1",
+						"Id": "Reservoir4",
+						"ModuleName": "Reservoir4",
+						"Name": "Reservoir4",
 						"IsShow": "true",
 						"MultiItem": [
 							{
-								"Id": "Reservoir1",
-								"ModuleName": "Reservoir1",
-								"Name": "Reservoir1",
+								"Id": "Reservoir4",
+								"ModuleName": "Reservoir4",
+								"Name": "Reservoir4",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "StandardHotReservoirsView"
 							},
 							{
-								"Id": "PMCounter1",
-								"ModuleName": "Reservoir1",
-								"Name": "Res1PMCt",
+								"Id": "PMCounter4",
+								"ModuleName": "Reservoir4",
+								"Name": "Res4PMCt",
 								"IsInit": "true",
 								"IsShow": "true",
 								"View": "PMCounterView"