using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TeamAAS_VP.Enums; using TeamAAS_VP.Models; using TouchSocket.Core; using TouchSocket.SerialPorts; using TouchSocket.Sockets; namespace TeamAAS_VP.Core.Lights { public class SerialPortProtocol : ICommunicationProtocol { private SerialPortClient _client; private IWaitingClient _waitClient; private readonly SerialPortConfig _config; public bool IsConnected => _client?.Online == true; public Terminator Terminator { get; set; } = Terminator.None; public Encoding Encoding { get; set; } = Encoding.ASCII; public event Action ConnectionChanged; public event Action DataReceived; public event Action DataSent; public SerialPortProtocol(SerialPortConfig config) { _config = config; } public async Task ConnectAsync() { try { _client = new SerialPortClient(); var config = new TouchSocketConfig() .SetSerialPortOption(new SerialPortOption() { PortName = _config.PortName, BaudRate = _config.BaudRate, DataBits = _config.DataBits, Parity = _config.Parity, StopBits = _config.StopBits }) .SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout = TimeSpan.FromMilliseconds(100) }); _client.Setup(config); var result = await _client.TryConnectAsync(); if (result.IsSuccess) { _waitClient = _client.CreateWaitingClient(new WaitingOptions()); ConnectionChanged?.Invoke(this, true); return true; } ConnectionChanged?.Invoke(this, false); return false; } catch { ConnectionChanged?.Invoke(this, false); return false; } } public Task DisconnectAsync() { ConnectionChanged?.Invoke(this, false); _client?.Close(); return Task.CompletedTask; } public async Task SendAndReceiveAsync(byte[] data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); var response = await _waitClient.SendThenReturnAsync(data, timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return response; } public Task SendAsync(byte[] data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); _client.Send(data); return Task.CompletedTask; } public async Task SendAndReceiveAsync(string data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); var response = await SendAndReceiveAsync(Encoding.GetBytes(data), timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return Encoding.GetString(response); } public string SendAndReceive(string data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); var response = _waitClient.SendThenReturn(Encoding.GetBytes(data), timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return Encoding.GetString(response); } public byte[] SendAndReceive(byte[] data, int timeout = 5000) { if (_waitClient == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); var response = _waitClient.SendThenReturn(data, timeout); DataReceived?.Invoke(this, Encoding.GetString(response)); return response; } public void Send(string data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); _client.Send(Encoding.GetBytes(data)); } public async Task SendAsync(string data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, data); await _client.SendAsync(Encoding.GetBytes(data)); } public void Send(byte[] data) { if (_client == null) throw new InvalidOperationException("Not connected"); DataSent?.Invoke(this, Encoding.GetString(data)); _client.Send(data); } public void Dispose() { _client?.Dispose(); _waitClient = null; } } }