using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using System; using System.Collections.Concurrent; 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.ResistivityProbe { public class ThorntonSerialDevice { #region Delegate public delegate void ThorntonDataChanged(string name,List lstContent); #endregion #region 常量 private const string CONSTANT_COMMAND = "D00Z\r"; private const char SPLIT_CHARACTER = '\t'; #endregion #region 内部变量 /// /// 连接状态 /// private bool _connected; /// /// 串口 /// private SerialPort _serialPort; /// /// 模块名称 /// private string _name; /// /// 定时器 /// private PeriodicJob _periodJob; /// /// 接收超时 /// private int _receiveTimeout = 2000; /// /// 错误信息 /// private string _errmsg = ""; /// /// 重连 /// private bool _reconnected; /// /// 离线时间 /// private DateTime _offlineDateTime; /// /// 锁 /// private object _locker = new object(); #endregion #region 公共变量 public event ThorntonDataChanged OnDataChanged; #endregion #region 属性 /// /// 连接状态 /// public bool Connected { get { return _connected; } set { _connected = value; } } #endregion /// /// 构造函数 /// /// /// /// /// /// /// public ThorntonSerialDevice(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; _periodJob = new PeriodicJob(500, OnTimer, $"{_name}_reader", true, true); } /// /// 启动 /// public void Start() { //Open(); } /// /// 打开串口 /// private void Open() { lock (_locker) { if (!_connected) { try { if (!_serialPort.IsOpen) { _serialPort.Open(); } _connected = true; LOG.WriteLog(eEvent.INFO_RESISTIVITY, _name, $"connect port[{_serialPort.PortName}] success"); } catch (Exception ex) { WriteErrorMsg(ex.Message); } } } } /// /// 关闭 /// public void Close() { try { _connected = false; _serialPort.Close(); _periodJob.Stop(); } catch (Exception ex) { WriteErrorMsg(ex.Message); } } #region 事件 /// /// 串口错误 /// /// /// private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) { LOG.WriteLog(eEvent.ERR_RESISTIVITY, _name, e.EventType.ToString()); } #endregion /// /// 定时器 /// /// private bool OnTimer() { if (!_connected) { if (_reconnected) { Open(); } else { _periodJob.Stop(); } } else { ReadData(); } return true; } /// /// 读取数据 /// public void 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.ReadLine(); if(!string.IsNullOrEmpty(tmp)) { WriteInfoMsg(0,tmp); } if (tmp != CONSTANT_COMMAND) { str = tmp; break; } } else { Thread.Sleep(100); } } if (!string.IsNullOrEmpty(str)) { string[] strAry = str.Split(SPLIT_CHARACTER); if(strAry.Length>=4) { List lst = new List(); int length=strAry.Length%2==0?strAry.Length:strAry.Length-1; for(int i=2;i /// 记录错误信息 /// /// private void WriteErrorMsg(string msg, bool disConnected = true) { if (disConnected) { _connected = false; _offlineDateTime = DateTime.Now; } if (_errmsg != msg) { _errmsg = msg; LOG.WriteLog(eEvent.ERR_RESISTIVITY, _name, msg); } } /// /// 写日志 /// /// private void WriteInfoMsg(int logType, string str) { bool enableLog = false; if (SC.ContainsItem("Log.EnableResistivityLog")) { enableLog = SC.GetValue("Log.EnableResistivityLog"); } if (enableLog) { string type = logType == 0 ? "receive" : "send"; LOG.WriteBackgroundLog(eEvent.INFO_RESISTIVITY, _name, $"{type} {str}"); } } } }