Files
ADP/DeviceEditModule/ViewModels/SDS2000X_HDViewModel.cs
2026-06-22 14:29:38 +08:00

295 lines
12 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>
/// SDS2000X_HD 数字存储示波器控制面板 ViewModel。
/// </summary>
public class SDS2000X_HDViewModel : NavigateViewModelBase, IDisposable
{
#region
private readonly DeviceManager _deviceManager;
private SDS2000X_HD? _device;
private CancellationTokenSource? _cts;
#endregion
#region
private string _deviceName = "SDS2000X_HD";
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 int _channel = 1;
/// <summary>当前操作通道1~4。</summary>
public int Channel
{
get => _channel;
set => SetProperty(ref _channel, value);
}
private double _voltsPerDiv = 1.0;
/// <summary>垂直电压档位V/div。</summary>
public double VoltsPerDiv
{
get => _voltsPerDiv;
set => SetProperty(ref _voltsPerDiv, value);
}
private double _offset = 0.0;
/// <summary>垂直偏移V。</summary>
public double Offset
{
get => _offset;
set => SetProperty(ref _offset, value);
}
private bool _is50Ohm;
/// <summary>是否使用 50Ω 输入阻抗false 为 1MΩ。</summary>
public bool Is50Ohm
{
get => _is50Ohm;
set => SetProperty(ref _is50Ohm, value);
}
private double _timeBase = 0.001;
/// <summary>水平时基档位s/div。</summary>
public double TimeBase
{
get => _timeBase;
set => SetProperty(ref _timeBase, value);
}
private double _triggerLevel = 0.0;
/// <summary>触发电平V。</summary>
public double TriggerLevel
{
get => _triggerLevel;
set => SetProperty(ref _triggerLevel, value);
}
private string _triggerSource = "C1";
/// <summary>触发源C1/C2/C3/C4/EX/LINE。</summary>
public string TriggerSource
{
get => _triggerSource;
set => SetProperty(ref _triggerSource, value);
}
#endregion
#region
private string _measuredVpp = "—";
public string MeasuredVpp
{
get => _measuredVpp;
set => SetProperty(ref _measuredVpp, value);
}
private string _measuredFrequency = "—";
public string MeasuredFrequency
{
get => _measuredFrequency;
set => SetProperty(ref _measuredFrequency, value);
}
private string _measuredRms = "—";
public string MeasuredRms
{
get => _measuredRms;
set => SetProperty(ref _measuredRms, 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 RunCommand { get; }
public ICommand StopCommand { get; }
public ICommand SingleCommand { get; }
public ICommand ForceTriggerCommand { get; }
public ICommand SetChannelOnCommand { get; }
public ICommand SetChannelOffCommand { get; }
public ICommand SetVoltsDivCommand { get; }
public ICommand SetOffsetCommand { get; }
public ICommand SetImpedance50Command { get; }
public ICommand SetImpedance1MCommand { get; }
public ICommand SetTimeBaseCommand { get; }
public ICommand SetTriggerLevelCommand { get; }
public ICommand SetTriggerSourceCommand { get; }
public ICommand QueryMeasurementsCommand{ get; }
public ICommand QueryVppCommand { get; }
public ICommand QueryFrequencyCommand { get; }
public ICommand QueryRmsCommand { get; }
#endregion
public SDS2000X_HDViewModel(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("设备已重置"); }));
RunCommand = new DelegateCommand(async () => await Exec(async () => { await _device!._RUN(Ct()); AppendLog("已开始捕获"); }));
StopCommand = new DelegateCommand(async () => await Exec(async () => { await _device!._STOP(Ct()); AppendLog("已停止捕获"); }));
SingleCommand = new DelegateCommand(async () => await Exec(async () => { await _device!._SINGLE(Ct()); AppendLog("已触发单次捕获"); }));
ForceTriggerCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Ct()); AppendLog("已强制触发"); }));
SetChannelOnCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Channel, true, Ct()); AppendLog($"通道 {Channel} 已开启"); }));
SetChannelOffCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Channel, false, Ct()); AppendLog($"通道 {Channel} 已关闭"); }));
SetVoltsDivCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Channel, VoltsPerDiv, Ct()); AppendLog($"C{Channel} 电压档位已设为 {VoltsPerDiv} V/div"); }));
SetOffsetCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Channel, Offset, Ct()); AppendLog($"C{Channel} 垂直偏移已设为 {Offset} V"); }));
SetImpedance50Command = new DelegateCommand(async () => await Exec(async () => { await _device!.(Channel, true, Ct()); AppendLog($"C{Channel} 输入阻抗已设为 50Ω"); }));
SetImpedance1MCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(Channel, false, Ct()); AppendLog($"C{Channel} 输入阻抗已设为 1MΩ"); }));
SetTimeBaseCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(TimeBase, Ct()); AppendLog($"水平时基已设为 {TimeBase} s/div"); }));
SetTriggerLevelCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(TriggerLevel, Ct()); AppendLog($"触发电平已设为 {TriggerLevel} V"); }));
SetTriggerSourceCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.(TriggerSource, Ct()); AppendLog($"触发源已设为 {TriggerSource}"); }));
QueryMeasurementsCommand = new DelegateCommand(async () => await Exec(async () =>
{
MeasuredVpp = await _device!.(Channel, Ct());
MeasuredFrequency = await _device!.(Channel, Ct());
MeasuredRms = await _device!.(Channel, Ct());
AppendLog($"C{Channel} 测量 → Vpp:{MeasuredVpp} Freq:{MeasuredFrequency}Hz RMS:{MeasuredRms}V");
}));
QueryVppCommand = new DelegateCommand(async () => await Exec(async () => { MeasuredVpp = await _device!.(Channel, Ct()); AppendLog($"C{Channel} Vpp: {MeasuredVpp}"); }));
QueryFrequencyCommand = new DelegateCommand(async () => await Exec(async () => { MeasuredFrequency = await _device!.(Channel, Ct()); AppendLog($"C{Channel} Freq: {MeasuredFrequency}"); }));
QueryRmsCommand = new DelegateCommand(async () => await Exec(async () => { MeasuredRms = await _device!.(Channel, Ct()); AppendLog($"C{Channel} RMS: {MeasuredRms}"); }));
Initialize();
}
#region / Navigation
public void Initialize(string? deviceName = null)
{
SDS2000X_HD? found = null;
string? foundName = null;
if (deviceName != null &&
_deviceManager.DeviceMap.TryGetValue(deviceName, out var d) &&
d is SDS2000X_HD s)
{
found = s;
foundName = deviceName;
}
else
{
foreach (var kv in _deviceManager.DeviceMap)
{
if (kv.Value is SDS2000X_HD sds)
{
found = sds;
foundName = kv.Key;
break;
}
}
}
_device = found;
DeviceName = foundName ?? "SDS2000X_HD (未找到)";
IsConnected = _device?.IsConnected ?? false;
AppendLog(found != null
? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "" : "")}"
: "未在 DeviceManager 中找到 SDS2000X_HD 设备,请先初始化设备配置。");
}
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();
}
}
}