From fef4b32c41be6a1e70c25e1adaa83a748d4f8ae7 Mon Sep 17 00:00:00 2001 From: WenJY Date: Fri, 12 Jun 2026 16:59:24 +0800 Subject: [PATCH] =?UTF-8?q?add=20-=20=E6=B7=BB=E5=8A=A0=E7=A0=81=E5=9E=9B?= =?UTF-8?q?=E7=BA=BF=20HMI=20=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 3 +- Sln.Wcs.UI/App.axaml.cs | 1 + .../ViewModels/HMI/PalletizerHMIViewModel.cs | 99 +++++++++ Sln.Wcs.UI/ViewModels/NavigationViewModel.cs | 27 ++- Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml | 194 ++++++++++++++++++ .../Views/HMI/PalletizerHMIView.axaml.cs | 11 + 6 files changed, 325 insertions(+), 10 deletions(-) create mode 100644 Sln.Wcs.UI/ViewModels/HMI/PalletizerHMIViewModel.cs create mode 100644 Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml create mode 100644 Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml.cs diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 5249587..af39aa9 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -19,7 +19,8 @@ "Bash(git status *)", "Bash(dotnet /Users/wenxiansheng/.nuget/packages/avalonia/11.1.5/lib/netstandard2.0/Avalonia.Base.dll type list)", "Bash(dotnet new *)", - "Bash(dotnet add *)" + "Bash(dotnet add *)", + "Bash(python3 *)" ] } } diff --git a/Sln.Wcs.UI/App.axaml.cs b/Sln.Wcs.UI/App.axaml.cs index 1f380a0..b32f224 100644 --- a/Sln.Wcs.UI/App.axaml.cs +++ b/Sln.Wcs.UI/App.axaml.cs @@ -92,6 +92,7 @@ public partial class App : Application services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); // 引擎进程管理 services.AddSingleton(); diff --git a/Sln.Wcs.UI/ViewModels/HMI/PalletizerHMIViewModel.cs b/Sln.Wcs.UI/ViewModels/HMI/PalletizerHMIViewModel.cs new file mode 100644 index 0000000..d4e0d7c --- /dev/null +++ b/Sln.Wcs.UI/ViewModels/HMI/PalletizerHMIViewModel.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Avalonia.Controls; + +namespace Sln.Wcs.UI.ViewModels.HMI; + +public class HmiSignalItem +{ + public string Name { get; set; } = ""; + public string Address { get; set; } = ""; + public string Value { get; set; } = "OFF"; + public bool IsOn => Value == "ON"; +} + +public partial class PalletizerHMIViewModel +{ + public string PageTitle => "码垛机 HMI"; + + public ObservableCollection Manual1Items { get; } = new(); + public ObservableCollection Manual2Items { get; } = new(); + public ObservableCollection AlarmItems { get; } = new(); + public ObservableCollection InputItems { get; } = new(); + public ObservableCollection OutputItems { get; } = new(); + + public PalletizerHMIViewModel() + { + // 手动操作 + Manual1Items = new ObservableCollection + { + new(){Name="1#滚筒线正转",Address="DB100.DBX0.0"}, new(){Name="1#皮带线正转",Address="DB100.DBX0.1"}, + new(){Name="1#侧推机构伸出",Address="DB100.DBX0.2"}, new(){Name="1#侧推机构缩回",Address="DB100.DBX0.3"}, + new(){Name="1#阻挡上升",Address="DB100.DBX0.4"}, new(){Name="1#阻挡下降",Address="DB100.DBX0.5"}, + new(){Name="1#侧推转弯伸出",Address="DB100.DBX0.6"}, new(){Name="1#侧推转弯缩回",Address="DB100.DBX0.7"}, + }; + Manual2Items = new ObservableCollection + { + new(){Name="2#滚筒线正转",Address="DB100.DBX16.0"}, new(){Name="2#皮带线正转",Address="DB100.DBX16.1"}, + new(){Name="2#侧推机构伸出",Address="DB100.DBX16.2"}, new(){Name="2#侧推机构缩回",Address="DB100.DBX16.3"}, + new(){Name="2#阻挡上升",Address="DB100.DBX16.4"}, new(){Name="2#阻挡下降",Address="DB100.DBX16.5"}, + new(){Name="2#侧推机构2伸出",Address="DB100.DBX16.6"}, new(){Name="2#侧推机构2缩回",Address="DB100.DBX16.7"}, + }; + + // 报警 + AlarmItems = new ObservableCollection + { + new(){Name="1号滚筒线异常",Address="DB102.DBX0.0"}, new(){Name="1号皮带线异常",Address="DB102.DBX0.1"}, + new(){Name="2号滚筒线异常",Address="DB102.DBX0.2"}, new(){Name="2号皮带线异常",Address="DB102.DBX0.3"}, + new(){Name="1号侧推伸出超时",Address="DB102.DBX0.4"}, new(){Name="1号侧推缩回超时",Address="DB102.DBX0.5"}, + new(){Name="1号阻挡伸出超时",Address="DB102.DBX0.6"}, new(){Name="1号阻挡缩回超时",Address="DB102.DBX0.7"}, + new(){Name="1号侧推转弯伸出超时",Address="DB102.DBX1.0"}, new(){Name="1号侧推转弯缩回超时",Address="DB102.DBX1.1"}, + new(){Name="2号侧推伸出超时",Address="DB102.DBX1.2"}, new(){Name="2号侧推缩回超时",Address="DB102.DBX1.3"}, + new(){Name="2号阻挡伸出超时",Address="DB102.DBX1.4"}, new(){Name="2号阻挡缩回超时",Address="DB102.DBX1.5"}, + }; + + // 输入 + InputItems = new ObservableCollection + { + new(){Name="急停",Address="DB103.DBX0.0"}, new(){Name="复位1",Address="DB103.DBX0.1"}, + new(){Name="手动1",Address="DB103.DBX0.2"}, new(){Name="自动1",Address="DB103.DBX0.3"}, + new(){Name="实施1",Address="DB103.DBX0.4"}, new(){Name="复位2",Address="DB103.DBX0.5"}, + new(){Name="手动2",Address="DB103.DBX0.6"}, new(){Name="自动2",Address="DB103.DBX0.7"}, + new(){Name="实施2",Address="DB103.DBX1.0"}, new(){Name="1号入口到位",Address="DB103.DBX1.1"}, + new(){Name="1号出口到位",Address="DB103.DBX1.2"}, new(){Name="1号喷码到位",Address="DB103.DBX1.3"}, + new(){Name="1号阻挡原位",Address="DB103.DBX1.4"}, new(){Name="1号阻挡工作位",Address="DB103.DBX1.5"}, + new(){Name="1号侧推原位",Address="DB103.DBX1.6"}, new(){Name="1号侧推工作位",Address="DB103.DBX1.7"}, + new(){Name="1号扫码位置",Address="DB103.DBX2.0"}, new(){Name="2号入口到位",Address="DB103.DBX2.1"}, + new(){Name="2号出口到位",Address="DB103.DBX2.2"}, new(){Name="2号喷码到位",Address="DB103.DBX2.3"}, + new(){Name="2号阻挡原位",Address="DB103.DBX2.4"}, new(){Name="2号阻挡工作位",Address="DB103.DBX2.5"}, + new(){Name="2号侧推原位",Address="DB103.DBX2.6"}, new(){Name="2号侧推工作位",Address="DB103.DBX2.7"}, + new(){Name="2号扫码位置",Address="DB103.DBX3.0"}, new(){Name="1号滚筒电机异常",Address="DB103.DBX3.1"}, + new(){Name="1号皮带电机异常",Address="DB103.DBX3.2"}, new(){Name="2号滚筒电机异常",Address="DB103.DBX3.3"}, + new(){Name="2号皮带电机异常",Address="DB103.DBX3.4"}, new(){Name="1号侧推转弯原位",Address="DB103.DBX3.5"}, + new(){Name="1号侧推转弯工作位",Address="DB103.DBX3.6"}, + }; + + // 输出 + OutputItems = new ObservableCollection + { + new(){Name="1号滚筒线正转",Address="DB103.DBX4.0"}, new(){Name="1号皮带线正转",Address="DB103.DBX4.1"}, + new(){Name="2号滚筒线正转",Address="DB103.DBX4.2"}, new(){Name="2号皮带线正转",Address="DB103.DBX4.3"}, + new(){Name="1号侧推机构伸出",Address="DB103.DBX4.4"}, new(){Name="1号侧推机构缩回",Address="DB103.DBX4.5"}, + new(){Name="2号侧推机构伸出",Address="DB103.DBX4.6"}, new(){Name="2号侧推机构缩回",Address="DB103.DBX4.7"}, + new(){Name="1号阻挡器伸出",Address="DB103.DBX5.0"}, new(){Name="1号阻挡器缩回",Address="DB103.DBX5.1"}, + new(){Name="2号阻挡器伸出",Address="DB103.DBX5.2"}, new(){Name="2号阻挡器缩回",Address="DB103.DBX5.3"}, + new(){Name="1号侧推转弯伸出",Address="DB103.DBX5.4"}, new(){Name="1号侧推转弯缩回",Address="DB103.DBX5.5"}, + new(){Name="电源指示灯",Address="DB103.DBX5.6"}, new(){Name="红灯",Address="DB103.DBX5.7"}, + new(){Name="黄灯",Address="DB103.DBX6.0"}, new(){Name="绿灯",Address="DB103.DBX6.1"}, + new(){Name="蜂鸣",Address="DB103.DBX6.2"}, new(){Name="运行灯1",Address="DB103.DBX6.3"}, + new(){Name="复位灯1",Address="DB103.DBX6.4"}, new(){Name="运行灯2",Address="DB103.DBX6.5"}, + new(){Name="复位灯2",Address="DB103.DBX6.6"}, + }; + } + + public Control CreateView() + { + var view = new Views.HMI.PalletizerHMIView { DataContext = this }; + return view; + } +} diff --git a/Sln.Wcs.UI/ViewModels/NavigationViewModel.cs b/Sln.Wcs.UI/ViewModels/NavigationViewModel.cs index 49bf42b..f2f6ee7 100644 --- a/Sln.Wcs.UI/ViewModels/NavigationViewModel.cs +++ b/Sln.Wcs.UI/ViewModels/NavigationViewModel.cs @@ -6,6 +6,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using Microsoft.Extensions.DependencyInjection; using Sln.Wcs.UI.ViewModels.Base; using Sln.Wcs.UI.ViewModels.Device; +using Sln.Wcs.UI.ViewModels.HMI; using Sln.Wcs.UI.ViewModels.Path; using Sln.Wcs.UI.ViewModels.Task; using Sln.Wcs.UI.Views; @@ -15,7 +16,7 @@ namespace Sln.Wcs.UI.ViewModels; public partial class NavigationViewModel : ObservableObject { private readonly IServiceProvider _sp; - private readonly Dictionary _vmCache = new(); + private readonly Dictionary _vmCache = new(); private readonly Dictionary _viewCache = new(); private Control? _homeView; @@ -61,6 +62,10 @@ public partial class NavigationViewModel : ObservableObject new("任务队列", () => NavigateTo("任务管理")), new("任务明细", () => NavigateTo("任务管理")), })); + TopMenuItems.Add(new TopMenuItem("HMI", new List + { + new("码垛机监控", () => NavigateTo("HMI")), + })); } private string? _currentModule; @@ -82,23 +87,27 @@ public partial class NavigationViewModel : ObservableObject PageChanged?.Invoke(new SystemMonitorView(_sp.GetRequiredService())); } - private void NavigateTo(string module) where T : ICrudPageViewModel + private void NavigateTo(string module) where T : class { var type = typeof(T); - if (!_vmCache.TryGetValue(type, out var vm)) + if (!_vmCache.TryGetValue(type, out var obj)) { - vm = _sp.GetRequiredService(); - _vmCache[type] = vm; + obj = _sp.GetRequiredService(); + _vmCache[type] = obj; } if (!_viewCache.TryGetValue(type, out var view)) { - view = vm.CreateView(); - view.DataContext = vm; + view = ((dynamic)obj).CreateView(); + view.DataContext = obj; _viewCache[type] = view; } - CurrentPageTitle = $"{module} > {vm.PageTitle}"; + + var title = (obj as dynamic).PageTitle ?? type.Name; + CurrentPageTitle = $"{module} > {title}"; PageChanged?.Invoke(view); - vm.Load(); + + var load = obj.GetType().GetMethod("Load"); + load?.Invoke(obj, null); } } diff --git a/Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml b/Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml new file mode 100644 index 0000000..0b4ab0e --- /dev/null +++ b/Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml.cs b/Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml.cs new file mode 100644 index 0000000..be43ee0 --- /dev/null +++ b/Sln.Wcs.UI/Views/HMI/PalletizerHMIView.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; + +namespace Sln.Wcs.UI.Views.HMI; + +public partial class PalletizerHMIView : UserControl +{ + public PalletizerHMIView() + { + InitializeComponent(); + } +}