/*
Pseudocode (详细计划):
- 定义类 SerialPortProtocol,实现 ICommunicationProtocol。
- 字段:
- _client: SerialPortClient 实例,用于串口通信。
- _waitClient: 等待客户端,用于发送后等待响应。
- _config: 只读配置对象 SerialPortConfig。
- 属性:
- IsConnected: 检查 _client 是否在线。
- Terminator: 终止符设置(默认 None)。
- Encoding: 编码(默认 ASCII)。
- 事件:
- ConnectionChanged: 连接状态变化时触发。
- DataReceived: 接收数据时触发(字符串形式)。
- DataSent: 发送数据时触发(字符串形式)。
- 构造函数:
- 接收 SerialPortConfig 并保存到 _config。
- ConnectAsync:
- 创建 SerialPortClient。
- 构建 TouchSocketConfig,设置串口选项(端口名、波特率、数据位、校验、停止位)。
- 设置数据处理适配器 PeriodPackageAdapter(CacheTimeout 100ms)。
- 调用 _client.Setup(config) 并 TryConnectAsync。
- 若成功,创建等待客户端并触发 ConnectionChanged(true),返回 true;否则触发 ConnectionChanged(false),返回 false。
- 捕获异常时也触发 ConnectionChanged(false) 并返回 false。
- DisconnectAsync:
- 触发 ConnectionChanged(false),关闭 _client。
- Send/SendAsync(字节/字符串):
- 检查 _client 是否存在,否则抛出 InvalidOperationException。
- 触发 DataSent(字符串形式)。
- 使用 _client.Send 或 _client.SendAsync 发送数据。
- SendAndReceive/SendAndReceiveAsync(字节/字符串):
- 检查 _waitClient,否则抛出 InvalidOperationException。
- 触发 DataSent。
- 使用 _waitClient.SendThenReturn(Sync/Async) 等待响应。
- 触发 DataReceived 并返回响应(字节或字符串)。
- Dispose:
-释放 _client 并置空 _waitClient。
- 为所有公开成员添加 XML 文档注释,描述参数、返回值与异常。
*/
using System;
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
{
///
/// 使用 TouchSocket 的串口通信协议封装。
/// 提供同步/异步的发送与收发方法,并通过事件报告连接与数据状态。
///
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;
///
/// 文本编码,默认使用 ASCII 编码。
///
public Encoding Encoding { get; set; } = Encoding.ASCII;
///
/// 当连接状态改变时触发。参数为触发对象和连接状态(true=已连接)。
///
public event Action