261 lines
8.0 KiB
C#
261 lines
8.0 KiB
C#
using Common.Attributes;
|
||
using DeviceCommand.Base;
|
||
using Logger;
|
||
using System;
|
||
using System.Linq;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace DeviceCommand.Device
|
||
{
|
||
[BOBCommand]
|
||
public class E36233A : Tcp
|
||
{
|
||
public E36233A(string ipAddress, int port, int sendTimeout, int receiveTimeout)
|
||
{
|
||
ConfigureDevice(ipAddress, port, sendTimeout, receiveTimeout);
|
||
}
|
||
#region 心跳
|
||
private CancellationTokenSource _cancellationTokenSource;
|
||
private Task? _heartbeatTask;
|
||
private const int HeartbeatInterval = 3000;
|
||
public bool IsActive = false;
|
||
public int ReConnectionAttempts = 0;
|
||
public const int MaxReconnectAttempts = 10;
|
||
public override async Task<bool> ConnectAsync(CancellationToken ct = default)
|
||
{
|
||
await _commLock.WaitAsync(ct);
|
||
try
|
||
{
|
||
if (TcpClient != null && !TcpClient.Connected) TcpClient = new();
|
||
if (TcpClient.Connected)
|
||
{
|
||
return true;
|
||
}
|
||
await TcpClient.ConnectAsync(IPAddress, Port, ct);
|
||
IsActive = true;
|
||
StartHeartbeat();
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return false;
|
||
}
|
||
finally
|
||
{
|
||
_commLock.Release();
|
||
}
|
||
}
|
||
public override void Close()
|
||
{
|
||
if (!TcpClient.Connected)
|
||
{
|
||
throw new InvalidOperationException("TCP 没有连接成功");
|
||
}
|
||
if (TcpClient.Connected)
|
||
{
|
||
TcpClient.Close();
|
||
StopHeartbeat();
|
||
}
|
||
}
|
||
// 启动设备的心跳
|
||
public void StartHeartbeat()
|
||
{
|
||
if (_heartbeatTask != null)
|
||
return;
|
||
if (_cancellationTokenSource == null || _cancellationTokenSource.IsCancellationRequested)
|
||
_cancellationTokenSource = new();
|
||
_heartbeatTask = Task.Run(() => HeartbeatLoop(_cancellationTokenSource.Token));
|
||
}
|
||
|
||
// 停止设备的心跳
|
||
public void StopHeartbeat()
|
||
{
|
||
IsActive = false;
|
||
_cancellationTokenSource.Cancel();
|
||
_heartbeatTask = null;
|
||
}
|
||
|
||
private async Task HeartbeatLoop(CancellationToken ct)
|
||
{
|
||
while (!ct.IsCancellationRequested)
|
||
{
|
||
await Task.Delay(HeartbeatInterval, ct);
|
||
|
||
try
|
||
{
|
||
await 设置为远程模式();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
IsActive = false;
|
||
ReConnectionAttempts++;
|
||
if (MaxReconnectAttempts < ReConnectionAttempts)
|
||
{
|
||
StopHeartbeat();
|
||
return;
|
||
}
|
||
await ReconnectDevice(ct);
|
||
}
|
||
}
|
||
}
|
||
private async Task ReconnectDevice(CancellationToken ct)
|
||
{
|
||
try
|
||
{
|
||
bool resultConnect = await ConnectAsync(ct);
|
||
if (resultConnect)
|
||
{
|
||
ReConnectionAttempts = 0;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
}
|
||
}
|
||
#endregion
|
||
#region 设置命令(不自动切换通道)
|
||
|
||
/// <summary>
|
||
/// 设置当前操作通道
|
||
/// </summary>
|
||
public async Task 设置通道(int 通道, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"INST:NSEL {通道}\n", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询当前通道
|
||
/// </summary>
|
||
public async Task<string> 查询当前通道(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("INST:NSEL?\n", ct);
|
||
return await ReadAsync(ct: ct);
|
||
}
|
||
|
||
public async Task 清除输出保护(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("OUTP:PROT:CLE\n", ct);
|
||
}
|
||
|
||
public async Task 设置电源输出(bool 开关, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"OUTP {(开关 ? "ON" : "OFF")}\n", ct);
|
||
}
|
||
|
||
public async Task 设置为远程模式(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("SYST:REM\n", ct);
|
||
}
|
||
|
||
public async Task 蜂鸣器测试(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("SYST:BEEP\n", ct);
|
||
}
|
||
|
||
public async Task 设置电流(double 电流, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"CURR {电流}\n", ct);
|
||
}
|
||
|
||
public async Task 设置电流保护OCP电流(double 电流, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"CURR:PROT {电流}\n", ct);
|
||
}
|
||
|
||
public async Task 设置OCP开关(bool 开关, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"CURR:PROT:STAT {(开关 ? "ON" : "OFF")}\n", ct);
|
||
}
|
||
|
||
public async Task 设置电压(double 电压, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"VOLT {电压}\n", ct);
|
||
}
|
||
|
||
public async Task 设置电压保护OVP电压(double 电压, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"VOLT:PROT {电压}\n", ct);
|
||
}
|
||
|
||
public async Task 设置OVP开关(bool 开关, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"VOLT:PROT:STAT {(开关 ? "ON" : "OFF")}\n", ct);
|
||
}
|
||
|
||
public async Task 设置功率保护功率(double 功率值, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"POW:PROT {功率值}\n", ct);
|
||
}
|
||
|
||
public async Task 设置功率保护开关(bool 开关, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"POW:PROT:STAT {(开关 ? "ON" : "OFF")}\n", ct);
|
||
}
|
||
|
||
public async Task 设置电流斜率(double 上升斜率, double 下降斜率, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"CURR:SLEW:UP {上升斜率}\n", ct);
|
||
await SendAsync($"CURR:SLEW:DOWN {下降斜率}\n", ct);
|
||
}
|
||
|
||
public async Task 设置电压斜率(double 上升斜率, double 下降斜率, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"VOLT:SLEW:UP {上升斜率}\n", ct);
|
||
await SendAsync($"VOLT:SLEW:DOWN {下降斜率}\n", ct);
|
||
}
|
||
|
||
public async Task 发送自定义命令(string 指令, CancellationToken ct = default)
|
||
{
|
||
await SendAsync($"{指令}\n", ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询设备基本信息
|
||
/// </summary>
|
||
public async Task<string> 查询设备信息(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("*IDN?\n", ct);
|
||
return await ReadAsync(ct: ct);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 查询命令
|
||
|
||
/// <summary>
|
||
/// 查询当前电压测量值
|
||
/// </summary>
|
||
public async Task<double> 查询电压(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("MEAS:VOLT?\n", ct);
|
||
string result = await ReadAsync(ct: ct);
|
||
return double.Parse(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询当前电流测量值
|
||
/// </summary>
|
||
public async Task<double> 查询电流(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("MEAS:CURR?\n", ct);
|
||
string result = await ReadAsync(ct: ct);
|
||
return double.Parse(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询当前功率测量值
|
||
/// </summary>
|
||
public async Task<double> 查询功率(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("MEAS:POW?\n", ct);
|
||
string result = await ReadAsync(ct: ct);
|
||
return double.Parse(result);
|
||
}
|
||
|
||
#endregion
|
||
|
||
}
|
||
}
|