From 66bb6d36baa7fcd0809fb0bc536e4e7556cbe636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chsc=E2=80=9D?= <“huangsucan@kaiyili-lab.com”> Date: Tue, 4 Aug 2026 15:10:37 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DeviceCommand/Devices/ANEVH80.cs | 22 + DeviceCommand/Devices/IT6015C.cs | 363 ---------------- DeviceCommand/Devices/IT6036C .cs | 395 ------------------ .../Devices/{MCc06U.cs => MCc30W.cs} | 4 +- DeviceCommand/Devices/S7200.cs | 213 ++++++++++ DeviceCommand/Devices/TektronixMSO.cs | 98 ++--- .../ViewModels/IT6015CViewModel.cs | 147 ------- .../ViewModels/IT6036CViewModel.cs | 147 ------- DeviceEditModule/Views/IT6015CView.xaml | 15 - DeviceEditModule/Views/IT6015CView.xaml.cs | 28 -- DeviceEditModule/Views/IT6036CView.xaml | 16 - DeviceEditModule/Views/IT6036CView.xaml.cs | 28 -- 12 files changed, 283 insertions(+), 1193 deletions(-) create mode 100644 DeviceCommand/Devices/ANEVH80.cs delete mode 100644 DeviceCommand/Devices/IT6015C.cs delete mode 100644 DeviceCommand/Devices/IT6036C .cs rename DeviceCommand/Devices/{MCc06U.cs => MCc30W.cs} (77%) create mode 100644 DeviceCommand/Devices/S7200.cs delete mode 100644 DeviceEditModule/ViewModels/IT6015CViewModel.cs delete mode 100644 DeviceEditModule/ViewModels/IT6036CViewModel.cs delete mode 100644 DeviceEditModule/Views/IT6015CView.xaml delete mode 100644 DeviceEditModule/Views/IT6015CView.xaml.cs delete mode 100644 DeviceEditModule/Views/IT6036CView.xaml delete mode 100644 DeviceEditModule/Views/IT6036CView.xaml.cs diff --git a/DeviceCommand/Devices/ANEVH80.cs b/DeviceCommand/Devices/ANEVH80.cs new file mode 100644 index 0000000..ea8429b --- /dev/null +++ b/DeviceCommand/Devices/ANEVH80.cs @@ -0,0 +1,22 @@ +using Common.Attributes; +using DeviceCommand.Base; +using Model.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DeviceCommand.Devices +{ + /// + /// 水冷机 一对一 + /// + [ACPCommand] + public class ANEVH80 : Tcp + { + public ANEVH80(TcpConfig config) : base(config) + { + } + } +} diff --git a/DeviceCommand/Devices/IT6015C.cs b/DeviceCommand/Devices/IT6015C.cs deleted file mode 100644 index e553872..0000000 --- a/DeviceCommand/Devices/IT6015C.cs +++ /dev/null @@ -1,363 +0,0 @@ -using Common.Attributes; -using DeviceCommand.Base; -using Model.Models; -using System; -using System.Globalization; -using System.Threading; -using System.Threading.Tasks; - -namespace DeviceCommand.Devices -{ - /// - /// 低压直流源载一体机 一对一 - /// - [ACPCommand] - public class IT6015C : Tcp - { - // SCPI 指令结束符 - private const string ScpiDelimiter = "\n"; - - public IT6015C(TcpConfig config) : base(config) - { - } - - #region 源载公用或系统必备命令 - - // ================= 1. IEEE 488.2 公共命令 ================= - - public virtual async Task 清除状态寄存器(CancellationToken ct = default) - { - await SendAsync($"*CLS{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询设备标识(CancellationToken ct = default) - { - return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 重置设备(CancellationToken ct = default) - { - await SendAsync($"*RST{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询状态字节(CancellationToken ct = default) - { - return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 查询SCPI版本号(CancellationToken ct = default) - { - return await WriteReadAsync($":SYSTem:VERSion?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - - // ================= 2. 系统远程与状态控制 ================= - - public virtual async Task 切换远程控制模式(CancellationToken ct = default) - { - await SendAsync($"SYSTem:REMote{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 切换本地控制模式(CancellationToken ct = default) - { - await SendAsync($"SYSTem:LOCal{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 锁定远程键盘(CancellationToken ct = default) - { - await SendAsync($"SYSTem:RWLock{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询错误信息(CancellationToken ct = default) - { - return await WriteReadAsync($"SYSTem:ERRor?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 清除错误队列(CancellationToken ct = default) - { - await SendAsync($"SYSTem:CLEar{ScpiDelimiter}", ct); //[cite: 1] - } - - - // ================= 3. 功能模式与优先级设置 ================= - - /// - /// 设置电源优先工作模式 (CV 电压优先 或 CC 电流优先) - /// - public virtual async Task 设置优先模式(IT6000CPriorityMode 模式, CancellationToken ct = default) - { - await SendAsync($"FUNCTION {模式}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询优先模式(CancellationToken ct = default) - { - return await WriteReadAsync($"FUNCTION?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置瞬变/功能模式 (固定, LIST, 电池测试, PV曲线, 汽车波形) - /// - public virtual async Task 设置功能模式(IT6000CFunctionMode 模式, CancellationToken ct = default) - { - await SendAsync($"FUNCTION:MODE {模式}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询功能模式(CancellationToken ct = default) - { - return await WriteReadAsync($"FUNCTION:MODE?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - - // ================= 4. 输出开关与保护清除 ================= - - public virtual async Task 设置输出开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"OUTPut {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询输出开关状态(CancellationToken ct = default) - { - return await WriteReadAsync($"OUTPut:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 清除保护告警(CancellationToken ct = default) - { - await SendAsync($"OUTPut:PROTection:CLEar{ScpiDelimiter}", ct); //[cite: 1] - } - - - // ================= 5. 基础设定 (正值代表输出,负值代表吸收) ================= - - /// - /// 设置输出/吸收电压 (仅在 CV 模式下生效) - /// - public virtual async Task 设置电压(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电压设定值(CancellationToken ct = default) - { - return await WriteReadAsync($"VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置输出/吸收电流 (仅在 CC 模式下生效。设定负值即作为负载吸收电流) - /// - public virtual async Task 设置电流(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电流设定值(CancellationToken ct = default) - { - return await WriteReadAsync($"CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置电压上升/下降斜率 (单位: V/s) - /// - public virtual async Task 设置电压斜率(double 斜率Vs, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:SLEW {0:F4}{1}", 斜率Vs, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - - // ================= 6. 保护功能配置 (OVP, OCP, OPP) ================= - - public virtual async Task 设置过压保护开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"VOLTage:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 设置过压保护阈值(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:PROTection {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 设置过流保护开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"CURRent:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 设置过流保护阈值(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:PROTection {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 设置过功率保护开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"POWer:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 设置过功率保护阈值(double 功率, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "POWer:PROTection {0:F2}{1}", 功率, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - - // ================= 7. 测量回读 (MEASure 与 FETCh) ================= - - [Monitorable("直流源载实际电压")] - public virtual async Task 查询实际电压(CancellationToken ct = default) - { - return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - [Monitorable("直流源载实际电流")] - public virtual async Task 查询实际电流(CancellationToken ct = default) - { - return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - [Monitorable("直流源载实际功率")] - public virtual async Task 查询实际功率(CancellationToken ct = default) - { - return await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 查询瞬时电压最大值(CancellationToken ct = default) - { - return await WriteReadAsync($"FETCh:VOLTage:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 查询瞬时电流最小值(CancellationToken ct = default) - { - return await WriteReadAsync($"FETCh:CURRent:MINimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - #endregion - - - #region 直流源 (Source) 专用命令 - - /// - /// 设置 CV 优先模式下的电流限制上限值 (I+, 正向源限流) - /// - public virtual async Task 设置电流限制上限(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:LIMit:POSitive {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电流限制上限(CancellationToken ct = default) - { - return await WriteReadAsync($"CURRent:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置 CC 优先模式下的电压限制上限值 (Vh, 正向源限压) - /// - public virtual async Task 设置电压限制上限(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:LIMit:POSitive {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电压限制上限(CancellationToken ct = default) - { - return await WriteReadAsync($"VOLTage:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置功率上限值 (P+, 源模式功率限制) - /// - public virtual async Task 设置功率限制上限(double 功率, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "POWer:LIMit:POSitive {0:F2}{1}", 功率, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询功率限制上限(CancellationToken ct = default) - { - return await WriteReadAsync($"POWer:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - #endregion - - - #region 电子负载 (Load) 专用命令 - - /// - /// 设置 CV 优先模式下的电流限制下限值 (I-, 载模式电流吸收限制) - /// - public virtual async Task 设置电流限制下限(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:LIMit:NEGative {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电流限制下限(CancellationToken ct = default) - { - return await WriteReadAsync($"CURRent:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置 CC 优先模式下的电压限制下限值 (Vl, 载模式放电截止电压) - /// - public virtual async Task 设置电压限制下限(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:LIMit:NEGative {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电压限制下限(CancellationToken ct = default) - { - return await WriteReadAsync($"VOLTage:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置功率下限值 (P-, 载模式吸收功率限制) - /// - public virtual async Task 设置功率限制下限(double 功率, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "POWer:LIMit:NEGative {0:F2}{1}", 功率, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询功率限制下限(CancellationToken ct = default) - { - return await WriteReadAsync($"POWer:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 开启或关闭恒阻 (CR) 负载模式 (执行前必须处于 CC 优先模式) - /// - public virtual async Task 设置CR模式开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"SINK:RESistance:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询CR模式开关(CancellationToken ct = default) - { - return await WriteReadAsync($"SINK:RESistance:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置恒阻 (CR) 模式下的电阻值 (单位: Ω) - /// - public virtual async Task 设置CR电阻值(double 电阻, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "SINK:RESistance {0:F2}{1}", 电阻, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询CR电阻值(CancellationToken ct = default) - { - return await WriteReadAsync($"SINK:RESistance?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - #endregion - } -} \ No newline at end of file diff --git a/DeviceCommand/Devices/IT6036C .cs b/DeviceCommand/Devices/IT6036C .cs deleted file mode 100644 index d82af8e..0000000 --- a/DeviceCommand/Devices/IT6036C .cs +++ /dev/null @@ -1,395 +0,0 @@ -using Common.Attributes; -using DeviceCommand.Base; -using Model.Models; -using System; -using System.Globalization; -using System.Threading; -using System.Threading.Tasks; - -namespace DeviceCommand.Devices -{ - /// - ///高压直流源载一体机 一对一 - /// - #region 枚举定义 - - /// - /// IT6000C 优先工作模式 (CV优先 / CC优先) - /// - public enum IT6000CPriorityMode - { - /// 恒压优先模式 (CV优先) - VOLTage, - /// 恒流优先模式 (CC优先) - CURRent - } - - /// - /// IT6000C 瞬变功能模式 - /// - public enum IT6000CFunctionMode - { - /// 固定模式 (普通输出) - FIXed, - /// List 列表模式 - LIST, - /// 电池测试模式 - BATTer, - /// 光伏/太阳能板曲线模拟模式 - SOLar, - /// 汽车波形模拟模式 - CARProfile - } - - #endregion - - [ACPCommand] - public class IT6036C : Tcp - { - // SCPI 指令结束符 - private const string ScpiDelimiter = "\n"; - - public IT6036C (TcpConfig config) : base(config) - { - } - - #region 源载公用或系统必备命令 - - // ================= 1. IEEE 488.2 公共命令 ================= - - public virtual async Task 清除状态寄存器(CancellationToken ct = default) - { - await SendAsync($"*CLS{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询设备标识(CancellationToken ct = default) - { - return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 重置设备(CancellationToken ct = default) - { - await SendAsync($"*RST{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询状态字节(CancellationToken ct = default) - { - return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 查询SCPI版本号(CancellationToken ct = default) - { - return await WriteReadAsync($":SYSTem:VERSion?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - - // ================= 2. 系统远程与状态控制 ================= - - public virtual async Task 切换远程控制模式(CancellationToken ct = default) - { - await SendAsync($"SYSTem:REMote{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 切换本地控制模式(CancellationToken ct = default) - { - await SendAsync($"SYSTem:LOCal{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 锁定远程键盘(CancellationToken ct = default) - { - await SendAsync($"SYSTem:RWLock{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询错误信息(CancellationToken ct = default) - { - return await WriteReadAsync($"SYSTem:ERRor?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 清除错误队列(CancellationToken ct = default) - { - await SendAsync($"SYSTem:CLEar{ScpiDelimiter}", ct); //[cite: 1] - } - - - // ================= 3. 功能模式与优先级设置 ================= - - /// - /// 设置电源优先工作模式 (CV 电压优先 或 CC 电流优先) - /// - public virtual async Task 设置优先模式(IT6000CPriorityMode 模式, CancellationToken ct = default) - { - await SendAsync($"FUNCTION {模式}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询优先模式(CancellationToken ct = default) - { - return await WriteReadAsync($"FUNCTION?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置瞬变/功能模式 (固定, LIST, 电池测试, PV曲线, 汽车波形) - /// - public virtual async Task 设置功能模式(IT6000CFunctionMode 模式, CancellationToken ct = default) - { - await SendAsync($"FUNCTION:MODE {模式}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询功能模式(CancellationToken ct = default) - { - return await WriteReadAsync($"FUNCTION:MODE?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - - // ================= 4. 输出开关与保护清除 ================= - - public virtual async Task 设置输出开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"OUTPut {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询输出开关状态(CancellationToken ct = default) - { - return await WriteReadAsync($"OUTPut:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 清除保护告警(CancellationToken ct = default) - { - await SendAsync($"OUTPut:PROTection:CLEar{ScpiDelimiter}", ct); //[cite: 1] - } - - - // ================= 5. 基础设定 (正值代表输出,负值代表吸收) ================= - - /// - /// 设置输出/吸收电压 (仅在 CV 模式下生效) - /// - public virtual async Task 设置电压(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电压设定值(CancellationToken ct = default) - { - return await WriteReadAsync($"VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置输出/吸收电流 (仅在 CC 模式下生效。设定负值即作为负载吸收电流) - /// - public virtual async Task 设置电流(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电流设定值(CancellationToken ct = default) - { - return await WriteReadAsync($"CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置电压上升/下降斜率 (单位: V/s) - /// - public virtual async Task 设置电压斜率(double 斜率Vs, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:SLEW {0:F4}{1}", 斜率Vs, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - - // ================= 6. 保护功能配置 (OVP, OCP, OPP) ================= - - public virtual async Task 设置过压保护开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"VOLTage:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 设置过压保护阈值(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:PROTection {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 设置过流保护开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"CURRent:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 设置过流保护阈值(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:PROTection {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 设置过功率保护开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"POWer:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 设置过功率保护阈值(double 功率, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "POWer:PROTection {0:F2}{1}", 功率, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - - // ================= 7. 测量回读 (MEASure 与 FETCh) ================= - - [Monitorable("直流源载实际电压")] - public virtual async Task 查询实际电压(CancellationToken ct = default) - { - return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - [Monitorable("直流源载实际电流")] - public virtual async Task 查询实际电流(CancellationToken ct = default) - { - return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - [Monitorable("直流源载实际功率")] - public virtual async Task 查询实际功率(CancellationToken ct = default) - { - return await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 查询瞬时电压最大值(CancellationToken ct = default) - { - return await WriteReadAsync($"FETCh:VOLTage:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - public virtual async Task 查询瞬时电流最小值(CancellationToken ct = default) - { - return await WriteReadAsync($"FETCh:CURRent:MINimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - #endregion - - - #region 直流源 (Source) 专用命令 - - /// - /// 设置 CV 优先模式下的电流限制上限值 (I+, 正向源限流) - /// - public virtual async Task 设置电流限制上限(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:LIMit:POSitive {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电流限制上限(CancellationToken ct = default) - { - return await WriteReadAsync($"CURRent:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置 CC 优先模式下的电压限制上限值 (Vh, 正向源限压) - /// - public virtual async Task 设置电压限制上限(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:LIMit:POSitive {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电压限制上限(CancellationToken ct = default) - { - return await WriteReadAsync($"VOLTage:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置功率上限值 (P+, 源模式功率限制) - /// - public virtual async Task 设置功率限制上限(double 功率, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "POWer:LIMit:POSitive {0:F2}{1}", 功率, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询功率限制上限(CancellationToken ct = default) - { - return await WriteReadAsync($"POWer:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - #endregion - - - #region 电子负载 (Load) 专用命令 - - /// - /// 设置 CV 优先模式下的电流限制下限值 (I-, 载模式电流吸收限制) - /// - public virtual async Task 设置电流限制下限(double 电流, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:LIMit:NEGative {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电流限制下限(CancellationToken ct = default) - { - return await WriteReadAsync($"CURRent:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置 CC 优先模式下的电压限制下限值 (Vl, 载模式放电截止电压) - /// - public virtual async Task 设置电压限制下限(double 电压, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:LIMit:NEGative {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询电压限制下限(CancellationToken ct = default) - { - return await WriteReadAsync($"VOLTage:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置功率下限值 (P-, 载模式吸收功率限制) - /// - public virtual async Task 设置功率限制下限(double 功率, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "POWer:LIMit:NEGative {0:F2}{1}", 功率, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询功率限制下限(CancellationToken ct = default) - { - return await WriteReadAsync($"POWer:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 开启或关闭恒阻 (CR) 负载模式 (执行前必须处于 CC 优先模式) - /// - public virtual async Task 设置CR模式开关(bool 开启, CancellationToken ct = default) - { - string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"SINK:RESistance:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1] - } - - public virtual async Task 查询CR模式开关(CancellationToken ct = default) - { - return await WriteReadAsync($"SINK:RESistance:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - /// - /// 设置恒阻 (CR) 模式下的电阻值 (单位: Ω) - /// - public virtual async Task 设置CR电阻值(double 电阻, CancellationToken ct = default) - { - string cmd = string.Format(CultureInfo.InvariantCulture, "SINK:RESistance {0:F2}{1}", 电阻, ScpiDelimiter); //[cite: 1] - await SendAsync(cmd, ct); - } - - public virtual async Task 查询CR电阻值(CancellationToken ct = default) - { - return await WriteReadAsync($"SINK:RESistance?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] - } - - #endregion - } -} \ No newline at end of file diff --git a/DeviceCommand/Devices/MCc06U.cs b/DeviceCommand/Devices/MCc30W.cs similarity index 77% rename from DeviceCommand/Devices/MCc06U.cs rename to DeviceCommand/Devices/MCc30W.cs index 738b4b1..4d5b718 100644 --- a/DeviceCommand/Devices/MCc06U.cs +++ b/DeviceCommand/Devices/MCc30W.cs @@ -11,9 +11,9 @@ namespace DeviceCommand.Devices /// /// 水冷机 一拖三 /// - public class MCc06U:ModbusTcp + public class MCc30W:ModbusTcp { - public MCc06U(TcpConfig config) : base(config) + public MCc30W(TcpConfig config) : base(config) { } } diff --git a/DeviceCommand/Devices/S7200.cs b/DeviceCommand/Devices/S7200.cs new file mode 100644 index 0000000..357b217 --- /dev/null +++ b/DeviceCommand/Devices/S7200.cs @@ -0,0 +1,213 @@ +using Common.Attributes; +using DeviceCommand.Base; +using System; +using System.Threading; +using System.Threading.Tasks; +// 根据您的项目实际路径保留枚举的引用 +// using 通讯驱动Base.枚举; + +namespace DeviceCommand.Devices +{ + public enum S7200负载模式_枚举 + { + CC, + CV, + CP, + CR, + CVCC, + CRCC, + CVCR, + AUTO + } + public enum S7200直流源模式_枚举 + { + VOLTage, + CURRent, + BATTest, + BATSim, + SOLar, + EN50530, + LIST, + UDW, + SQUare, + TRIangle, + SINusoid, + DIN40839_12V, + DIN40839_24V, + IS016750_SHORTDROP_12V, + IS016750_SHORTDROP_24V, + IS016750_RESETTEST, + IS016750_STARTINGPROFILE_12V_1, + IS016750_STARTINGPROFILE_12V_2, + IS016750_STARTINGPROFILE_12V_3, + IS016750_STARTINGPROFILE_12V_4, + IS016750_STARTINGPROFILE_24V_1, + IS016750_STARTINGPROFILE_24V_2, + IS016750_STARTINGPROFILE_24V_3, + IS016750_LOADDUMP_TESTA_12V, + IS016750_LOADDUMP_TESTA_24V, + IS016750_LOADDUMP_TESTB_12V, + IS016750_LOADDUMP_TESTB_24V, + LV123_HV_1, + LV123_HV_2A, + LV123_HV_2B, + LV123_HV_3 + } + public enum S7200工作模式_枚举 + { + 电源模式, + 负载模式, + } + /// + /// 高压直流源载一体机 (适配 IT6000C SCPI指令集) + /// + [ACPCommand] + public class S7200 : Tcp + { + // SCPI 指令结束符 + private const string ScpiDelimiter = "\n"; + + #region 设置 + + public async Task 设置为远程模式(CancellationToken ct = default) + { + await SendAsync($"SYSTem:REMote{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置电源工作模式(S7200工作模式_枚举 开关, CancellationToken ct = default) + { + // IT6000C 为双向无缝切换,底层硬件无需显式发送源载切换指令 + // 保留此方法仅为兼容您原有上位机的工步调用流程,直接返回即可 + await Task.CompletedTask; + } + + public async Task 设置直流源工作模式(S7200直流源模式_枚举 模式, CancellationToken ct = default) + { + // 原指令: MODE {模式} -> 现 IT6000C 指令: FUNCtion {模式} (如 VOLTage / CURRent)[cite: 1] + // 若枚举 ToString() 后不匹配,建议在此处加 Switch 转换 + await SendAsync($"FUNCtion {模式}{ScpiDelimiter}", ct); + } + + public async Task 设置负载工作模式(S7200负载模式_枚举 模式, CancellationToken ct = default) + { + // IT6000C 负载控制通过负向边界实现。若是想开启纯电阻模式,可调用 SINK:RESistance:STATe ON[cite: 1] + await Task.CompletedTask; + } + + public async Task 设置通道开关(bool 开关, CancellationToken ct = default) + { + await SendAsync($"OUTPut {(开关 ? 1 : 0)}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置CC模式电流(double 电流, CancellationToken ct = default) + { + await SendAsync($"CURRent {电流}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置CC电压H(double 电流, CancellationToken ct = default) // 沿用原参数名“电流”,实际是设定电压上限 + { + await SendAsync($"VOLTage:LIMit:POSitive {电流}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置CC电压L(double 电流, CancellationToken ct = default) // 沿用原参数名“电流”,实际是设定电压下限 + { + await SendAsync($"VOLTage:LIMit:NEGative {电流}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置CV正向电流(double 电流, CancellationToken ct = default) + { + await SendAsync($"CURRent:LIMit:POSitive {电流}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置CV反向电流(double 电流, CancellationToken ct = default) + { + // 提醒: 此处传入的参数如果是正数,建议在外部或此处转换为负值,因为载模式限制需要负数[cite: 1] + await SendAsync($"CURRent:LIMit:NEGative {电流}{ScpiDelimiter}", ct); + } + + public async Task 设置正向功率阈值(double 功率, CancellationToken ct = default) + { + await SendAsync($"POWer:LIMit:POSitive {功率}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置反向功率阈值(double 功率, CancellationToken ct = default) + { + // 提醒: 此处传入的参数必须为负数[cite: 1] + await SendAsync($"POWer:LIMit:NEGative {功率}{ScpiDelimiter}", ct); + } + + public async Task 设置电压(double 电压, CancellationToken ct = default) + { + await SendAsync($"VOLTage {电压}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 清除保护状态(CancellationToken ct = default) + { + await SendAsync($"OUTPut:PROTection:CLEar{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置OCP开关(bool v, CancellationToken ct = default) + { + await SendAsync($"CURRent:PROTection:STATe {(v ? 1 : 0)}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置OVP开关(bool v, CancellationToken ct = default) + { + await SendAsync($"VOLTage:PROTection:STATe {(v ? 1 : 0)}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置电压保护OVP电压(double oVP电压, CancellationToken ct = default) + { + await SendAsync($"VOLTage:PROTection {oVP电压}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置电流保护OCP电流(double oCP电流, CancellationToken ct = default) + { + await SendAsync($"CURRent:PROTection {oCP电流}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置功率保护开关(bool v, CancellationToken ct = default) + { + await SendAsync($"POWer:PROTection:STATe {(v ? 1 : 0)}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 设置功率保护功率(double oPP功率, CancellationToken ct = default) + { + await SendAsync($"POWer:PROTection {oPP功率}{ScpiDelimiter}", ct); //[cite: 1] + } + + public async Task 发送自定义命令(string 指令, CancellationToken ct = default) + { + await SendAsync($"{指令}{ScpiDelimiter}", ct); + } + + #endregion + + #region 查询 + + public async Task 查询设备信息(CancellationToken ct = default) + { + return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] + } + + public async Task 查询实时电压(CancellationToken ct = default) + { + var str = await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] + return double.TryParse(str, out double result) ? result : 0; + } + + public async Task 查询实时电流(CancellationToken ct = default) + { + var str = await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] + return double.TryParse(str, out double result) ? result : 0; + } + + public async Task 查询功率(CancellationToken ct = default) + { + var str = await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] + return double.TryParse(str, out double result) ? result : 0; + } + + #endregion + } +} \ No newline at end of file diff --git a/DeviceCommand/Devices/TektronixMSO.cs b/DeviceCommand/Devices/TektronixMSO.cs index 81c36f8..5fccf61 100644 --- a/DeviceCommand/Devices/TektronixMSO.cs +++ b/DeviceCommand/Devices/TektronixMSO.cs @@ -11,12 +11,12 @@ using System.Threading.Tasks; namespace DeviceCommand.Devices { /// - /// 示波器 MDO/MSO/DPO 系列 + /// 示波器 MSO 4/5/6 系列 /// #region 枚举定义 /// - /// Tektronix MSO/MDO 采集模式 + /// Tektronix MSO 采集模式 /// public enum TekAcquisitionMode { @@ -33,7 +33,7 @@ namespace DeviceCommand.Devices } /// - /// Tektronix MSO/MDO 测量类型 (部分常用) + /// Tektronix MSO 测量类型 (部分常用) /// public enum TekMeasurementType { @@ -50,7 +50,7 @@ namespace DeviceCommand.Devices [ACPCommand] public class TektronixMSO : Tcp { - // SCPI 指令结束符 (文档中提到消息终止符需使用 LF)[cite: 1] + // SCPI 指令结束符 (消息终止符需使用 LF) private const string ScpiDelimiter = "\n"; public TektronixMSO(TcpConfig config) : base(config) @@ -61,19 +61,19 @@ namespace DeviceCommand.Devices public virtual async Task 查询设备标识(CancellationToken ct = default) { - // 返回仪器的标识代码[cite: 1] + // 返回仪器的标识代码[cite: 2] return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); } public virtual async Task 查询忙碌状态(CancellationToken ct = default) { - // 查询仪器是否处于忙碌状态,常用于同步操作[cite: 1] + // 查询仪器是否处于忙碌状态,常用于同步操作[cite: 2] return await WriteReadAsync($"BUSY?{ScpiDelimiter}", ScpiDelimiter, ct); } public virtual async Task 执行自校准(CancellationToken ct = default) { - // 指示仪器执行信号路径校准 (SPC)[cite: 1] + // 指示仪器执行信号路径校准 (SPC)[cite: 2] await SendAsync($"*CAL?{ScpiDelimiter}", ct); } @@ -86,19 +86,20 @@ namespace DeviceCommand.Devices /// public virtual async Task 设置采集状态(bool 运行, CancellationToken ct = default) { - // 启动、停止或返回采集状态[cite: 1] + // 启动、停止或返回采集状态[cite: 2] string 参数 = 运行 ? "RUN" : "STOP"; await SendAsync($"ACQuire:STATE {参数}{ScpiDelimiter}", ct); } public virtual async Task 查询采集状态(CancellationToken ct = default) { - return await WriteReadAsync($"ACQuire:STATE?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1] + // 启动、停止或返回采集状态[cite: 2] + return await WriteReadAsync($"ACQuire:STATE?{ScpiDelimiter}", ScpiDelimiter, ct); } public virtual async Task 设置采集模式(TekAcquisitionMode 模式, CancellationToken ct = default) { - // 设置或查询采集模式[cite: 1] + // 设置或查询采集模式[cite: 2] await SendAsync($"ACQuire:MODe {模式}{ScpiDelimiter}", ct); } @@ -108,20 +109,20 @@ namespace DeviceCommand.Devices public virtual async Task 设置水平刻度(double 秒每格, CancellationToken ct = default) { - // 设置或查询水平刻度 (Scale)[cite: 1] + // 设置或查询水平刻度 (Scale)[cite: 2] string cmd = string.Format(CultureInfo.InvariantCulture, "HORizontal:SCAle {0:E}{1}", 秒每格, ScpiDelimiter); await SendAsync(cmd, ct); } public virtual async Task 设置记录长度(long 长度, CancellationToken ct = default) { - // 设置或查询记录长度[cite: 1] + // 设置或查询水平记录长度[cite: 2] await SendAsync($"HORizontal:RECOrdlength {长度}{ScpiDelimiter}", ct); } public virtual async Task 查询采样率(CancellationToken ct = default) { - // 查询水平采样率。注:此命令在当前系列设备中为只读[cite: 1] + // 查询水平采样率[cite: 2] return await WriteReadAsync($"HORizontal:SAMPLERate?{ScpiDelimiter}", ScpiDelimiter, ct); } @@ -134,9 +135,9 @@ namespace DeviceCommand.Devices /// public virtual async Task 设置通道显示开关(int 通道号, bool 开启, CancellationToken ct = default) { - // 开启或关闭指定通道的波形显示[cite: 1] + // 4/5/6 Series MSO 标准通道显示指令[cite: 2] string 参数 = 开启 ? "ON" : "OFF"; - await SendAsync($"SELect:CH{通道号} {参数}{ScpiDelimiter}", ct); + await SendAsync($"DISplay:GLObal:CH{通道号}:STATE {参数}{ScpiDelimiter}", ct); } /// @@ -144,7 +145,6 @@ namespace DeviceCommand.Devices /// public virtual async Task 设置通道垂直刻度(int 通道号, double 伏特每格, CancellationToken ct = default) { - // 设置指定通道的垂直刻度[cite: 1] string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:SCAle {1:E}{2}", 通道号, 伏特每格, ScpiDelimiter); await SendAsync(cmd, ct); } @@ -154,7 +154,6 @@ namespace DeviceCommand.Devices /// public virtual async Task 设置通道垂直位置(int 通道号, double 格数, CancellationToken ct = default) { - // 设置指定通道的通道垂直位置[cite: 1] string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:POSition {1:F2}{2}", 通道号, 格数, ScpiDelimiter); await SendAsync(cmd, ct); } @@ -164,43 +163,43 @@ namespace DeviceCommand.Devices #region 5. 自动测量 (Measurement) /// - /// 开启指定的测量项槽位 (1-8) + /// 动态添加并开启一个测量项 /// public virtual async Task 开启测量项(int 测量项编号, CancellationToken ct = default) { - // 指定该测量槽位是否计算并在屏幕显示[cite: 1] - await SendAsync($"MEASUrement:MEAS{测量项编号}:STATE ON{ScpiDelimiter}", ct); + // 4/5/6 Series MSO 必须先动态创建测量项[cite: 2] + await SendAsync($"MEASUrement:ADDNew \"MEAS{测量项编号}\"{ScpiDelimiter}", ct); } public virtual async Task 设置测量类型(int 测量项编号, TekMeasurementType 类型, CancellationToken ct = default) { - // 设置或查询指定测量槽位的测量类型[cite: 1] + // 设置或查询测量类型[cite: 2] await SendAsync($"MEASUrement:MEAS{测量项编号}:TYPe {类型}{ScpiDelimiter}", ct); } public virtual async Task 设置测量源(int 测量项编号, string 源名称, CancellationToken ct = default) { - // 设置单通道测量的 "from" 源信号[cite: 1] + // 4/5/6 Series 中设置测量源[cite: 2] await SendAsync($"MEASUrement:MEAS{测量项编号}:SOUrce1 {源名称}{ScpiDelimiter}", ct); } - [Monitorable("测量项的当前值")] + [Monitorable("测量项的当前采集平均值")] public virtual async Task 查询测量项当前值(int 测量项编号, CancellationToken ct = default) { - // 返回指定的测量项当前值[cite: 1] - return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:VALue?{ScpiDelimiter}", ScpiDelimiter, ct); + // 4/5/6 Series 获取当前采集值的标准方式,查询平均值[cite: 2] + return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:CURRentacq:MEAN?{ScpiDelimiter}", ScpiDelimiter, ct); } - public virtual async Task 查询测量项平均值(int 测量项编号, CancellationToken ct = default) + public virtual async Task 查询测量项全局平均值(int 测量项编号, CancellationToken ct = default) { - // 返回自上次统计重置以来累积的平均值[cite: 1] - return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:MEAN?{ScpiDelimiter}", ScpiDelimiter, ct); + // 获取所有采集(AllAcqs)历史累积的平均值[cite: 2] + return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:ALLAcqs:MEAN?{ScpiDelimiter}", ScpiDelimiter, ct); } - public virtual async Task 查询测量项最大值(int 测量项编号, CancellationToken ct = default) + public virtual async Task 查询测量项全局最大值(int 测量项编号, CancellationToken ct = default) { - // 返回自上次统计重置以来找到的最大值[cite: 1] - return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); + // 获取所有采集(AllAcqs)历史累积的最大值[cite: 2] + return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:ALLAcqs:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); } #endregion @@ -214,28 +213,24 @@ namespace DeviceCommand.Devices /// 异步取消令牌 public virtual async Task 保存屏幕截图(string 上位机文件路径, CancellationToken ct = default) { - // 根据之前的排查,您的设备使用 E: 作为 U 盘挂载点 string 临时文件 = "E:/temp1.png"; - // 1. 设置保存图像的格式为 PNG[cite: 1] - await SendAsync($"SAVE:IMAGE:FILEFormat PNG{ScpiDelimiter}", ct); + // 1. 直接保存截图到示波器U盘 (自动识别 .png 扩展名)[cite: 2] + await SendAsync($"SAVe:IMAGe \"{临时文件}\"{ScpiDelimiter}", ct); - // 2. 捕获屏幕并保存到示波器的 U 盘中[cite: 1] - await SendAsync($"SAVE:IMAGE \"{临时文件}\"{ScpiDelimiter}", ct); - - // 3. 发送 *OPC? 并等待返回 1,确保图像文件已经完全写入磁盘[cite: 1] + // 2. 发送 *OPC? 并等待返回 1,确保图像文件已经完全写入磁盘[cite: 2] await WriteReadAsync($"*OPC?{ScpiDelimiter}", ScpiDelimiter, ct); - // 4. 将文件内容读取到当前通信接口[cite: 1] + // 3. 将文件内容读取到当前通信接口[cite: 2] await SendAsync($"FILESystem:READFile \"{临时文件}\"{ScpiDelimiter}", ct); - // 5. 提取底层的二进制块 (Block Data)[cite: 1] + // 4. 提取底层的二进制块 (Block Data) byte[] imageBytes = await ReadBinaryBlockAsync(ct); - // 6. 将提取的二进制字节流写入上位机本地磁盘 + // 5. 将提取的二进制字节流写入上位机本地磁盘 await File.WriteAllBytesAsync(上位机文件路径, imageBytes, ct); - // 7. 删除示波器上的临时文件,保持设备存储干净[cite: 1] + // 6. 删除示波器上的临时文件,保持设备存储干净[cite: 2] await SendAsync($"FILESystem:DELEte \"{临时文件}\"{ScpiDelimiter}", ct); } @@ -258,14 +253,13 @@ namespace DeviceCommand.Devices /// /// 辅助方法:读取 IEEE 488.2 标准的二进制块数据 (Block Data) - /// 手册规范: ::= {#[...][...]}[cite: 1] /// protected virtual async Task ReadBinaryBlockAsync(CancellationToken ct = default) { var stream = GetNetworkStream(); byte[] singleByte = new byte[1]; - // 1. 逐字节读取,直到读到起始符 '#'[cite: 1] + // 1. 逐字节读取,直到读到起始符 '#' while (true) { int read = await stream.ReadAsync(singleByte, 0, 1, ct); @@ -273,13 +267,13 @@ namespace DeviceCommand.Devices if (singleByte[0] == (byte)'#') break; } - // 2. 读取 1 个字符 ,它代表接下来有多少个字符表示数据长度[cite: 1] + // 2. 读取 1 个字符 ,它代表接下来有多少个字符表示数据长度 await stream.ReadAsync(singleByte, 0, 1, ct); char nzDigChar = (char)singleByte[0]; if (!char.IsDigit(nzDigChar)) throw new InvalidDataException($"无效的块头标识: {nzDigChar}"); int lengthBytesCount = int.Parse(nzDigChar.ToString()); - // 3. 读取 所指示的长度字符,将其解析为整数 N[cite: 1] + // 3. 读取 所指示的长度字符,将其解析为整数 N byte[] lengthBytes = new byte[lengthBytesCount]; int currentRead = 0; while (currentRead < lengthBytesCount) @@ -290,7 +284,7 @@ namespace DeviceCommand.Devices } int dataLength = int.Parse(Encoding.ASCII.GetString(lengthBytes)); - // 4. 从流中精确读取 N 个字节 ...,这就是完整的图像数据[cite: 1] + // 4. 从流中精确读取 N 个字节 ...,这就是完整的图像数据 byte[] imageData = new byte[dataLength]; int totalBytesRead = 0; while (totalBytesRead < dataLength) @@ -300,7 +294,7 @@ namespace DeviceCommand.Devices totalBytesRead += read; } - // 5. 结尾可能包含 (例如 LF \n),将其读取并丢弃以清空缓冲区[cite: 1] + // 5. 结尾可能包含 (例如 LF \n),将其读取并丢弃以清空缓冲区 try { await stream.ReadAsync(singleByte, 0, 1, ct); @@ -319,7 +313,7 @@ namespace DeviceCommand.Devices /// public virtual async Task 清除错误队列Async(CancellationToken ct = default) { - // 发送 *CLS 指令清空状态[cite: 1] + // 发送 *CLS 指令清空状态[cite: 2] await SendAsync($"*CLS{ScpiDelimiter}", ct); } @@ -328,7 +322,7 @@ namespace DeviceCommand.Devices /// public virtual async Task 查询错误数量Async(CancellationToken ct = default) { - // 返回事件队列中的事件数量[cite: 1] + // 返回事件队列中的事件数量 return await WriteReadAsync($"EVQty?{ScpiDelimiter}", ScpiDelimiter, ct); } @@ -337,7 +331,7 @@ namespace DeviceCommand.Devices /// public virtual async Task 读取单条错误消息Async(CancellationToken ct = default) { - // 返回事件队列中的事件代码和消息[cite: 1] + // 返回事件队列中的事件代码和消息 return await WriteReadAsync($"EVMsg?{ScpiDelimiter}", ScpiDelimiter, ct); } @@ -346,7 +340,7 @@ namespace DeviceCommand.Devices /// public virtual async Task 读取所有错误消息Async(CancellationToken ct = default) { - // 返回所有事件及其消息[cite: 1] + // 返回所有事件及其消息 return await WriteReadAsync($"ALLEv?{ScpiDelimiter}", ScpiDelimiter, ct); } diff --git a/DeviceEditModule/ViewModels/IT6015CViewModel.cs b/DeviceEditModule/ViewModels/IT6015CViewModel.cs deleted file mode 100644 index 2ab86e3..0000000 --- a/DeviceEditModule/ViewModels/IT6015CViewModel.cs +++ /dev/null @@ -1,147 +0,0 @@ -using DeviceCommand.Devices; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UIShare.GlobalVariable; -using UIShare.ViewModelBase; - -namespace DeviceEditModule.ViewModels -{ - public class IT6015CViewModel : NavigateViewModelBase, IDisposable - { - #region 私有字段 - private readonly DeviceManager _deviceManager; - private IT6015C? _device; - private CancellationTokenSource? _cts; - #endregion - #region 属性 - private string _deviceName = "IT6015C"; - 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; - /// 正在执行设备命令时为 true,用于 UI 忙碌状态指示。 - public bool IsBusy - { - get => _isBusy; - set => SetProperty(ref _isBusy, value); - } - private string _responseLog = string.Empty; - /// 命令响应日志(最新消息在顶部)。 - public string ResponseLog - { - get => _responseLog; - set => SetProperty(ref _responseLog, value); - } - - #endregion - #region 命令 - #endregion - public IT6015CViewModel(IContainerProvider containerProvider) : base(containerProvider) - { - _deviceManager = containerProvider.Resolve(); - } - public void Dispose() - { - _cts?.Cancel(); - _cts?.Dispose(); - } - #region 初始化 / Navigation - - /// - /// 从 DeviceManager 中查找IT6015C设备实例。 - /// 优先按 查找,否则取第一个匹配类型的设备。 - /// - public void Initialize(string? deviceName = null) - { - IT6015C? found = null; - string? foundName = null; - if (deviceName != null && - _deviceManager.DeviceMap.TryGetValue(deviceName, out var d) && - d is IT6015C e) - { - found = e; - foundName = deviceName; - } - else - { - foreach (var kv in _deviceManager.DeviceMap) - { - if (kv.Value is IT6015C it) - { - found = it; - foundName = kv.Key; - break; - } - } - } - - _device = found; - DeviceName = foundName ?? "IT7800E (未找到)"; - IsConnected = _device?.IsConnected ?? false; - - AppendLog(found != null - ? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "已连接" : "未连接")}" - : "未在 DeviceManager 中找到 IT7800E 设备,请先初始化设备配置。"); - } - #region 辅助 - - private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; - - private async Task Exec(Func 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 override void OnNavigatedTo(NavigationContext context) - { - var name = context.Parameters.GetValue("DeviceName"); - Initialize(name); - } - - #endregion - } -} diff --git a/DeviceEditModule/ViewModels/IT6036CViewModel.cs b/DeviceEditModule/ViewModels/IT6036CViewModel.cs deleted file mode 100644 index 306b840..0000000 --- a/DeviceEditModule/ViewModels/IT6036CViewModel.cs +++ /dev/null @@ -1,147 +0,0 @@ -using DeviceCommand.Devices; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UIShare.GlobalVariable; -using UIShare.ViewModelBase; - -namespace DeviceEditModule.ViewModels -{ - public class IT6036CViewModel : NavigateViewModelBase, IDisposable - { - #region 私有字段 - private readonly DeviceManager _deviceManager; - private IT6036C? _device; - private CancellationTokenSource? _cts; - #endregion - #region 属性 - private string _deviceName = "IT6036C"; - 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; - /// 正在执行设备命令时为 true,用于 UI 忙碌状态指示。 - public bool IsBusy - { - get => _isBusy; - set => SetProperty(ref _isBusy, value); - } - private string _responseLog = string.Empty; - /// 命令响应日志(最新消息在顶部)。 - public string ResponseLog - { - get => _responseLog; - set => SetProperty(ref _responseLog, value); - } - - #endregion - #region 命令 - #endregion - public IT6036CViewModel(IContainerProvider containerProvider) : base(containerProvider) - { - _deviceManager = containerProvider.Resolve(); - } - public void Dispose() - { - _cts?.Cancel(); - _cts?.Dispose(); - } - #region 初始化 / Navigation - - /// - /// 从 DeviceManager 中查找IT6036C设备实例。 - /// 优先按 查找,否则取第一个匹配类型的设备。 - /// - public void Initialize(string? deviceName = null) - { - IT6036C? found = null; - string? foundName = null; - if (deviceName != null && - _deviceManager.DeviceMap.TryGetValue(deviceName, out var d) && - d is IT6036C e) - { - found = e; - foundName = deviceName; - } - else - { - foreach (var kv in _deviceManager.DeviceMap) - { - if (kv.Value is IT6036C it) - { - found = it; - foundName = kv.Key; - break; - } - } - } - - _device = found; - DeviceName = foundName ?? "IT7800E (未找到)"; - IsConnected = _device?.IsConnected ?? false; - - AppendLog(found != null - ? $"已关联设备 [{DeviceName}],连接状态:{(IsConnected ? "已连接" : "未连接")}" - : "未在 DeviceManager 中找到 IT7800E 设备,请先初始化设备配置。"); - } - #region 辅助 - - private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token; - - private async Task Exec(Func 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 override void OnNavigatedTo(NavigationContext context) - { - var name = context.Parameters.GetValue("DeviceName"); - Initialize(name); - } - - #endregion - } -} diff --git a/DeviceEditModule/Views/IT6015CView.xaml b/DeviceEditModule/Views/IT6015CView.xaml deleted file mode 100644 index 644ac40..0000000 --- a/DeviceEditModule/Views/IT6015CView.xaml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/DeviceEditModule/Views/IT6015CView.xaml.cs b/DeviceEditModule/Views/IT6015CView.xaml.cs deleted file mode 100644 index b32f553..0000000 --- a/DeviceEditModule/Views/IT6015CView.xaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace DeviceEditModule.Views -{ - /// - /// IT6015CView.xaml 的交互逻辑 - /// - public partial class IT6015CView : UserControl - { - public IT6015CView() - { - InitializeComponent(); - } - } -} diff --git a/DeviceEditModule/Views/IT6036CView.xaml b/DeviceEditModule/Views/IT6036CView.xaml deleted file mode 100644 index f24e832..0000000 --- a/DeviceEditModule/Views/IT6036CView.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - diff --git a/DeviceEditModule/Views/IT6036CView.xaml.cs b/DeviceEditModule/Views/IT6036CView.xaml.cs deleted file mode 100644 index 502368d..0000000 --- a/DeviceEditModule/Views/IT6036CView.xaml.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace DeviceEditModule.Views -{ - /// - /// IT6036CView.xaml 的交互逻辑 - /// - public partial class IT6036CView : Page - { - public IT6036CView() - { - InitializeComponent(); - } - } -}