Files
ADP/DeviceCommand/Devices/IT7800E.cs
T

445 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Common.Attributes;
using DeviceCommand.Base;
using Model.Models;
using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
namespace DeviceCommand.Devices
{
#region 枚举定义
/// <summary>
/// 电源电气/耦合模式
/// </summary>
public enum PowerCouplingMode
{
/// <summary> 纯交流模式 </summary>
AC,
/// <summary> 纯直流模式 </summary>
DC,
/// <summary> 交直流混合模式 </summary>
ACDC,
/// <summary> 直交流混合模式 </summary>
DCAC
}
/// <summary>
/// 设备操作运行角色/模式
/// </summary>
public enum DeviceOperationMode
{
/// <summary> 电压源模式(常规源) </summary>
VOLTage,
/// <summary> 电子负载模式(放电拉载) </summary>
LOAD,
/// <summary> 电流源模式 </summary>
CURRent
}
/// <summary>
/// 设备相位/输出模式[cite: 2]
/// </summary>
public enum DevicePhaseMode
{
/// <summary> 单相模式 </summary>
ONE,
/// <summary> 三相模式 </summary>
THRee,
/// <summary> 反相模式 </summary>
DIFFerence,
/// <summary> 多通道模式 </summary>
MULTichannel
}
#endregion
[ADPCommand]
public class IT7800E : Tcp
{
// 八台产品共用一个,使用换行符 \n (ASCII 0x0A) 作为 SCPI 结束符[cite: 1]
private const string ScpiDelimiter = "\n";
public IT7800E(TcpConfig config) : base(config)
{
}
#region 1. IEEE 488.2 公共命令
/// <summary>
/// 清除错误队列和状态字节
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 清除错误队列和状态字节(CancellationToken ct = default)
{
await SendAsync($"*CLS{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 查询设备标识
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>设备标识字符串(制造商, 产品型号, 序列号, 固件版本)</returns>
public virtual async Task<string> 查询设备标识(CancellationToken ct = default)
{
return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 重置设备
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 重置设备(CancellationToken ct = default)
{
await SendAsync($"*RST{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 读取状态字节
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>状态字节寄存器值</returns>
public virtual async Task<string> 读取状态字节(CancellationToken ct = default)
{
return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
#region 2. 耦合模式与拉载开关控制
/// <summary>
/// 设置电源输出源的电气模式/工作耦合模式 (AC, DC, ACDC, DCAC)[cite: 1]
/// </summary>
/// <param name="模式">电气耦合模式 (AC/DC/ACDC/DCAC)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置电源模式(PowerCouplingMode 模式, CancellationToken ct = default)
{
await SendAsync($":SOURce:FUNCtion {模式}{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 查询电源当前的工作电气模式[cite: 1]
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>当前工作电气模式字符串</returns>
public virtual async Task<string> 查询电源模式(CancellationToken ct = default)
{
return await WriteReadAsync($":SOURce:FUNCtion?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 设置DC输出开关
/// </summary>
/// <param name="开启">true: 开启输出, false: 关闭输出</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置DC输出(bool 开启, CancellationToken ct = default)
{
string 参数 = 开启 ? "ON" : "OFF"; //[cite: 1]
await SendAsync($":OUTPut {参数}{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 查询DC输出状态
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>输出状态字符串(ON 或 OFF</returns>
public virtual async Task<string> 查询DC输出状态(CancellationToken ct = default)
{
return await WriteReadAsync($":OUTPut?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
#endregion
#region 3. 设定输出参数设置 (AC 电压/频率/DC 电压)
/// <summary>
/// 设置交流电压
/// </summary>
/// <param name="电压">交流电压设定值 (单位: V)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置交流电压(double 电压, CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce:VOLTage {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1]
await SendAsync(cmd, ct);
}
/// <summary>
/// 设置直流电压
/// </summary>
/// <param name="电压">直流电压设定值 (单位: V)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置直流电压(double 电压, CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce:VOLTage:DC {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1]
await SendAsync(cmd, ct);
}
/// <summary>
/// 设置频率
/// </summary>
/// <param name="频率">频率设定值 (单位: Hz)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置频率(double 频率, CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce:FREQuency {0:F2}{1}", 频率, ScpiDelimiter); //[cite: 1]
await SendAsync(cmd, ct);
}
/// <summary>
/// 设置电流
/// </summary>
/// <param name="电流">电流设定值 (单位: A)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置电流(double 电流, CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce:CURRent {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1]
await SendAsync(cmd, ct);
}
#endregion
#region 4. 测量与数据回测(高频数据轮询核心)
/// <summary>
/// 查询实际电压
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>实际电压测量值 (单位: V)</returns>
[Monitorable("交流电源电压")]
public virtual async Task<double> 查询实际电压(CancellationToken ct = default)
{
string response = await WriteReadAsync($":MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
return double.TryParse(response, out double result) ? result : double.NaN;
}
/// <summary>
/// 查询实际电流
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>实际电流测量值 (单位: A)</returns>
[Monitorable("交流电源电流")]
public virtual async Task<double> 查询实际电流(CancellationToken ct = default)
{
string response = await WriteReadAsync($":MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
return double.TryParse(response, out double result) ? result : double.NaN;
}
/// <summary>
/// 查询实际功率
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>实际有功功率测量值 (单位: W)</returns>
[Monitorable("交流电源功率")]
public virtual async Task<double> 查询实际功率(CancellationToken ct = default)
{
string response = await WriteReadAsync($":MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct);
return double.TryParse(response, out double result) ? result : double.NaN;
}
/// <summary>
/// 查询视在功率
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>视在功率测量值 (单位: VA)</returns>
public virtual async Task<double> 查询视在功率(CancellationToken ct = default)
{
string response = await WriteReadAsync($":MEASure:POWer:APParent?{ScpiDelimiter}", ScpiDelimiter, ct);
return double.TryParse(response, out double result) ? result : double.NaN;
}
/// <summary>
/// 查询实际频率
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>实际频率测量值 (单位: Hz)</returns>
public virtual async Task<double> 查询实际频率(CancellationToken ct = default)
{
string response = await WriteReadAsync($":MEASure:FREQuency?{ScpiDelimiter}", ScpiDelimiter, ct);
return double.TryParse(response, out double result) ? result : double.NaN;
}
/// <summary>
/// 查询功率因数
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>功率因数测量值</returns>
public virtual async Task<double> 查询功率因数(CancellationToken ct = default)
{
string response = await WriteReadAsync($":MEASure:POWer:PFACtor?{ScpiDelimiter}", ScpiDelimiter, ct);
return double.TryParse(response, out double result) ? result : double.NaN;
}
#endregion
#region 5. 保护参数设置与系统监控
/// <summary>
/// 设置过流保护_OCP
/// </summary>
/// <param name="电流">过流保护阈值 (单位: A, RMS值)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置过流保护_OCP(double 电流, CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce:CURRent:PROTection:RMS {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1]
await SendAsync(cmd, ct);
}
/// <summary>
/// 设置过压保护_OVP
/// </summary>
/// <param name="电压">过压保护阈值 (单位: V, 峰值)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置过压保护_OVP(double 电压, CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce:VOLTage:PROTection:PEAK {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1]
await SendAsync(cmd, ct);
}
/// <summary>
/// 查询错误信息
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>错误代码和描述信息</returns>
public virtual async Task<string> 查询错误信息(CancellationToken ct = default)
{
return await WriteReadAsync($":SYSTem:ERRor?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 切换远程控制模式
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 切换远程控制模式(CancellationToken ct = default)
{
await SendAsync($":SYSTem:REMote{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 切换本地控制模式
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 切换本地控制模式(CancellationToken ct = default)
{
await SendAsync($":SYSTem:LOCal{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 清除保护告警
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 清除保护告警(CancellationToken ct = default)
{
await SendAsync($":OUTPut:PROTection:CLEar{ScpiDelimiter}", ct); //[cite: 1]
}
#endregion
#region 6. 充放电与能量统计扩展命令
/// <summary>
/// 清除最近的安时(Ah)与瓦时(Wh)统计数据[cite: 1]
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 清除充放电电量统计(CancellationToken ct = default)
{
await SendAsync($"SENSe:AHOur:RESet{ScpiDelimiter}", ct); //[cite: 1]
await SendAsync($"SENSe:WHOur:RESet{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 读取当前充放电累计的安时值 (单位: Ah)[cite: 1]
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>累计安时值 (单位: Ah)</returns>
public virtual async Task<string> 查询累计安时_Ah(CancellationToken ct = default)
{
return await WriteReadAsync($"FETCh:AHOur?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 读取当前充放电累计的瓦时值 (单位: Wh)[cite: 1]
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>累计瓦时值 (单位: Wh)</returns>
public virtual async Task<string> 查询累计瓦时_Wh(CancellationToken ct = default)
{
return await WriteReadAsync($"FETCh:WHOur?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 读取充放电积分持续时间 (单位: 秒)[cite: 1]
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>积分持续时间 (单位: 秒)</returns>
public virtual async Task<string> 查询积分时间(CancellationToken ct = default)
{
return await WriteReadAsync($"FETCh:ENERgy:TIME?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
}
/// <summary>
/// 切换设备的操作模式 (VOLTage: 电源模式, LOAD: 负载模式/放电, CURRent: 电流源)[cite: 1]
/// </summary>
/// <param name="模式">操作模式 (VOLTage/LOAD/CURRent)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置操作模式(DeviceOperationMode 模式, CancellationToken ct = default)
{
await SendAsync($"SYSTem:OPERation:MODE {模式}{ScpiDelimiter}", ct); //[cite: 1]
}
/// <summary>
/// 设置放电截止电压/电压下限 (单位: V,用于防止电池过放)[cite: 1]
/// </summary>
/// <param name="电压">放电截止电压/电压下限 (单位: V)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置电压下限(double 电压, CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce:VOLTage:LIMit:LOW {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1]
await SendAsync(cmd, ct);
}
#endregion
#region 7. 相位输出模式设置 (单相/三相/反相)[cite: 2]
/// <summary>
/// 设置电源相位输出模式 (ONE:单相 / THRee:三相 / DIFFerence:反相 / MULTichannel:多通道)[cite: 2]
/// </summary>
/// <param name="模式">相位输出模式</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置输出模式(DevicePhaseMode 模式, CancellationToken ct = default)
{
await SendAsync($"SYSTem:FUNCtion {模式}{ScpiDelimiter}", ct); //[cite: 2]
}
/// <summary>
/// 切换为单相模式 (SYST:FUNC ONE)[cite: 2]
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 切换为单相模式(CancellationToken ct = default)
{
await SendAsync($"SYSTem:FUNCtion ONE{ScpiDelimiter}", ct); //[cite: 2]
}
/// <summary>
/// 切换为反相模式 (SYST:FUNC DIFFerence)[cite: 2]
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 切换为反相模式(CancellationToken ct = default)
{
await SendAsync($"SYSTem:FUNCtion DIFFerence{ScpiDelimiter}", ct); //[cite: 2]
}
/// <summary>
/// 查询当前输出模式 (单相/三相/反相/多通道)[cite: 2]
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>返回 ONE, THRee, DIFFerence 或 MULTichannel[cite: 2]</returns>
public virtual async Task<string> 查询输出模式(CancellationToken ct = default)
{
return await WriteReadAsync($"SYSTem:FUNCtion?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 2]
}
#endregion
}
}