靻岇姢 瓴靸

宸ヤ笟椋庢牸UI浼樺寲 - SCADA/HMI娣辫壊涓婚銆佺瓑瀹藉瓧浣撱丩ED鐘舵佺伅

纾 鏇 1 欤 鞝
攵氇
旎る皨
49a52d13ed
4臧滌潣 氤瓴诫悳 韺岇澕609臧滌潣 於旉皜鞛戩梾 攴鸽Μ瓿 634臧滌潣 韺岇澕鞚 靷牅
  1. 35 79
      src/YZWater.Avalonia/Controls/StatusCard.cs
  2. 34 54
      src/YZWater.Avalonia/Views/MainWindow.axaml
  3. 419 168
      src/YZWater.Avalonia/Views/ViewAView.axaml
  4. 121 333
      src/YZWater.Core/ViewModels/ViewAViewModel.cs

+ 35 - 79
src/YZWater.Avalonia/Controls/StatusCard.cs

@@ -1,13 +1,12 @@
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Media;
-using System;
 using System.Globalization;
 
 namespace YZWater.Avalonia.Controls;
 
 /// <summary>
-/// 鐘舵佸崱鐗囨帶浠 - 鏄剧ず璁惧鐘舵佷俊鎭
+/// 鐘舵佸崱鐗囨帶浠 - 宸ヤ笟椋庢牸
 /// </summary>
 public class StatusCard : Control
 {
@@ -15,55 +14,26 @@ public class StatusCard : Control
         AvaloniaProperty.Register<StatusCard, string>(nameof(Title), "璁惧");
 
     public static readonly StyledProperty<string> StatusProperty =
-        AvaloniaProperty.Register<StatusCard, string>(nameof(Status), "杩愯涓");
+        AvaloniaProperty.Register<StatusCard, string>(nameof(Status), "RUNNING");
 
     public static readonly StyledProperty<string> IconProperty =
-        AvaloniaProperty.Register<StatusCard, string>(nameof(Icon), "鈿欙笍");
+        AvaloniaProperty.Register<StatusCard, string>(nameof(Icon), "P1");
 
     public static readonly StyledProperty<bool> IsActiveProperty =
         AvaloniaProperty.Register<StatusCard, bool>(nameof(IsActive), false);
 
     public static readonly StyledProperty<IBrush> ActiveColorProperty =
-        AvaloniaProperty.Register<StatusCard, IBrush>(nameof(ActiveColor), new SolidColorBrush(Color.Parse("#4CAF50")));
+        AvaloniaProperty.Register<StatusCard, IBrush>(nameof(ActiveColor), new SolidColorBrush(Color.Parse("#00897B")));
 
     public static readonly StyledProperty<IBrush> InactiveColorProperty =
-        AvaloniaProperty.Register<StatusCard, IBrush>(nameof(InactiveColor), new SolidColorBrush(Color.Parse("#607D8B")));
+        AvaloniaProperty.Register<StatusCard, IBrush>(nameof(InactiveColor), new SolidColorBrush(Color.Parse("#4B5563")));
 
-    public string Title
-    {
-        get => GetValue(TitleProperty);
-        set => SetValue(TitleProperty, value);
-    }
-
-    public string Status
-    {
-        get => GetValue(StatusProperty);
-        set => SetValue(StatusProperty, value);
-    }
-
-    public string Icon
-    {
-        get => GetValue(IconProperty);
-        set => SetValue(IconProperty, value);
-    }
-
-    public bool IsActive
-    {
-        get => GetValue(IsActiveProperty);
-        set => SetValue(IsActiveProperty, value);
-    }
-
-    public IBrush ActiveColor
-    {
-        get => GetValue(ActiveColorProperty);
-        set => SetValue(ActiveColorProperty, value);
-    }
-
-    public IBrush InactiveColor
-    {
-        get => GetValue(InactiveColorProperty);
-        set => SetValue(InactiveColorProperty, value);
-    }
+    public string Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); }
+    public string Status { get => GetValue(StatusProperty); set => SetValue(StatusProperty, value); }
+    public string Icon { get => GetValue(IconProperty); set => SetValue(IconProperty, value); }
+    public bool IsActive { get => GetValue(IsActiveProperty); set => SetValue(IsActiveProperty, value); }
+    public IBrush ActiveColor { get => GetValue(ActiveColorProperty); set => SetValue(ActiveColorProperty, value); }
+    public IBrush InactiveColor { get => GetValue(InactiveColorProperty); set => SetValue(InactiveColorProperty, value); }
 
     static StatusCard()
     {
@@ -76,61 +46,47 @@ public class StatusCard : Control
         base.Render(context);
 
         var bounds = new Rect(Bounds.Size);
-        var typeface = new Typeface("Microsoft YaHei");
         var statusColor = IsActive ? ActiveColor : InactiveColor;
         var statusBrush = statusColor as SolidColorBrush ?? new SolidColorBrush(Colors.Gray);
+        var monoTypeface = new Typeface("Consolas, monospace");
+        var labelTypeface = new Typeface("Microsoft YaHei");
 
-        // 缁樺埗鍗$墖鑳屾櫙
-        var cardBg = new SolidColorBrush(Color.Parse("#1E272E"));
-        var cardPen = new Pen(new SolidColorBrush(Color.Parse("#37474F")), 1);
-        context.DrawRectangle(cardBg, cardPen, new Rect(0, 0, bounds.Width, bounds.Height));
+        // 鍗$墖鑳屾櫙
+        context.DrawRectangle(new SolidColorBrush(Color.Parse("#0D1117")), null, bounds);
 
-        // 缁樺埗宸︿晶鐘舵佹潯
-        context.DrawRectangle(statusColor, null, new Rect(0, 0, 4, bounds.Height));
+        // 宸︿晶鐘舵佹潯
+        context.DrawRectangle(statusColor, null, new Rect(0, 0, 3, bounds.Height));
 
-        // 缁樺埗鐘舵佹寚绀虹伅
-        var indicatorSize = 10;
-        var indicatorX = 15;
-        var indicatorY = bounds.Height / 2 - indicatorSize / 2;
-
-        // 鎸囩ず鐏彂鍏夋晥鏋
+        // LED 鎸囩ず鐏
+        var ledX = 12.0;
+        var ledY = bounds.Height / 2 - 5;
         if (IsActive)
         {
             context.DrawEllipse(new SolidColorBrush(statusBrush.Color, 0.3), null,
-                new Rect(indicatorX - 3, indicatorY - 3, indicatorSize + 6, indicatorSize + 6));
+                new Rect(ledX - 3, ledY - 3, 16, 16));
         }
+        context.DrawEllipse(statusColor, null, new Rect(ledX, ledY, 10, 10));
 
-        context.DrawEllipse(statusColor, null,
-            new Rect(indicatorX, indicatorY, indicatorSize, indicatorSize));
+        // 鍥炬爣鏂囧瓧
+        var iconText = new FormattedText(Icon, CultureInfo.CurrentCulture,
+            FlowDirection.LeftToRight, monoTypeface, 11, new SolidColorBrush(Colors.White));
+        context.DrawText(iconText, new Point(28, 6));
 
-        // 缁樺埗鏍囬
+        // 鏍囬
         var titleText = new FormattedText(Title, CultureInfo.CurrentCulture,
-            FlowDirection.LeftToRight, new Typeface("Microsoft YaHei", FontStyle.Normal, FontWeight.Bold),
-            12, new SolidColorBrush(Colors.White));
-        context.DrawText(titleText, new Point(35, 8));
+            FlowDirection.LeftToRight, labelTypeface, 10, new SolidColorBrush(Color.Parse("#9CA3AF")));
+        context.DrawText(titleText, new Point(28, 22));
 
-        // 缁樺埗鐘舵佹枃鏈
+        // 鐘舵佹枃瀛
+        var statusTextColor = IsActive ? "#00897B" : "#6B7280";
         var statusText = new FormattedText(Status, CultureInfo.CurrentCulture,
-            FlowDirection.LeftToRight, typeface, 10, new SolidColorBrush(statusBrush.Color));
-        context.DrawText(statusText, new Point(35, 25));
-
-        // 缁樺埗鍒嗛殧绾
-        var separatorY = bounds.Height - 25;
-        context.DrawLine(new Pen(new SolidColorBrush(Color.Parse("#37474F")), 1),
-            new Point(10, separatorY), new Point(bounds.Width - 10, separatorY));
-
-        // 缁樺埗鍥炬爣
-        if (!string.IsNullOrEmpty(Icon))
-        {
-            var iconText = new FormattedText(Icon, CultureInfo.CurrentCulture,
-                FlowDirection.LeftToRight, new Typeface("Microsoft YaHei"), 20,
-                new SolidColorBrush(Colors.White));
-            context.DrawText(iconText, new Point(bounds.Width - 35, 10));
-        }
+            FlowDirection.LeftToRight, monoTypeface, 9,
+            new SolidColorBrush(Color.Parse(statusTextColor)));
+        context.DrawText(statusText, new Point(bounds.Width - statusText.Width - 10, bounds.Height / 2 - statusText.Height / 2));
     }
 
     protected override Size MeasureOverride(Size availableSize)
     {
-        return new Size(150, 60);
+        return new Size(230, 42);
     }
 }

+ 34 - 54
src/YZWater.Avalonia/Views/MainWindow.axaml

@@ -5,79 +5,59 @@
         xmlns:controls="using:YZWater.Avalonia.Controls"
         x:Class="YZWater.Avalonia.Views.MainWindow"
         x:DataType="vm:MainViewModel"
-        Title="{Binding Title}"
-        Width="1280"
-        Height="800"
-        MinWidth="800"
-        MinHeight="600"
+        Title="YZ WATER - 姹℃按澶勭悊鐩戞帶绯荤粺"
+        Width="1280" Height="800"
+        MinWidth="1024" MinHeight="700"
         WindowStartupLocation="CenterScreen"
-        Background="#1a1a2e">
+        Background="#0A0E14">
 
     <Window.DataContext>
         <vm:MainViewModel/>
     </Window.DataContext>
 
-    <!-- 浣跨敤鑷傚簲瀹瑰櫒鍖呰9鏁翠釜鍐呭 -->
     <controls:AdaptiveContainer DesignWidth="1280" DesignHeight="800"
-                                 Stretch="Uniform" MinScale="0.6" MaxScale="1.5">
+                                 Stretch="Uniform" MinScale="0.7" MaxScale="1.5">
         <DockPanel>
-            <!-- 椤堕儴鏍囬鏍 -->
-            <Border DockPanel.Dock="Top" Background="#1E3A5F" Padding="10">
-                <Grid ColumnDefinitions="Auto,*,Auto,Auto">
-                    <!-- Logo 鍜屾爣棰 -->
-                    <StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="10">
-                        <TextBlock Text="馃彮" FontSize="24" VerticalAlignment="Center"/>
-                        <TextBlock Text="{Binding Title}"
-                                   FontSize="20"
-                                   FontWeight="Bold"
-                                   Foreground="White"
-                                   VerticalAlignment="Center"/>
-                    </StackPanel>
-
-                    <!-- PLC 杩炴帴鐘舵 -->
-                    <StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="10" Margin="20,0">
-                        <Ellipse Width="12" Height="12" Fill="Green"/>
-                        <TextBlock Text="{Binding IsPlcConnected, StringFormat='PLC: {0}'}"
-                                   Foreground="White"
-                                   VerticalAlignment="Center"/>
-                    </StackPanel>
-
-                    <!-- 鏃堕棿鏄剧ず -->
-                    <TextBlock Grid.Column="3"
-                               Text="{Binding CurrentTime}"
-                               Foreground="White"
-                               FontSize="16"
-                               VerticalAlignment="Center"/>
-                </Grid>
-            </Border>
-
-            <!-- 搴曢儴瀵艰埅鏍 -->
-            <Border DockPanel.Dock="Bottom" Background="#2C5F8A" Padding="5">
-                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="20">
-                    <Button Content="馃搳 涓诲伐鑹" Command="{Binding ShowViewACommand}" Padding="15,8"/>
-                    <Button Content="鈿欙笍 鍙傛暟璁剧疆" Command="{Binding ShowViewBCommand}" Padding="15,8"/>
-                    <Button Content="馃搱 娴侀噺璁板綍" Command="{Binding ShowViewCCommand}" Padding="15,8"/>
-                    <Button Content="馃敂 鎶ヨ璁板綍" Command="{Binding ShowViewDCommand}" Padding="15,8"/>
-                    <Button Content="鈩癸笍 鍏充簬" Command="{Binding ShowViewECommand}" Padding="15,8"/>
+            <!-- 鈺愨晲鈺 搴曢儴瀵艰埅鏍 鈺愨晲鈺 -->
+            <Border DockPanel.Dock="Bottom" Background="#111820" BorderBrush="#1C2333" BorderThickness="0,1,0,0" Padding="4,0">
+                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="0">
+                    <Button Content="PROCESS" Command="{Binding ShowViewACommand}"
+                            FontFamily="Consolas, monospace" FontSize="11" Padding="20,8"
+                            Background="Transparent" Foreground="#00897B" BorderThickness="0"/>
+                    <Border Background="#1C2333" Width="1" Height="20" VerticalAlignment="Center"/>
+                    <Button Content="PARAMS" Command="{Binding ShowViewBCommand}"
+                            FontFamily="Consolas, monospace" FontSize="11" Padding="20,8"
+                            Background="Transparent" Foreground="#9CA3AF" BorderThickness="0"/>
+                    <Border Background="#1C2333" Width="1" Height="20" VerticalAlignment="Center"/>
+                    <Button Content="FLOW" Command="{Binding ShowViewCCommand}"
+                            FontFamily="Consolas, monospace" FontSize="11" Padding="20,8"
+                            Background="Transparent" Foreground="#9CA3AF" BorderThickness="0"/>
+                    <Border Background="#1C2333" Width="1" Height="20" VerticalAlignment="Center"/>
+                    <Button Content="ALARM" Command="{Binding ShowViewDCommand}"
+                            FontFamily="Consolas, monospace" FontSize="11" Padding="20,8"
+                            Background="Transparent" Foreground="#9CA3AF" BorderThickness="0"/>
+                    <Border Background="#1C2333" Width="1" Height="20" VerticalAlignment="Center"/>
+                    <Button Content="ABOUT" Command="{Binding ShowViewECommand}"
+                            FontFamily="Consolas, monospace" FontSize="11" Padding="20,8"
+                            Background="Transparent" Foreground="#9CA3AF" BorderThickness="0"/>
                 </StackPanel>
             </Border>
 
-            <!-- 涓诲唴瀹瑰尯鍩 -->
-            <TabControl SelectedIndex="{Binding SelectedTabIndex}" Padding="10"
-                        Background="Transparent">
-                <TabItem Header="涓诲伐鑹" IsVisible="False">
+            <!-- 鈺愨晲鈺 涓诲唴瀹瑰尯鍩 鈺愨晲鈺 -->
+            <TabControl SelectedIndex="{Binding SelectedTabIndex}" Background="#0A0E14">
+                <TabItem Header="PROCESS" IsVisible="False">
                     <views:ViewAView/>
                 </TabItem>
-                <TabItem Header="鍙傛暟璁剧疆" IsVisible="False">
+                <TabItem Header="PARAMS" IsVisible="False">
                     <views:ViewBView/>
                 </TabItem>
-                <TabItem Header="娴侀噺璁板綍" IsVisible="False">
+                <TabItem Header="FLOW" IsVisible="False">
                     <views:ViewCView/>
                 </TabItem>
-                <TabItem Header="鎶ヨ璁板綍" IsVisible="False">
+                <TabItem Header="ALARM" IsVisible="False">
                     <views:ViewDView/>
                 </TabItem>
-                <TabItem Header="鍏充簬" IsVisible="False">
+                <TabItem Header="ABOUT" IsVisible="False">
                     <views:ViewEView/>
                 </TabItem>
             </TabControl>

+ 419 - 168
src/YZWater.Avalonia/Views/ViewAView.axaml

@@ -9,236 +9,487 @@
         <vm:ViewAViewModel/>
     </UserControl.DataContext>
 
-    <Border Background="#0D1117" Width="1280" Height="800">
-        <Grid RowDefinitions="Auto,*,Auto" Margin="15">
-
-            <!-- 椤堕儴宸ュ叿鏍 -->
-            <Border Grid.Row="0" Background="#161B22" CornerRadius="8" Padding="12" Margin="0,0,0,10">
-                <Grid ColumnDefinitions="Auto,*,Auto,Auto">
-                    <!-- 宸︿晶鏍囬 -->
-                    <StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="10">
-                        <TextBlock Text="馃彮" FontSize="20" VerticalAlignment="Center"/>
-                        <StackPanel>
-                            <TextBlock Text="姹℃按澶勭悊鐩戞帶绯荤粺" FontWeight="Bold" FontSize="16" Foreground="White"/>
-                            <TextBlock Text="瀹炴椂宸ヨ壓娴佺▼" FontSize="11" Foreground="#8B949E"/>
-                        </StackPanel>
+    <!-- 宸ヤ笟娣辫壊鑳屾櫙 -->
+    <Border Background="#0A0E14" Width="1280" Height="800">
+        <Grid RowDefinitions="48,*,32" Margin="0">
+
+            <!-- 鈺愨晲鈺 椤堕儴鏍囬鏍 鈺愨晲鈺 -->
+            <Border Grid.Row="0" Background="#111820" BorderBrush="#1C2333" BorderThickness="0,0,0,1">
+                <Grid ColumnDefinitions="Auto,*,Auto,Auto,Auto" Margin="16,0">
+                    <!-- 绯荤粺鏍囬 -->
+                    <StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="12" VerticalAlignment="Center">
+                        <Border Background="#00897B" Width="4" Height="24" CornerRadius="2"/>
+                        <TextBlock Text="YZ WATER" FontSize="16" FontWeight="Bold"
+                                   Foreground="#E0E0E0" FontFamily="Consolas, monospace"
+                                   VerticalAlignment="Center"/>
+                        <TextBlock Text="姹℃按澶勭悊鐩戞帶绯荤粺" FontSize="13"
+                                   Foreground="#6B7280" VerticalAlignment="Center"/>
                     </StackPanel>
 
-                    <!-- 涓棿杩炴帴鐘舵 -->
-                    <StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="15" Margin="20,0">
-                        <Border Background="#238636" CornerRadius="12" Padding="10,5">
-                            <StackPanel Orientation="Horizontal" Spacing="5">
-                                <Ellipse Width="8" Height="8" Fill="White"/>
-                                <TextBlock Text="PLC 宸茶繛鎺" Foreground="White" FontSize="11"/>
-                            </StackPanel>
-                        </Border>
-                        <Button Content="杩炴帴" Command="{Binding ConnectPlcCommand}" Padding="12,4"/>
-                        <Button Content="鏂紑" Command="{Binding DisconnectPlcCommand}" Padding="12,4"/>
-                        <Button Content="鍒锋柊" Command="{Binding RefreshDataCommand}" Padding="12,4"/>
+                    <!-- PLC 杩炴帴鐘舵 LED -->
+                    <StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center" Margin="24,0">
+                        <Border Width="10" Height="10" CornerRadius="5" Background="#00897B"/>
+                        <TextBlock Text="PLC" FontFamily="Consolas, monospace" FontSize="11"
+                                   Foreground="#9CA3AF" VerticalAlignment="Center"/>
+                        <TextBlock Text="CONNECTED" FontFamily="Consolas, monospace" FontSize="11"
+                                   Foreground="#00897B" VerticalAlignment="Center"/>
+                    </StackPanel>
+
+                    <!-- 鎿嶄綔鎸夐挳 -->
+                    <StackPanel Grid.Column="3" Orientation="Horizontal" Spacing="4" VerticalAlignment="Center" Margin="16,0">
+                        <Button Content="CONNECT" Command="{Binding ConnectPlcCommand}"
+                                FontFamily="Consolas, monospace" FontSize="10" Padding="10,4"
+                                Background="#1C2333" Foreground="#00897B" BorderBrush="#00897B"/>
+                        <Button Content="DISCONNECT" Command="{Binding DisconnectPlcCommand}"
+                                FontFamily="Consolas, monospace" FontSize="10" Padding="10,4"
+                                Background="#1C2333" Foreground="#EF4444" BorderBrush="#EF4444"/>
+                        <Button Content="REFRESH" Command="{Binding RefreshDataCommand}"
+                                FontFamily="Consolas, monospace" FontSize="10" Padding="10,4"
+                                Background="#1C2333" Foreground="#3B82F6" BorderBrush="#3B82F6"/>
                     </StackPanel>
 
-                    <!-- 鍙充晶鏃堕棿 -->
-                    <StackPanel Grid.Column="3" VerticalAlignment="Center">
+                    <!-- 鏃堕挓 -->
+                    <StackPanel Grid.Column="4" VerticalAlignment="Center" HorizontalAlignment="Right">
                         <TextBlock Text="{Binding CurrentTime, StringFormat='{}{0:HH:mm:ss}'}"
-                                   FontSize="18" FontWeight="Bold" Foreground="#58A6FF"/>
+                                   FontFamily="Consolas, monospace" FontSize="18" FontWeight="Bold"
+                                   Foreground="#00897B"/>
                         <TextBlock Text="{Binding CurrentTime, StringFormat='{}{0:yyyy-MM-dd}'}"
-                                   FontSize="11" Foreground="#8B949E" HorizontalAlignment="Right"/>
+                                   FontFamily="Consolas, monospace" FontSize="10"
+                                   Foreground="#4B5563" HorizontalAlignment="Right"/>
                     </StackPanel>
                 </Grid>
             </Border>
 
-            <!-- 涓棿涓诲唴瀹瑰尯 -->
-            <Grid Grid.Row="1" ColumnDefinitions="*,280">
-
-                <!-- 宸︿晶宸ヨ壓娴佺▼鍥 -->
-                <Border Grid.Column="0" Background="#161B22" CornerRadius="8" Padding="10" Margin="0,0,10,0">
-                    <Canvas Width="900" Height="550">
-
-                        <!-- 姘寸缁 -->
-                        <StackPanel Orientation="Horizontal" Canvas.Left="20" Canvas.Top="20" Spacing="30">
-                            <!-- 鍏ュ彛姹 -->
-                            <StackPanel>
-                                <controls:WaterTankControl Width="120" Height="160"
-                                                           WaterLevel="{Binding Tank1Level}" Text="鍏ュ彛姹"
-                                                           WaterColor="#00BCD4"/>
-                                <TextBlock Text="{Binding Tank1Level, StringFormat='娑蹭綅: {0:F1}%'}"
-                                           Foreground="#8B949E" FontSize="11" HorizontalAlignment="Center" Margin="0,5,0,0"/>
-                            </StackPanel>
-
-                            <!-- 姹1 -->
-                            <StackPanel>
-                                <controls:WaterTankControl Width="120" Height="160"
-                                                           WaterLevel="{Binding Tank2Level}" Text="鐢熷寲姹"
-                                                           WaterColor="#26A69A"/>
-                                <TextBlock Text="{Binding Tank2Level, StringFormat='娑蹭綅: {0:F1}%'}"
-                                           Foreground="#8B949E" FontSize="11" HorizontalAlignment="Center" Margin="0,5,0,0"/>
-                            </StackPanel>
+            <!-- 鈺愨晲鈺 涓棿涓诲唴瀹瑰尯 鈺愨晲鈺 -->
+            <Grid Grid.Row="1" ColumnDefinitions="*,260" Margin="8,4">
 
-                            <!-- 姹2 -->
-                            <StackPanel>
-                                <controls:WaterTankControl Width="120" Height="160"
-                                                           WaterLevel="{Binding Tank3Level}" Text="娌夋穩姹"
-                                                           WaterColor="#42A5F5"/>
-                                <TextBlock Text="{Binding Tank3Level, StringFormat='娑蹭綅: {0:F1}%'}"
-                                           Foreground="#8B949E" FontSize="11" HorizontalAlignment="Center" Margin="0,5,0,0"/>
-                            </StackPanel>
+                <!-- 宸︿晶锛氬伐鑹烘祦绋嬪浘 -->
+                <Border Grid.Column="0" Background="#111820" CornerRadius="2" Margin="0,0,4,0"
+                        BorderBrush="#1C2333" BorderThickness="1">
+                    <Grid RowDefinitions="Auto,*,Auto" Margin="12,8">
 
-                            <!-- 鍑哄彛姹 -->
-                            <StackPanel>
-                                <controls:WaterTankControl Width="120" Height="160"
-                                                           WaterLevel="{Binding Tank4Level}" Text="鍑哄彛姹"
-                                                           WaterColor="#66BB6A"/>
-                                <TextBlock Text="{Binding Tank4Level, StringFormat='娑蹭綅: {0:F1}%'}"
-                                           Foreground="#8B949E" FontSize="11" HorizontalAlignment="Center" Margin="0,5,0,0"/>
-                            </StackPanel>
+                        <!-- 娴佺▼鍥炬爣棰 -->
+                        <StackPanel Grid.Row="0" Orientation="Horizontal" Spacing="8" Margin="0,0,0,8">
+                            <Border Background="#00897B" Width="3" Height="16" CornerRadius="1"/>
+                            <TextBlock Text="PROCESS FLOW" FontFamily="Consolas, monospace"
+                                       FontSize="12" FontWeight="Bold" Foreground="#9CA3AF"/>
                         </StackPanel>
 
-                        <!-- 绠¢亾杩炴帴 -->
-                        <controls:PipeLineControl Canvas.Left="20" Canvas.Top="200" Width="540" Height="25"
-                                                  IsFlow="{Binding IsInflowRunning}" IsHorizontal="True"/>
+                        <!-- 宸ヨ壓娴佺▼ Canvas -->
+                        <Border Grid.Row="1" Background="#0D1117" CornerRadius="2" Padding="8">
+                            <Canvas Width="900" Height="480">
 
-                        <!-- 闃闂ㄧ粍 -->
-                        <StackPanel Orientation="Horizontal" Canvas.Left="50" Canvas.Top="240" Spacing="80">
-                            <controls:ValveControl Width="40" Height="50" Status="{Binding Valve1Status}" Text="杩涙按"/>
-                            <controls:ValveControl Width="40" Height="50" Status="{Binding Valve2Status}" Text="鏇濇皵"/>
-                            <controls:ValveControl Width="40" Height="50" Status="{Binding Valve3Status}" Text="鍥炴祦"/>
-                            <controls:ValveControl Width="40" Height="50" Status="{Binding Valve4Status}" Text="鍑烘按"/>
-                        </StackPanel>
+                                <!-- 鈹鈹鈹 姘寸缁 鈹鈹鈹 -->
+                                <!-- 鍏ュ彛姹 -->
+                                <StackPanel Orientation="Vertical" Canvas.Left="30" Canvas.Top="20">
+                                    <controls:WaterTankControl Width="110" Height="140"
+                                                               WaterLevel="{Binding Tank1Level}" Text="鍏ュ彛姹"
+                                                               WaterColor="#00897B" BorderColor="#1C2333"/>
+                                    <Border Background="#1C2333" Padding="6,3" Margin="0,4,0,0">
+                                        <TextBlock Text="{Binding Tank1Level, StringFormat='LV: {0:F1}%'}"
+                                                   FontFamily="Consolas, monospace" FontSize="11"
+                                                   Foreground="#00897B" HorizontalAlignment="Center"/>
+                                    </Border>
+                                </StackPanel>
 
-                        <!-- 娉电粍 -->
-                        <StackPanel Orientation="Horizontal" Canvas.Left="30" Canvas.Top="310" Spacing="25">
-                            <controls:PumpControl Width="70" Height="80"
-                                                  IsRunning="{Binding Pump1Running}" Frequency="50" Text="杩涙按娉1"/>
-                            <controls:PumpControl Width="70" Height="80"
-                                                  IsRunning="{Binding Pump2Running}" Frequency="45" Text="杩涙按娉2"/>
-                            <controls:PumpControl Width="70" Height="80"
-                                                  IsRunning="{Binding Pump3Running}" Frequency="40" Text="鍥炴祦娉"/>
-                            <controls:PumpControl Width="70" Height="80"
-                                                  IsRunning="{Binding Pump4Running}" Frequency="35" Text="鎺掓偿娉"/>
-                            <controls:PumpControl Width="70" Height="80"
-                                                  IsRunning="{Binding Pump5Running}" Frequency="55" Text="鍔犺嵂娉"/>
-                        </StackPanel>
+                                <!-- 鐢熷寲姹 -->
+                                <StackPanel Orientation="Vertical" Canvas.Left="180" Canvas.Top="20">
+                                    <controls:WaterTankControl Width="110" Height="140"
+                                                               WaterLevel="{Binding Tank2Level}" Text="鐢熷寲姹"
+                                                               WaterColor="#0288D1" BorderColor="#1C2333"/>
+                                    <Border Background="#1C2333" Padding="6,3" Margin="0,4,0,0">
+                                        <TextBlock Text="{Binding Tank2Level, StringFormat='LV: {0:F1}%'}"
+                                                   FontFamily="Consolas, monospace" FontSize="11"
+                                                   Foreground="#0288D1" HorizontalAlignment="Center"/>
+                                    </Border>
+                                </StackPanel>
 
-                        <!-- 椋庢満缁 -->
-                        <StackPanel Orientation="Horizontal" Canvas.Left="120" Canvas.Top="410" Spacing="50">
-                            <controls:FanControl Width="50" Height="50" IsRunning="{Binding Fan1Running}" Speed="1" Text="椋庢満1"/>
-                            <controls:FanControl Width="50" Height="50" IsRunning="{Binding Fan2Running}" Speed="1.5" Text="椋庢満2"/>
-                        </StackPanel>
+                                <!-- 娌夋穩姹 -->
+                                <StackPanel Orientation="Vertical" Canvas.Left="330" Canvas.Top="20">
+                                    <controls:WaterTankControl Width="110" Height="140"
+                                                               WaterLevel="{Binding Tank3Level}" Text="娌夋穩姹"
+                                                               WaterColor="#7B1FA2" BorderColor="#1C2333"/>
+                                    <Border Background="#1C2333" Padding="6,3" Margin="0,4,0,0">
+                                        <TextBlock Text="{Binding Tank3Level, StringFormat='LV: {0:F1}%'}"
+                                                   FontFamily="Consolas, monospace" FontSize="11"
+                                                   Foreground="#7B1FA2" HorizontalAlignment="Center"/>
+                                    </Border>
+                                </StackPanel>
 
-                        <!-- 妯″紡鍒囨崲 -->
-                        <Border Canvas.Left="750" Canvas.Top="20" Width="120" Height="50"
-                                Background="#21262D" CornerRadius="8">
-                            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
-                                <TextBlock Text="杩愯妯″紡" FontSize="10" Foreground="#8B949E" HorizontalAlignment="Center"/>
-                                <controls:ValveControl Width="30" Height="30"
-                                                       Status="{Binding ModeStatus}" Text=""/>
-                            </StackPanel>
+                                <!-- 鍑哄彛姹 -->
+                                <StackPanel Orientation="Vertical" Canvas.Left="480" Canvas.Top="20">
+                                    <controls:WaterTankControl Width="110" Height="140"
+                                                               WaterLevel="{Binding Tank4Level}" Text="鍑哄彛姹"
+                                                               WaterColor="#2E7D32" BorderColor="#1C2333"/>
+                                    <Border Background="#1C2333" Padding="6,3" Margin="0,4,0,0">
+                                        <TextBlock Text="{Binding Tank4Level, StringFormat='LV: {0:F1}%'}"
+                                                   FontFamily="Consolas, monospace" FontSize="11"
+                                                   Foreground="#2E7D32" HorizontalAlignment="Center"/>
+                                    </Border>
+                                </StackPanel>
+
+                                <!-- 鈹鈹鈹 绠¢亾 鈹鈹鈹 -->
+                                <controls:PipeLineControl Canvas.Left="30" Canvas.Top="180" Width="560" Height="20"
+                                                          IsFlow="{Binding IsInflowRunning}" IsHorizontal="True"
+                                                          PipeColor="#1C2333" WaterColor="#00897B"/>
+
+                                <!-- 鈹鈹鈹 闃闂ㄧ粍 鈹鈹鈹 -->
+                                <controls:ValveControl Canvas.Left="60" Canvas.Top="215" Width="36" Height="44"
+                                                       Status="{Binding Valve1Status}" Text="V1"
+                                                       ValveColor="#F59E0B" BackgroundColor="#1C2333"/>
+                                <controls:ValveControl Canvas.Left="190" Canvas.Top="215" Width="36" Height="44"
+                                                       Status="{Binding Valve2Status}" Text="V2"
+                                                       ValveColor="#F59E0B" BackgroundColor="#1C2333"/>
+                                <controls:ValveControl Canvas.Left="320" Canvas.Top="215" Width="36" Height="44"
+                                                       Status="{Binding Valve3Status}" Text="V3"
+                                                       ValveColor="#F59E0B" BackgroundColor="#1C2333"/>
+                                <controls:ValveControl Canvas.Left="450" Canvas.Top="215" Width="36" Height="44"
+                                                       Status="{Binding Valve4Status}" Text="V4"
+                                                       ValveColor="#F59E0B" BackgroundColor="#1C2333"/>
+
+                                <!-- 鈹鈹鈹 娉电粍 鈹鈹鈹 -->
+                                <StackPanel Orientation="Horizontal" Canvas.Left="30" Canvas.Top="280" Spacing="20">
+                                    <StackPanel>
+                                        <controls:PumpControl Width="64" Height="72"
+                                                              IsRunning="{Binding Pump1Running}" Frequency="50" Text="P1"/>
+                                        <TextBlock Text="杩涙按娉1" FontFamily="Consolas, monospace" FontSize="9"
+                                                   Foreground="#6B7280" HorizontalAlignment="Center" Margin="0,2,0,0"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <controls:PumpControl Width="64" Height="72"
+                                                              IsRunning="{Binding Pump2Running}" Frequency="45" Text="P2"/>
+                                        <TextBlock Text="杩涙按娉2" FontFamily="Consolas, monospace" FontSize="9"
+                                                   Foreground="#6B7280" HorizontalAlignment="Center" Margin="0,2,0,0"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <controls:PumpControl Width="64" Height="72"
+                                                              IsRunning="{Binding Pump3Running}" Frequency="40" Text="P3"/>
+                                        <TextBlock Text="鍥炴祦娉" FontFamily="Consolas, monospace" FontSize="9"
+                                                   Foreground="#6B7280" HorizontalAlignment="Center" Margin="0,2,0,0"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <controls:PumpControl Width="64" Height="72"
+                                                              IsRunning="{Binding Pump4Running}" Frequency="35" Text="P4"/>
+                                        <TextBlock Text="鎺掓偿娉" FontFamily="Consolas, monospace" FontSize="9"
+                                                   Foreground="#6B7280" HorizontalAlignment="Center" Margin="0,2,0,0"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <controls:PumpControl Width="64" Height="72"
+                                                              IsRunning="{Binding Pump5Running}" Frequency="55" Text="P5"/>
+                                        <TextBlock Text="鍔犺嵂娉" FontFamily="Consolas, monospace" FontSize="9"
+                                                   Foreground="#6B7280" HorizontalAlignment="Center" Margin="0,2,0,0"/>
+                                    </StackPanel>
+                                </StackPanel>
+
+                                <!-- 鈹鈹鈹 椋庢満缁 鈹鈹鈹 -->
+                                <StackPanel Orientation="Horizontal" Canvas.Left="120" Canvas.Top="375" Spacing="40">
+                                    <StackPanel>
+                                        <controls:FanControl Width="44" Height="44"
+                                                              IsRunning="{Binding Fan1Running}" Speed="1" Text="F1"/>
+                                        <TextBlock Text="椋庢満1" FontFamily="Consolas, monospace" FontSize="9"
+                                                   Foreground="#6B7280" HorizontalAlignment="Center" Margin="0,2,0,0"/>
+                                    </StackPanel>
+                                    <StackPanel>
+                                        <controls:FanControl Width="44" Height="44"
+                                                              IsRunning="{Binding Fan2Running}" Speed="1.5" Text="F2"/>
+                                        <TextBlock Text="椋庢満2" FontFamily="Consolas, monospace" FontSize="9"
+                                                   Foreground="#6B7280" HorizontalAlignment="Center" Margin="0,2,0,0"/>
+                                    </StackPanel>
+                                </StackPanel>
+
+                                <!-- 鈹鈹鈹 娴佸悜绠ご 鈹鈹鈹 -->
+                                <TextBlock Text="鈫" Canvas.Left="145" Canvas.Top="75" FontSize="20" Foreground="#00897B"/>
+                                <TextBlock Text="鈫" Canvas.Left="295" Canvas.Top="75" FontSize="20" Foreground="#00897B"/>
+                                <TextBlock Text="鈫" Canvas.Left="445" Canvas.Top="75" FontSize="20" Foreground="#00897B"/>
+                                <TextBlock Text="鈫" Canvas.Left="595" Canvas.Top="75" FontSize="20" Foreground="#00897B"/>
+
+                                <!-- 鈹鈹鈹 妯″紡鍒囨崲 鈹鈹鈹 -->
+                                <Border Canvas.Left="700" Canvas.Top="20" Width="160" Height="80"
+                                        Background="#111820" BorderBrush="#1C2333" BorderThickness="1" CornerRadius="2">
+                                    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="6">
+                                        <TextBlock Text="MODE" FontFamily="Consolas, monospace"
+                                                   FontSize="10" Foreground="#6B7280" HorizontalAlignment="Center"/>
+                                        <controls:ValveControl Width="40" Height="40"
+                                                               Status="{Binding ModeStatus}" Text="AUTO"
+                                                               ValveColor="#00897B" BackgroundColor="#1C2333"/>
+                                    </StackPanel>
+                                </Border>
+
+                                <!-- 鈹鈹鈹 瀹炴椂鏁版嵁闈㈡澘 鈹鈹鈹 -->
+                                <Border Canvas.Left="700" Canvas.Top="110" Width="160" Height="180"
+                                        Background="#111820" BorderBrush="#1C2333" BorderThickness="1" CornerRadius="2">
+                                    <StackPanel Margin="10,8" Spacing="8">
+                                        <TextBlock Text="REALTIME" FontFamily="Consolas, monospace"
+                                                   FontSize="10" Foreground="#6B7280"/>
+
+                                        <StackPanel Spacing="2">
+                                            <TextBlock Text="INFLOW" FontFamily="Consolas, monospace" FontSize="9" Foreground="#4B5563"/>
+                                            <TextBlock FontFamily="Consolas, monospace" FontSize="16" FontWeight="Bold" Foreground="#00897B">
+                                                <Run Text="{Binding InflowRate, StringFormat='{}{0:F1}'}"/>
+                                                <Run Text=" m鲁/h" FontSize="10" Foreground="#6B7280"/>
+                                            </TextBlock>
+                                        </StackPanel>
+
+                                        <Border Background="#1C2333" Height="1"/>
+
+                                        <StackPanel Spacing="2">
+                                            <TextBlock Text="OUTFLOW" FontFamily="Consolas, monospace" FontSize="9" Foreground="#4B5563"/>
+                                            <TextBlock FontFamily="Consolas, monospace" FontSize="16" FontWeight="Bold" Foreground="#2E7D32">
+                                                <Run Text="{Binding OutflowRate, StringFormat='{}{0:F1}'}"/>
+                                                <Run Text=" m鲁/h" FontSize="10" Foreground="#6B7280"/>
+                                            </TextBlock>
+                                        </StackPanel>
+
+                                        <Border Background="#1C2333" Height="1"/>
+
+                                        <StackPanel Spacing="2">
+                                            <TextBlock Text="DELTA" FontFamily="Consolas, monospace" FontSize="9" Foreground="#4B5563"/>
+                                            <TextBlock FontFamily="Consolas, monospace" FontSize="14" Foreground="#F59E0B">
+                                                <Run Text="{Binding FlowDelta, StringFormat='{}{0:F1}'}"/>
+                                                <Run Text=" m鲁/h" FontSize="10" Foreground="#6B7280"/>
+                                            </TextBlock>
+                                        </StackPanel>
+                                    </StackPanel>
+                                </Border>
+
+                                <!-- 鈹鈹鈹 杩愯缁熻 鈹鈹鈹 -->
+                                <Border Canvas.Left="700" Canvas.Top="300" Width="160" Height="140"
+                                        Background="#111820" BorderBrush="#1C2333" BorderThickness="1" CornerRadius="2">
+                                    <StackPanel Margin="10,8" Spacing="6">
+                                        <TextBlock Text="STATISTICS" FontFamily="Consolas, monospace"
+                                                   FontSize="10" Foreground="#6B7280"/>
+
+                                        <Grid ColumnDefinitions="*,Auto">
+                                            <TextBlock Grid.Column="0" Text="RUNTIME" FontFamily="Consolas, monospace" FontSize="10" Foreground="#4B5563"/>
+                                            <TextBlock Grid.Column="1" Text="{Binding RunningTime}" FontFamily="Consolas, monospace" FontSize="10" Foreground="#9CA3AF"/>
+                                        </Grid>
+
+                                        <Grid ColumnDefinitions="*,Auto">
+                                            <TextBlock Grid.Column="0" Text="DEVICES" FontFamily="Consolas, monospace" FontSize="10" Foreground="#4B5563"/>
+                                            <TextBlock Grid.Column="1" Text="{Binding RunningDeviceCount, StringFormat='{}{0} ON'}" FontFamily="Consolas, monospace" FontSize="10" Foreground="#00897B"/>
+                                        </Grid>
+
+                                        <Grid ColumnDefinitions="*,Auto">
+                                            <TextBlock Grid.Column="0" Text="ALARMS" FontFamily="Consolas, monospace" FontSize="10" Foreground="#4B5563"/>
+                                            <TextBlock Grid.Column="1" Text="{Binding AlarmCount, StringFormat='{}{0}'}" FontFamily="Consolas, monospace" FontSize="10" Foreground="#EF4444"/>
+                                        </Grid>
+
+                                        <Border Background="#1C2333" Height="1"/>
+
+                                        <TextBlock Text="EFFICIENCY" FontFamily="Consolas, monospace" FontSize="10" Foreground="#4B5563"/>
+                                        <TextBlock FontFamily="Consolas, monospace" FontSize="18" FontWeight="Bold" Foreground="#00897B">
+                                            <Run Text="{Binding Efficiency, StringFormat='{}{0:F0}'}"/>
+                                            <Run Text="%" FontSize="12" Foreground="#6B7280"/>
+                                        </TextBlock>
+                                    </StackPanel>
+                                </Border>
+                            </Canvas>
                         </Border>
 
-                        <!-- 娴佺▼绠ご -->
-                        <Path Data="M 140 100 L 200 100" Stroke="#58A6FF" StrokeThickness="2">
-                            <Path.Data>
-                                <StreamGeometry>M 140 100 L 200 100</StreamGeometry>
-                            </Path.Data>
-                        </Path>
-                        <Path Data="M 320 100 L 380 100" Stroke="#58A6FF" StrokeThickness="2"/>
-                        <Path Data="M 500 100 L 560 100" Stroke="#58A6FF" StrokeThickness="2"/>
-                    </Canvas>
+                        <!-- 搴曢儴璁惧鐘舵佹潯 -->
+                        <Border Grid.Row="2" Background="#111820" CornerRadius="2" Margin="0,4,0,0" Padding="8,6">
+                            <StackPanel Orientation="Horizontal" Spacing="16">
+                                <!-- 璁惧 LED 鎸囩ず -->
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Pump1StatusColor}"/>
+                                    <TextBlock Text="P1" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Pump2StatusColor}"/>
+                                    <TextBlock Text="P2" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Pump3StatusColor}"/>
+                                    <TextBlock Text="P3" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Pump4StatusColor}"/>
+                                    <TextBlock Text="P4" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Pump5StatusColor}"/>
+                                    <TextBlock Text="P5" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+
+                                <Border Background="#1C2333" Width="1" Height="16"/>
+
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Fan1StatusColor}"/>
+                                    <TextBlock Text="F1" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Fan2StatusColor}"/>
+                                    <TextBlock Text="F2" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+
+                                <Border Background="#1C2333" Width="1" Height="16"/>
+
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Valve1StatusColor}"/>
+                                    <TextBlock Text="V1" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Valve2StatusColor}"/>
+                                    <TextBlock Text="V2" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Valve3StatusColor}"/>
+                                    <TextBlock Text="V3" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal" Spacing="4">
+                                    <Border Width="8" Height="8" CornerRadius="4"
+                                            Background="{Binding Valve4StatusColor}"/>
+                                    <TextBlock Text="V4" FontFamily="Consolas, monospace" FontSize="10" Foreground="#6B7280"/>
+                                </StackPanel>
+                            </StackPanel>
+                        </Border>
+                    </Grid>
                 </Border>
 
                 <!-- 鍙充晶闈㈡澘 -->
-                <Grid Grid.Column="1" RowDefinitions="Auto,Auto,Auto,*,Auto">
+                <Grid Grid.Column="1" RowDefinitions="Auto,Auto,*,Auto">
 
                     <!-- 娴侀噺浠〃 -->
-                    <Border Grid.Row="0" Background="#161B22" CornerRadius="8" Padding="10" Margin="0,0,0,10">
+                    <Border Grid.Row="0" Background="#111820" CornerRadius="2" Padding="10,8" Margin="0,0,0,4"
+                            BorderBrush="#1C2333" BorderThickness="1">
                         <StackPanel>
-                            <TextBlock Text="娴侀噺鐩戞祴" FontWeight="Bold" Foreground="White" Margin="0,0,0,10"/>
+                            <StackPanel Orientation="Horizontal" Spacing="6" Margin="0,0,0,8">
+                                <Border Background="#00897B" Width="3" Height="14" CornerRadius="1"/>
+                                <TextBlock Text="FLOW METERS" FontFamily="Consolas, monospace"
+                                           FontSize="11" Foreground="#9CA3AF"/>
+                            </StackPanel>
                             <Grid ColumnDefinitions="*,*">
-                                <controls:GaugeControl Grid.Column="0" Width="120" Height="140"
-                                                       Value="{Binding InflowRate}" Title="杩涙按" Unit="m鲁/h"
-                                                       MaxValue="100"/>
-                                <controls:GaugeControl Grid.Column="1" Width="120" Height="140"
-                                                       Value="{Binding OutflowRate}" Title="鍑烘按" Unit="m鲁/h"
-                                                       MaxValue="100"
-                                                       ValueColor="#66BB6A"/>
+                                <controls:GaugeControl Grid.Column="0" Width="110" Height="130"
+                                                       Value="{Binding InflowRate}" Title="IN" Unit="m鲁/h"
+                                                       MaxValue="100" ValueColor="#00897B"/>
+                                <controls:GaugeControl Grid.Column="1" Width="110" Height="130"
+                                                       Value="{Binding OutflowRate}" Title="OUT" Unit="m鲁/h"
+                                                       MaxValue="100" ValueColor="#2E7D32"/>
                             </Grid>
                         </StackPanel>
                     </Border>
 
                     <!-- 璁惧鐘舵 -->
-                    <Border Grid.Row="1" Background="#161B22" CornerRadius="8" Padding="10" Margin="0,0,0,10">
+                    <Border Grid.Row="1" Background="#111820" CornerRadius="2" Padding="10,8" Margin="0,0,0,4"
+                            BorderBrush="#1C2333" BorderThickness="1">
                         <StackPanel>
-                            <TextBlock Text="璁惧鐘舵" FontWeight="Bold" Foreground="White" Margin="0,0,0,10"/>
-                            <StackPanel Spacing="5">
-                                <controls:StatusCard Title="杩涙按娉1" Status="{Binding Pump1Status}" Icon="馃攧"
+                            <StackPanel Orientation="Horizontal" Spacing="6" Margin="0,0,0,8">
+                                <Border Background="#F59E0B" Width="3" Height="14" CornerRadius="1"/>
+                                <TextBlock Text="DEVICE STATUS" FontFamily="Consolas, monospace"
+                                           FontSize="11" Foreground="#9CA3AF"/>
+                            </StackPanel>
+                            <StackPanel Spacing="3">
+                                <controls:StatusCard Title="杩涙按娉1" Status="{Binding Pump1Status}" Icon="P1"
                                                      IsActive="{Binding Pump1Running}"/>
-                                <controls:StatusCard Title="杩涙按娉2" Status="{Binding Pump2Status}" Icon="馃攧"
+                                <controls:StatusCard Title="杩涙按娉2" Status="{Binding Pump2Status}" Icon="P2"
                                                      IsActive="{Binding Pump2Running}"/>
-                                <controls:StatusCard Title="鍥炴祦娉" Status="{Binding Pump3Status}" Icon="馃攧"
+                                <controls:StatusCard Title="鍥炴祦娉" Status="{Binding Pump3Status}" Icon="P3"
                                                      IsActive="{Binding Pump3Running}"/>
-                                <controls:StatusCard Title="椋庢満1" Status="{Binding Fan1Status}" Icon="馃寑"
+                                <controls:StatusCard Title="椋庢満1" Status="{Binding Fan1Status}" Icon="F1"
                                                      IsActive="{Binding Fan1Running}"/>
-                                <controls:StatusCard Title="椋庢満2" Status="{Binding Fan2Status}" Icon="馃寑"
+                                <controls:StatusCard Title="椋庢満2" Status="{Binding Fan2Status}" Icon="F2"
                                                      IsActive="{Binding Fan2Running}"/>
                             </StackPanel>
                         </StackPanel>
                     </Border>
 
-                    <!-- 鎶ヨ淇℃伅 -->
-                    <Border Grid.Row="2" Background="#161B22" CornerRadius="8" Padding="10" Margin="0,0,0,10"
+                    <!-- 鎶ヨ闈㈡澘 -->
+                    <Border Grid.Row="2" Background="#111820" CornerRadius="2" Padding="10,8" Margin="0,0,0,4"
+                            BorderBrush="#1C2333" BorderThickness="1"
                             IsVisible="{Binding HasAlarm}">
                         <StackPanel>
-                            <TextBlock Text="鈿狅笍 鎶ヨ淇℃伅" FontWeight="Bold" Foreground="#F85149" Margin="0,0,0,10"/>
-                            <Border Background="#F85149" CornerRadius="5" Padding="10">
-                                <TextBlock Text="{Binding AlarmMessage}" Foreground="White" TextWrapping="Wrap"/>
+                            <StackPanel Orientation="Horizontal" Spacing="6" Margin="0,0,0,8">
+                                <Border Background="#EF4444" Width="3" Height="14" CornerRadius="1"/>
+                                <TextBlock Text="ALARM" FontFamily="Consolas, monospace"
+                                           FontSize="11" Foreground="#EF4444"/>
+                                <TextBlock Text="{Binding AlarmCount, StringFormat='({0})'}"
+                                           FontFamily="Consolas, monospace" FontSize="11" Foreground="#EF4444"/>
+                            </StackPanel>
+                            <Border Background="#1C0000" BorderBrush="#EF4444" BorderThickness="1" Padding="8">
+                                <TextBlock Text="{Binding AlarmMessage}" Foreground="#EF4444"
+                                           FontFamily="Consolas, monospace" FontSize="11"
+                                           TextWrapping="Wrap"/>
                             </Border>
                         </StackPanel>
                     </Border>
 
                     <!-- 蹇嵎鎿嶄綔 -->
-                    <Border Grid.Row="4" Background="#161B22" CornerRadius="8" Padding="10">
+                    <Border Grid.Row="3" Background="#111820" CornerRadius="2" Padding="10,8"
+                            BorderBrush="#1C2333" BorderThickness="1">
                         <StackPanel>
-                            <TextBlock Text="蹇嵎鎿嶄綔" FontWeight="Bold" Foreground="White" Margin="0,0,0,10"/>
+                            <StackPanel Orientation="Horizontal" Spacing="6" Margin="0,0,0,8">
+                                <Border Background="#3B82F6" Width="3" Height="14" CornerRadius="1"/>
+                                <TextBlock Text="QUICK OPS" FontFamily="Consolas, monospace"
+                                           FontSize="11" Foreground="#9CA3AF"/>
+                            </StackPanel>
                             <WrapPanel HorizontalAlignment="Center">
-                                <Button Content="鍏ㄩ儴鍚姩" Margin="5" Padding="12,6"/>
-                                <Button Content="鍏ㄩ儴鍋滄" Margin="5" Padding="12,6"/>
-                                <Button Content="鎶ヨ纭" Margin="5" Padding="12,6"/>
-                                <Button Content="鏁版嵁瀵煎嚭" Margin="5" Padding="12,6"/>
+                                <Button Content="START ALL" Margin="3" Padding="10,5"
+                                        FontFamily="Consolas, monospace" FontSize="10"
+                                        Background="#1C2333" Foreground="#00897B" BorderBrush="#00897B"/>
+                                <Button Content="STOP ALL" Margin="3" Padding="10,5"
+                                        FontFamily="Consolas, monospace" FontSize="10"
+                                        Background="#1C2333" Foreground="#EF4444" BorderBrush="#EF4444"/>
+                                <Button Content="ACK ALARM" Margin="3" Padding="10,5"
+                                        FontFamily="Consolas, monospace" FontSize="10"
+                                        Background="#1C2333" Foreground="#F59E0B" BorderBrush="#F59E0B"/>
+                                <Button Content="EXPORT" Margin="3" Padding="10,5"
+                                        FontFamily="Consolas, monospace" FontSize="10"
+                                        Background="#1C2333" Foreground="#3B82F6" BorderBrush="#3B82F6"/>
                             </WrapPanel>
                         </StackPanel>
                     </Border>
                 </Grid>
             </Grid>
 
-            <!-- 搴曢儴鐘舵佹爮 -->
-            <Border Grid.Row="2" Background="#161B22" CornerRadius="8" Padding="12" Margin="0,10,0,0">
-                <Grid ColumnDefinitions="Auto,*,Auto,Auto,Auto">
-                    <StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="20">
-                        <TextBlock Foreground="#8B949E" FontSize="11">
-                            <Run Text="杩涙按: "/>
-                            <Run Text="{Binding InflowRate, StringFormat='{}{0:F1} m鲁/h'}" Foreground="#58A6FF"/>
-                        </TextBlock>
-                        <TextBlock Foreground="#8B949E" FontSize="11">
-                            <Run Text="鍑烘按: "/>
-                            <Run Text="{Binding OutflowRate, StringFormat='{}{0:F1} m鲁/h'}" Foreground="#66BB6A"/>
-                        </TextBlock>
-                    </StackPanel>
+            <!-- 鈺愨晲鈺 搴曢儴鐘舵佹爮 鈺愨晲鈺 -->
+            <Border Grid.Row="2" Background="#111820" BorderBrush="#1C2333" BorderThickness="0,1,0,0">
+                <Grid ColumnDefinitions="Auto,*,Auto,Auto,Auto,Auto" Margin="16,0">
+                    <TextBlock Grid.Column="0" VerticalAlignment="Center"
+                               FontFamily="Consolas, monospace" FontSize="11" Foreground="#4B5563">
+                        <Run Text="INFLOW: "/>
+                        <Run Text="{Binding InflowRate, StringFormat='{}{0:F1}'}" Foreground="#00897B"/>
+                        <Run Text=" m鲁/h"/>
+                    </TextBlock>
+
+                    <TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="24,0"
+                               FontFamily="Consolas, monospace" FontSize="11" Foreground="#4B5563">
+                        <Run Text="OUTFLOW: "/>
+                        <Run Text="{Binding OutflowRate, StringFormat='{}{0:F1}'}" Foreground="#2E7D32"/>
+                        <Run Text=" m鲁/h"/>
+                    </TextBlock>
+
+                    <TextBlock Grid.Column="2" VerticalAlignment="Center"
+                               FontFamily="Consolas, monospace" FontSize="11" Foreground="#4B5563">
+                        <Run Text="DEVICES: "/>
+                        <Run Text="{Binding RunningDeviceCount, StringFormat='{}{0}'}" Foreground="#00897B"/>
+                        <Run Text=" ACTIVE"/>
+                    </TextBlock>
 
-                    <TextBlock Grid.Column="2" Foreground="#8B949E" FontSize="11">
-                        <Run Text="杩愯璁惧: "/>
-                        <Run Text="{Binding RunningDeviceCount}" Foreground="#58A6FF"/>
-                        <Run Text=" 鍙"/>
+                    <TextBlock Grid.Column="3" VerticalAlignment="Center" Margin="24,0"
+                               FontFamily="Consolas, monospace" FontSize="11" Foreground="#4B5563">
+                        <Run Text="ALARM: "/>
+                        <Run Text="{Binding AlarmCount, StringFormat='{}{0}'}" Foreground="#EF4444"/>
                     </TextBlock>
 
-                    <TextBlock Grid.Column="3" Foreground="#8B949E" FontSize="11" Margin="20,0">
-                        <Run Text="鎶ヨ: "/>
-                        <Run Text="{Binding AlarmCount}" Foreground="#F85149"/>
-                        <Run Text=" 鏉"/>
+                    <TextBlock Grid.Column="4" VerticalAlignment="Center" Margin="24,0"
+                               FontFamily="Consolas, monospace" FontSize="11" Foreground="#4B5563">
+                        <Run Text="UPTIME: "/>
+                        <Run Text="{Binding RunningTime}" Foreground="#9CA3AF"/>
                     </TextBlock>
 
-                    <TextBlock Grid.Column="4" Foreground="#8B949E" FontSize="11">
-                        <Run Text="绯荤粺杩愯: "/>
-                        <Run Text="{Binding RunningTime}" Foreground="#58A6FF"/>
+                    <TextBlock Grid.Column="5" VerticalAlignment="Center"
+                               FontFamily="Consolas, monospace" FontSize="11" Foreground="#4B5563">
+                        <Run Text="v3.0.0"/>
                     </TextBlock>
                 </Grid>
             </Border>

+ 121 - 333
src/YZWater.Core/ViewModels/ViewAViewModel.cs

@@ -7,180 +7,121 @@ using YZWater.Core.Services;
 namespace YZWater.Core.ViewModels;
 
 /// <summary>
-/// 涓诲伐鑹鸿鍥 ViewModel锛浼樺寲鐗堬級
+/// 涓诲伐鑹鸿鍥 ViewModel锛宸ヤ笟椋庢牸鐗堬級
 /// </summary>
 public partial class ViewAViewModel : ObservableObject
 {
     private DateTime _startTime = DateTime.Now;
 
-    // 娑蹭綅鏁版嵁
-    [ObservableProperty]
-    private float _tank1Level = 65.5f;
-
-    [ObservableProperty]
-    private float _tank2Level = 72.3f;
-
-    [ObservableProperty]
-    private float _tank3Level = 58.8f;
-
-    [ObservableProperty]
-    private float _tank4Level = 45.2f;
-
-    // 娴侀噺鏁版嵁
-    [ObservableProperty]
-    private float _inflowRate = 35.6f;
-
-    [ObservableProperty]
-    private float _outflowRate = 32.1f;
-
-    // 娉电姸鎬
-    [ObservableProperty]
-    private bool _pump1Running = true;
-
-    [ObservableProperty]
-    private bool _pump2Running = false;
-
-    [ObservableProperty]
-    private bool _pump3Running = true;
-
-    [ObservableProperty]
-    private bool _pump4Running = false;
-
-    [ObservableProperty]
-    private bool _pump5Running = true;
-
-    // 椋庢墖鐘舵
-    [ObservableProperty]
-    private bool _fan1Running = true;
-
-    [ObservableProperty]
-    private bool _fan2Running = false;
-
-    // 璁惧鐘舵佹枃鏈
-    [ObservableProperty]
-    private string _pump1Status = "杩愯涓 - 50Hz";
-
-    [ObservableProperty]
-    private string _pump2Status = "宸插仠姝";
-
-    [ObservableProperty]
-    private string _pump3Status = "杩愯涓 - 40Hz";
-
-    [ObservableProperty]
-    private string _pump4Status = "宸插仠姝";
-
-    [ObservableProperty]
-    private string _pump5Status = "杩愯涓 - 55Hz";
-
-    [ObservableProperty]
-    private string _fan1Status = "杩愯涓 - 1500RPM";
-
-    [ObservableProperty]
-    private string _fan2Status = "宸插仠姝";
-
-    // 闃闂ㄧ姸鎬
-    [ObservableProperty]
-    private ValveStatus _valve1Status = ValveStatus.Open;
-
-    [ObservableProperty]
-    private ValveStatus _valve2Status = ValveStatus.Open;
-
-    [ObservableProperty]
-    private ValveStatus _valve3Status = ValveStatus.Middle;
-
-    [ObservableProperty]
-    private ValveStatus _valve4Status = ValveStatus.Closed;
-
-    // 妯″紡鐘舵
-    [ObservableProperty]
-    private ValveStatus _modeStatus = ValveStatus.Open;
-
-    // 娴佸姩鐘舵
-    [ObservableProperty]
-    private bool _isInflowRunning = true;
-
-    [ObservableProperty]
-    private bool _isOutflowRunning = true;
-
-    // 鎶ヨ鐘舵
-    [ObservableProperty]
-    private bool _hasAlarm = true;
-
-    [ObservableProperty]
-    private string _alarmMessage = "1鍙锋按姹犳恫浣嶆帴杩戦珮闄 (65.5%)";
-
-    [ObservableProperty]
-    private int _alarmCount = 1;
-
-    // 杩炴帴鐘舵
-    [ObservableProperty]
-    private bool _isPlcConnected = true;
-
-    // 璁惧璁℃暟
-    [ObservableProperty]
-    private int _runningDeviceCount = 5;
-
-    // 杩愯鏃堕棿
-    [ObservableProperty]
-    private string _runningTime = "0澶 2灏忔椂 35鍒";
-
-    // 褰撳墠鏃堕棿
-    [ObservableProperty]
-    private DateTime _currentTime = DateTime.Now;
+    // 鈹鈹鈹 娑蹭綅鏁版嵁 鈹鈹鈹
+    [ObservableProperty] private float _tank1Level = 65.5f;
+    [ObservableProperty] private float _tank2Level = 72.3f;
+    [ObservableProperty] private float _tank3Level = 58.8f;
+    [ObservableProperty] private float _tank4Level = 45.2f;
+
+    // 鈹鈹鈹 娴侀噺鏁版嵁 鈹鈹鈹
+    [ObservableProperty] private float _inflowRate = 35.6f;
+    [ObservableProperty] private float _outflowRate = 32.1f;
+    [ObservableProperty] private float _flowDelta = 3.5f;
+
+    // 鈹鈹鈹 娉电姸鎬 鈹鈹鈹
+    [ObservableProperty] private bool _pump1Running = true;
+    [ObservableProperty] private bool _pump2Running = false;
+    [ObservableProperty] private bool _pump3Running = true;
+    [ObservableProperty] private bool _pump4Running = false;
+    [ObservableProperty] private bool _pump5Running = true;
+
+    // 鈹鈹鈹 娉电姸鎬侀鑹 鈹鈹鈹
+    [ObservableProperty] private string _pump1StatusColor = "#00897B";
+    [ObservableProperty] private string _pump2StatusColor = "#4B5563";
+    [ObservableProperty] private string _pump3StatusColor = "#00897B";
+    [ObservableProperty] private string _pump4StatusColor = "#4B5563";
+    [ObservableProperty] private string _pump5StatusColor = "#00897B";
+
+    // 鈹鈹鈹 娉电姸鎬佹枃鏈 鈹鈹鈹
+    [ObservableProperty] private string _pump1Status = "RUNNING 50Hz";
+    [ObservableProperty] private string _pump2Status = "STOPPED";
+    [ObservableProperty] private string _pump3Status = "RUNNING 40Hz";
+    [ObservableProperty] private string _pump4Status = "STOPPED";
+    [ObservableProperty] private string _pump5Status = "RUNNING 55Hz";
+
+    // 鈹鈹鈹 椋庢墖鐘舵 鈹鈹鈹
+    [ObservableProperty] private bool _fan1Running = true;
+    [ObservableProperty] private bool _fan2Running = false;
+    [ObservableProperty] private string _fan1StatusColor = "#00897B";
+    [ObservableProperty] private string _fan2StatusColor = "#4B5563";
+    [ObservableProperty] private string _fan1Status = "RUNNING 1500RPM";
+    [ObservableProperty] private string _fan2Status = "STOPPED";
+
+    // 鈹鈹鈹 闃闂ㄧ姸鎬 鈹鈹鈹
+    [ObservableProperty] private ValveStatus _valve1Status = ValveStatus.Open;
+    [ObservableProperty] private ValveStatus _valve2Status = ValveStatus.Open;
+    [ObservableProperty] private ValveStatus _valve3Status = ValveStatus.Middle;
+    [ObservableProperty] private ValveStatus _valve4Status = ValveStatus.Closed;
+    [ObservableProperty] private string _valve1StatusColor = "#00897B";
+    [ObservableProperty] private string _valve2StatusColor = "#00897B";
+    [ObservableProperty] private string _valve3StatusColor = "#F59E0B";
+    [ObservableProperty] private string _valve4StatusColor = "#4B5563";
+
+    // 鈹鈹鈹 妯″紡 鈹鈹鈹
+    [ObservableProperty] private ValveStatus _modeStatus = ValveStatus.Open;
+
+    // 鈹鈹鈹 娴佸姩鐘舵 鈹鈹鈹
+    [ObservableProperty] private bool _isInflowRunning = true;
+    [ObservableProperty] private bool _isOutflowRunning = true;
+
+    // 鈹鈹鈹 鎶ヨ 鈹鈹鈹
+    [ObservableProperty] private bool _hasAlarm = true;
+    [ObservableProperty] private string _alarmMessage = "TANK1 LEVEL HIGH (65.5%)";
+    [ObservableProperty] private int _alarmCount = 1;
+
+    // 鈹鈹鈹 杩炴帴 鈹鈹鈹
+    [ObservableProperty] private bool _isPlcConnected = true;
+
+    // 鈹鈹鈹 缁熻 鈹鈹鈹
+    [ObservableProperty] private int _runningDeviceCount = 5;
+    [ObservableProperty] private string _runningTime = "0d 2h 35m";
+    [ObservableProperty] private double _efficiency = 92.5;
+
+    // 鈹鈹鈹 鏃堕棿 鈹鈹鈹
+    [ObservableProperty] private DateTime _currentTime = DateTime.Now;
 
     public ViewAViewModel()
     {
         StartTimers();
     }
 
-    /// <summary>
-    /// 鍚姩瀹氭椂鍣
-    /// </summary>
     private void StartTimers()
     {
-        // 鏃堕棿鏇存柊瀹氭椂鍣
         var timeTimer = new System.Timers.Timer(1000);
         timeTimer.Elapsed += (s, e) =>
         {
             CurrentTime = DateTime.Now;
             var elapsed = DateTime.Now - _startTime;
-            RunningTime = $"{elapsed.Days}澶 {elapsed.Hours}灏忔椂 {elapsed.Minutes}鍒";
+            RunningTime = $"{elapsed.Days}d {elapsed.Hours}h {elapsed.Minutes}m";
         };
         timeTimer.Start();
 
-        // 鏁版嵁妯℃嫙瀹氭椂鍣
         var dataTimer = new System.Timers.Timer(3000);
-        dataTimer.Elapsed += (s, e) =>
-        {
-            SimulateDataChanges();
-        };
+        dataTimer.Elapsed += (s, e) => SimulateDataChanges();
         dataTimer.Start();
     }
 
-    /// <summary>
-    /// 妯℃嫙鏁版嵁鍙樺寲
-    /// </summary>
     private void SimulateDataChanges()
     {
-        var random = new Random();
-
-        // 妯℃嫙娑蹭綅娉㈠姩
-        Tank1Level = Math.Max(0, Math.Min(100, Tank1Level + (float)(random.NextDouble() * 2 - 1)));
-        Tank2Level = Math.Max(0, Math.Min(100, Tank2Level + (float)(random.NextDouble() * 2 - 1)));
-        Tank3Level = Math.Max(0, Math.Min(100, Tank3Level + (float)(random.NextDouble() * 2 - 1)));
-        Tank4Level = Math.Max(0, Math.Min(100, Tank4Level + (float)(random.NextDouble() * 2 - 1)));
-
-        // 妯℃嫙娴侀噺娉㈠姩
-        InflowRate = Math.Max(0, InflowRate + (float)(random.NextDouble() * 4 - 2));
-        OutflowRate = Math.Max(0, OutflowRate + (float)(random.NextDouble() * 4 - 2));
-
-        // 妫鏌ユ姤璀
+        var r = new Random();
+        Tank1Level = Clamp(Tank1Level + (float)(r.NextDouble() * 2 - 1), 0, 100);
+        Tank2Level = Clamp(Tank2Level + (float)(r.NextDouble() * 2 - 1), 0, 100);
+        Tank3Level = Clamp(Tank3Level + (float)(r.NextDouble() * 2 - 1), 0, 100);
+        Tank4Level = Clamp(Tank4Level + (float)(r.NextDouble() * 2 - 1), 0, 100);
+        InflowRate = Math.Max(0, InflowRate + (float)(r.NextDouble() * 4 - 2));
+        OutflowRate = Math.Max(0, OutflowRate + (float)(r.NextDouble() * 4 - 2));
+        FlowDelta = InflowRate - OutflowRate;
+        Efficiency = 85 + r.NextDouble() * 10;
         CheckAlarms();
+        UpdateDeviceStatuses();
     }
 
-    /// <summary>
-    /// 妫鏌ユ姤璀︽潯浠
-    /// </summary>
     private void CheckAlarms()
     {
         var config = ConfigService.GetConfig();
@@ -193,85 +134,69 @@ public partial class ViewAViewModel : ObservableObject
         if (Tank1Level > config.LevelHighAlarm)
         {
             HasAlarm = true;
-            AlarmMessage = $"1鍙锋按姹犳恫浣嶆帴杩戦珮闄 ({Tank1Level:F1}%)";
+            AlarmMessage = $"TANK1 LEVEL HIGH ({Tank1Level:F1}%)";
             AlarmCount++;
         }
         else if (Tank1Level < config.LevelLowAlarm)
         {
             HasAlarm = true;
-            AlarmMessage = $"1鍙锋按姹犳恫浣嶈繃浣 ({Tank1Level:F1}%)";
-            AlarmCount++;
-        }
-
-        if (Tank2Level > config.LevelHighAlarm)
-        {
-            HasAlarm = true;
-            AlarmMessage += $"\n2鍙锋按姹犳恫浣嶆帴杩戦珮闄 ({Tank2Level:F1}%)";
+            AlarmMessage = $"TANK1 LEVEL LOW ({Tank1Level:F1}%)";
             AlarmCount++;
         }
 
         if (InflowRate > config.FlowHighAlarm)
         {
             HasAlarm = true;
-            AlarmMessage += $"\n杩涙按娴侀噺杩囬珮 ({InflowRate:F1} m鲁/h)";
+            AlarmMessage += $"\nINFLOW HIGH ({InflowRate:F1} m鲁/h)";
             AlarmCount++;
         }
 
-        // 鏇存柊杩愯璁惧鏁
         RunningDeviceCount = (Pump1Running ? 1 : 0) + (Pump2Running ? 1 : 0) +
                             (Pump3Running ? 1 : 0) + (Pump4Running ? 1 : 0) +
                             (Pump5Running ? 1 : 0) + (Fan1Running ? 1 : 0) +
                             (Fan2Running ? 1 : 0);
-
-        // 鏇存柊璁惧鐘舵佹枃鏈
-        UpdateDeviceStatusText();
     }
 
-    /// <summary>
-    /// 鏇存柊璁惧鐘舵佹枃鏈
-    /// </summary>
-    private void UpdateDeviceStatusText()
+    private void UpdateDeviceStatuses()
     {
-        Pump1Status = Pump1Running ? "杩愯涓 - 50Hz" : "宸插仠姝";
-        Pump2Status = Pump2Running ? "杩愯涓 - 45Hz" : "宸插仠姝";
-        Pump3Status = Pump3Running ? "杩愯涓 - 40Hz" : "宸插仠姝";
-        Pump4Status = Pump4Running ? "杩愯涓 - 35Hz" : "宸插仠姝";
-        Pump5Status = Pump5Running ? "杩愯涓 - 55Hz" : "宸插仠姝";
-        Fan1Status = Fan1Running ? "杩愯涓 - 1500RPM" : "宸插仠姝";
-        Fan2Status = Fan2Running ? "杩愯涓 - 1200RPM" : "宸插仠姝";
+        Pump1StatusColor = Pump1Running ? "#00897B" : "#4B5563";
+        Pump2StatusColor = Pump2Running ? "#00897B" : "#4B5563";
+        Pump3StatusColor = Pump3Running ? "#00897B" : "#4B5563";
+        Pump4StatusColor = Pump4Running ? "#00897B" : "#4B5563";
+        Pump5StatusColor = Pump5Running ? "#00897B" : "#4B5563";
+        Fan1StatusColor = Fan1Running ? "#00897B" : "#4B5563";
+        Fan2StatusColor = Fan2Running ? "#00897B" : "#4B5563";
+
+        Valve1StatusColor = Valve1Status == ValveStatus.Open ? "#00897B" :
+                            Valve1Status == ValveStatus.Middle ? "#F59E0B" : "#4B5563";
+        Valve2StatusColor = Valve2Status == ValveStatus.Open ? "#00897B" :
+                            Valve2Status == ValveStatus.Middle ? "#F59E0B" : "#4B5563";
+        Valve3StatusColor = Valve3Status == ValveStatus.Open ? "#00897B" :
+                            Valve3Status == ValveStatus.Middle ? "#F59E0B" : "#4B5563";
+        Valve4StatusColor = Valve4Status == ValveStatus.Open ? "#00897B" :
+                            Valve4Status == ValveStatus.Middle ? "#F59E0B" : "#4B5563";
+
+        Pump1Status = Pump1Running ? "RUNNING 50Hz" : "STOPPED";
+        Pump2Status = Pump2Running ? "RUNNING 45Hz" : "STOPPED";
+        Pump3Status = Pump3Running ? "RUNNING 40Hz" : "STOPPED";
+        Pump4Status = Pump4Running ? "RUNNING 35Hz" : "STOPPED";
+        Pump5Status = Pump5Running ? "RUNNING 55Hz" : "STOPPED";
+        Fan1Status = Fan1Running ? "RUNNING 1500RPM" : "STOPPED";
+        Fan2Status = Fan2Running ? "RUNNING 1200RPM" : "STOPPED";
     }
 
-    /// <summary>
-    /// 杩炴帴 PLC
-    /// </summary>
+    private static float Clamp(float value, float min, float max) => Math.Max(min, Math.Min(max, value));
+
     [RelayCommand]
-    private async Task ConnectPlcAsync()
-    {
-        IsPlcConnected = await PlcService.ConnectAsync();
-    }
+    private async Task ConnectPlcAsync() => IsPlcConnected = await PlcService.ConnectAsync();
 
-    /// <summary>
-    /// 鏂紑 PLC
-    /// </summary>
     [RelayCommand]
-    private void DisconnectPlc()
-    {
-        PlcService.Disconnect();
-        IsPlcConnected = false;
-    }
+    private void DisconnectPlc() { PlcService.Disconnect(); IsPlcConnected = false; }
 
-    /// <summary>
-    /// 鍒锋柊鏁版嵁
-    /// </summary>
     [RelayCommand]
     private async Task RefreshDataAsync()
     {
-        if (!PlcService.IsConnected)
-        {
-            Log.Warning("PLC 鏈繛鎺ワ紝浣跨敤妯℃嫙鏁版嵁");
-            return;
-        }
-
+        if (!PlcService.IsConnected) return;
         try
         {
             Tank1Level = await PlcService.ReadFloatAsync("VD100");
@@ -280,151 +205,14 @@ public partial class ViewAViewModel : ObservableObject
             Tank4Level = await PlcService.ReadFloatAsync("VD112");
             InflowRate = await PlcService.ReadFloatAsync("VD200");
             OutflowRate = await PlcService.ReadFloatAsync("VD204");
-            Pump1Running = await PlcService.ReadBoolAsync("Q0.0");
-            Pump2Running = await PlcService.ReadBoolAsync("Q0.1");
-            Pump3Running = await PlcService.ReadBoolAsync("Q0.2");
-            Fan1Running = await PlcService.ReadBoolAsync("Q0.3");
-            Fan2Running = await PlcService.ReadBoolAsync("Q0.4");
-
+            FlowDelta = InflowRate - OutflowRate;
             CheckAlarms();
         }
-        catch (Exception ex)
-        {
-            Log.Error(ex, "鍒锋柊鏁版嵁澶辫触");
-        }
-    }
-
-    /// <summary>
-    /// 鎺у埗娉
-    /// </summary>
-    [RelayCommand]
-    private async Task TogglePumpAsync(string pumpId)
-    {
-        var currentState = pumpId switch
-        {
-            "P001" => Pump1Running,
-            "P002" => Pump2Running,
-            "P003" => Pump3Running,
-            "P004" => Pump4Running,
-            "P005" => Pump5Running,
-            _ => false
-        };
-
-        var address = pumpId switch
-        {
-            "P001" => "Q0.0",
-            "P002" => "Q0.1",
-            "P003" => "Q0.2",
-            "P004" => "Q0.3",
-            "P005" => "Q0.4",
-            _ => ""
-        };
-
-        if (PlcService.IsConnected)
-        {
-            await PlcService.WriteBoolAsync(address, !currentState);
-        }
-
-        switch (pumpId)
-        {
-            case "P001": Pump1Running = !currentState; break;
-            case "P002": Pump2Running = !currentState; break;
-            case "P003": Pump3Running = !currentState; break;
-            case "P004": Pump4Running = !currentState; break;
-            case "P005": Pump5Running = !currentState; break;
-        }
-
-        CheckAlarms();
-    }
-
-    /// <summary>
-    /// 鎺у埗椋庢墖
-    /// </summary>
-    [RelayCommand]
-    private async Task ToggleFanAsync(string fanId)
-    {
-        var currentState = fanId switch
-        {
-            "F001" => Fan1Running,
-            "F002" => Fan2Running,
-            _ => false
-        };
-
-        if (PlcService.IsConnected)
-        {
-            var address = fanId == "F001" ? "Q0.3" : "Q0.4";
-            await PlcService.WriteBoolAsync(address, !currentState);
-        }
-
-        if (fanId == "F001") Fan1Running = !currentState;
-        else Fan2Running = !currentState;
-
-        CheckAlarms();
-    }
-
-    /// <summary>
-    /// 鎺у埗闃闂
-    /// </summary>
-    [RelayCommand]
-    private async Task ToggleValveAsync(string valveId)
-    {
-        var currentStatus = valveId switch
-        {
-            "V001" => Valve1Status,
-            "V002" => Valve2Status,
-            "V003" => Valve3Status,
-            "V004" => Valve4Status,
-            _ => ValveStatus.Middle
-        };
-
-        var newStatus = currentStatus switch
-        {
-            ValveStatus.Closed => ValveStatus.Middle,
-            ValveStatus.Middle => ValveStatus.Open,
-            ValveStatus.Open => ValveStatus.Closed,
-            _ => ValveStatus.Middle
-        };
-
-        if (PlcService.IsConnected)
-        {
-            var address = valveId switch
-            {
-                "V001" => "Q1.0",
-                "V002" => "Q1.1",
-                "V003" => "Q1.2",
-                "V004" => "Q1.3",
-                _ => ""
-            };
-            await PlcService.WriteBoolAsync(address, newStatus == ValveStatus.Open);
-        }
-
-        switch (valveId)
-        {
-            case "V001": Valve1Status = newStatus; break;
-            case "V002": Valve2Status = newStatus; break;
-            case "V003": Valve3Status = newStatus; break;
-            case "V004": Valve4Status = newStatus; break;
-        }
+        catch (Exception ex) { Log.Error(ex, "Refresh failed"); }
     }
 }
 
 /// <summary>
 /// 闃闂ㄧ姸鎬佹灇涓
 /// </summary>
-public enum ValveStatus
-{
-    /// <summary>
-    /// 鍏抽棴
-    /// </summary>
-    Closed,
-
-    /// <summary>
-    /// 涓棿浣嶇疆
-    /// </summary>
-    Middle,
-
-    /// <summary>
-    /// 鎵撳紑
-    /// </summary>
-    Open
-}
+public enum ValveStatus { Closed, Middle, Open }