using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MECF.Framework.Common.Device.BarcodeReader
{
public class BarcodeReaderSerialDevice
{
#region Delegate
public delegate void BarcodeReaderDataChanged(string name, string lstContent);
#endregion
#region 常量
private const string CONSTANT_COMMAND = "LON\r";
private const char SPLIT_CHARACTER = '\t';
#endregion
#region 内部变量
///
/// 连接状态
///
private bool _connected;
///
/// 串口
///
private SerialPort _serialPort;
///
/// 模块名称
///
private string _name;
///
/// 接收超时
///
private int _receiveTimeout = 2000;
///
/// 错误信息
///
private string _errmsg = "";
///
/// 重连
///
private bool _reconnected;
///
/// 离线时间
///
private DateTime _offlineDateTime;
#endregion
#region 公共变量
//发布者 定义事件
public event BarcodeReaderDataChanged OnDataChanged;
#endregion
#region 属性
///
/// 连接状态
///
public bool Connected
{
get { return _connected; }
set { _connected = value; }
}
#endregion
///
/// 构造函数
///
///
///
///
///
///
///
public BarcodeReaderSerialDevice(string name, string portName, int baudRate = 9600, StopBits stopBits = StopBits.One, int dataBits = 8, Parity parity = Parity.None, bool reconnected = false, int receiveTimeout = 2000)
{
_serialPort = new SerialPort();
_serialPort.BaudRate = baudRate;
_serialPort.StopBits = stopBits;
_serialPort.DataBits = dataBits;
_serialPort.Parity = parity;
_serialPort.PortName = portName;
_serialPort.ErrorReceived += SerialPort_ErrorReceived;
_serialPort.WriteTimeout = receiveTimeout;
_serialPort.ReadTimeout = receiveTimeout;
_receiveTimeout = receiveTimeout;
_name = name;
_reconnected = reconnected;
}
///
/// 启动
///
public void Start()
{
Open();
}
///
/// 打开串口
///
private void Open()
{
if (!_connected)
{
try
{
if (!_serialPort.IsOpen)
{
_serialPort.Open();
}
_connected = true;
LOG.WriteLog(eEvent.INFO_BARCODEREADER, _name, $"connect port[{_serialPort.PortName}] success");
}
catch (Exception ex)
{
WriteErrorMsg(ex.Message);
}
}
}
///
/// 关闭
///
public void Close()
{
try
{
_connected = false;
_serialPort.Close();
}
catch (Exception ex)
{
WriteErrorMsg(ex.Message);
}
}
#region 事件
///
/// 串口错误
///
///
///
private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
LOG.WriteLog(eEvent.ERR_BARCODEREADER, _name, e.EventType.ToString());
}
#endregion
///
/// 读取数据
///
public string ReadData()
{
try
{
_serialPort.WriteLine(CONSTANT_COMMAND);
DateTime dt = DateTime.Now;
string str = "";
while (DateTime.Now.Subtract(dt).TotalMilliseconds <= _receiveTimeout)
{
if (_serialPort.BytesToRead > 0)
{
string tmp = _serialPort.ReadExisting();
if (!string.IsNullOrEmpty(tmp))
{
str = tmp;
WriteInfoMsg(0, tmp);
break;
}
}
else
{
Thread.Sleep(100);
}
}
if (!string.IsNullOrEmpty(str))
{
if (OnDataChanged != null)
{
OnDataChanged(_name, str);
}
return str;
}
else
{
LOG.WriteLog(eEvent.WARN_BARCODEREADER, _name, "No barcode Information received");
return "";
}
}
catch (Exception ex)
{
WriteErrorMsg(ex.Message);
LOG.WriteLog(eEvent.WARN_BARCODEREADER, _name, "Read barcode failed, Try to Reconnect");
Open();
return "";
}
}
///
/// 记录错误信息
///
///
private void WriteErrorMsg(string msg, bool disConnected = true)
{
if (disConnected)
{
_connected = false;
_offlineDateTime = DateTime.Now;
}
if (_errmsg != msg)
{
_errmsg = msg;
LOG.WriteLog(eEvent.ERR_BARCODEREADER, _name, msg);
}
}
///
/// 写日志
///
///
private void WriteInfoMsg(int logType, string str)
{
bool enableLog = false;
if (SC.ContainsItem("Log.EnableBarcodeReaderLog"))
{
enableLog = SC.GetValue("Log.EnableBarcodeReaderLog");
}
if (enableLog)
{
string type = logType == 0 ? "receive" : "send";
LOG.WriteBackgroundLog(eEvent.ERR_BARCODEREADER, _name, $"{type} {str}");
}
}
}
}