267 lines
8.8 KiB
C#
267 lines
8.8 KiB
C#
using Common.Attributes;
|
||
using DeviceCommand.Base;
|
||
using Logger;
|
||
using System;
|
||
using System.IO.Ports;
|
||
using System.Net;
|
||
using System.Net.Sockets;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace DeviceCommand.Device
|
||
{
|
||
[BOBCommand]
|
||
public class IT6724C : Serial_Port
|
||
{
|
||
public IT6724C(string COMPort, int BaudRate, int DataBits, StopBits stopBits, Parity parity, int ReadTimeout, int ReceiveTimeout)
|
||
{
|
||
ConfigureDevice(COMPort, BaudRate, DataBits, stopBits, parity, ReadTimeout, 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)
|
||
{
|
||
try
|
||
{
|
||
if (SerialPort.IsOpen)
|
||
SerialPort.Close();
|
||
|
||
SerialPort.PortName = PortName;
|
||
SerialPort.BaudRate = BaudRate;
|
||
SerialPort.DataBits = DataBits;
|
||
SerialPort.StopBits = StopBits;
|
||
SerialPort.Parity = Parity;
|
||
SerialPort.ReadTimeout = ReadTimeout;
|
||
SerialPort.WriteTimeout = WriteTimeout;
|
||
if (SerialPort.IsOpen) return true;
|
||
SerialPort.Open();
|
||
IsActive = true;
|
||
StartHeartbeat();
|
||
|
||
return true;
|
||
}
|
||
finally
|
||
{
|
||
|
||
}
|
||
}
|
||
public override void Close()
|
||
{
|
||
StopHeartbeat();
|
||
if (SerialPort.IsOpen) SerialPort.Close();
|
||
}
|
||
|
||
public void StartHeartbeat()
|
||
{
|
||
if (_heartbeatTask != null && !_heartbeatTask.IsCompleted)
|
||
return;
|
||
|
||
_cancellationTokenSource?.Cancel();
|
||
_cancellationTokenSource?.Dispose();
|
||
|
||
_cancellationTokenSource = new CancellationTokenSource();
|
||
|
||
_heartbeatTask = Task.Run(() => HeartbeatLoop(_cancellationTokenSource.Token));
|
||
}
|
||
|
||
public void StopHeartbeat()
|
||
{
|
||
try
|
||
{
|
||
IsActive = false;
|
||
_cancellationTokenSource.Cancel();
|
||
_heartbeatTask = null;
|
||
}
|
||
catch { }
|
||
|
||
_heartbeatTask = null;
|
||
}
|
||
|
||
private async Task HeartbeatLoop(CancellationToken ct)
|
||
{
|
||
while (!ct.IsCancellationRequested)
|
||
{
|
||
await Task.Delay(HeartbeatInterval, ct);
|
||
|
||
try
|
||
{
|
||
await 设置为远程模式(ct);
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
IsActive = false;
|
||
ReConnectionAttempts++;
|
||
|
||
if (ReConnectionAttempts > MaxReconnectAttempts)
|
||
{
|
||
LoggerHelper.InfoWithNotify("IT6724C重连多次失败");
|
||
StopHeartbeat();
|
||
return;
|
||
}
|
||
|
||
await ReconnectDevice(ct);
|
||
}
|
||
}
|
||
}
|
||
|
||
private async Task ReconnectDevice(CancellationToken ct)
|
||
{
|
||
try
|
||
{
|
||
bool ok = await ConnectAsync(ct);
|
||
if (ok)
|
||
ReConnectionAttempts = 0;
|
||
}
|
||
catch { }
|
||
}
|
||
#endregion
|
||
|
||
|
||
|
||
#region 设置命令
|
||
|
||
/// <summary>
|
||
/// 设置电源输出状态,true 为开,false 为关
|
||
/// </summary>
|
||
public virtual async Task 设置电源输出(bool 开关, CancellationToken ct = default)
|
||
=>await SendAsync($"OUTPut {(开关 ? 1 : 0)}\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 切换到远程控制模式
|
||
/// </summary>
|
||
public virtual async Task 设置为远程模式(CancellationToken ct = default)
|
||
=>await SendAsync("SYSTem:REMote\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 蜂鸣器测试
|
||
/// </summary>
|
||
public virtual async Task 蜂鸣器测试(CancellationToken ct = default)
|
||
=>await SendAsync("SYSTem:BEEPer\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 设置输出电流(单位:A)
|
||
/// </summary>
|
||
public virtual async Task 设置电流(double 电流, CancellationToken ct = default)
|
||
=>await SendAsync($"CURRent {电流}\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 设置过流保护电流(OCP,单位:A)
|
||
/// </summary>
|
||
public virtual async Task 设置电流保护OCP电流(double 电流, CancellationToken ct = default)
|
||
=>await SendAsync($"CURRent:PROTection {电流}\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 设置过流保护状态,true 为启用,false 为禁用
|
||
/// </summary>
|
||
public virtual async Task 设置OCP开关(bool 开关, CancellationToken ct = default)
|
||
=>await SendAsync($"CURRent:PROTection:STATe {(开关 ? 1 : 0)}\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 清除过流保护触发状态
|
||
/// </summary>
|
||
public virtual async Task 清除电流保护(CancellationToken ct = default)
|
||
=>await SendAsync("CURRent:PROTection:CLEar\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 设置输出电压(单位:V)
|
||
/// </summary>
|
||
public virtual async Task 设置电压(double 电压, CancellationToken ct = default)
|
||
=>await SendAsync($"VOLTage {电压}\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 设置过压保护电压(OVP,单位:V)
|
||
/// </summary>
|
||
public virtual async Task 设置电压保护OVP电压(double 电压, CancellationToken ct = default)
|
||
=>await SendAsync($"VOLT:PROTection {电压}\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 设置过压保护状态,true 为启用,false 为禁用
|
||
/// </summary>
|
||
public virtual async Task 设置OVP开关(bool 开关, CancellationToken ct = default)
|
||
=>await SendAsync($"VOLT:PROTection:STATe {(开关 ? 1 : 0)}\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 清除过压保护触发状态
|
||
/// </summary>
|
||
public virtual async Task 清除电压保护(CancellationToken ct = default)
|
||
=> await SendAsync("VOLT:PROTection:CLEar\r\n", ct);
|
||
|
||
/// <summary>
|
||
/// 发送自定义命令
|
||
/// </summary>
|
||
public virtual async Task 发送自定义命令(string 指令, CancellationToken ct = default)
|
||
=>await SendAsync($"{指令}\r\n", ct);
|
||
|
||
#endregion
|
||
|
||
#region 查询命令
|
||
|
||
/// <summary>
|
||
/// 查询仪器标识,返回制造商、型号、序列号、固件版本
|
||
/// </summary>
|
||
public virtual async Task<string> 查询设备信息(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("*IDN?\r\n", ct);
|
||
return await ReadAsync(ct: ct);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询过流保护是否触发,返回 true 表示触发
|
||
/// </summary>
|
||
public virtual async Task<bool> 查询电流保护状态(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("CURRent:PROTection:TRIPed?\r\n", ct);
|
||
var result = await ReadAsync(ct: ct);
|
||
return result == "1";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询过压保护是否触发,返回 true 表示触发
|
||
/// </summary>
|
||
public virtual async Task<bool> 查询电压保护状态(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("VOLT:PROTection:TRIPed?\r\n", ct);
|
||
var result = await ReadAsync(ct: ct);
|
||
return result == "1";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询实际输出电流(单位:A)
|
||
/// </summary>
|
||
public virtual async Task<double> 查询实时电流(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("MEASure:CURRent?\r\n", ct);
|
||
var result = await ReadAsync(ct: ct);
|
||
return Convert.ToDouble(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询实际输出电压(单位:V)
|
||
/// </summary>
|
||
public virtual async Task<double> 查询实时电压(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("MEASure:VOLTage?\r\n", ct);
|
||
var result = await ReadAsync(ct: ct);
|
||
return Convert.ToDouble(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询实际输出功率(单位:W)
|
||
/// </summary>
|
||
public virtual async Task<double> 查询实时功率(CancellationToken ct = default)
|
||
{
|
||
await SendAsync("MEASure:POWer?\r\n", ct);
|
||
var result = await ReadAsync(ct: ct);
|
||
return Convert.ToDouble(result);
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|