Files
DMS/DMS.WPF/ViewModels/Dialogs/ImportOpcUaDialogViewModel.cs

170 lines
5.0 KiB
C#
Raw Normal View History

using AutoMapper;
2025-08-25 20:16:57 +08:00
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DMS.Core.Enums;
using DMS.Core.Helper;
2025-08-25 20:16:57 +08:00
using DMS.Core.Models;
using DMS.Helper;
2025-08-25 21:26:18 +08:00
using DMS.Infrastructure.Interfaces.Services;
2025-09-01 21:03:34 +08:00
using DMS.Infrastructure.Models;
2025-08-25 20:16:57 +08:00
using DMS.WPF.ViewModels.Items;
2025-08-25 21:26:18 +08:00
using Opc.Ua;
2025-08-25 20:16:57 +08:00
using Opc.Ua.Client;
2025-09-02 15:02:39 +08:00
using System.Collections;
2025-08-25 20:16:57 +08:00
using System.Collections.ObjectModel;
namespace DMS.WPF.ViewModels.Dialogs;
public partial class ImportOpcUaDialogViewModel : DialogViewModelBase<List<VariableItemViewModel>>
{
[ObservableProperty]
private string _endpointUrl = "opc.tcp://127.0.0.1:4855"; // 默认值
2025-09-01 21:03:34 +08:00
[ObservableProperty]
private OpcUaNodeItemViewModel _rootOpcUaNode;
2025-08-25 20:16:57 +08:00
[ObservableProperty]
2025-09-02 15:02:39 +08:00
private ObservableCollection<VariableItemViewModel> _opcUaNodeVariables=new ObservableCollection<VariableItemViewModel>();
2025-08-25 20:16:57 +08:00
2025-09-02 15:02:39 +08:00
[ObservableProperty]
private IList _selectedVariables = new ArrayList();
2025-08-25 20:16:57 +08:00
[ObservableProperty]
private bool _selectAllVariables;
[ObservableProperty]
private bool _isConnected;
2025-08-25 21:26:18 +08:00
[ObservableProperty]
2025-09-01 21:03:34 +08:00
private string _connectButtonText = "连接服务器";
2025-08-25 21:26:18 +08:00
[ObservableProperty]
private bool _isConnectButtonEnabled = true;
2025-08-25 20:16:57 +08:00
private Session _session;
2025-08-25 21:26:18 +08:00
private readonly IOpcUaService _opcUaService;
private readonly IMapper _mapper;
2025-08-25 21:26:18 +08:00
private CancellationTokenSource _cancellationTokenSource;
public ImportOpcUaDialogViewModel(IOpcUaService opcUaService,IMapper mapper)
2025-08-25 20:16:57 +08:00
{
2025-08-25 21:26:18 +08:00
this._opcUaService = opcUaService;
this._mapper = mapper;
RootOpcUaNode = new OpcUaNodeItemViewModel() { DisplayName = "根节点", NodeId = Objects.ObjectsFolder, IsExpanded = true };
2025-09-01 21:03:34 +08:00
_cancellationTokenSource = new CancellationTokenSource();
2025-08-25 20:16:57 +08:00
}
[RelayCommand]
private async Task Connect()
{
try
{
// 断开现有连接
2025-09-01 21:03:34 +08:00
if (!_opcUaService.IsConnected)
2025-08-25 20:16:57 +08:00
{
2025-09-01 21:03:34 +08:00
await _opcUaService.ConnectAsync(EndpointUrl);
2025-08-25 20:16:57 +08:00
}
2025-09-01 21:03:34 +08:00
if (_opcUaService.IsConnected)
2025-08-25 21:26:18 +08:00
{
IsConnected=true;
2025-08-25 21:26:18 +08:00
ConnectButtonText = "已连接";
IsConnectButtonEnabled = false;
}
2025-08-25 20:16:57 +08:00
// 浏览根节点
2025-09-01 21:03:34 +08:00
var childrens= await _opcUaService.BrowseNode(_mapper.Map<OpcUaNode>(RootOpcUaNode));
RootOpcUaNode.Children = _mapper.Map<ObservableCollection<OpcUaNodeItemViewModel>>(childrens);
2025-09-01 21:03:34 +08:00
2025-08-25 20:16:57 +08:00
}
catch (Exception ex)
{
IsConnected = false;
2025-08-25 21:26:18 +08:00
IsConnectButtonEnabled = false;
ConnectButtonText = "连接服务器";
2025-08-25 20:16:57 +08:00
NotificationHelper.ShowError($"连接 OPC UA 服务器失败: {EndpointUrl} - {ex.Message}", ex);
}
}
2025-09-02 15:02:39 +08:00
[RelayCommand]
private async void SecondaryButton()
{
await _opcUaService.DisconnectAsync();
Close(SelectedVariables.Cast<VariableItemViewModel>().ToList());
}
[RelayCommand]
private async void PrimaryButton()
{
await _opcUaService.DisconnectAsync();
2025-09-02 15:02:39 +08:00
Close(OpcUaNodeVariables.ToList());
}
[RelayCommand]
private async void CloseButton()
{
await _opcUaService.DisconnectAsync();
}
2025-08-25 20:16:57 +08:00
/// <summary>
/// 处理来自服务器的数据变化通知
/// </summary>
private static void OnNotification(MonitoredItem item, MonitoredItemNotificationEventArgs e)
{
foreach (var value in item.DequeueValues())
{
Console.WriteLine(
$"[通知] {item.DisplayName}: {value.Value} | 时间戳: {value.SourceTimestamp.ToLocalTime()} | 状态: {value.StatusCode}");
}
}
public async Task LoadNodeVariables(OpcUaNodeItemViewModel node)
{
try
{
2025-09-02 15:02:39 +08:00
OpcUaNodeVariables.Clear();
2025-08-25 20:16:57 +08:00
// 加载节点的子项
node.IsExpanded = true;
node.IsSelected = true;
var childrens = await _opcUaService.BrowseNode(_mapper.Map<OpcUaNode>(node));
foreach (var children in childrens)
{
var opcNodeItem = _mapper.Map<OpcUaNodeItemViewModel>(children);
if (children.NodeClass == NodeClass.Variable)
{
2025-09-02 15:02:39 +08:00
OpcUaNodeVariables.Add(new VariableItemViewModel
{
Name = children.DisplayName, // 修正:使用子节点的显示名称
OpcUaNodeId = children.NodeId.ToString(),
Protocol = ProtocolType.OpcUa,
CSharpDataType=children.DataType,
IsActive = true // 默认选中
});
}
else
{
node.Children.Add(opcNodeItem);
}
}
}
catch (Exception ex)
{
NlogHelper.Error($"加载 OPC UA 节点变量失败: {node.NodeId} - {ex.Message}", ex);
NotificationHelper.ShowError($"加载 OPC UA 节点变量失败: {node.NodeId} - {ex.Message}", ex);
}
}
2025-08-25 20:16:57 +08:00
}