添加项目文件。

This commit is contained in:
czj
2026-06-05 10:57:09 +08:00
parent f29671b374
commit d960cb5912
166 changed files with 15996 additions and 0 deletions

View File

@@ -0,0 +1,459 @@
using Common.Attributes;
using DeviceCommand.Base;
using System;
using System.ComponentModel;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
namespace DeviceCommand.Device
{
[ADPCommand]
public class N36600 : Tcp
{
private CancellationTokenSource? _heartbeatCts;
private Task? _heartbeatTask;
private const int HeartbeatInterval = 3000; // 心跳间隔 3 秒
public bool IsActive { get; private set; } = false;
public int ReConnectionAttempts { get; private set; } = 0;
public const int MaxReconnectAttempts = 10;
// 手册第 4 页明确规定:每条命令后面都要加结束符 0x0A (\n)
private const string SCPIDelimiter = "\n";
public N36600(string ipAddress, int port, int sendTimeout, int receiveTimeout)
{
ConfigureDevice(ipAddress, port, sendTimeout, receiveTimeout);
}
/// <summary>
/// 建立 TCP 连接,成功后自动激活心跳
/// </summary>
public new async Task<bool> ConnectAsync(CancellationToken ct = default)
{
bool isConnected = await base.ConnectAsync(ct);
if (isConnected)
{
IsActive = true;
ReConnectionAttempts = 0;
StartHeartbeat();
}
return isConnected;
}
public override void Close()
{
StopHeartbeat();
base.Close();
}
#region 线
[Browsable(false)]
public void StartHeartbeat()
{
if (_heartbeatTask != null && !_heartbeatTask.IsCompleted)
return;
_heartbeatCts?.Cancel();
_heartbeatCts?.Dispose();
_heartbeatCts = new CancellationTokenSource();
_heartbeatTask = Task.Run(() => HeartbeatLoop(_heartbeatCts.Token));
}
[Browsable(false)]
public void StopHeartbeat()
{
IsActive = false;
if (_heartbeatCts != null && !_heartbeatCts.IsCancellationRequested)
{
_heartbeatCts.Cancel();
}
_heartbeatTask = null;
}
private async Task HeartbeatLoop(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
try
{
await Task.Delay(HeartbeatInterval, ct);
if (ct.IsCancellationRequested) break;
// 使用公共查询命令发送心跳,确保通道连接正常,且不破坏远程或本地锁定状态
await SendAsync($"*IDN?{SCPIDelimiter}", ct);
IsActive = true;
ReConnectionAttempts = 0;
}
catch (Exception)
{
IsActive = false;
ReConnectionAttempts++;
if (ReConnectionAttempts > MaxReconnectAttempts)
{
StopHeartbeat();
base.Close();
return;
}
await ReconnectDeviceAsync(ct);
}
}
}
private async Task ReconnectDeviceAsync(CancellationToken ct)
{
try
{
await ConnectAsync(ct);
}
catch (Exception)
{
// 静默处理,等待下一轮心跳重试
}
}
#endregion
#region 3.1 IEEE 488.2
/// <summary>
/// 3.1.1 读取电源的相关信息(制造商, 产品标号, 产品序列号, 软件版本号)
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"*IDN?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.1.2 从指定的单位中恢复 *SAV 命令保存的设定值 (参数1~99)
/// </summary>
public virtual async Task (int , CancellationToken ct = default)
{
if ( < 1 || > 99) throw new ArgumentOutOfRangeException(nameof(), "组别有效范围为 1~99");
await SendAsync($"*RCL {组别}{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.1.3 将仪器当前系统状态保存到非易失性内存中 (参数1~99)
/// </summary>
public virtual async Task (int , CancellationToken ct = default)
{
if ( < 1 || > 99) throw new ArgumentOutOfRangeException(nameof(), "组别有效范围为 1~99");
await SendAsync($"*SAV {组别}{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.1.4 远程控制触发一次
/// </summary>
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($"*TRG{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.1.5 返回状态、采集电压、采集电流 (格式: 状态码,电压值,电流值)
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($"*ALL?{SCPIDelimiter}", SCPIDelimiter, ct);
}
#endregion
#region 3.2 APPLy
/// <summary>
/// 3.2.1 设置输出电压和输出电流值
/// </summary>
public virtual async Task (double , double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":APPLY {0:F3},{1:F3}{2}", , , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.2.1 查询当前设定的输出电压和电流值
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":APPLY?{SCPIDelimiter}", SCPIDelimiter, ct);
}
#endregion
#region 3.5 MEASure
/// <summary>
/// 3.5.1 查询通道输出端子上测得的直流电流值 (A)
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":MEASure:CURRent?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.5.2 查询通道输出端子上测得的直流功率值 (W)
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":MEASure:POWer?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.5.3 查询通道输出端子上测得的直流电压值 (V)
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":MEASure:VOLTage?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.5.4 查询通道输出端子上测得的电压、电流和功率的组合值
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":MEASure:VAP?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.5.5 查询通道输出端子上测得的电池容量
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":MEASure:CAPAcity?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.5.6 查询通道输出端子上测得的恒流输出时间长度 (单位: ms)
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":MEASure:TIMEr:CC?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.5.7 查询通道输出端子上测得的输出时间长度
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":MEASure:TIME:OUTPut?{SCPIDelimiter}", SCPIDelimiter, ct);
}
#endregion
#region 3.6 OUTPut
/// <summary>
/// 3.6.1 设置电源输出开关
/// </summary>
public virtual async Task DC输出(bool , CancellationToken ct = default)
{
string = ? "ON" : "OFF";
await SendAsync($":OUTPut {状态}{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.6.1 查询通道输出状态 (返回 ON 或 OFF)
/// </summary>
public virtual async Task<string> DC输出状态(CancellationToken ct = default)
{
return await WriteReadAsync($":OUTPut?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.6.2 控制电源输出定时器的开关状态
/// </summary>
public virtual async Task (bool , CancellationToken ct = default)
{
string = ? "ON" : "OFF";
await SendAsync($":OUTPut:TIMEr {状态}{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.6.3 设定电源输出定时器的时间 (单位: s, 范围: 0.1 ~ 999999.9)
/// </summary>
public virtual async Task (double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":OUTPut:TIMEr:DATA {0:F1}{1}", , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.6.4 设定电源输出的模式优先权 (CV优先 或 CC优先)
/// </summary>
public virtual async Task (bool CV优先, CancellationToken ct = default)
{
string = CV优先 ? "CV" : "CC";
await SendAsync($":OUTPut:MODE {模式}{SCPIDelimiter}", ct);
}
#endregion
#region 3.7 SOURce
/// <summary>
/// 3.7.1.1 清除输出电流保护(OCP)电路状态
/// </summary>
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($":CURRent:PROTection:CLEar{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.7.1.2 使能或禁止当前输出电流保护(OCP)电路
/// </summary>
public virtual async Task 使(bool , CancellationToken ct = default)
{
string = ? "ON" : "OFF";
await SendAsync($":CURRent:PROTection:STATE {状态}{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.7.1.4 设置输出电流保护(OCP)阀值 (A)
/// </summary>
public virtual async Task (double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":CURRent:PROTection {0:F3}{1}", , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.7.1.7 设置电源的输出电流值 (A)
/// </summary>
public virtual async Task (double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":CURRent {0:F3}{1}", , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.7.2.1 清除输出电压保护(OVP)电路状态
/// </summary>
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($":VOLTage:PROTection:CLEar{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.7.2.2 使能或禁止当前输出电压保护(OVP)电路
/// </summary>
public virtual async Task 使(bool , CancellationToken ct = default)
{
string = ? "ON" : "OFF";
await SendAsync($":VOLTage:PROTection:STATE {状态}{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.7.2.4 设置输出电压保护(OVP)阀值 (V)
/// </summary>
public virtual async Task (double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":VOLTage:PROTection {0:F3}{1}", , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.7.2.7 设置电源的输出电压值 (V)
/// </summary>
public virtual async Task (double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":VOLTage {0:F3}{1}", , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.7.2.8 设定电压输出范围的上限电压值 (V)
/// </summary>
public virtual async Task (double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":VOLTage:LIMIT {0:F3}{1}", , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.7.3.1 设置输出功率值 (W)
/// </summary>
public virtual async Task (double , CancellationToken ct = default)
{
string cmd = string.Format(CultureInfo.InvariantCulture, ":POWer {0:F3}{1}", , SCPIDelimiter);
await SendAsync(cmd, ct);
}
/// <summary>
/// 3.7.3.2 禁止或使能当前恒功率(CP)输出
/// </summary>
public virtual async Task 使(bool , CancellationToken ct = default)
{
string = ? "ON" : "OFF";
await SendAsync($":POWer:STATE {状态}{SCPIDelimiter}", ct);
}
#endregion
#region 3.9 SYSTem
/// <summary>
/// 3.9.1 控制蜂鸣器开关
/// </summary>
public virtual async Task (bool , CancellationToken ct = default)
{
string = ? "ON" : "OFF";
await SendAsync($":SYSTem:BEEPer:STATE {状态}{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.9.2 使蜂鸣器强制鸣叫一声
/// </summary>
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($":SYSTem:BEEPer{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.9.4 查询仪器当前出错记录数量 (最大 18 组)
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":SYSTem:ERRor:COUNT?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.9.5 读取仪器的出错信息 (成功返回 0,"No error")
/// </summary>
public virtual async Task<string> (CancellationToken ct = default)
{
return await WriteReadAsync($":SYSTem:ERRor?{SCPIDelimiter}", SCPIDelimiter, ct);
}
/// <summary>
/// 3.9.7 设置电源为面板控制模式 (本地 Local 状态,前面板按键可用)
/// </summary>
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($":SYSTem:LOCal{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.9.8 设置电源为远程控制模式 (Remote 状态)
/// </summary>
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($":SYSTem:REMote{SCPIDelimiter}", ct);
}
/// <summary>
/// 3.9.9 通过通信接口设置电源为远程控制锁定模式
/// </summary>
public virtual async Task (CancellationToken ct = default)
{
await SendAsync($":SYSTem:RWLock{SCPIDelimiter}", ct);
}
#endregion
}
}