Compare commits
6 Commits
df520f91ac
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66bb6d36ba | ||
|
|
7250080a24 | ||
|
|
537c4554ae | ||
|
|
857bd3fb56 | ||
| ef52530a14 | |||
| 7e6c342908 |
22
DeviceCommand/Devices/ANEVH80.cs
Normal file
22
DeviceCommand/Devices/ANEVH80.cs
Normal 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,64 +49,102 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 3. LIST 步阶参数配置
|
#region 3. LIST 步阶参数配置 (独立发送版 - 三参数固定版)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配置单相的 LIST 序列参数
|
/// 切换目标相位并设置波形为正弦波
|
||||||
/// 传入的数组长度必须保持一致,代表 LIST 的每个 Step(SEQ)
|
/// 建议在发送具体 LIST 参数前调用一次即可
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="phase">相位 (1: L1, 2: L2, 3: L3)</param>
|
/// <param name="phase">相位 (1: L1, 2: L2, 3: L3)</param>
|
||||||
/// <param name="degrees">各步起始角度 (如 [0, 0, 0])</param>
|
public virtual async Task 切换相位Async(int phase, CancellationToken ct = default)
|
||||||
/// <param name="vacStart">各步交流起始电压 (如 [230, 11.5, 230])</param>
|
|
||||||
/// <param name="vacEnd">各步交流结束电压 (如 [230, 11.5, 230])</param>
|
|
||||||
/// <param name="vdcStart">各步直流起始电压</param>
|
|
||||||
/// <param name="vdcEnd">各步直流结束电压</param>
|
|
||||||
/// <param name="freqStart">各步起始频率</param>
|
|
||||||
/// <param name="freqEnd">各步结束频率</param>
|
|
||||||
/// <param name="dwellTimeMs">各步执行时间(单位: 毫秒)</param>
|
|
||||||
public virtual async Task 配置单相List序列(
|
|
||||||
int phase,
|
|
||||||
double[] degrees,
|
|
||||||
double[] vacStart, double[] vacEnd,
|
|
||||||
double[] vdcStart, double[] vdcEnd,
|
|
||||||
double[] freqStart, double[] freqEnd,
|
|
||||||
double[] dwellTimeMs,
|
|
||||||
CancellationToken ct = default)
|
|
||||||
{
|
{
|
||||||
if (phase < 1 || phase > 3) throw new ArgumentOutOfRangeException(nameof(phase), "相位必须为 1, 2, 或 3");
|
if (phase < 1 || phase > 3)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(phase), "相位必须为 1, 2, 或 3");
|
||||||
|
|
||||||
// 选择相位并设置为正弦波
|
|
||||||
await SendAsync($"INST:NSEL {phase}{ScpiDelimiter}", ct);
|
await SendAsync($"INST:NSEL {phase}{ScpiDelimiter}", ct);
|
||||||
await SendAsync($"FUNC:SHAP:A SINE{ScpiDelimiter}", ct);
|
await SendAsync($"FUNC:SHAP:A SINE{ScpiDelimiter}", ct);
|
||||||
|
|
||||||
// 转换数组为 SCPI 需要的逗号分隔字符串
|
|
||||||
string strDegrees = JoinParameters(degrees);
|
|
||||||
string strVacStart = JoinParameters(vacStart);
|
|
||||||
string strVacEnd = JoinParameters(vacEnd);
|
|
||||||
string strVdcStart = JoinParameters(vdcStart);
|
|
||||||
string strVdcEnd = JoinParameters(vdcEnd);
|
|
||||||
string strFreqStart = JoinParameters(freqStart);
|
|
||||||
string strFreqEnd = JoinParameters(freqEnd);
|
|
||||||
string strDwell = JoinParameters(dwellTimeMs);
|
|
||||||
|
|
||||||
// 下发序列参数
|
|
||||||
// 注意 Chroma 部分指令是 DEGR,部分固件版本是 DEGRee,这里统一使用简写 DEGR,兼容性最好
|
|
||||||
await SendAsync($"LIST:DEGR {strDegrees}{ScpiDelimiter}", ct);
|
|
||||||
await SendAsync($"LIST:VOLT:AC:STAR {strVacStart}{ScpiDelimiter}", ct);
|
|
||||||
await SendAsync($"LIST:VOLT:AC:END {strVacEnd}{ScpiDelimiter}", ct);
|
|
||||||
await SendAsync($"LIST:VOLT:DC:STAR {strVdcStart}{ScpiDelimiter}", ct);
|
|
||||||
await SendAsync($"LIST:VOLT:DC:END {strVdcEnd}{ScpiDelimiter}", ct);
|
|
||||||
await SendAsync($"LIST:FREQ:STAR {strFreqStart}{ScpiDelimiter}", ct);
|
|
||||||
await SendAsync($"LIST:FREQ:END {strFreqEnd}{ScpiDelimiter}", ct);
|
|
||||||
await SendAsync($"LIST:DWEL {strDwell}{ScpiDelimiter}", ct);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 辅助方法:将 double 数组转换为逗号分隔的字符串,确保小数点格式正确
|
/// 配置 LIST 各步起始角度
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string JoinParameters(double[] values)
|
public virtual async Task 配置List起始角度Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return string.Join(",", values.Select(v => v.ToString("0.###", CultureInfo.InvariantCulture)));
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:DEGR {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置 LIST 各步交流起始电压
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 配置List交流起始电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:VOLT:AC:STAR {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置 LIST 各步交流结束电压
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 配置List交流结束电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:VOLT:AC:END {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置 LIST 各步直流起始电压
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 配置List直流起始电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:VOLT:DC:STAR {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置 LIST 各步直流结束电压
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 配置List直流结束电压Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:VOLT:DC:END {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置 LIST 各步起始频率
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 配置List起始频率Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:FREQ:STAR {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置 LIST 各步结束频率
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 配置List结束频率Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:FREQ:END {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置 LIST 各步执行时间 (单位: 毫秒)
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 配置List执行时间Async(double step1, double step2, double step3, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string strValues = JoinParameters(step1, step2, step3);
|
||||||
|
await SendAsync($"LIST:DWEL {strValues}{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 辅助方法:将三个 double 值转换为逗号分隔的字符串,确保小数点格式正确
|
||||||
|
/// </summary>
|
||||||
|
private string JoinParameters(double val1, double val2, double val3)
|
||||||
|
{
|
||||||
|
return $"{val1.ToString("0.###", CultureInfo.InvariantCulture)}," +
|
||||||
|
$"{val2.ToString("0.###", CultureInfo.InvariantCulture)}," +
|
||||||
|
$"{val3.ToString("0.###", CultureInfo.InvariantCulture)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -1,302 +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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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>
|
|
||||||
/// 设置 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>
|
|
||||||
/// 设置电压上升/下降斜率 (单位: V/s, 数值越大变化越快)[cite: 1]
|
|
||||||
/// </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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 6. 保护功能配置 (OVP, OCP, OPP)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭过压保护 (OVP)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭过流保护 (OCP)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭过功率保护 (OPP)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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 8. 负载电阻/CR模式设置 (仅限 CC 优先模式)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭恒阻 (CR) 负载模式[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>执行该指令前,必须确保设备处于 CC 优先模式,否则会报错</remarks>
|
|
||||||
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) 模式下的电阻值 (单位: Ω)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>必须在先开启 CR 模式才能使用,设置为 0 相当于关闭 CR 模式</remarks>
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,334 +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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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>
|
|
||||||
/// 设置 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>
|
|
||||||
/// 设置电压上升/下降斜率 (单位: V/s, 数值越大变化越快)[cite: 1]
|
|
||||||
/// </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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 6. 保护功能配置 (OVP, OCP, OPP)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭过压保护 (OVP)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭过流保护 (OCP)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭过功率保护 (OPP)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 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 8. 负载电阻/CR模式设置 (仅限 CC 优先模式)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启或关闭恒阻 (CR) 负载模式[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>执行该指令前,必须确保设备处于 CC 优先模式,否则会报错</remarks>
|
|
||||||
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) 模式下的电阻值 (单位: Ω)[cite: 1]
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>必须在先开启 CR 模式才能使用,设置为 0 相当于关闭 CR 模式</remarks>
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
213
DeviceCommand/Devices/S7200.cs
Normal file
213
DeviceCommand/Devices/S7200.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,13 +3,15 @@ using DeviceCommand.Base;
|
|||||||
using Model.Models;
|
using Model.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace DeviceCommand.Devices
|
namespace DeviceCommand.Devices
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 示波器 一拖三
|
/// 示波器 MSO 4/5/6 系列
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#region 枚举定义
|
#region 枚举定义
|
||||||
|
|
||||||
@@ -48,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)
|
||||||
@@ -59,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,34 +109,33 @@ 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 设置采样率(double 采样率, CancellationToken ct = default)
|
public virtual async Task<string> 查询采样率(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 设置或查询水平采样率[cite: 1]
|
// 查询水平采样率[cite: 2]
|
||||||
string cmd = string.Format(CultureInfo.InvariantCulture, "HORizontal:SAMPLERate {0:E}{1}", 采样率, ScpiDelimiter);
|
return await WriteReadAsync($"HORizontal:SAMPLERate?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
await SendAsync(cmd, ct);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 4. 通道与显示控制 (Display & Vertical)
|
#region 4. 通道与显示控制 (Vertical)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 全局启用或关闭某通道的显示
|
/// 全局启用或关闭某通道的显示
|
||||||
/// </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($"DISplay:GLObal:CH{通道号}:STATE {参数}{ScpiDelimiter}", ct);
|
await SendAsync($"DISplay:GLObal:CH{通道号}:STATE {参数}{ScpiDelimiter}", ct);
|
||||||
}
|
}
|
||||||
@@ -143,8 +145,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual async Task 设置通道垂直刻度(int 通道号, double 伏特每格, CancellationToken ct = default)
|
public virtual async Task 设置通道垂直刻度(int 通道号, double 伏特每格, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 设置或查询指定Waveform View内指定通道的垂直缩放比例(注:WaveView<x> 通常为1)[cite: 1]
|
string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:SCAle {1:E}{2}", 通道号, 伏特每格, ScpiDelimiter);
|
||||||
string cmd = string.Format(CultureInfo.InvariantCulture, "DISplay:WAVEView1:CH{0}:VERTical:SCAle {1:E}{2}", 通道号, 伏特每格, ScpiDelimiter);
|
|
||||||
await SendAsync(cmd, ct);
|
await SendAsync(cmd, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,8 +154,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual async Task 设置通道垂直位置(int 通道号, double 格数, CancellationToken ct = default)
|
public virtual async Task 设置通道垂直位置(int 通道号, double 格数, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 设置或查询指定Waveform View内指定通道的垂直位置(以格为单位)[cite: 1]
|
string cmd = string.Format(CultureInfo.InvariantCulture, "CH{0}:POSition {1:F2}{2}", 通道号, 格数, ScpiDelimiter);
|
||||||
string cmd = string.Format(CultureInfo.InvariantCulture, "DISplay:WAVEView1:CH{0}:VERTical:POSition {1:F2}{2}", 通道号, 格数, ScpiDelimiter);
|
|
||||||
await SendAsync(cmd, ct);
|
await SendAsync(cmd, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,37 +163,185 @@ namespace DeviceCommand.Devices
|
|||||||
#region 5. 自动测量 (Measurement)
|
#region 5. 自动测量 (Measurement)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 新增一个测量项槽位
|
/// 动态添加并开启一个测量项
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual async Task 添加测量项(CancellationToken ct = default)
|
public virtual async Task 开启测量项(int 测量项编号, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 添加一个测量项[cite: 1]
|
// 4/5/6 Series MSO 必须先动态创建测量项[cite: 2]
|
||||||
await SendAsync($"MEASUrement:ADDMEAS{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)
|
||||||
{
|
{
|
||||||
// 设置或查询局部输入源 (例如 CH1, CH2)[cite: 1]
|
// 4/5/6 Series 中设置测量源[cite: 2]
|
||||||
await SendAsync($"MEASUrement:MEAS{测量项编号}:SOURCE {源名称}{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{测量项编号}:RESUlts:CURRentacq:MEAN?{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{测量项编号}:RESUlts:CURRentacq:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct);
|
return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:ALLAcqs:MEAN?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task<string> 查询测量项全局最大值(int 测量项编号, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
// 获取所有采集(AllAcqs)历史累积的最大值[cite: 2]
|
||||||
|
return await WriteReadAsync($"MEASUrement:MEAS{测量项编号}:RESUlts:ALLAcqs:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 6. 屏幕截图与文件系统 (Hard Copy & File System)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 捕获示波器屏幕并保存到上位机本地路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="上位机文件路径">保存到电脑本地的文件路径 (例如: @"C:\temp\screen.png")</param>
|
||||||
|
/// <param name="ct">异步取消令牌</param>
|
||||||
|
public virtual async Task 保存屏幕截图(string 上位机文件路径, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
string 临时文件 = "E:/temp1.png";
|
||||||
|
|
||||||
|
// 1. 直接保存截图到示波器U盘 (自动识别 .png 扩展名)[cite: 2]
|
||||||
|
await SendAsync($"SAVe:IMAGe \"{临时文件}\"{ScpiDelimiter}", ct);
|
||||||
|
|
||||||
|
// 2. 发送 *OPC? 并等待返回 1,确保图像文件已经完全写入磁盘[cite: 2]
|
||||||
|
await WriteReadAsync($"*OPC?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
|
||||||
|
// 3. 将文件内容读取到当前通信接口[cite: 2]
|
||||||
|
await SendAsync($"FILESystem:READFile \"{临时文件}\"{ScpiDelimiter}", ct);
|
||||||
|
|
||||||
|
// 4. 提取底层的二进制块 (Block Data)
|
||||||
|
byte[] imageBytes = await ReadBinaryBlockAsync(ct);
|
||||||
|
|
||||||
|
// 5. 将提取的二进制字节流写入上位机本地磁盘
|
||||||
|
await File.WriteAllBytesAsync(上位机文件路径, imageBytes, ct);
|
||||||
|
|
||||||
|
// 6. 删除示波器上的临时文件,保持设备存储干净[cite: 2]
|
||||||
|
await SendAsync($"FILESystem:DELEte \"{临时文件}\"{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ⚠️ 请在这里将您的网络流对接起来!
|
||||||
|
/// 依据您 Tcp 基类的设计,返回用于读取底层字节流的 Stream。
|
||||||
|
/// </summary>
|
||||||
|
protected virtual Stream GetNetworkStream()
|
||||||
|
{
|
||||||
|
// 【修改提示】:
|
||||||
|
// 如果您的基类暴露了 TcpClient,请取消注释并使用这一行:
|
||||||
|
// return this.TcpClient.GetStream();
|
||||||
|
|
||||||
|
// 如果您的基类直接叫 _stream 或 Stream,请返回它:
|
||||||
|
// return this.Stream;
|
||||||
|
|
||||||
|
// 假如不知道怎么填,请查看 Tcp 类的源码。
|
||||||
|
throw new NotImplementedException("请在此方法中返回基类的 NetworkStream 或 Socket 流对象。");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 辅助方法:读取 IEEE 488.2 标准的二进制块数据 (Block Data)
|
||||||
|
/// </summary>
|
||||||
|
protected virtual async Task<byte[]> ReadBinaryBlockAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
var stream = GetNetworkStream();
|
||||||
|
byte[] singleByte = new byte[1];
|
||||||
|
|
||||||
|
// 1. 逐字节读取,直到读到起始符 '#'
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int read = await stream.ReadAsync(singleByte, 0, 1, ct);
|
||||||
|
if (read == 0) throw new EndOfStreamException("通信中断:未找到二进制块起始符 '#'");
|
||||||
|
if (singleByte[0] == (byte)'#') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 读取 1 个字符 <NZDig>,它代表接下来有多少个字符表示数据长度
|
||||||
|
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. 读取 <NZDig> 所指示的长度字符,将其解析为整数 N
|
||||||
|
byte[] lengthBytes = new byte[lengthBytesCount];
|
||||||
|
int currentRead = 0;
|
||||||
|
while (currentRead < lengthBytesCount)
|
||||||
|
{
|
||||||
|
int read = await stream.ReadAsync(lengthBytes, currentRead, lengthBytesCount - currentRead, ct);
|
||||||
|
if (read == 0) throw new EndOfStreamException("通信中断:读取数据长度失败");
|
||||||
|
currentRead += read;
|
||||||
|
}
|
||||||
|
int dataLength = int.Parse(Encoding.ASCII.GetString(lengthBytes));
|
||||||
|
|
||||||
|
// 4. 从流中精确读取 N 个字节 <DChar>...,这就是完整的图像数据
|
||||||
|
byte[] imageData = new byte[dataLength];
|
||||||
|
int totalBytesRead = 0;
|
||||||
|
while (totalBytesRead < dataLength)
|
||||||
|
{
|
||||||
|
int read = await stream.ReadAsync(imageData, totalBytesRead, dataLength - totalBytesRead, ct);
|
||||||
|
if (read == 0) throw new EndOfStreamException("通信中断:读取图像数据不完整");
|
||||||
|
totalBytesRead += read;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 结尾可能包含 <EOM> (例如 LF \n),将其读取并丢弃以清空缓冲区
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await stream.ReadAsync(singleByte, 0, 1, ct);
|
||||||
|
}
|
||||||
|
catch { /* 忽略末尾符读取的可能超时 */ }
|
||||||
|
|
||||||
|
return imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 7. 状态与错误队列 (Status and Error)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除所有的状态寄存器和错误/事件队列
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task 清除错误队列Async(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
// 发送 *CLS 指令清空状态[cite: 2]
|
||||||
|
await SendAsync($"*CLS{ScpiDelimiter}", ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询错误队列中当前的事件/错误数量
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task<string> 查询错误数量Async(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
// 返回事件队列中的事件数量
|
||||||
|
return await WriteReadAsync($"EVQty?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从错误队列中读取最早的一个事件/错误(包含代码和详细消息),并将其从队列中弹出
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task<string> 读取单条错误消息Async(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
// 返回事件队列中的事件代码和消息
|
||||||
|
return await WriteReadAsync($"EVMsg?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读取并清空队列中的所有错误和事件消息
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task<string> 读取所有错误消息Async(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
// 返回所有事件及其消息
|
||||||
|
return await WriteReadAsync($"ALLEv?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,201 +4,86 @@
|
|||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True">
|
prism:ViewModelLocator.AutoWireViewModel="True">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
|
<!-- 背景:多层柔光圆 -->
|
||||||
<!-- 工业深色背景 -->
|
|
||||||
<Grid.Background>
|
<Grid.Background>
|
||||||
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
|
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
||||||
<GradientStop Color="#0F172A" Offset="0"/>
|
<GradientStop Color="#E8F0FE" Offset="0"/>
|
||||||
<GradientStop Color="#020617" Offset="1"/>
|
<GradientStop Color="#F3E8FF" Offset="0.5"/>
|
||||||
|
<GradientStop Color="#FCE7F3" Offset="1"/>
|
||||||
</LinearGradientBrush>
|
</LinearGradientBrush>
|
||||||
</Grid.Background>
|
</Grid.Background>
|
||||||
|
|
||||||
|
<!-- 背景装饰光斑 -->
|
||||||
|
<Ellipse Width="200" Height="200" Fill="#93C5FD" Opacity="0.3"
|
||||||
|
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-50,-50,0,0"/>
|
||||||
|
<Ellipse Width="150" Height="150" Fill="#C4B5FD" Opacity="0.3"
|
||||||
|
HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-30,-30"/>
|
||||||
|
|
||||||
<!-- 工业卡片 -->
|
<!-- 中心磨砂卡片 -->
|
||||||
<Border Width="360"
|
<Border Width="380" Height="440" CornerRadius="20"
|
||||||
Height="430"
|
Background="#CCFFFFFF" BorderBrush="#E2E8F0" BorderThickness="1"
|
||||||
CornerRadius="18"
|
HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
Background="#111827"
|
|
||||||
BorderBrush="#334155"
|
|
||||||
BorderThickness="1"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
|
|
||||||
<Border.Effect>
|
<Border.Effect>
|
||||||
<DropShadowEffect BlurRadius="25"
|
<DropShadowEffect BlurRadius="40" ShadowDepth="0" Opacity="0.12"/>
|
||||||
ShadowDepth="8"
|
|
||||||
Opacity="0.5"/>
|
|
||||||
</Border.Effect>
|
</Border.Effect>
|
||||||
|
<Grid Margin="32">
|
||||||
|
|
||||||
<Grid Margin="28">
|
|
||||||
|
|
||||||
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- 顶部 -->
|
||||||
|
<StackPanel Grid.Row="0" HorizontalAlignment="Center">
|
||||||
<!-- 顶部设备状态 -->
|
<Border Width="64" Height="64" Background="#E0E7FF" CornerRadius="32">
|
||||||
<StackPanel Grid.Row="0"
|
<materialDesign:PackIcon Kind="Chip" Width="32" Height="32"
|
||||||
HorizontalAlignment="Center">
|
Foreground="#4F46E5"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
<materialDesign:PackIcon
|
</Border>
|
||||||
Kind="Chip"
|
|
||||||
Width="30"
|
<StackPanel Orientation="Horizontal" Margin="0,10,0,0"
|
||||||
Height="30"
|
HorizontalAlignment="Center">
|
||||||
Foreground="#38BDF8"/>
|
|
||||||
|
<TextBlock Text="{Binding TestStatus}" FontSize="13" Foreground="#64748B"/>
|
||||||
|
|
||||||
<TextBlock Text="PROTOCOL CONTROLLER"
|
|
||||||
Margin="0,12,0,0"
|
|
||||||
FontSize="14"
|
|
||||||
FontWeight="Bold"
|
|
||||||
Foreground="#CBD5E1"
|
|
||||||
HorizontalAlignment="Center"/>
|
|
||||||
|
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
Margin="0,12,0,0">
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 状态灯 -->
|
|
||||||
<Ellipse Width="10"
|
|
||||||
Height="10"
|
|
||||||
Fill="#22C55E"
|
|
||||||
Margin="0,0,8,0"/>
|
|
||||||
|
|
||||||
|
|
||||||
<TextBlock Text="{Binding TestStatus}"
|
|
||||||
FontSize="13"
|
|
||||||
Foreground="#94A3B8"/>
|
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- 中央按钮 -->
|
||||||
|
<Grid Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<Button Width="130" Height="130"
|
||||||
|
Command="{Binding StartProtocolCommand}"
|
||||||
<!-- 中央启动按钮 -->
|
Background="#7C3AED" BorderBrush="#6D28D9" BorderThickness="0"
|
||||||
<Grid Grid.Row="1"
|
materialDesign:ElevationAssist.Elevation="Dp6">
|
||||||
VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Center">
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 外圈 -->
|
|
||||||
<Ellipse Width="210"
|
|
||||||
Height="210"
|
|
||||||
Fill="#0B1220"
|
|
||||||
Stroke="#334155"
|
|
||||||
StrokeThickness="2"/>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 内圈 -->
|
|
||||||
<Ellipse Width="170"
|
|
||||||
Height="170"
|
|
||||||
Fill="#1E293B"
|
|
||||||
Stroke="#475569"
|
|
||||||
StrokeThickness="2"/>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 启动按钮 -->
|
|
||||||
<Button
|
|
||||||
Command="{Binding StartProtocolCommand}"
|
|
||||||
Width="130"
|
|
||||||
Height="130"
|
|
||||||
Background="#020617"
|
|
||||||
BorderBrush="#38BDF8"
|
|
||||||
BorderThickness="3"
|
|
||||||
Style="{StaticResource MaterialDesignFloatingActionButton}">
|
|
||||||
|
|
||||||
|
|
||||||
<Button.Resources>
|
<Button.Resources>
|
||||||
<Style TargetType="Border">
|
<Style TargetType="Border">
|
||||||
<Setter Property="CornerRadius"
|
<Setter Property="CornerRadius" Value="65"/>
|
||||||
Value="65"/>
|
|
||||||
</Style>
|
</Style>
|
||||||
</Button.Resources>
|
</Button.Resources>
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<materialDesign:PackIcon Kind="Power" Width="44" Height="44"
|
||||||
|
Foreground="#FFFFFF" HorizontalAlignment="Center"/>
|
||||||
<Grid>
|
<TextBlock Text="START" Margin="0,6,0,0"
|
||||||
|
FontSize="14" FontWeight="Bold"
|
||||||
<materialDesign:PackIcon
|
Foreground="#FFFFFF" HorizontalAlignment="Center"/>
|
||||||
Kind="Power"
|
</StackPanel>
|
||||||
Width="55"
|
|
||||||
Height="55"
|
|
||||||
Foreground="#38BDF8"/>
|
|
||||||
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- 底部 -->
|
||||||
|
<StackPanel Grid.Row="2" HorizontalAlignment="Center">
|
||||||
|
<Border Background="#E0E7FF" CornerRadius="8" Padding="16,6">
|
||||||
|
|
||||||
|
|
||||||
<!-- 底部状态 -->
|
|
||||||
<StackPanel Grid.Row="2"
|
|
||||||
HorizontalAlignment="Center">
|
|
||||||
|
|
||||||
|
|
||||||
<Border Background="#052E16"
|
|
||||||
CornerRadius="8"
|
|
||||||
Padding="20,6">
|
|
||||||
|
|
||||||
|
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Ellipse Width="8" Height="8" Fill="#4F46E5" Margin="0,0,6,0"/>
|
||||||
|
<TextBlock Text="系统准备中" FontSize="13"
|
||||||
<Ellipse Width="8"
|
FontWeight="Bold" Foreground="#4338CA"/>
|
||||||
Height="8"
|
|
||||||
Fill="#22C55E"
|
|
||||||
Margin="0,0,8,0"/>
|
|
||||||
|
|
||||||
|
|
||||||
<TextBlock Text="SYSTEM READY"
|
|
||||||
FontWeight="Bold"
|
|
||||||
FontSize="14"
|
|
||||||
Foreground="#4ADE80"/>
|
|
||||||
|
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
</Border>
|
</Border>
|
||||||
|
<TextBlock Text="点击按钮加载测试序列" Margin="0,10,0,0"
|
||||||
|
FontSize="12" Foreground="#94A3B8" HorizontalAlignment="Center"/>
|
||||||
|
|
||||||
<TextBlock Text="点击启动按钮加载测试序列"
|
|
||||||
FontSize="12"
|
|
||||||
Foreground="#64748B"
|
|
||||||
Margin="0,12,0,0"
|
|
||||||
HorizontalAlignment="Center"/>
|
|
||||||
|
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
Reference in New Issue
Block a user