Files
ADP/DeviceEditModule/ViewModels/N36200ViewModel.cs
2026-06-12 16:55:47 +08:00

310 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using DeviceCommand.Device;
using Prism.Commands;
using Prism.Ioc;
using System;
using System.Threading;
using System.Windows.Input;
using UIShare.GlobalVariable;
using UIShare.ViewModelBase;
namespace DeviceEditModule.ViewModels
{
/// <summary>
/// N36200 宽范围可编程直流电源控制面板 ViewModel。
/// <para>
/// 注册为 Navigation View可通过 EventAggregator 添加为 DialogMangerView 中的 Tab
/// <code>
/// var view = container.Resolve&lt;N36200View&gt;();
/// (view.DataContext as N36200ViewModel)?.Initialize("N36200");
/// _eventAggregator.GetEvent&lt;AddDialogTabEvent&gt;().Publish(
/// new DialogTabInfo { Title = "N36200", Content = view });
/// </code>
/// </para>
/// </summary>
public class N36200ViewModel : NavigateViewModelBase, IDisposable
{
#region
private readonly DeviceManager _deviceManager;
private N36200? _device;
private CancellationTokenSource? _cts;
#endregion
#region
private string _deviceName = "N36200";
public string DeviceName
{
get => _deviceName;
set => SetProperty(ref _deviceName, value);
}
private bool _isConnected;
public bool IsConnected
{
get => _isConnected;
set => SetProperty(ref _isConnected, value);
}
private bool _isBusy;
public bool IsBusy
{
get => _isBusy;
set => SetProperty(ref _isBusy, value);
}
#endregion
#region
private double _voltage = 12.0;
/// <summary>待设置的输出电压值V。</summary>
public double Voltage
{
get => _voltage;
set => SetProperty(ref _voltage, value);
}
private double _currentLimit = 5.0;
/// <summary>待设置的限流值A。</summary>
public double CurrentLimit
{
get => _currentLimit;
set => SetProperty(ref _currentLimit, value);
}
private string _selectedMode = "NORMal";
/// <summary>待设置的运行模式NORMal / CHARge / SEQuence / CPOWer / CARWave / APG。</summary>
public string SelectedMode
{
get => _selectedMode;
set => SetProperty(ref _selectedMode, value);
}
private double _ovpValue = 15.0;
/// <summary>过压保护值V。</summary>
public double OvpValue
{
get => _ovpValue;
set => SetProperty(ref _ovpValue, value);
}
private double _ocpValue = 6.0;
/// <summary>过流保护值A。</summary>
public double OcpValue
{
get => _ocpValue;
set => SetProperty(ref _ocpValue, value);
}
private double _uvpValue = 0.0;
/// <summary>欠压保护值V。</summary>
public double UvpValue
{
get => _uvpValue;
set => SetProperty(ref _uvpValue, value);
}
private double _oppValue = 100.0;
/// <summary>过功率保护值W。</summary>
public double OppValue
{
get => _oppValue;
set => SetProperty(ref _oppValue, value);
}
#endregion
#region
private string _measuredVoltage = "—";
public string MeasuredVoltage
{
get => _measuredVoltage;
set => SetProperty(ref _measuredVoltage, value);
}
private string _measuredCurrent = "—";
public string MeasuredCurrent
{
get => _measuredCurrent;
set => SetProperty(ref _measuredCurrent, value);
}
private string _measuredPower = "—";
public string MeasuredPower
{
get => _measuredPower;
set => SetProperty(ref _measuredPower, value);
}
private string _deviceStatus = "—";
/// <summary>设备状态字OUTPut:STATe? 查询结果)。</summary>
public string DeviceStatus
{
get => _deviceStatus;
set => SetProperty(ref _deviceStatus, value);
}
private string _responseLog = string.Empty;
/// <summary>命令响应日志(最新消息在顶部)。</summary>
public string ResponseLog
{
get => _responseLog;
set => SetProperty(ref _responseLog, value);
}
#endregion
#region
public ICommand QueryIdentityCommand { get; }
public ICommand ResetDeviceCommand { get; }
public ICommand OutputOnCommand { get; }
public ICommand OutputOffCommand { get; }
public ICommand SetVoltageCommand { get; }
public ICommand SetCurrentCommand { get; }
public ICommand SetModeCommand { get; }
public ICommand QueryAllMeasureCommand { get; }
public ICommand QueryStatusCommand { get; }
public ICommand SetOvpCommand { get; }
public ICommand SetOcpCommand { get; }
public ICommand SetUvpCommand { get; }
public ICommand SetOppCommand { get; }
public ICommand ClearAlarmCommand { get; }
#endregion
public N36200ViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
_deviceManager = containerProvider.Resolve<DeviceManager>();
QueryIdentityCommand = new DelegateCommand(async () => await Exec(async () => AppendLog("IDN: " + await _device!.(Ct()))));
ResetDeviceCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Ct()); AppendLog("设备已重置耗时约10s"); }));
OutputOnCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.DC输出(true, Ct()); AppendLog("输出已开启"); }));
OutputOffCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.DC输出(false, Ct()); AppendLog("输出已关闭"); }));
SetVoltageCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Voltage, Ct()); AppendLog($"电压已设为 {Voltage} V"); }));
SetCurrentCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(CurrentLimit, Ct()); AppendLog($"限流已设为 {CurrentLimit} A"); }));
SetModeCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(SelectedMode, Ct()); AppendLog($"模式已设为 {SelectedMode}"); }));
SetOvpCommand = new DelegateCommand(async () => await Exec(async () => { await _device!._OVP(OvpValue, Ct()); AppendLog($"OVP已设为 {OvpValue} V"); }));
SetOcpCommand = new DelegateCommand(async () => await Exec(async () => { await _device!._OCP(OcpValue, Ct()); AppendLog($"OCP已设为 {OcpValue} A"); }));
SetUvpCommand = new DelegateCommand(async () => await Exec(async () => { await _device!._UVP(UvpValue, Ct()); AppendLog($"UVP已设为 {UvpValue} V"); }));
SetOppCommand = new DelegateCommand(async () => await Exec(async () => { await _device!._OPP(OppValue, Ct()); AppendLog($"OPP已设为 {OppValue} W"); }));
ClearAlarmCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Ct()); AppendLog("告警已清除"); }));
QueryStatusCommand = new DelegateCommand(async () => await Exec(async () =>
{
DeviceStatus = await _device!.(Ct());
AppendLog($"状态字: {DeviceStatus}");
}));
QueryAllMeasureCommand = new DelegateCommand(async () => await Exec(async () =>
{
MeasuredVoltage = await _device!.(Ct());
MeasuredCurrent = await _device!.(Ct());
MeasuredPower = await _device!.(Ct());
AppendLog($"测量 → 电压:{MeasuredVoltage}V 电流:{MeasuredCurrent}A 功率:{MeasuredPower}W");
}));
Initialize();
}
#region / Navigation
/// <summary>
/// 从 DeviceManager 中查找 N36200 设备实例。
/// 优先按 <paramref name="deviceName"/> 查找,否则取第一个匹配类型的设备。
/// </summary>
public void Initialize(string? deviceName = null)
{
N36200? found = null;
string? foundName = null;
if (deviceName != null &&
_deviceManager.DeviceMap.TryGetValue(deviceName, out var d) &&
d is N36200 n)
{
found = n;
foundName = deviceName;
}
else
{
foreach (var kv in _deviceManager.DeviceMap)
{
if (kv.Value is N36200 n36)
{
found = n36;
foundName = kv.Key;
break;
}
}
}
_device = found;
DeviceName = foundName ?? "N36200 (未找到)";
IsConnected = _device?.IsConnected ?? false;
AppendLog(found != null
? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "" : "")}"
: "未在 DeviceManager 中找到 N36200 设备,请先初始化设备配置。");
}
public override void OnNavigatedTo(NavigationContext context)
{
var name = context.Parameters.GetValue<string?>("DeviceName");
Initialize(name);
}
#endregion
#region
private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token;
private async Task Exec(Func<Task> action)
{
if (_device == null)
{
AppendLog("错误:未关联到设备实例,请检查设备配置。");
return;
}
if (IsBusy) return;
IsBusy = true;
try
{
await action();
IsConnected = _device.IsConnected;
}
catch (OperationCanceledException)
{
AppendLog("命令超时或已取消。");
}
catch (Exception ex)
{
AppendLog($"错误:{ex.Message}");
}
finally
{
IsBusy = false;
}
}
private void AppendLog(string message)
{
var line = $"[{DateTime.Now:HH:mm:ss}] {message}";
ResponseLog = ResponseLog.Length > 4000
? line + "\n" + ResponseLog[..3000]
: line + "\n" + ResponseLog;
}
#endregion
public void Dispose()
{
_cts?.Cancel();
_cts?.Dispose();
}
}
}