驱动更新

This commit is contained in:
“hsc”
2026-08-04 15:10:37 +08:00
parent 7250080a24
commit 66bb6d36ba
12 changed files with 283 additions and 1193 deletions

View File

@@ -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
{
/// <summary>
/// 水冷机 一对一
/// </summary>
[ACPCommand]
public class ANEVH80 : Tcp
{
public ANEVH80(TcpConfig config) : base(config)
{
}
}
}

View File

@@ -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
{
/// <summary>
/// 低压直流源载一体机 一对一
/// </summary>
[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<string> (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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
public virtual async Task<string> 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<string> (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. 功能模式与优先级设置 =================
/// <summary>
/// 设置电源优先工作模式 (CV 电压优先 或 CC 电流优先)
/// </summary>
public virtual async Task (IT6000CPriorityMode , CancellationToken ct = default)
{
await SendAsync($"FUNCTION {模式}{ScpiDelimiter}", ct); //[cite: 1]
}
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"FUNCTION?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置瞬变/功能模式 (固定, LIST, 电池测试, PV曲线, 汽车波形)
/// </summary>
public virtual async Task (IT6000CFunctionMode , CancellationToken ct = default)
{
await SendAsync($"FUNCTION:MODE {模式}{ScpiDelimiter}", ct); //[cite: 1]
}
public virtual async Task<string> (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<string> (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. 基础设定 (正值代表输出,负值代表吸收) =================
/// <summary>
/// 设置输出/吸收电压 (仅在 CV 模式下生效)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置输出/吸收电流 (仅在 CC 模式下生效。设定负值即作为负载吸收电流)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置电压上升/下降斜率 (单位: V/s)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
[Monitorable("直流源载实际电流")]
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
[Monitorable("直流源载实际功率")]
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"FETCh:VOLTage:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"FETCh:CURRent:MINimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
#region (Source)
/// <summary>
/// 设置 CV 优先模式下的电流限制上限值 (I+, 正向源限流)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"CURRent:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置 CC 优先模式下的电压限制上限值 (Vh, 正向源限压)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"VOLTage:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置功率上限值 (P+, 源模式功率限制)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"POWer:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
#region (Load)
/// <summary>
/// 设置 CV 优先模式下的电流限制下限值 (I-, 载模式电流吸收限制)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"CURRent:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置 CC 优先模式下的电压限制下限值 (Vl, 载模式放电截止电压)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"VOLTage:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置功率下限值 (P-, 载模式吸收功率限制)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"POWer:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 开启或关闭恒阻 (CR) 负载模式 (执行前必须处于 CC 优先模式)
/// </summary>
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<string> CR模式开关(CancellationToken ct = default)
{
return await WriteReadAsync($"SINK:RESistance:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置恒阻 (CR) 模式下的电阻值 (单位: Ω)
/// </summary>
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<string> CR电阻值(CancellationToken ct = default)
{
return await WriteReadAsync($"SINK:RESistance?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
}
}

View File

@@ -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
{
/// <summary>
///高压直流源载一体机 一对一
/// </summary>
#region
/// <summary>
/// IT6000C 优先工作模式 (CV优先 / CC优先)
/// </summary>
public enum IT6000CPriorityMode
{
/// <summary> 恒压优先模式 (CV优先) </summary>
VOLTage,
/// <summary> 恒流优先模式 (CC优先) </summary>
CURRent
}
/// <summary>
/// IT6000C 瞬变功能模式
/// </summary>
public enum IT6000CFunctionMode
{
/// <summary> 固定模式 (普通输出) </summary>
FIXed,
/// <summary> List 列表模式 </summary>
LIST,
/// <summary> 电池测试模式 </summary>
BATTer,
/// <summary> 光伏/太阳能板曲线模拟模式 </summary>
SOLar,
/// <summary> 汽车波形模拟模式 </summary>
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<string> (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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
public virtual async Task<string> 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<string> (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. 功能模式与优先级设置 =================
/// <summary>
/// 设置电源优先工作模式 (CV 电压优先 或 CC 电流优先)
/// </summary>
public virtual async Task (IT6000CPriorityMode , CancellationToken ct = default)
{
await SendAsync($"FUNCTION {模式}{ScpiDelimiter}", ct); //[cite: 1]
}
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"FUNCTION?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置瞬变/功能模式 (固定, LIST, 电池测试, PV曲线, 汽车波形)
/// </summary>
public virtual async Task (IT6000CFunctionMode , CancellationToken ct = default)
{
await SendAsync($"FUNCTION:MODE {模式}{ScpiDelimiter}", ct); //[cite: 1]
}
public virtual async Task<string> (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<string> (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. 基础设定 (正值代表输出,负值代表吸收) =================
/// <summary>
/// 设置输出/吸收电压 (仅在 CV 模式下生效)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置输出/吸收电流 (仅在 CC 模式下生效。设定负值即作为负载吸收电流)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置电压上升/下降斜率 (单位: V/s)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
[Monitorable("直流源载实际电流")]
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
[Monitorable("直流源载实际功率")]
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"FETCh:VOLTage:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"FETCh:CURRent:MINimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
#region (Source)
/// <summary>
/// 设置 CV 优先模式下的电流限制上限值 (I+, 正向源限流)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"CURRent:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置 CC 优先模式下的电压限制上限值 (Vh, 正向源限压)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"VOLTage:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置功率上限值 (P+, 源模式功率限制)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"POWer:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
#region (Load)
/// <summary>
/// 设置 CV 优先模式下的电流限制下限值 (I-, 载模式电流吸收限制)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"CURRent:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置 CC 优先模式下的电压限制下限值 (Vl, 载模式放电截止电压)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"VOLTage:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置功率下限值 (P-, 载模式吸收功率限制)
/// </summary>
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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"POWer:LIMit:NEGative?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 开启或关闭恒阻 (CR) 负载模式 (执行前必须处于 CC 优先模式)
/// </summary>
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<string> CR模式开关(CancellationToken ct = default)
{
return await WriteReadAsync($"SINK:RESistance:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置恒阻 (CR) 模式下的电阻值 (单位: Ω)
/// </summary>
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<string> CR电阻值(CancellationToken ct = default)
{
return await WriteReadAsync($"SINK:RESistance?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
}
}

View File

@@ -11,9 +11,9 @@ namespace DeviceCommand.Devices
/// <summary> /// <summary>
/// 水冷机 一拖三 /// 水冷机 一拖三
/// </summary> /// </summary>
public class MCc06U:ModbusTcp public class MCc30W:ModbusTcp
{ {
public MCc06U(TcpConfig config) : base(config) public MCc30W(TcpConfig config) : base(config)
{ {
} }
} }

View File

@@ -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工作模式_枚举
{
,
,
}
/// <summary>
/// 高压直流源载一体机 (适配 IT6000C SCPI指令集)
/// </summary>
[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<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
public async Task<double> (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<double> (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<double> (CancellationToken ct = default)
{
var str = await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
return double.TryParse(str, out double result) ? result : 0;
}
#endregion
}
}

View File

@@ -11,12 +11,12 @@ using System.Threading.Tasks;
namespace DeviceCommand.Devices namespace DeviceCommand.Devices
{ {
/// <summary> /// <summary>
/// 示波器 MDO/MSO/DPO 系列 /// 示波器 MSO 4/5/6 系列
/// </summary> /// </summary>
#region #region
/// <summary> /// <summary>
/// Tektronix MSO/MDO 采集模式 /// Tektronix MSO 采集模式
/// </summary> /// </summary>
public enum TekAcquisitionMode public enum TekAcquisitionMode
{ {
@@ -33,7 +33,7 @@ namespace DeviceCommand.Devices
} }
/// <summary> /// <summary>
/// Tektronix MSO/MDO 测量类型 (部分常用) /// Tektronix MSO 测量类型 (部分常用)
/// </summary> /// </summary>
public enum TekMeasurementType public enum TekMeasurementType
{ {
@@ -50,7 +50,7 @@ namespace DeviceCommand.Devices
[ACPCommand] [ACPCommand]
public class TektronixMSO : Tcp public class TektronixMSO : Tcp
{ {
// SCPI 指令结束符 (文档中提到消息终止符需使用 LF)[cite: 1] // SCPI 指令结束符 (消息终止符需使用 LF)
private const string ScpiDelimiter = "\n"; private const string ScpiDelimiter = "\n";
public TektronixMSO(TcpConfig config) : base(config) public TektronixMSO(TcpConfig config) : base(config)
@@ -61,19 +61,19 @@ namespace DeviceCommand.Devices
public virtual async Task<string> (CancellationToken ct = default) public virtual async Task<string> (CancellationToken ct = default)
{ {
// 返回仪器的标识代码[cite: 1] // 返回仪器的标识代码[cite: 2]
return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
public virtual async Task<string> (CancellationToken ct = default) public virtual async Task<string> (CancellationToken ct = default)
{ {
// 查询仪器是否处于忙碌状态,常用于同步操作[cite: 1] // 查询仪器是否处于忙碌状态,常用于同步操作[cite: 2]
return await WriteReadAsync($"BUSY?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"BUSY?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
public virtual async Task (CancellationToken ct = default) public virtual async Task (CancellationToken ct = default)
{ {
// 指示仪器执行信号路径校准 (SPC)[cite: 1] // 指示仪器执行信号路径校准 (SPC)[cite: 2]
await SendAsync($"*CAL?{ScpiDelimiter}", ct); await SendAsync($"*CAL?{ScpiDelimiter}", ct);
} }
@@ -86,19 +86,20 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task (bool , CancellationToken ct = default) public virtual async Task (bool , CancellationToken ct = default)
{ {
// 启动、停止或返回采集状态[cite: 1] // 启动、停止或返回采集状态[cite: 2]
string = ? "RUN" : "STOP"; string = ? "RUN" : "STOP";
await SendAsync($"ACQuire:STATE {参数}{ScpiDelimiter}", ct); await SendAsync($"ACQuire:STATE {参数}{ScpiDelimiter}", ct);
} }
public virtual async Task<string> (CancellationToken ct = default) public virtual async Task<string> (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) public virtual async Task (TekAcquisitionMode , CancellationToken ct = default)
{ {
// 设置或查询采集模式[cite: 1] // 设置或查询采集模式[cite: 2]
await SendAsync($"ACQuire:MODe {模式}{ScpiDelimiter}", ct); await SendAsync($"ACQuire:MODe {模式}{ScpiDelimiter}", ct);
} }
@@ -108,20 +109,20 @@ namespace DeviceCommand.Devices
public virtual async Task (double , CancellationToken ct = default) 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); string cmd = string.Format(CultureInfo.InvariantCulture, "HORizontal:SCAle {0:E}{1}", , ScpiDelimiter);
await SendAsync(cmd, ct); await SendAsync(cmd, ct);
} }
public virtual async Task (long , CancellationToken ct = default) public virtual async Task (long , CancellationToken ct = default)
{ {
// 设置或查询记录长度[cite: 1] // 设置或查询水平记录长度[cite: 2]
await SendAsync($"HORizontal:RECOrdlength {长度}{ScpiDelimiter}", ct); await SendAsync($"HORizontal:RECOrdlength {长度}{ScpiDelimiter}", ct);
} }
public virtual async Task<string> (CancellationToken ct = default) public virtual async Task<string> (CancellationToken ct = default)
{ {
// 查询水平采样率。注:此命令在当前系列设备中为只读[cite: 1] // 查询水平采样率[cite: 2]
return await WriteReadAsync($"HORizontal:SAMPLERate?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"HORizontal:SAMPLERate?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
@@ -134,9 +135,9 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task (int , bool , CancellationToken ct = default) public virtual async Task (int , bool , CancellationToken ct = default)
{ {
// 开启或关闭指定通道的波形显示[cite: 1] // 4/5/6 Series MSO 标准通道显示指令[cite: 2]
string = ? "ON" : "OFF"; string = ? "ON" : "OFF";
await SendAsync($"SELect:CH{通道号} {参数}{ScpiDelimiter}", ct); await SendAsync($"DISplay:GLObal:CH{通道号}:STATE {参数}{ScpiDelimiter}", ct);
} }
/// <summary> /// <summary>
@@ -144,7 +145,6 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task (int , double , CancellationToken ct = default) public virtual async Task (int , double , CancellationToken ct = default)
{ {
// 设置指定通道的垂直刻度[cite: 1]
string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:SCAle {1:E}{2}", , , ScpiDelimiter); string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:SCAle {1:E}{2}", , , ScpiDelimiter);
await SendAsync(cmd, ct); await SendAsync(cmd, ct);
} }
@@ -154,7 +154,6 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task (int , double , CancellationToken ct = default) public virtual async Task (int , double , CancellationToken ct = default)
{ {
// 设置指定通道的通道垂直位置[cite: 1]
string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:POSition {1:F2}{2}", , , ScpiDelimiter); string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:POSition {1:F2}{2}", , , ScpiDelimiter);
await SendAsync(cmd, ct); await SendAsync(cmd, ct);
} }
@@ -164,43 +163,43 @@ namespace DeviceCommand.Devices
#region 5. (Measurement) #region 5. (Measurement)
/// <summary> /// <summary>
/// 开启指定的测量项槽位 (1-8) /// 动态添加并开启一个测量项
/// </summary> /// </summary>
public virtual async Task (int , CancellationToken ct = default) public virtual async Task (int , CancellationToken ct = default)
{ {
// 指定该测量槽位是否计算并在屏幕显示[cite: 1] // 4/5/6 Series MSO 必须先动态创建测量项[cite: 2]
await SendAsync($"MEASUrement:MEAS{测量项编号}:STATE ON{ScpiDelimiter}", ct); await SendAsync($"MEASUrement:ADDNew \"MEAS{}\"{ScpiDelimiter}", ct);
} }
public virtual async Task (int , TekMeasurementType , CancellationToken ct = default) public virtual async Task (int , TekMeasurementType , CancellationToken ct = default)
{ {
// 设置或查询指定测量槽位的测量类型[cite: 1] // 设置或查询测量类型[cite: 2]
await SendAsync($"MEASUrement:MEAS{测量项编号}:TYPe {类型}{ScpiDelimiter}", ct); await SendAsync($"MEASUrement:MEAS{测量项编号}:TYPe {类型}{ScpiDelimiter}", ct);
} }
public virtual async Task (int , string , CancellationToken ct = default) 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); await SendAsync($"MEASUrement:MEAS{测量项编号}:SOUrce1 {源名称}{ScpiDelimiter}", ct);
} }
[Monitorable("测量项的当前值")] [Monitorable("测量项的当前采集平均值")]
public virtual async Task<string> (int , CancellationToken ct = default) public virtual async Task<string> (int , CancellationToken ct = default)
{ {
// 返回指定的测量项当前值[cite: 1] // 4/5/6 Series 获取当前采集值的标准方式,查询平均值[cite: 2]
return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:VALue?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:CURRentacq:MEAN?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
public virtual async Task<string> (int , CancellationToken ct = default) public virtual async Task<string> (int , CancellationToken ct = default)
{ {
// 返回自上次统计重置以来累积的平均值[cite: 1] // 获取所有采集(AllAcqs)历史累积的平均值[cite: 2]
return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:MEAN?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:ALLAcqs:MEAN?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
public virtual async Task<string> (int , CancellationToken ct = default) public virtual async Task<string> (int , CancellationToken ct = default)
{ {
// 返回自上次统计重置以来找到的最大值[cite: 1] // 获取所有采集(AllAcqs)历史累积的最大值[cite: 2]
return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:ALLAcqs:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
#endregion #endregion
@@ -214,28 +213,24 @@ namespace DeviceCommand.Devices
/// <param name="ct">异步取消令牌</param> /// <param name="ct">异步取消令牌</param>
public virtual async Task (string , CancellationToken ct = default) public virtual async Task (string , CancellationToken ct = default)
{ {
// 根据之前的排查,您的设备使用 E: 作为 U 盘挂载点
string = "E:/temp1.png"; string = "E:/temp1.png";
// 1. 设置保存图像的格式为 PNG[cite: 1] // 1. 直接保存截图到示波器U盘 (自动识别 .png 扩展名)[cite: 2]
await SendAsync($"SAVE:IMAGE:FILEFormat PNG{ScpiDelimiter}", ct); await SendAsync($"SAVe:IMAGe \"{}\"{ScpiDelimiter}", ct);
// 2. 捕获屏幕并保存到示波器的 U 盘中[cite: 1] // 2. 发送 *OPC? 并等待返回 1确保图像文件已经完全写入磁盘[cite: 2]
await SendAsync($"SAVE:IMAGE \"{}\"{ScpiDelimiter}", ct);
// 3. 发送 *OPC? 并等待返回 1确保图像文件已经完全写入磁盘[cite: 1]
await WriteReadAsync($"*OPC?{ScpiDelimiter}", ScpiDelimiter, ct); await WriteReadAsync($"*OPC?{ScpiDelimiter}", ScpiDelimiter, ct);
// 4. 将文件内容读取到当前通信接口[cite: 1] // 3. 将文件内容读取到当前通信接口[cite: 2]
await SendAsync($"FILESystem:READFile \"{}\"{ScpiDelimiter}", ct); await SendAsync($"FILESystem:READFile \"{}\"{ScpiDelimiter}", ct);
// 5. 提取底层的二进制块 (Block Data)[cite: 1] // 4. 提取底层的二进制块 (Block Data)
byte[] imageBytes = await ReadBinaryBlockAsync(ct); byte[] imageBytes = await ReadBinaryBlockAsync(ct);
// 6. 将提取的二进制字节流写入上位机本地磁盘 // 5. 将提取的二进制字节流写入上位机本地磁盘
await File.WriteAllBytesAsync(, imageBytes, ct); await File.WriteAllBytesAsync(, imageBytes, ct);
// 7. 删除示波器上的临时文件,保持设备存储干净[cite: 1] // 6. 删除示波器上的临时文件,保持设备存储干净[cite: 2]
await SendAsync($"FILESystem:DELEte \"{}\"{ScpiDelimiter}", ct); await SendAsync($"FILESystem:DELEte \"{}\"{ScpiDelimiter}", ct);
} }
@@ -258,14 +253,13 @@ namespace DeviceCommand.Devices
/// <summary> /// <summary>
/// 辅助方法:读取 IEEE 488.2 标准的二进制块数据 (Block Data) /// 辅助方法:读取 IEEE 488.2 标准的二进制块数据 (Block Data)
/// 手册规范:<Block> ::= {#<NZDig><Dig>[<Dig>...][<DChar>...]}[cite: 1]
/// </summary> /// </summary>
protected virtual async Task<byte[]> ReadBinaryBlockAsync(CancellationToken ct = default) protected virtual async Task<byte[]> ReadBinaryBlockAsync(CancellationToken ct = default)
{ {
var stream = GetNetworkStream(); var stream = GetNetworkStream();
byte[] singleByte = new byte[1]; byte[] singleByte = new byte[1];
// 1. 逐字节读取,直到读到起始符 '#'[cite: 1] // 1. 逐字节读取,直到读到起始符 '#'
while (true) while (true)
{ {
int read = await stream.ReadAsync(singleByte, 0, 1, ct); int read = await stream.ReadAsync(singleByte, 0, 1, ct);
@@ -273,13 +267,13 @@ namespace DeviceCommand.Devices
if (singleByte[0] == (byte)'#') break; if (singleByte[0] == (byte)'#') break;
} }
// 2. 读取 1 个字符 <NZDig>,它代表接下来有多少个字符表示数据长度[cite: 1] // 2. 读取 1 个字符 <NZDig>,它代表接下来有多少个字符表示数据长度
await stream.ReadAsync(singleByte, 0, 1, ct); await stream.ReadAsync(singleByte, 0, 1, ct);
char nzDigChar = (char)singleByte[0]; char nzDigChar = (char)singleByte[0];
if (!char.IsDigit(nzDigChar)) throw new InvalidDataException($"无效的块头标识: {nzDigChar}"); if (!char.IsDigit(nzDigChar)) throw new InvalidDataException($"无效的块头标识: {nzDigChar}");
int lengthBytesCount = int.Parse(nzDigChar.ToString()); int lengthBytesCount = int.Parse(nzDigChar.ToString());
// 3. 读取 <NZDig> 所指示的长度字符,将其解析为整数 N[cite: 1] // 3. 读取 <NZDig> 所指示的长度字符,将其解析为整数 N
byte[] lengthBytes = new byte[lengthBytesCount]; byte[] lengthBytes = new byte[lengthBytesCount];
int currentRead = 0; int currentRead = 0;
while (currentRead < lengthBytesCount) while (currentRead < lengthBytesCount)
@@ -290,7 +284,7 @@ namespace DeviceCommand.Devices
} }
int dataLength = int.Parse(Encoding.ASCII.GetString(lengthBytes)); int dataLength = int.Parse(Encoding.ASCII.GetString(lengthBytes));
// 4. 从流中精确读取 N 个字节 <DChar>...,这就是完整的图像数据[cite: 1] // 4. 从流中精确读取 N 个字节 <DChar>...,这就是完整的图像数据
byte[] imageData = new byte[dataLength]; byte[] imageData = new byte[dataLength];
int totalBytesRead = 0; int totalBytesRead = 0;
while (totalBytesRead < dataLength) while (totalBytesRead < dataLength)
@@ -300,7 +294,7 @@ namespace DeviceCommand.Devices
totalBytesRead += read; totalBytesRead += read;
} }
// 5. 结尾可能包含 <EOM> (例如 LF \n),将其读取并丢弃以清空缓冲区[cite: 1] // 5. 结尾可能包含 <EOM> (例如 LF \n),将其读取并丢弃以清空缓冲区
try try
{ {
await stream.ReadAsync(singleByte, 0, 1, ct); await stream.ReadAsync(singleByte, 0, 1, ct);
@@ -319,7 +313,7 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task Async(CancellationToken ct = default) public virtual async Task Async(CancellationToken ct = default)
{ {
// 发送 *CLS 指令清空状态[cite: 1] // 发送 *CLS 指令清空状态[cite: 2]
await SendAsync($"*CLS{ScpiDelimiter}", ct); await SendAsync($"*CLS{ScpiDelimiter}", ct);
} }
@@ -328,7 +322,7 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task<string> Async(CancellationToken ct = default) public virtual async Task<string> Async(CancellationToken ct = default)
{ {
// 返回事件队列中的事件数量[cite: 1] // 返回事件队列中的事件数量
return await WriteReadAsync($"EVQty?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"EVQty?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
@@ -337,7 +331,7 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task<string> Async(CancellationToken ct = default) public virtual async Task<string> Async(CancellationToken ct = default)
{ {
// 返回事件队列中的事件代码和消息[cite: 1] // 返回事件队列中的事件代码和消息
return await WriteReadAsync($"EVMsg?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"EVMsg?{ScpiDelimiter}", ScpiDelimiter, ct);
} }
@@ -346,7 +340,7 @@ namespace DeviceCommand.Devices
/// </summary> /// </summary>
public virtual async Task<string> Async(CancellationToken ct = default) public virtual async Task<string> Async(CancellationToken ct = default)
{ {
// 返回所有事件及其消息[cite: 1] // 返回所有事件及其消息
return await WriteReadAsync($"ALLEv?{ScpiDelimiter}", ScpiDelimiter, ct); return await WriteReadAsync($"ALLEv?{ScpiDelimiter}", ScpiDelimiter, ct);
} }

View File

@@ -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;
/// <summary>正在执行设备命令时为 true用于 UI 忙碌状态指示。</summary>
public bool IsBusy
{
get => _isBusy;
set => SetProperty(ref _isBusy, value);
}
private string _responseLog = string.Empty;
/// <summary>命令响应日志(最新消息在顶部)。</summary>
public string ResponseLog
{
get => _responseLog;
set => SetProperty(ref _responseLog, value);
}
#endregion
#region
#endregion
public IT6015CViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
_deviceManager = containerProvider.Resolve<DeviceManager>();
}
public void Dispose()
{
_cts?.Cancel();
_cts?.Dispose();
}
#region / Navigation
/// <summary>
/// 从 DeviceManager 中查找IT6015C设备实例。
/// 优先按 <paramref name="deviceName"/> 查找,否则取第一个匹配类型的设备。
/// </summary>
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<Task> action)
{
if (_device == null)
{
AppendLog("错误:未关联到设备实例,请检查设备配置。");
return;
}
if (IsBusy) return;
IsBusy = true;
try
{
await action();
IsConnected = _device.IsConnected;
}
catch (OperationCanceledException)
{
AppendLog("命令超时或已取消。");
}
catch (Exception ex)
{
AppendLog($"错误:{ex.Message}");
}
finally
{
IsBusy = false;
}
}
private void AppendLog(string message)
{
var line = $"[{DateTime.Now:HH:mm:ss}] {message}";
ResponseLog = ResponseLog.Length > 4000
? line + "\n" + ResponseLog[..3000]
: line + "\n" + ResponseLog;
}
#endregion
public override void OnNavigatedTo(NavigationContext context)
{
var name = context.Parameters.GetValue<string?>("DeviceName");
Initialize(name);
}
#endregion
}
}

View File

@@ -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;
/// <summary>正在执行设备命令时为 true用于 UI 忙碌状态指示。</summary>
public bool IsBusy
{
get => _isBusy;
set => SetProperty(ref _isBusy, value);
}
private string _responseLog = string.Empty;
/// <summary>命令响应日志(最新消息在顶部)。</summary>
public string ResponseLog
{
get => _responseLog;
set => SetProperty(ref _responseLog, value);
}
#endregion
#region
#endregion
public IT6036CViewModel(IContainerProvider containerProvider) : base(containerProvider)
{
_deviceManager = containerProvider.Resolve<DeviceManager>();
}
public void Dispose()
{
_cts?.Cancel();
_cts?.Dispose();
}
#region / Navigation
/// <summary>
/// 从 DeviceManager 中查找IT6036C设备实例。
/// 优先按 <paramref name="deviceName"/> 查找,否则取第一个匹配类型的设备。
/// </summary>
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<Task> action)
{
if (_device == null)
{
AppendLog("错误:未关联到设备实例,请检查设备配置。");
return;
}
if (IsBusy) return;
IsBusy = true;
try
{
await action();
IsConnected = _device.IsConnected;
}
catch (OperationCanceledException)
{
AppendLog("命令超时或已取消。");
}
catch (Exception ex)
{
AppendLog($"错误:{ex.Message}");
}
finally
{
IsBusy = false;
}
}
private void AppendLog(string message)
{
var line = $"[{DateTime.Now:HH:mm:ss}] {message}";
ResponseLog = ResponseLog.Length > 4000
? line + "\n" + ResponseLog[..3000]
: line + "\n" + ResponseLog;
}
#endregion
public override void OnNavigatedTo(NavigationContext context)
{
var name = context.Parameters.GetValue<string?>("DeviceName");
Initialize(name);
}
#endregion
}
}

View File

@@ -1,15 +0,0 @@
<UserControl x:Class="DeviceEditModule.Views.IT6015CView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
mc:Ignorable="d"
prism:ViewModelLocator.AutoWireViewModel="False"
d:DesignHeight="760" d:DesignWidth="860">
<Grid>
</Grid>
</UserControl>

View File

@@ -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
{
/// <summary>
/// IT6015CView.xaml 的交互逻辑
/// </summary>
public partial class IT6015CView : UserControl
{
public IT6015CView()
{
InitializeComponent();
}
}
}

View File

@@ -1,16 +0,0 @@
<Page x:Class="DeviceEditModule.Views.IT6036CView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:UIShare.Converters;assembly=UIShare"
mc:Ignorable="d"
prism:ViewModelLocator.AutoWireViewModel="False"
d:DesignHeight="760" d:DesignWidth="860">
<Grid>
</Grid>
</Page>

View File

@@ -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
{
/// <summary>
/// IT6036CView.xaml 的交互逻辑
/// </summary>
public partial class IT6036CView : Page
{
public IT6036CView()
{
InitializeComponent();
}
}
}