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}"); } } } }