using ivf_tl_Entity.GlobalEnums;
using System.IO.Ports;
namespace ivf_tl_Entity.ComEntitys
{
///
/// 串口发送接收助手
///
public class Channel
{
///
/// 异常日志
/// 异常、名称、参数
///
public event Action ExceptionLogEvent;
///
/// 错误日志
///
public event Action ErrorLogEvent;
///
/// 指令记录日志
///
public event Action CommandLogEvent;
///
/// 接收指令
///
public event Action DataReceived;
///
///
///
///
///
///
///
///
///
///
///
///
public Channel(int house, string comName, int bufferManagerSize, int BaudRate, int DataBits, StopBits stopBits, Parity parity, int ReadTimeout, int WriteTimeout)
{
_comName = comName;
_house = house;
_bufferManagerSize = bufferManagerSize;
_baudRate = BaudRate;
_dataBits = DataBits;
_stopBits = stopBits;
_parity = parity;
_readTimeout = ReadTimeout;
_writeTimeout = WriteTimeout;
ringBufferManager = new RingBufferManager(_bufferManagerSize);
GetSerialPortValue(_house, _comName, _baudRate, _dataBits, _stopBits, _parity, _readTimeout, _writeTimeout);
}
///
///
///
///
///
public Channel(int house, string comName)
{
_comName = comName;
_house = house;
ringBufferManager = new RingBufferManager(_bufferManagerSize);
GetSerialPortValue(_house, _comName, _baudRate, _dataBits, _stopBits, _parity, _readTimeout, _writeTimeout);
}
public RingBufferManager ringBufferManager;
public SerialPort serialPort;
private CustomProtocol customProtocol;
private int _house = 0;
private string _comName;
private int _bufferManagerSize = 1024;
///
/// 波特率
///
private int _baudRate = 9600;
///
/// 数据位
///
private int _dataBits = 8;
///
/// 停止位
///
private StopBits _stopBits = StopBits.One;
///
/// 奇偶校验位
///
private Parity _parity = Parity.None;
///
/// 串口读取超时
///
private int _readTimeout = 3000;
///
/// 串口写入超时
///
private int _writeTimeout = 3000;
///
/// 获取实例
///
/// houseid
/// 串口名称
/// 缓冲区大小
/// 波特率
/// 数据位
/// 停止位
/// 奇偶校验位
/// 串口读取超时
/// 串口写入超时
///
public bool GetSerialPortValue(int house, string comName, int BaudRate, int DataBits, StopBits stopBits, Parity parity, int ReadTimeout, int WriteTimeout)
{
try
{
serialPort = new SerialPort();
serialPort.PortName = comName;
//波特率
serialPort.BaudRate = BaudRate;
//数据位
serialPort.DataBits = DataBits;
//两个停止位
serialPort.StopBits = stopBits;
//无奇偶校验位
serialPort.Parity = parity;
serialPort.ReadTimeout = ReadTimeout;
serialPort.WriteTimeout = WriteTimeout;
serialPort.DataReceived += SerialPort_DataReceived;
return true;
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]创建SerialPort实例", $"[house:{house}][com:{comName}]", LogEnum.RunException);
return false;
}
}
///
/// 接收数据
///
///
///
///
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string loginfo = $"[{_house}][{customProtocol.comName}][{customProtocol.commandNumber}][{customProtocol.commandType}]";
try
{
DateTime dateTime = DateTime.Now;
byte[] buffer = new byte[serialPort.BytesToRead];
serialPort.Read(buffer, 0, buffer.Length);
CommandLogEvent?.Invoke(_house, DateTime.Now, $"{loginfo}[Rec:{StringHelper.ByteToHexStr(buffer)}]", LogEnum.PortComRecord);
ringBufferManager.WriteBuffer(buffer, 0, buffer.Length);
if (ringBufferManager.DataCount >= customProtocol.lenght)
{
if (ringBufferManager.DataCount > customProtocol.lenght)
{
ErrorLogEvent?.Invoke($"{loginfo}缓冲区字节数大于预期", LogEnum.RunError);
}
byte[] receivedBuffer = new byte[customProtocol.lenght];
ringBufferManager.ReadBuffer(receivedBuffer, 0, customProtocol.lenght);
//ringBufferManager.Clear(customProtocol.lenght);
ringBufferManager.Clear();
customProtocol.receivedBuffer = receivedBuffer;
if (customProtocol.receivedBuffer[customProtocol.lenght - 2] != 0)
{
customProtocol.IsSuccess = false;
ErrorLogEvent?.Invoke($"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}]下位机操作失败回复", LogEnum.RunError);
}
var check = Commander.CheckORC(customProtocol.receivedBuffer);
CommandLogEvent?.Invoke(_house, DateTime.Now, $"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}][校验结果:{check}]", LogEnum.HouseComRecord);
if (!check)
{
ErrorLogEvent?.Invoke($"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}]下位机回复校验失败", LogEnum.RunError);
}
CommandLogEvent?.Invoke(_house, DateTime.Now, $"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}][Receive:{StringHelper.ByteToHexStr(customProtocol.receivedBuffer)}]", LogEnum.PortComRecord);
DataReceived?.Invoke(customProtocol);
}
}
catch (Exception ex)
{
string canshu = $"{loginfo}[Send:{StringHelper.ByteToHexStr(customProtocol.sendBuffer)}]";
ExceptionLogEvent?.Invoke(ex, $"[{_house}][{customProtocol.comName}][{customProtocol.commandNumber}]串口接收数据", canshu, LogEnum.RunException);
}
}
///
/// 发送数据
///
///
public bool Send(CustomProtocol protocol)
{
customProtocol = protocol;
customProtocol.comName = _comName;
string logInfo = $"[{_house}][{protocol.comName}][{protocol.commandNumber}][{protocol.commandType}][Send:{StringHelper.ByteToHexStr(protocol.sendBuffer)}]";
try
{
serialPort.Write(customProtocol.sendBuffer, 0, customProtocol.sendBuffer.Length);
CommandLogEvent?.Invoke(_house, DateTime.Now, logInfo, LogEnum.PortComRecord);
return true;
}
catch (Exception e1)
{
ExceptionLogEvent?.Invoke(e1, $"[{_house}][{_comName}]发送指令", logInfo, LogEnum.RunException);
return false;
}
}
///
/// 打开串口
///
public bool OpenPort()
{
try
{
serialPort.Open();
return true;
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"{_house}模块{serialPort.PortName}串口打开", null, LogEnum.RunException);
return false;
}
}
///
/// 关闭串口
///
public bool ClosePort()
{
try
{
serialPort.Close();
return true;
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"{_house}模块{serialPort.PortName}串口关闭", null, LogEnum.RunException);
return false;
}
}
///
/// 清理串口缓冲区
///
///
public bool DiscardPortBuffer()
{
try
{
serialPort.DiscardInBuffer();
serialPort.DiscardOutBuffer();
return true;
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]清理串口缓冲区", null, LogEnum.RunException);
return false;
}
}
///
/// 释放串口类
///
///
public bool PortDispose()
{
try
{
serialPort.Dispose();
return true;
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]释放串口类", null, LogEnum.RunException);
return false;
}
}
///
/// 重新打开串口
///
///
public bool ReopenPort()
{
ringBufferManager.Clear();
for (int i = 0; i < 3; i++)
{
try
{
bool DiscardBuffer = DiscardPortBuffer();
bool closePort = ClosePort();
bool portdispose = PortDispose();
var a = GetSerialPortValue(_house, _comName, _baudRate, _dataBits, _stopBits, _parity, _readTimeout, _writeTimeout);
if (a)
{
var b = OpenPort();
if (b)
{
return true;
}
}
}
catch (Exception ex)
{
ExceptionLogEvent?.Invoke(ex, $"[{_house}][{_comName}]重新打开串口", null, LogEnum.RunException);
}
}
return false;
}
}
}