using Common.Attributes; using DeviceCommand.Base; using Logger; using System.Threading; using System.Threading.Tasks; namespace DeviceCommand.Device { [BOBCommand] public class EAEL9080 : Tcp { public EAEL9080(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 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 设置远程控制(true); } 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 // 查询设备信息 public virtual async Task 查询设备信息(CancellationToken ct = default) { return await WriteReadAsync($"*IDN?\r\n", "\n", ct: ct); } // 重置设备 public virtual async Task 重置设备(CancellationToken ct = default) { await SendAsync($"*RST\r\n", ct); } public virtual async Task 清除保护状态(CancellationToken ct = default) { await SendAsync($"OUTPut:PROTection:CLEar\r\n", ct); } // 打开输出 public virtual async Task 打开输出(CancellationToken ct = default) { await SendAsync($"OUTPut ON\r\n", ct); } // 关闭输出 public virtual async Task 关闭输出(CancellationToken ct = default) { await SendAsync($"OUTPut OFF\r\n", ct); } // 设置远程控制 public virtual async Task 设置远程控制(bool 激活, CancellationToken ct = default) { await SendAsync($"SYSTem:LOCK {(激活 ? "ON" : "OFF")}\r\n", ct); } // 查询远程控制状态 public virtual async Task 查询远程控制状态(CancellationToken ct = default) { return await WriteReadAsync($"SYSTem:LOCK:OWNer?\r\n", "\n", ct: ct); } // 设置电压 public virtual async Task 设置电压(double 电压, CancellationToken ct = default) { await SendAsync($"SOURce:VOLTage {电压}V\r\n", ct); } // 设置电流 public virtual async Task 设置电流(double 电流, CancellationToken ct = default) { await SendAsync($"SOURce:CURRent {电流}A\r\n", ct); } // 设置功率 public virtual async Task 设置功率(double 功率, CancellationToken ct = default) { await SendAsync($"SOURce:POWer {功率}W\r\n", ct); } // 设置电阻 public virtual async Task 设置电阻(double 电阻, CancellationToken ct = default) { await SendAsync($"SOURce:RESistance {电阻}Ω\r\n", ct); } // 设置过压保护 public virtual async Task 设置过压保护(double 电压, CancellationToken ct = default) { await SendAsync($"SOURce:VOLTage:PROTection {电压}V\r\n", ct); } // 设置过流保护 public virtual async Task 设置过流保护(double 电流, CancellationToken ct = default) { await SendAsync($"SOURce:CURRent:PROTection {电流}A\r\n", ct); } // 设置过功率保护 public virtual async Task 设置过功率保护(double 功率, CancellationToken ct = default) { await SendAsync($"SOURce:POWer:PROTection {功率}W\r\n", ct); } // 查询电压 public virtual async Task 查询电压(CancellationToken ct = default) { var str = await WriteReadAsync($"MEASure:VOLTage?\r\n", "\n", ct: ct); return Convert.ToDouble(str); } // 查询电流 public virtual async Task 查询电流(CancellationToken ct = default) { var str = await WriteReadAsync($"MEASure:CURRent?\r\n", "\n", ct: ct); return Convert.ToDouble(str); } // 查询功率 public virtual async Task 查询功率(CancellationToken ct = default) { var str = await WriteReadAsync($"MEASure:POWer?\r\n", "\n", ct: ct); return Convert.ToDouble(str); } // 批量查询电压、电流、功率 public virtual async Task<(double 电压, double 电流, double 功率)> 查询批量数据(CancellationToken ct = default) { var str = await WriteReadAsync($"MEASure:ARRay?\r\n", "\n", ct: ct); var values = str.Split(','); return ( Convert.ToDouble(values[0]), Convert.ToDouble(values[1]), Convert.ToDouble(values[2]) ); } // 查询标称电压 public virtual async Task 查询标称电压(CancellationToken ct = default) { var str = await WriteReadAsync($"SYSTem:NOMinal:VOLTage?\r\n", "\n", ct: ct); return Convert.ToDouble(str); } // 查询标称电流 public virtual async Task 查询标称电流(CancellationToken ct = default) { var str = await WriteReadAsync($"SYSTem:NOMinal:CURRent?\r\n", "\n", ct: ct); return Convert.ToDouble(str); } #region 多通道支持 // 激活指定通道 public virtual async Task 激活通道(int 通道号, CancellationToken ct = default) { await SendAsync($"INST:SEL CH{通道号}\r\n", ct); } // 查询当前激活的通道 public virtual async Task 查询当前激活通道(CancellationToken ct = default) { return await WriteReadAsync($"INST:SEL?\r\n", "\n", ct); } // 激活所有通道 public virtual async Task 激活所有通道(CancellationToken ct = default) { await SendAsync("INST:SEL ALL\r\n", ct); } // 设置指定通道电压 public virtual async Task 设置通道电压(int 通道号, double 电压, CancellationToken ct = default) { await SendAsync($"CH{通道号}:VOLT {电压}V\r\n", ct); } // 设置指定通道电流 public virtual async Task 设置通道电流(int 通道号, double 电流, CancellationToken ct = default) { await SendAsync($"CH{通道号}:CURR {电流}A\r\n", ct); } // 设置指定通道功率 public virtual async Task 设置通道功率(int 通道号, double 功率, CancellationToken ct = default) { await SendAsync($"CH{通道号}:POW {功率}W\r\n", ct); } // 设置指定通道 Sink 模式电流 public virtual async Task 设置通道Sink电流(int 通道号, double 电流, CancellationToken ct = default) { await SendAsync($"CH{通道号}:SINK:CURR {电流}A\r\n", ct); } // 启动指定通道输出 public virtual async Task 启动通道输出(int 通道号, CancellationToken ct = default) { await SendAsync($"CH{通道号}:OUTP ON\r\n", ct); } // 关闭指定通道输出 public virtual async Task 关闭通道输出(int 通道号, CancellationToken ct = default) { await SendAsync($"CH{通道号}:OUTP OFF\r\n", ct); } // 同时启停所有通道输出 public virtual async Task 同步启动所有通道输出(CancellationToken ct = default) { await SendAsync("INST:ALL:OUTP ON\r\n", ct); } public virtual async Task 同步关闭所有通道输出(CancellationToken ct = default) { await SendAsync("INST:ALL:OUTP OFF\r\n", ct); } // 查询指定通道的电压、电流和功率(批量) public virtual async Task<(double 电压, double 电流, double 功率)> 查询通道批量数据(int 通道号, CancellationToken ct = default) { var str = await WriteReadAsync($"CH{通道号}:MEAS:ARR?\r\n", "\n", ct); var values = str.Split(','); return ( Convert.ToDouble(values[0]), // 电压 Convert.ToDouble(values[1]), // 电流 Convert.ToDouble(values[2]) // 功率 ); } #endregion } }