Files
ADP/DeviceEditModule/ViewModels/N36200ViewModel.cs
T

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.Devices;
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 double _measuredVoltage;
public double MeasuredVoltage
{
get => _measuredVoltage;
set => SetProperty(ref _measuredVoltage, value);
}
private double _measuredCurrent;
public double MeasuredCurrent
{
get => _measuredCurrent;
set => SetProperty(ref _measuredCurrent, value);
}
private double _measuredPower;
public double 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();
}
}
}