diff --git a/DeviceEditModule/DeviceEditModule.cs b/DeviceEditModule/DeviceEditModule.cs index 032dbd6..1e73203 100644 --- a/DeviceEditModule/DeviceEditModule.cs +++ b/DeviceEditModule/DeviceEditModule.cs @@ -15,8 +15,22 @@ namespace DeviceEditModule containerRegistry.RegisterDialog("DialogMangerView"); // 设备编辑 View 注册为 Navigation(被动态解析后作为 Tab 内容嵌入 DialogMangerView) - //containerRegistry.RegisterForNavigation("IT7800EView"); - //containerRegistry.Register(); + containerRegistry.RegisterForNavigation("DG1000ZView"); + containerRegistry.RegisterForNavigation("IT6720View"); + containerRegistry.RegisterForNavigation("PW8001View"); + containerRegistry.RegisterForNavigation("ANEVH80View"); + containerRegistry.RegisterForNavigation("Chroma61800View"); + containerRegistry.RegisterForNavigation("MCc30WView"); + containerRegistry.RegisterForNavigation("RLT1000View"); + containerRegistry.RegisterForNavigation("S7200View"); + containerRegistry.Register(); + containerRegistry.Register(); + containerRegistry.Register(); + containerRegistry.Register(); + containerRegistry.Register(); + containerRegistry.Register(); + containerRegistry.Register(); + containerRegistry.Register(); } } } diff --git a/DeviceEditModule/ViewModels/ANEVH80ViewModel.cs b/DeviceEditModule/ViewModels/ANEVH80ViewModel.cs new file mode 100644 index 0000000..790c795 --- /dev/null +++ b/DeviceEditModule/ViewModels/ANEVH80ViewModel.cs @@ -0,0 +1,115 @@ +using DeviceCommand.Devices; +using Prism.Commands; +using Prism.Ioc; +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Input; +using UIShare.GlobalVariable; +using UIShare.ViewModelBase; + +namespace DeviceEditModule.ViewModels +{ + /// + /// ANEVH80 电子负载 控制面板 ViewModel + /// + public class ANEVH80ViewModel : NavigateViewModelBase, IDisposable + { + private readonly DeviceManager _dm; + private ANEVH80? _dev; + private CancellationTokenSource? _cts; + + private string _deviceName = "ANEVH80"; + 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); } + + #region 输入参数 + + #endregion + + #region 测量结果 + private double _measuredValue; + public double MeasuredValue { get => _measuredValue; set => SetProperty(ref _measuredValue, value); } + private string _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand QueryIdn { get; } public ICommand Measure { get; } + #endregion + + public ANEVH80ViewModel(IContainerProvider cp) : base(cp) + { + _dm = cp.Resolve(); + QueryIdn = new DelegateCommand(async () => await Exec(async () => Log("IDN: 占位符设备"))); + Measure = new DelegateCommand(async () => await Exec(async () => { MeasuredValue = await _dev!.占位符(Ct()); Log($"测量值={MeasuredValue}"); })); + Initialize(); + } + + #region 初始化 / Navigation + + public void Initialize(string? deviceName = null) + { + ANEVH80? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is ANEVH80 e) + { found = e; fn = deviceName; } + else + { + foreach (var kv in _dm.DeviceMap) + if (kv.Value is ANEVH80 it) { found = it; fn = kv.Key; break; } + } + _dev = found; + DeviceName = fn ?? "ANEVH80 (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 ANEVH80 设备"); + } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + + #region 辅助 + + private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; + + private async Task Exec(Func action) + { + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } + if (IsBusy) return; + IsBusy = true; + try + { + await action(); + IsConnected = _dev.IsConnected; + } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } + } + + private void Log(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(); + } + } +} diff --git a/DeviceEditModule/ViewModels/Chroma61800ViewModel.cs b/DeviceEditModule/ViewModels/Chroma61800ViewModel.cs new file mode 100644 index 0000000..19cf583 --- /dev/null +++ b/DeviceEditModule/ViewModels/Chroma61800ViewModel.cs @@ -0,0 +1,142 @@ +using DeviceCommand.Devices; +using Prism.Commands; +using Prism.Ioc; +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Input; +using UIShare.GlobalVariable; +using UIShare.ViewModelBase; + +namespace DeviceEditModule.ViewModels +{ + /// + /// Chroma61800 交流源一拖三 控制面板 ViewModel + /// + public class Chroma61800ViewModel : NavigateViewModelBase, IDisposable + { + private readonly DeviceManager _dm; + private Chroma61800? _dev; + private CancellationTokenSource? _cts; + + private string _deviceName = "Chroma61800"; + 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); } + + #region 输入参数 + private double _voltage; public double Voltage { get => _voltage; set => SetProperty(ref _voltage, value); } + private double _frequency = 50; public double Frequency { get => _frequency; set => SetProperty(ref _frequency, value); } + private string _waveform = "SINE"; public string Waveform { get => _waveform; set => SetProperty(ref _waveform, 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 _measuredFrequency; + public double MeasuredFrequency { get => _measuredFrequency; set => SetProperty(ref _measuredFrequency, value); } + private double _measuredPower; + public double MeasuredPower { get => _measuredPower; set => SetProperty(ref _measuredPower, value); } + private string _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand QueryIdn { get; } public ICommand Reset { get; } + public ICommand OutOn { get; } public ICommand OutOff { get; } + public ICommand SetV { get; } public ICommand SetF { get; } public ICommand SetWave { get; } + public ICommand SetThreePhase { get; } public ICommand SetSinglePhase { get; } + public ICommand QMeas { get; } + #endregion + + public Chroma61800ViewModel(IContainerProvider cp) : base(cp) + { + _dm = cp.Resolve(); + QueryIdn = new DelegateCommand(async () => await Exec(async () => Log("IDN:" + await _dev!.查询设备信息Async(Ct())))); + Reset = new DelegateCommand(async () => await Exec(async () => { await _dev!.复位Async(Ct()); Log("设备已复位"); })); + OutOn = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置输出开关Async(true, Ct()); Log("输出已开启"); })); + OutOff = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置输出开关Async(false, Ct()); Log("输出已关闭"); })); + SetV = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置交流电压Async(Voltage, Ct()); Log($"电压={Voltage}V"); })); + SetF = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置频率Async(Frequency, Ct()); Log($"频率={Frequency}Hz"); })); + SetWave = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置波形Async(Waveform, Ct()); Log($"波形={Waveform}"); })); + SetThreePhase = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置单三相模式Async(true, Ct()); Log("三相模式"); })); + SetSinglePhase = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置单三相模式Async(false, Ct()); Log("单相模式"); })); + QMeas = new DelegateCommand(async () => await Exec(async () => + { + MeasuredVoltage = await _dev!.读取交流电压Async(Ct()); + MeasuredCurrent = await _dev!.读取交流电流Async(Ct()); + MeasuredFrequency = await _dev!.读取频率Async(Ct()); + MeasuredPower = await _dev!.读取真实功率Async(Ct()); + Log($"测量→V:{MeasuredVoltage} I:{MeasuredCurrent} F:{MeasuredFrequency} P:{MeasuredPower}"); + })); + Initialize(); + } + + #region 初始化 / Navigation + + public void Initialize(string? deviceName = null) + { + Chroma61800? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is Chroma61800 e) + { found = e; fn = deviceName; } + else + { + foreach (var kv in _dm.DeviceMap) + if (kv.Value is Chroma61800 it) { found = it; fn = kv.Key; break; } + } + _dev = found; + DeviceName = fn ?? "Chroma61800 (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 Chroma61800 设备"); + } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + + #region 辅助 + + private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; + + private async Task Exec(Func action) + { + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } + if (IsBusy) return; + IsBusy = true; + try + { + await action(); + IsConnected = _dev.IsConnected; + } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } + } + + private void Log(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(); + } + } +} diff --git a/DeviceEditModule/ViewModels/DG1000ZViewModel.cs b/DeviceEditModule/ViewModels/DG1000ZViewModel.cs index 79fef6f..6768503 100644 --- a/DeviceEditModule/ViewModels/DG1000ZViewModel.cs +++ b/DeviceEditModule/ViewModels/DG1000ZViewModel.cs @@ -1,133 +1,122 @@ -using DeviceCommand.Devices; +using DeviceCommand.Devices; +using Prism.Commands; +using Prism.Ioc; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Threading; using System.Threading.Tasks; +using System.Windows.Input; using UIShare.GlobalVariable; using UIShare.ViewModelBase; namespace DeviceEditModule.ViewModels { + /// + /// DG1000Z 信号发生器一拖三 控制面板 ViewModel + /// public class DG1000ZViewModel : NavigateViewModelBase, IDisposable { - #region 私有字段 - private readonly DeviceManager _deviceManager; - private DG1000Z? _device; + private readonly DeviceManager _dm; + private DG1000Z? _dev; private CancellationTokenSource? _cts; - #endregion - #region 属性 + private string _deviceName = "DG1000Z"; - public string DeviceName - { - get => _deviceName; - set => SetProperty(ref _deviceName, value); - } - + public string DeviceName { get => _deviceName; set => SetProperty(ref _deviceName, value); } private bool _isConnected; - public bool IsConnected - { - get => _isConnected; - set => SetProperty(ref _isConnected, value); - } + public bool IsConnected { get => _isConnected; set => SetProperty(ref _isConnected, value); } private bool _isBusy; - /// 正在执行设备命令时为 true,用于 UI 忙碌状态指示。 - public bool IsBusy + public bool IsBusy { get => _isBusy; set => SetProperty(ref _isBusy, value); } + + #region 输入参数 + private int _channel = 1; public int Channel { get => _channel; set => SetProperty(ref _channel, value); } + private double _frequency = 1000; public double Frequency { get => _frequency; set => SetProperty(ref _frequency, value); } + private double _amplitude = 5; public double Amplitude { get => _amplitude; set => SetProperty(ref _amplitude, value); } + private double _offsetVoltage; public double OffsetVoltage { get => _offsetVoltage; set => SetProperty(ref _offsetVoltage, value); } + private double _dutyCycle = 50; public double DutyCycle { get => _dutyCycle; set => SetProperty(ref _dutyCycle, value); } + #endregion + + #region 测量结果 + private double _measuredFrequency; + public double MeasuredFrequency { get => _measuredFrequency; set => SetProperty(ref _measuredFrequency, value); } + private double _measuredAmplitude; + public double MeasuredAmplitude { get => _measuredAmplitude; set => SetProperty(ref _measuredAmplitude, value); } + private string _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand QueryIdn { get; } public ICommand Reset { get; } + public ICommand OutOn { get; } public ICommand OutOff { get; } + public ICommand SetFreq { get; } public ICommand SetAmp { get; } public ICommand SetOffset { get; } + public ICommand SetDuty { get; } public ICommand QueryFreq { get; } public ICommand QueryAmp { get; } + public ICommand QueryCounter { get; } public ICommand QueryError { get; } + #endregion + + public DG1000ZViewModel(IContainerProvider cp) : base(cp) { - get => _isBusy; - set => SetProperty(ref _isBusy, value); - } - private string _responseLog = string.Empty; - /// 命令响应日志(最新消息在顶部)。 - public string ResponseLog - { - get => _responseLog; - set => SetProperty(ref _responseLog, value); + _dm = cp.Resolve(); + QueryIdn = new DelegateCommand(async () => await Exec(async () => Log("IDN:" + await _dev!.查询设备标识(Ct())))); + Reset = new DelegateCommand(async () => await Exec(async () => { await _dev!.重置设备(Ct()); Log("设备已重置"); })); + OutOn = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置通道输出状态(Channel, true, Ct()); Log($"CH{Channel}输出开"); })); + OutOff = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置通道输出状态(Channel, false, Ct()); Log($"CH{Channel}输出关"); })); + SetFreq = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置频率(Channel, Frequency, Ct()); Log($"CH{Channel}频率={Frequency}Hz"); })); + SetAmp = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置幅度(Channel, Amplitude, Ct()); Log($"CH{Channel}幅度={Amplitude}Vpp"); })); + SetOffset = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置偏移电压(Channel, OffsetVoltage, Ct()); Log($"CH{Channel}偏移={OffsetVoltage}Vdc"); })); + SetDuty = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置方波占空比(Channel, DutyCycle, Ct()); Log($"CH{Channel}占空比={DutyCycle}%"); })); + QueryFreq = new DelegateCommand(async () => await Exec(async () => { MeasuredFrequency = await _dev!.查询频率(Channel, Ct()); Log($"CH{Channel}频率={MeasuredFrequency}Hz"); })); + QueryAmp = new DelegateCommand(async () => await Exec(async () => { MeasuredAmplitude = await _dev!.查询幅度(Channel, Ct()); Log($"CH{Channel}幅度={MeasuredAmplitude}Vpp"); })); + QueryCounter = new DelegateCommand(async () => await Exec(async () => { MeasuredFrequency = await _dev!.查询频率计测量值(Ct()); Log($"频率计={MeasuredFrequency}Hz"); })); + QueryError = new DelegateCommand(async () => await Exec(async () => Log("错误:" + await _dev!.查询错误信息(Ct())))); + Initialize(); } - #endregion - #region 命令 - #endregion - public DG1000ZViewModel(IContainerProvider containerProvider) : base(containerProvider) - { - _deviceManager = containerProvider.Resolve(); - } - public void Dispose() - { - _cts?.Cancel(); - _cts?.Dispose(); - } #region 初始化 / Navigation - /// - /// 从 DeviceManager 中查找DG1000Z设备实例。 - /// 优先按 查找,否则取第一个匹配类型的设备。 - /// public void Initialize(string? deviceName = null) { - DG1000Z? found = null; - string? foundName = null; - if (deviceName != null && - _deviceManager.DeviceMap.TryGetValue(deviceName, out var d) && - d is DG1000Z e) - { - found = e; - foundName = deviceName; - } + DG1000Z? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is DG1000Z e) + { found = e; fn = deviceName; } else { - foreach (var kv in _deviceManager.DeviceMap) - { - if (kv.Value is DG1000Z it) - { - found = it; - foundName = kv.Key; - break; - } - } + foreach (var kv in _dm.DeviceMap) + if (kv.Value is DG1000Z it) { found = it; fn = kv.Key; break; } } - - _device = found; - DeviceName = foundName ?? "IT7800E (未找到)"; - IsConnected = _device?.IsConnected ?? false; - - AppendLog(found != null - ? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "已连接" : "未连接")}" - : "未在 DeviceManager 中找到 IT7800E 设备,请先初始化设备配置。"); + _dev = found; + DeviceName = fn ?? "DG1000Z (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 DG1000Z 设备"); } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + #region 辅助 private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; private async Task Exec(Func action) { - if (_device == null) - { - AppendLog("错误:未关联到设备实例,请检查设备配置。"); - return; - } + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } if (IsBusy) return; IsBusy = true; try { await action(); - IsConnected = _device.IsConnected; - } - catch (OperationCanceledException) - { - AppendLog("命令超时或已取消。"); - } - catch (Exception ex) - { - AppendLog($"错误:{ex.Message}"); - } - finally - { - IsBusy = false; + IsConnected = _dev.IsConnected; } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } } - private void AppendLog(string message) + private void Log(string message) { var line = $"[{DateTime.Now:HH:mm:ss}] {message}"; ResponseLog = ResponseLog.Length > 4000 @@ -136,12 +125,11 @@ namespace DeviceEditModule.ViewModels } #endregion - public override void OnNavigatedTo(NavigationContext context) - { - var name = context.Parameters.GetValue("DeviceName"); - Initialize(name); - } - #endregion + public void Dispose() + { + _cts?.Cancel(); + _cts?.Dispose(); + } } } diff --git a/DeviceEditModule/ViewModels/IT6720ViewModel.cs b/DeviceEditModule/ViewModels/IT6720ViewModel.cs index 1f81c54..538709f 100644 --- a/DeviceEditModule/ViewModels/IT6720ViewModel.cs +++ b/DeviceEditModule/ViewModels/IT6720ViewModel.cs @@ -1,133 +1,124 @@ -using DeviceCommand.Devices; +using DeviceCommand.Devices; +using Prism.Commands; +using Prism.Ioc; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Threading; using System.Threading.Tasks; +using System.Windows.Input; using UIShare.GlobalVariable; using UIShare.ViewModelBase; namespace DeviceEditModule.ViewModels { + /// + /// IT6720 低压电源一拖三 控制面板 ViewModel + /// public class IT6720ViewModel : NavigateViewModelBase, IDisposable { - #region 私有字段 - private readonly DeviceManager _deviceManager; - private IT6720? _device; + private readonly DeviceManager _dm; + private IT6720? _dev; private CancellationTokenSource? _cts; - #endregion - #region 属性 + private string _deviceName = "IT6720"; - public string DeviceName - { - get => _deviceName; - set => SetProperty(ref _deviceName, value); - } - + public string DeviceName { get => _deviceName; set => SetProperty(ref _deviceName, value); } private bool _isConnected; - public bool IsConnected - { - get => _isConnected; - set => SetProperty(ref _isConnected, value); - } + public bool IsConnected { get => _isConnected; set => SetProperty(ref _isConnected, value); } private bool _isBusy; - /// 正在执行设备命令时为 true,用于 UI 忙碌状态指示。 - public bool IsBusy + public bool IsBusy { get => _isBusy; set => SetProperty(ref _isBusy, value); } + + #region 输入参数 + private double _voltage; public double Voltage { get => _voltage; set => SetProperty(ref _voltage, value); } + private double _current; public double Current { get => _current; set => SetProperty(ref _current, value); } + private double _voltageLimit; public double VoltageLimit { get => _voltageLimit; set => SetProperty(ref _voltageLimit, 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 string _outputMode = ""; + public string OutputMode { get => _outputMode; set => SetProperty(ref _outputMode, value); } + private string _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand QueryIdn { get; } public ICommand OutOn { get; } public ICommand OutOff { get; } + public ICommand SetRemote { get; } public ICommand SetLocal { get; } + public ICommand SetV { get; } public ICommand SetI { get; } public ICommand SetVLim { get; } + public ICommand QMeas { get; } public ICommand QMode { get; } + #endregion + + public IT6720ViewModel(IContainerProvider cp) : base(cp) { - get => _isBusy; - set => SetProperty(ref _isBusy, value); - } - private string _responseLog = string.Empty; - /// 命令响应日志(最新消息在顶部)。 - public string ResponseLog - { - get => _responseLog; - set => SetProperty(ref _responseLog, value); + _dm = cp.Resolve(); + QueryIdn = new DelegateCommand(async () => await Exec(async () => Log("IDN:" + await _dev!.查询设备信息(Ct())))); + OutOn = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置输出开关(true, Ct()); Log("输出已开启"); })); + OutOff = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置输出开关(false, Ct()); Log("输出已关闭"); })); + SetRemote = new DelegateCommand(async () => await Exec(async () => { await _dev!.切换远程控制模式(true, Ct()); Log("远程控制"); })); + SetLocal = new DelegateCommand(async () => await Exec(async () => { await _dev!.切换本地控制模式(Ct()); Log("本地控制"); })); + SetV = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置输出电压(Voltage, Ct()); Log($"电压={Voltage}V"); })); + SetI = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置输出电流(Current, Ct()); Log($"电流={Current}A"); })); + SetVLim = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置电压上限(VoltageLimit, Ct()); Log($"电压上限={VoltageLimit}V"); })); + QMeas = new DelegateCommand(async () => await Exec(async () => + { + MeasuredVoltage = await _dev!.查询实际电压(Ct()); + MeasuredCurrent = await _dev!.查询实际电流(Ct()); + Log($"测量→V:{MeasuredVoltage} I:{MeasuredCurrent}"); + })); + QMode = new DelegateCommand(async () => await Exec(async () => { OutputMode = await _dev!.查询输出模式(Ct()); Log($"输出模式={OutputMode}"); })); + Initialize(); } - #endregion - #region 命令 - #endregion - public IT6720ViewModel(IContainerProvider containerProvider) : base(containerProvider) - { - _deviceManager = containerProvider.Resolve(); - } - public void Dispose() - { - _cts?.Cancel(); - _cts?.Dispose(); - } #region 初始化 / Navigation - /// - /// 从 DeviceManager 中查找IT6720设备实例。 - /// 优先按 查找,否则取第一个匹配类型的设备。 - /// public void Initialize(string? deviceName = null) { - IT6720? found = null; - string? foundName = null; - if (deviceName != null && - _deviceManager.DeviceMap.TryGetValue(deviceName, out var d) && - d is IT6720 e) - { - found = e; - foundName = deviceName; - } + IT6720? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is IT6720 e) + { found = e; fn = deviceName; } else { - foreach (var kv in _deviceManager.DeviceMap) - { - if (kv.Value is IT6720 it) - { - found = it; - foundName = kv.Key; - break; - } - } + foreach (var kv in _dm.DeviceMap) + if (kv.Value is IT6720 it) { found = it; fn = kv.Key; break; } } - - _device = found; - DeviceName = foundName ?? "IT7800E (未找到)"; - IsConnected = _device?.IsConnected ?? false; - - AppendLog(found != null - ? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "已连接" : "未连接")}" - : "未在 DeviceManager 中找到 IT7800E 设备,请先初始化设备配置。"); + _dev = found; + DeviceName = fn ?? "IT6720 (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 IT6720 设备"); } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + #region 辅助 private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; private async Task Exec(Func action) { - if (_device == null) - { - AppendLog("错误:未关联到设备实例,请检查设备配置。"); - return; - } + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } if (IsBusy) return; IsBusy = true; try { await action(); - IsConnected = _device.IsConnected; - } - catch (OperationCanceledException) - { - AppendLog("命令超时或已取消。"); - } - catch (Exception ex) - { - AppendLog($"错误:{ex.Message}"); - } - finally - { - IsBusy = false; + IsConnected = _dev.IsConnected; } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } } - private void AppendLog(string message) + private void Log(string message) { var line = $"[{DateTime.Now:HH:mm:ss}] {message}"; ResponseLog = ResponseLog.Length > 4000 @@ -136,12 +127,11 @@ namespace DeviceEditModule.ViewModels } #endregion - public override void OnNavigatedTo(NavigationContext context) - { - var name = context.Parameters.GetValue("DeviceName"); - Initialize(name); - } - #endregion + public void Dispose() + { + _cts?.Cancel(); + _cts?.Dispose(); + } } } diff --git a/DeviceEditModule/ViewModels/MCc30WViewModel.cs b/DeviceEditModule/ViewModels/MCc30WViewModel.cs new file mode 100644 index 0000000..ca2c525 --- /dev/null +++ b/DeviceEditModule/ViewModels/MCc30WViewModel.cs @@ -0,0 +1,140 @@ +using DeviceCommand.Devices; +using Prism.Commands; +using Prism.Ioc; +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Input; +using UIShare.GlobalVariable; +using UIShare.ViewModelBase; + +namespace DeviceEditModule.ViewModels +{ + /// + /// MCc30W 水冷机一拖三 控制面板 ViewModel + /// + public class MCc30WViewModel : NavigateViewModelBase, IDisposable + { + private readonly DeviceManager _dm; + private MCc30W? _dev; + private CancellationTokenSource? _cts; + + private string _deviceName = "MCc30W"; + 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); } + + #region 输入参数 + private int _loop = 1; public int Loop { get => _loop; set => SetProperty(ref _loop, value); } + private float _tempSet = 25f; public float TempSet { get => _tempSet; set => SetProperty(ref _tempSet, value); } + private float _flowSet = 10f; public float FlowSet { get => _flowSet; set => SetProperty(ref _flowSet, value); } + private float _pressSet = 100f; public float PressSet { get => _pressSet; set => SetProperty(ref _pressSet, value); } + #endregion + + #region 测量结果 + private float _currentTemp; + public float CurrentTemp { get => _currentTemp; set => SetProperty(ref _currentTemp, value); } + private float _currentFlow; + public float CurrentFlow { get => _currentFlow; set => SetProperty(ref _currentFlow, value); } + private float _currentPress; + public float CurrentPress { get => _currentPress; set => SetProperty(ref _currentPress, value); } + private uint _alarmInfo; + public uint AlarmInfo { get => _alarmInfo; set => SetProperty(ref _alarmInfo, value); } + private string _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand LoopOn { get; } public ICommand LoopOff { get; } + public ICommand SetTemp { get; } public ICommand SetFlow { get; } public ICommand SetPress { get; } + public ICommand AlarmReset { get; } public ICommand AlarmSilence { get; } + public ICommand ReadAll { get; } public ICommand ReadAlarm { get; } + #endregion + + public MCc30WViewModel(IContainerProvider cp) : base(cp) + { + _dm = cp.Resolve(); + LoopOn = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置回路运行Async(Loop, true, Ct()); Log($"回路{Loop}已启动"); })); + LoopOff = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置回路运行Async(Loop, false, Ct()); Log($"回路{Loop}已停止"); })); + SetTemp = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置出液目标温度Async(Loop, TempSet, Ct()); Log($"回路{Loop}温度={TempSet}℃"); })); + SetFlow = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置出液目标流量Async(Loop, FlowSet, Ct()); Log($"回路{Loop}流量={FlowSet}L/min"); })); + SetPress = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置出液目标压力Async(Loop, PressSet, Ct()); Log($"回路{Loop}压力={PressSet}kPa"); })); + AlarmReset = new DelegateCommand(async () => await Exec(async () => { await _dev!.报警复位Async(true, Ct()); await _dev!.报警复位Async(false, Ct()); Log("报警已复位"); })); + AlarmSilence = new DelegateCommand(async () => await Exec(async () => { await _dev!.报警消音Async(true, Ct()); Log("报警已消音"); })); + ReadAll = new DelegateCommand(async () => await Exec(async () => + { + CurrentTemp = await _dev!.读取出液当前温度Async(Loop, Ct()); + CurrentFlow = await _dev!.读取出液当前流量Async(Loop, Ct()); + CurrentPress = await _dev!.读取出液当前压力Async(Loop, Ct()); + Log($"回路{Loop}→T:{CurrentTemp}℃ F:{CurrentFlow}L/min P:{CurrentPress}kPa"); + })); + ReadAlarm = new DelegateCommand(async () => await Exec(async () => { AlarmInfo = await _dev!.读报警信息1Async(Ct()); Log($"报警信息={AlarmInfo}"); })); + Initialize(); + } + + #region 初始化 / Navigation + + public void Initialize(string? deviceName = null) + { + MCc30W? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is MCc30W e) + { found = e; fn = deviceName; } + else + { + foreach (var kv in _dm.DeviceMap) + if (kv.Value is MCc30W it) { found = it; fn = kv.Key; break; } + } + _dev = found; + DeviceName = fn ?? "MCc30W (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 MCc30W 设备"); + } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + + #region 辅助 + + private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; + + private async Task Exec(Func action) + { + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } + if (IsBusy) return; + IsBusy = true; + try + { + await action(); + IsConnected = _dev.IsConnected; + } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } + } + + private void Log(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(); + } + } +} diff --git a/DeviceEditModule/ViewModels/PW8001ViewModel.cs b/DeviceEditModule/ViewModels/PW8001ViewModel.cs index f081e49..e45a132 100644 --- a/DeviceEditModule/ViewModels/PW8001ViewModel.cs +++ b/DeviceEditModule/ViewModels/PW8001ViewModel.cs @@ -1,134 +1,128 @@ -using DeviceCommand.Device; -using DeviceCommand.Devices; +using DeviceCommand.Device; +using Prism.Commands; +using Prism.Ioc; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Threading; using System.Threading.Tasks; +using System.Windows.Input; using UIShare.GlobalVariable; using UIShare.ViewModelBase; namespace DeviceEditModule.ViewModels { + /// + /// PW8001 功率分析仪 控制面板 ViewModel + /// public class PW8001ViewModel : NavigateViewModelBase, IDisposable { - #region 私有字段 - private readonly DeviceManager _deviceManager; - private PW8001? _device; + private readonly DeviceManager _dm; + private PW8001? _dev; private CancellationTokenSource? _cts; - #endregion - #region 属性 + private string _deviceName = "PW8001"; - public string DeviceName - { - get => _deviceName; - set => SetProperty(ref _deviceName, value); - } - + public string DeviceName { get => _deviceName; set => SetProperty(ref _deviceName, value); } private bool _isConnected; - public bool IsConnected - { - get => _isConnected; - set => SetProperty(ref _isConnected, value); - } + public bool IsConnected { get => _isConnected; set => SetProperty(ref _isConnected, value); } private bool _isBusy; - /// 正在执行设备命令时为 true,用于 UI 忙碌状态指示。 - public bool IsBusy + public bool IsBusy { get => _isBusy; set => SetProperty(ref _isBusy, value); } + + #region 输入参数 + private int _channel = 1; public int Channel { get => _channel; set => SetProperty(ref _channel, 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 double _voltageTHD; + public double VoltageTHD { get => _voltageTHD; set => SetProperty(ref _voltageTHD, value); } + private double _currentTHD; + public double CurrentTHD { get => _currentTHD; set => SetProperty(ref _currentTHD, value); } + private double _totalPower; + public double TotalPower { get => _totalPower; set => SetProperty(ref _totalPower, value); } + private string _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand QueryIdn { get; } public ICommand Reset { get; } public ICommand Clear { get; } + public ICommand ModeWIDE { get; } public ICommand ModeIEC { get; } + public ICommand QV { get; } public ICommand QI { get; } public ICommand QP { get; } + public ICommand QP123 { get; } public ICommand QTHD { get; } + #endregion + + public PW8001ViewModel(IContainerProvider cp) : base(cp) { - get => _isBusy; - set => SetProperty(ref _isBusy, value); - } - private string _responseLog = string.Empty; - /// 命令响应日志(最新消息在顶部)。 - public string ResponseLog - { - get => _responseLog; - set => SetProperty(ref _responseLog, value); + _dm = cp.Resolve(); + QueryIdn = new DelegateCommand(async () => await Exec(async () => Log("IDN:" + await _dev!.查询机器信息(Ct())))); + Reset = new DelegateCommand(async () => await Exec(async () => { await _dev!.复位仪器(Ct()); Log("仪器已复位"); })); + Clear = new DelegateCommand(async () => await Exec(async () => { await _dev!.清除状态(Ct()); Log("状态已清除"); })); + ModeWIDE = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置测试模式_WIDE(Ct()); Log("WIDE模式"); })); + ModeIEC = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置测试模式_IEC(Ct()); Log("IEC模式"); })); + QV = new DelegateCommand(async () => await Exec(async () => { MeasuredVoltage = await _dev!.查询电压_不含变比(Channel, Ct()); Log($"CH{Channel}电压={MeasuredVoltage}V"); })); + QI = new DelegateCommand(async () => await Exec(async () => { MeasuredCurrent = await _dev!.查询电流_不含变比(Channel, Ct()); Log($"CH{Channel}电流={MeasuredCurrent}A"); })); + QP = new DelegateCommand(async () => await Exec(async () => { MeasuredPower = await _dev!.查询功率_不含变比(Channel, Ct()); Log($"CH{Channel}功率={MeasuredPower}W"); })); + QP123 = new DelegateCommand(async () => await Exec(async () => { TotalPower = await _dev!.查询总功率P123(Ct()); Log($"三相总功率={TotalPower}W"); })); + QTHD = new DelegateCommand(async () => await Exec(async () => + { + VoltageTHD = await _dev!.查询电压THD(Channel, Ct()); + CurrentTHD = await _dev!.查询电流THD(Channel, Ct()); + Log($"CH{Channel} THD→U:{VoltageTHD}% I:{CurrentTHD}%"); + })); + Initialize(); } - #endregion - #region 命令 - #endregion - public PW8001ViewModel(IContainerProvider containerProvider) : base(containerProvider) - { - _deviceManager = containerProvider.Resolve(); - } - public void Dispose() - { - _cts?.Cancel(); - _cts?.Dispose(); - } #region 初始化 / Navigation - /// - /// 从 DeviceManager 中查找PW8001设备实例。 - /// 优先按 查找,否则取第一个匹配类型的设备。 - /// public void Initialize(string? deviceName = null) { - PW8001? found = null; - string? foundName = null; - if (deviceName != null && - _deviceManager.DeviceMap.TryGetValue(deviceName, out var d) && - d is PW8001 e) - { - found = e; - foundName = deviceName; - } + PW8001? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is PW8001 e) + { found = e; fn = deviceName; } else { - foreach (var kv in _deviceManager.DeviceMap) - { - if (kv.Value is PW8001 it) - { - found = it; - foundName = kv.Key; - break; - } - } + foreach (var kv in _dm.DeviceMap) + if (kv.Value is PW8001 it) { found = it; fn = kv.Key; break; } } - - _device = found; - DeviceName = foundName ?? "IT7800E (未找到)"; - IsConnected = _device?.IsConnected ?? false; - - AppendLog(found != null - ? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "已连接" : "未连接")}" - : "未在 DeviceManager 中找到 IT7800E 设备,请先初始化设备配置。"); + _dev = found; + DeviceName = fn ?? "PW8001 (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 PW8001 设备"); } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + #region 辅助 private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; private async Task Exec(Func action) { - if (_device == null) - { - AppendLog("错误:未关联到设备实例,请检查设备配置。"); - return; - } + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } if (IsBusy) return; IsBusy = true; try { await action(); - IsConnected = _device.IsConnected; - } - catch (OperationCanceledException) - { - AppendLog("命令超时或已取消。"); - } - catch (Exception ex) - { - AppendLog($"错误:{ex.Message}"); - } - finally - { - IsBusy = false; + IsConnected = _dev.IsConnected; } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } } - private void AppendLog(string message) + private void Log(string message) { var line = $"[{DateTime.Now:HH:mm:ss}] {message}"; ResponseLog = ResponseLog.Length > 4000 @@ -137,12 +131,11 @@ namespace DeviceEditModule.ViewModels } #endregion - public override void OnNavigatedTo(NavigationContext context) - { - var name = context.Parameters.GetValue("DeviceName"); - Initialize(name); - } - #endregion + public void Dispose() + { + _cts?.Cancel(); + _cts?.Dispose(); + } } } diff --git a/DeviceEditModule/ViewModels/RLT1000ViewModel.cs b/DeviceEditModule/ViewModels/RLT1000ViewModel.cs new file mode 100644 index 0000000..9393401 --- /dev/null +++ b/DeviceEditModule/ViewModels/RLT1000ViewModel.cs @@ -0,0 +1,131 @@ +using DeviceCommand.Devices; +using Prism.Commands; +using Prism.Ioc; +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Input; +using UIShare.GlobalVariable; +using UIShare.ViewModelBase; + +namespace DeviceEditModule.ViewModels +{ + /// + /// RLT1000 环境箱 控制面板 ViewModel + /// + public class RLT1000ViewModel : NavigateViewModelBase, IDisposable + { + private readonly DeviceManager _dm; + private RLT1000? _dev; + private CancellationTokenSource? _cts; + + private string _deviceName = "RLT1000"; + 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); } + + #region 输入参数 + private float _targetTemp = 25f; public float TargetTemp { get => _targetTemp; set => SetProperty(ref _targetTemp, value); } + private float _targetHumidity = 50f; public float TargetHumidity { get => _targetHumidity; set => SetProperty(ref _targetHumidity, value); } + #endregion + + #region 测量结果 + private double _currentTemp; + public double CurrentTemp { get => _currentTemp; set => SetProperty(ref _currentTemp, value); } + private double _currentHumidity; + public double CurrentHumidity { get => _currentHumidity; set => SetProperty(ref _currentHumidity, value); } + private string _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand PowerOn { get; } public ICommand PowerOff { get; } + public ICommand SetRemote { get; } public ICommand SetLocal { get; } + public ICommand SetTemp { get; } public ICommand SetHumidity { get; } + public ICommand ReadAll { get; } + #endregion + + public RLT1000ViewModel(IContainerProvider cp) : base(cp) + { + _dm = cp.Resolve(); + PowerOn = new DelegateCommand(async () => await Exec(async () => { await _dev!.远程模式开机(Ct()); Log("环境箱已开机"); })); + PowerOff = new DelegateCommand(async () => await Exec(async () => { await _dev!.远程模式关机(Ct()); Log("环境箱已关机"); })); + SetRemote = new DelegateCommand(async () => await Exec(async () => { await _dev!.切换为远程模式(Ct()); Log("远程控制"); })); + SetLocal = new DelegateCommand(async () => await Exec(async () => { await _dev!.切换为本地模式(Ct()); Log("本地控制"); })); + SetTemp = new DelegateCommand(async () => await Exec(async () => { await _dev!.定值温度设定(TargetTemp, Ct()); Log($"温度={TargetTemp}℃"); })); + SetHumidity = new DelegateCommand(async () => await Exec(async () => { await _dev!.定值湿度设定(TargetHumidity, Ct()); Log($"湿度={TargetHumidity}%RH"); })); + ReadAll = new DelegateCommand(async () => await Exec(async () => + { + CurrentTemp = await _dev!.读取当前温度(Ct()); + CurrentHumidity = await _dev!.读取当前湿度(Ct()); + Log($"环境→T:{CurrentTemp}℃ H:{CurrentHumidity}%RH"); + })); + Initialize(); + } + + #region 初始化 / Navigation + + public void Initialize(string? deviceName = null) + { + RLT1000? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is RLT1000 e) + { found = e; fn = deviceName; } + else + { + foreach (var kv in _dm.DeviceMap) + if (kv.Value is RLT1000 it) { found = it; fn = kv.Key; break; } + } + _dev = found; + DeviceName = fn ?? "RLT1000 (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 RLT1000 设备"); + } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + + #region 辅助 + + private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; + + private async Task Exec(Func action) + { + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } + if (IsBusy) return; + IsBusy = true; + try + { + await action(); + IsConnected = _dev.IsConnected; + } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } + } + + private void Log(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(); + } + } +} diff --git a/DeviceEditModule/ViewModels/S7200ViewModel.cs b/DeviceEditModule/ViewModels/S7200ViewModel.cs new file mode 100644 index 0000000..9b71ecf --- /dev/null +++ b/DeviceEditModule/ViewModels/S7200ViewModel.cs @@ -0,0 +1,144 @@ +using DeviceCommand.Devices; +using Prism.Commands; +using Prism.Ioc; +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Input; +using UIShare.GlobalVariable; +using UIShare.ViewModelBase; + +namespace DeviceEditModule.ViewModels +{ + /// + /// S7200 高压直流源载一体机 控制面板 ViewModel + /// + public class S7200ViewModel : NavigateViewModelBase, IDisposable + { + private readonly DeviceManager _dm; + private S7200? _dev; + private CancellationTokenSource? _cts; + + private string _deviceName = "S7200"; + 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); } + + #region 输入参数 + private double _voltage; public double Voltage { get => _voltage; set => SetProperty(ref _voltage, value); } + private double _current; public double Current { get => _current; set => SetProperty(ref _current, value); } + private double _cvPosI = 10; public double CvPosI { get => _cvPosI; set => SetProperty(ref _cvPosI, value); } + private double _cvNegI = -10; public double CvNegI { get => _cvNegI; set => SetProperty(ref _cvNegI, value); } + private double _ovpValue; public double OvpValue { get => _ovpValue; set => SetProperty(ref _ovpValue, value); } + private double _ocpValue; public double OcpValue { get => _ocpValue; set => SetProperty(ref _ocpValue, 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 _responseLog = ""; + public string ResponseLog { get => _responseLog; set => SetProperty(ref _responseLog, value); } + #endregion + + #region 命令 + public ICommand QueryIdn { get; } public ICommand OutOn { get; } public ICommand OutOff { get; } + public ICommand SetRemote { get; } public ICommand ClearProt { get; } + public ICommand SetV { get; } public ICommand SetCC { get; } public ICommand SetCVPos { get; } public ICommand SetCVNeg { get; } + public ICommand SetOVP { get; } public ICommand SetOCP { get; } + public ICommand QMeas { get; } + #endregion + + public S7200ViewModel(IContainerProvider cp) : base(cp) + { + _dm = cp.Resolve(); + QueryIdn = new DelegateCommand(async () => await Exec(async () => Log("IDN:" + await _dev!.查询设备信息(Ct())))); + OutOn = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置通道开关(true, Ct()); Log("输出已开启"); })); + OutOff = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置通道开关(false, Ct()); Log("输出已关闭"); })); + SetRemote = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置为远程模式(Ct()); Log("远程控制"); })); + ClearProt = new DelegateCommand(async () => await Exec(async () => { await _dev!.清除保护状态(Ct()); Log("保护已清除"); })); + SetV = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置电压(Voltage, Ct()); Log($"电压={Voltage}V"); })); + SetCC = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置CC模式电流(Current, Ct()); Log($"CC电流={Current}A"); })); + SetCVPos = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置CV正向电流(CvPosI, Ct()); Log($"CV正向电流={CvPosI}A"); })); + SetCVNeg = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置CV反向电流(CvNegI, Ct()); Log($"CV反向电流={CvNegI}A"); })); + SetOVP = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置电压保护OVP电压(OvpValue, Ct()); Log($"OVP={OvpValue}V"); })); + SetOCP = new DelegateCommand(async () => await Exec(async () => { await _dev!.设置电流保护OCP电流(OcpValue, Ct()); Log($"OCP={OcpValue}A"); })); + QMeas = new DelegateCommand(async () => await Exec(async () => + { + MeasuredVoltage = await _dev!.查询实时电压(Ct()); + MeasuredCurrent = await _dev!.查询实时电流(Ct()); + MeasuredPower = await _dev!.查询功率(Ct()); + Log($"测量→V:{MeasuredVoltage} I:{MeasuredCurrent} P:{MeasuredPower}"); + })); + Initialize(); + } + + #region 初始化 / Navigation + + public void Initialize(string? deviceName = null) + { + S7200? found = null; string? fn = null; + if (deviceName != null && _dm.DeviceMap.TryGetValue(deviceName, out var d) && d is S7200 e) + { found = e; fn = deviceName; } + else + { + foreach (var kv in _dm.DeviceMap) + if (kv.Value is S7200 it) { found = it; fn = kv.Key; break; } + } + _dev = found; + DeviceName = fn ?? "S7200 (未找到)"; + IsConnected = _dev?.IsConnected ?? false; + Log(found != null + ? $"已关联设备 [{DeviceName}],连接:{(IsConnected ? "已连接" : "未连接")}" + : "未在 DeviceManager 中找到 S7200 设备"); + } + + public override void OnNavigatedTo(NavigationContext context) + { + var pName = context.Parameters.GetValue("DeviceName"); + Initialize(pName); + } + + #endregion + + #region 辅助 + + private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; + + private async Task Exec(Func action) + { + if (_dev == null) { Log("错误:未关联到设备实例,请检查设备配置。"); return; } + if (IsBusy) return; + IsBusy = true; + try + { + await action(); + IsConnected = _dev.IsConnected; + } + catch (OperationCanceledException) { Log("命令超时或已取消。"); } + catch (Exception ex) { Log($"错误:{ex.Message}"); } + finally { IsBusy = false; } + } + + private void Log(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(); + } + } +} diff --git a/DeviceEditModule/Views/ANEVH80View.xaml b/DeviceEditModule/Views/ANEVH80View.xaml new file mode 100644 index 0000000..2f46d6c --- /dev/null +++ b/DeviceEditModule/Views/ANEVH80View.xaml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +