Files
lmxopcua/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs
T
Joseph Doherty 64e3fbe035
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
docs: backfill XML documentation across 756 files
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public
members surfaced by commentchecker — resolves 5,847 of 5,869 issues
(99.6%) across three /fixdocs passes.
2026-05-28 08:10:17 -04:00

128 lines
3.9 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Opc.Ua;
using ZB.MOM.WW.OtOpcUa.Client.Shared;
using ZB.MOM.WW.OtOpcUa.Client.UI.Services;
namespace ZB.MOM.WW.OtOpcUa.Client.UI.ViewModels;
/// <summary>
/// ViewModel for the read/write panel.
/// </summary>
public partial class ReadWriteViewModel : ObservableObject
{
private readonly IUiDispatcher _dispatcher;
private readonly IOpcUaClientService _service;
[ObservableProperty] private string? _currentStatus;
[ObservableProperty] private string? _currentValue;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(ReadCommand))]
[NotifyCanExecuteChangedFor(nameof(WriteCommand))]
private bool _isConnected;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(ReadCommand))]
[NotifyCanExecuteChangedFor(nameof(WriteCommand))]
private string? _selectedNodeId;
[ObservableProperty] private string? _serverTimestamp;
[ObservableProperty] private string? _sourceTimestamp;
[ObservableProperty] private string? _writeStatus;
[ObservableProperty] private string? _writeValue;
/// <summary>Initializes a new instance of the ReadWriteViewModel class.</summary>
/// <param name="service">The OPC UA client service for read/write operations.</param>
/// <param name="dispatcher">The UI dispatcher for posting updates to the UI thread.</param>
public ReadWriteViewModel(IOpcUaClientService service, IUiDispatcher dispatcher)
{
_service = service;
_dispatcher = dispatcher;
}
/// <summary>Gets a value indicating whether a node is currently selected.</summary>
public bool IsNodeSelected => !string.IsNullOrEmpty(SelectedNodeId);
partial void OnSelectedNodeIdChanged(string? value)
{
OnPropertyChanged(nameof(IsNodeSelected));
if (!string.IsNullOrEmpty(value) && IsConnected) _ = ExecuteReadAsync();
}
private bool CanReadOrWrite()
{
return IsConnected && !string.IsNullOrEmpty(SelectedNodeId);
}
[RelayCommand(CanExecute = nameof(CanReadOrWrite))]
private async Task ReadAsync()
{
await ExecuteReadAsync();
}
private async Task ExecuteReadAsync()
{
if (string.IsNullOrEmpty(SelectedNodeId)) return;
try
{
var nodeId = NodeId.Parse(SelectedNodeId);
var dataValue = await _service.ReadValueAsync(nodeId);
_dispatcher.Post(() =>
{
CurrentValue = Helpers.ValueFormatter.Format(dataValue.Value);
CurrentStatus = Helpers.StatusCodeFormatter.Format(dataValue.StatusCode);
SourceTimestamp = dataValue.SourceTimestamp.ToString("O");
ServerTimestamp = dataValue.ServerTimestamp.ToString("O");
});
}
catch (Exception ex)
{
_dispatcher.Post(() =>
{
CurrentValue = null;
CurrentStatus = $"Error: {ex.Message}";
SourceTimestamp = null;
ServerTimestamp = null;
});
}
}
[RelayCommand(CanExecute = nameof(CanReadOrWrite))]
private async Task WriteAsync()
{
if (string.IsNullOrEmpty(SelectedNodeId) || WriteValue == null) return;
try
{
var nodeId = NodeId.Parse(SelectedNodeId);
var statusCode = await _service.WriteValueAsync(nodeId, WriteValue);
_dispatcher.Post(() => { WriteStatus = statusCode.ToString(); });
}
catch (Exception ex)
{
_dispatcher.Post(() => { WriteStatus = $"Error: {ex.Message}"; });
}
}
/// <summary>
/// Clears all displayed values.
/// </summary>
public void Clear()
{
SelectedNodeId = null;
CurrentValue = null;
CurrentStatus = null;
SourceTimestamp = null;
ServerTimestamp = null;
WriteValue = null;
WriteStatus = null;
}
}