using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Device.TemperatureController; 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 enum TemperatureVariableType { Decade=0, Kilo=1, Buffer=2, SignedDecade=3, Alarm=4 } public class TemperatureSerialDevice { #region Delegate public delegate void UpdateVariableValueChanged(string name,byte address, string variableName, object variableValue); #endregion #region 常量 private const byte SOH = 0x01; private const byte STX = 0x02; private const byte ETX = 0x03; private const byte ENQ = 0x05; private const byte ACK = 0x06; private const byte CR = 0x0D; private const byte ADD_FLAG = 0x30; private const byte MINUS_FLAG = 0x2D; #endregion #region 内部变量 /// /// 串口 /// private SerialPort _serialPort; /// /// 连接状态 /// private bool _connected; /// /// 模块名称 /// private string _name; /// /// 重连 /// private bool _reconnect; /// /// 队列锁 /// private object _locker = new object(); /// /// 发送队列 /// private List _sendQueueDatas = new List(); /// /// 定时器 /// private PeriodicJob _periodJob; /// /// 离线时间 /// private DateTime _offlineDateTime; /// /// 接收超时 /// private int _receiveTimeOut; /// /// 错误 /// private string _errorMsg = ""; /// /// 首次连接成功 /// private bool _isFirstConnected = false; #endregion #region 事件 /// /// 变量变更事件 /// public event UpdateVariableValueChanged OnUpdateVariableValueChanged; #endregion #region 属性 /// /// 连接状态 /// public bool Connected { get { return _connected; } set { _connected = value; } } #endregion /// /// 初始化 /// /// /// /// /// /// public TemperatureSerialDevice(string name, string portName, int baudRate = 9600, StopBits stopBits = StopBits.One, int dataBits = 8, Parity parity = Parity.None,bool reconnect=false,int receiveTimeout=2000) { _serialPort = new SerialPort(); _serialPort.BaudRate = baudRate; _serialPort.StopBits = stopBits; _serialPort.DataBits = dataBits; _serialPort.Parity = parity; _serialPort.PortName = portName; _serialPort.ReadTimeout = receiveTimeout; _serialPort.ErrorReceived += SerialPort_ErrorReceived; _name = name; _reconnect = reconnect; _receiveTimeOut = receiveTimeout; _periodJob = new PeriodicJob(50, OnTimer, $"{_name}_sender", false, true); } /// /// 初始化 /// public void Initialize() { _periodJob.Start(); } /// /// 启动 /// public void Start() { Open(); } /// /// 打开 /// private void Open() { if (!_connected) { try { if (!_serialPort.IsOpen) { _serialPort.Open(); } _connected = true; if (!_isFirstConnected) { _isFirstConnected = true; } LOG.WriteLog(eEvent.INFO_TEMPERATURE, _name, $"connect {_serialPort.PortName} Success"); } catch (Exception ex) { WriteErrorMsg(ex.Message); } } } /// /// 关闭 /// public void Close() { try { _connected = false; _serialPort.Close(); } catch (Exception ex) { WriteErrorMsg(ex.Message); } } /// /// 出现错误 /// /// /// private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) { LOG.WriteLog(eEvent.ERR_TEMPERATURE, _name, e.EventType.ToString()); } /// /// 定时器 /// /// private bool OnTimer() { if (!_connected) { ///离线超过5秒清理发送队列 if(DateTime.Now.Subtract(_offlineDateTime).TotalSeconds>=5&&_sendQueueDatas.Count>0) { ClearSendQueue(); } if (_reconnect) { if (_isFirstConnected) { Open(); } } else { _periodJob.Stop(); } return true; } else { SendData(); } return true; } /// /// 发送数据 /// private void SendData() { int queueCount = _sendQueueDatas.Count; if (_sendQueueDatas.Count != 0) { lock (_locker) { TemperatureSendData data = _sendQueueDatas[0]; _sendQueueDatas.RemoveAt(0); if (data != null) { if (data.Type == 0)//设置 { WriteInfoMsg(0, $"execute set {data.Type} queue length {queueCount}"); try { SettingOperation(data.Id, data.Command, data.Data); } catch (Exception ex) { WriteErrorMsg(ex.Message); } } else//读取变量 { WriteInfoMsg(0, $"execute read {data.Type} queue length {queueCount}"); ReadVariableData(data); } } } } } /// /// 读取变量 /// /// private void ReadVariableData(TemperatureSendData data) { switch(data.VariableType) { case TemperatureVariableType.Decade: if (ReadDecadeParam(data.Id, data.Command, out double decadeValue)) { _errorMsg = ""; UpdateVariableValue(data,decadeValue); } break; case TemperatureVariableType.Kilo: if (ReadKiloParam(data.Id, data.Command, out int kiloValue)) { _errorMsg = ""; UpdateVariableValue(data,kiloValue); } break; case TemperatureVariableType.SignedDecade: if(ReadSignedDecadeParam(data.Id,data.Command,out double signedDecadeValue)) { _errorMsg = ""; UpdateVariableValue(data,signedDecadeValue); } break; case TemperatureVariableType.Buffer: if(ReadBufferParam(data.Id,data.Command,out byte[] buffer,11)) { _errorMsg = ""; UpdateVariableValue(data,BitConverter.ToString(buffer)); } break; default: break; } } /// /// 变量数据 /// /// private void UpdateVariableValue(TemperatureSendData data,object variableValue) { data.VariableValue = variableValue; if(OnUpdateVariableValueChanged!=null) { OnUpdateVariableValueChanged(_name,data.Id, data.VariableName, data.VariableValue); } } /// /// 清空发送队列 /// private void ClearSendQueue() { try { while (_sendQueueDatas.Count != 0) { _sendQueueDatas.Clear(); } } catch(Exception ex) { WriteErrorMsg(ex.Message,false); } } /// /// 插入数据 /// /// private void InsertDataToQueue(TemperatureSendData data) { lock (_locker) { _sendQueueDatas.Insert(0, data); } } /// 插入数据 /// /// private void AddDataToQueue(TemperatureSendData data) { lock (_locker) { _sendQueueDatas.Add(data); } } #region Temperature /// /// 插入数据 /// /// private void InsertDatasToQueue(TemperatureSendData data,TemperatureSendData readData) { lock(_locker) { _sendQueueDatas.Insert(0, readData); _sendQueueDatas.Insert(0, data); } } /// /// 设置温度 /// /// /// /// public bool SetTargetTemperature(byte id,double temperature) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Command = 0x31; data.Data=GetDecadeBytes(temperature); data.Type = 0; TemperatureSendData readData = GetReadTargetTemperature(id); InsertDatasToQueue(data,readData); return true; } /// /// 获取读取目标温度指令 /// /// /// private TemperatureSendData GetReadTargetTemperature(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.Command = 0x31; data.VariableName = "TargetTemperature"; data.VariableType = TemperatureVariableType.Decade; return data; } /// /// 读取温度 /// /// /// /// public void ReadTargetTemperature(byte id) { TemperatureSendData data=GetReadTargetTemperature(id); AddDataToQueue(data); } /// /// 读取Heat Exchanger温度 /// /// /// /// public void ReadHeatExchangerInternelSensorTemperature(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.Command = 0x32; data.VariableName = "HeatExchangerTemperature"; data.VariableType = TemperatureVariableType.Decade; AddDataToQueue(data); } /// /// 读取Reservior温度 /// /// /// /// public void ReadReserviorExtendSensorTemperature(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.Command = 0x33; data.VariableName = "ReserviorTemperature"; data.VariableType = TemperatureVariableType.Decade; AddDataToQueue(data); } #endregion #region Alarm /// /// 读取Alarm状态 /// /// /// /// public void ReadAlarmStatus(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "Alarm"; data.Command = 0x34; data.VariableType = TemperatureVariableType.Buffer; AddDataToQueue(data); } #endregion #region Offset /// /// 设置温度 /// /// /// /// public void SetOffsetValue(byte id, double temperature) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x36; data.Data = GetOffsetBytes(temperature); TemperatureSendData readData = GetReadOffsetData(id); InsertDatasToQueue(data,readData); } /// /// 获取读取Offset数据 /// /// /// private TemperatureSendData GetReadOffsetData(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "Offset"; data.Command = 0x36; data.VariableType = TemperatureVariableType.SignedDecade; return data; } /// /// 读取Alarm状态 /// /// /// /// public void ReadOffsetValue(byte id) { TemperatureSendData data=GetReadOffsetData(id); AddDataToQueue(data); } #endregion #region Control Operation Model /// /// 设置Control Operation模式 /// /// /// /// public void SetControlOperationModel(byte id, int controlOperationModel) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x39; data.Data = GetKiloBytes(controlOperationModel); TemperatureSendData readData=GetReadControlOperationData(id); InsertDatasToQueue(data, readData); } /// /// 获取读取操作模式的数据 /// /// /// private TemperatureSendData GetReadControlOperationData(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "ControlOperationModel"; data.Command = 0x39; data.VariableType = TemperatureVariableType.Kilo; return data; } /// /// 读取Control Operation Model /// /// /// /// public void ReadControlOperationModel(byte id) { TemperatureSendData data = GetReadControlOperationData(id); InsertDataToQueue(data); } #endregion #region PB Range /// /// 设置PB范围 /// /// /// /// public void SetPBRange(byte id, double pbrange) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x41; data.Data = GetDecadeBytes(pbrange); InsertDataToQueue(data); } /// /// 读取PB范围 /// /// /// /// public void ReadPBRange(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "PBRange"; data.Command = 0x41; data.VariableType = TemperatureVariableType.Decade; AddDataToQueue(data); } #endregion #region ARW /// /// 设置ARW范围 /// /// /// /// public void SetARWRange(byte id, double arwRange) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x42; data.Data = GetDecadeBytes(arwRange); InsertDataToQueue(data); } /// /// 读取Heat Exchanger温度 /// /// /// /// public void ReadARWRange(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "ARWRange"; data.Command = 0x42; data.VariableType = TemperatureVariableType.Decade; AddDataToQueue(data); } #endregion #region I constant /// /// 设置I Constant /// /// /// /// public void SetIConstant(byte id, int iConstant) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x43; data.Data = GetKiloBytes(iConstant); InsertDataToQueue(data); } /// /// 读取Heat Exchanger温度 /// /// /// /// public void ReadIConstant(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "IConstant"; data.Command = 0x43; data.VariableType = TemperatureVariableType.Kilo; AddDataToQueue(data); } #endregion #region D constant /// /// 设置D Constant /// /// /// /// public void SetDConstant(byte id, int dConstant) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x44; data.Data = GetDecadeBytes(dConstant); InsertDataToQueue(data); } /// /// 读取D Constant /// /// /// /// public void ReadDConstant(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "DConstant"; data.Command = 0x44; data.VariableType = TemperatureVariableType.Decade; AddDataToQueue(data); } #endregion #region Output Ratio /// /// Output 比例 /// /// /// /// public void SetOutputRatio(byte id, int outputRatio) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x45; data.Data = GetKiloBytes(outputRatio); InsertDataToQueue(data); } /// /// 读取output比例 /// /// /// /// public void ReadOutputRatio(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "OutputRatio"; data.Command = 0x45; data.VariableType = TemperatureVariableType.Kilo; AddDataToQueue(data); } #endregion #region Heating Power upper limit /// /// Heating Power upper limit 比例 /// /// /// /// public void SetHeatingPowerUpperLimit(byte id, int upperLimit) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x46; data.Data = GetKiloBytes(upperLimit); InsertDataToQueue(data); } /// /// 读取output比例 /// /// /// /// public void ReadHeatingPowerUpperLimit(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "HeatingPowerUpperLimit"; data.Command = 0x46; data.VariableType = TemperatureVariableType.Kilo; AddDataToQueue(data); } #endregion #region Cooling Power upper limit /// /// Heating Power upper limit 比例 /// /// /// /// public void SetCoolingPowerUpperLimit(byte id, int upperLimit) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x47; data.Data = GetKiloBytes(upperLimit); InsertDataToQueue(data); } /// /// 读取output比例 /// /// /// /// public void ReadCoolingPowerUpperLimit(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 1; data.VariableName = "CoolingPowerUpperLimit"; data.Command = 0x47; data.VariableType = TemperatureVariableType.Kilo; AddDataToQueue(data); } #endregion #region Saving RAM to EEPROM /// /// 将RAM保存至EEPROM /// /// /// /// public void SaveRAMToEEPROM(byte id) { TemperatureSendData data = new TemperatureSendData(); data.Id = id; data.Type = 0; data.Command = 0x48; data.Data = new byte[] { }; InsertDataToQueue(data); } #endregion /// /// 读取千单位数据 /// /// /// /// /// private bool ReadKiloParam(byte id,byte command,out int param,int responseLength=12) { param = 0; try { byte[] response = AfterSendDataWithResponse(id, command,responseLength); if (response==null) { return false; } //解析 if (response[0] == SOH && response[11] == CR && response[3] == command) { if (response[1] == GetSendByteData(id)) { byte[] byt = new byte[4]; Array.Copy(response, 4, byt, 0, byt.Length); param = GetOriginalData(byt[0]) * 1000 + GetOriginalData(byt[1]) * 100 + GetOriginalData(byt[2]) * 10 + GetOriginalData(byt[3]); return true; } else { string msg = $"receive id {GetOriginalData(response[1])} is not matched with command id {id}"; WriteErrorMsg(msg, false); return false; } } else { string msg = "response data invalid"; WriteErrorMsg(msg, false); return false; } } catch (Exception ex) { WriteErrorMsg(ex.Message); return false; } } /// /// 根据十单位数据 /// /// /// /// /// private bool ReadDecadeParam(byte id, byte command, out double decadeValue, int responseLength = 12) { decadeValue = 0; byte[] response = AfterSendDataWithResponse(id, command,responseLength); if(response==null) { return false; } //解析 if (response[0] == SOH && response[11] == CR && response[3] == command) { if (response[1] == GetSendByteData(id)) { byte[] tmpData = new byte[4]; Array.Copy(response, 4, tmpData, 0, tmpData.Length); decadeValue = GetOriginalData(tmpData[0]) * 10 + GetOriginalData(tmpData[1]) + GetOriginalData(tmpData[2]) * 0.1 + GetOriginalData(tmpData[3]) * 0.01; return true; } else { string msg = $"receive id {GetOriginalData(response[1])} is not matched with command id {id}"; WriteErrorMsg(msg, false); return false; } } else { string msg = "response data invalid"; WriteErrorMsg(msg,false); return false; } } /// /// 根据有符号十单位数据 /// /// /// /// /// private bool ReadSignedDecadeParam(byte id, byte command, out double signedDecadeValue, int responseLength = 12) { signedDecadeValue = 0; byte[] response = AfterSendDataWithResponse(id, command, responseLength); if (response == null) { return false; } string err = "response data invalid"; //解析 if (response[0] == SOH && response[11] == CR && response[3] == command) { if (response[1] == GetSendByteData(id)) { byte[] byt = new byte[4]; Array.Copy(response, 4, byt, 0, byt.Length); double tmp = GetOriginalData(byt[1]) + GetOriginalData(byt[2]) * 0.1 + GetOriginalData(byt[3]) * 0.01; if (byt[0] == MINUS_FLAG) { signedDecadeValue = -tmp; return true; } else if (byt[0] == ADD_FLAG) { signedDecadeValue = tmp; return true; } else { WriteErrorMsg(err, false); return false; } } else { string msg = $"receive id {GetOriginalData(response[1])} is not matched with command id {id}"; WriteErrorMsg(msg, false); return false; } } else { WriteErrorMsg(err, false); return false; } } /// /// 根据数组数据 /// /// /// /// /// private bool ReadBufferParam(byte id, byte command, out byte[] buffer, int responseLength = 12) { buffer = null; byte[] response = AfterSendDataWithResponse(id, command, responseLength); if (response == null) { return false; } //解析 if (response[0] == SOH && response[responseLength-1] == CR && response[3] == command) { if (response[1] == GetSendByteData(id)) { buffer = new byte[responseLength - 8]; Array.Copy(response, 4, buffer, 0, buffer.Length); return true; } else { string msg = $"receive id {GetOriginalData(response[1])} is not matched with command id {id}"; WriteErrorMsg(msg, false); return false; } } else { string err = "response data invalid"; WriteErrorMsg(err,false); return false; } } /// /// 设置操作 /// /// /// /// /// private bool SettingOperation(byte id, byte command, byte[] byt) { ClearPreCache(); byte ut = GetSendByteData(id); byte[] data = new byte[byt.Length + 8]; data[0] = SOH; data[1] = ut; data[2] = STX; data[3] = command; if (byt != null && byt.Length != 0) { Array.Copy(byt, 0, data, 4, byt.Length); } data[data.Length - 4] = ETX; data[data.Length - 3] = 0; data[data.Length - 2] = 0; data[data.Length - 1] = CR; //检验 byte[] checksumData = new byte[data.Length - 5]; //从数据第2位至ETX前所有数组 Array.Copy(data, 1, checksumData, 0, checksumData.Length); byte[] checkSumByte = CalculateCheckSum(checksumData); Array.Copy(checkSumByte, 0, data, data.Length - 3, checkSumByte.Length); _serialPort.Write(data, 0, data.Length); WriteInfoMsg(1, data); //接收 byte[] response = ReadData(id,command,3); if (response != null) { if (response[0] == ACK && response[2] == CR && response[1] == ut) { return true; } else { string err = "response data invalid"; WriteErrorMsg(err, false); return false; } } else { return false; } } /// /// 发送数据后获取数组 /// /// /// /// private byte[] AfterSendDataWithResponse(byte id,byte command,int responseLength=12) { try { ClearPreCache(); byte ut = GetSendByteData(id); byte[] data = new byte[7] { SOH, ut, ENQ, command, 0, 0, CR }; //检验 byte[] checksumData = new byte[data.Length - 4]; //从数据第2位至ETX前所有数组 Array.Copy(data, 1, checksumData, 0, checksumData.Length); byte[] checkSumByte = CalculateCheckSum(checksumData); Array.Copy(checkSumByte, 0, data, data.Length - 3, checkSumByte.Length); _serialPort.Write(data, 0, data.Length); WriteInfoMsg(1, data); //接收 byte[] response = ReadData(id,command,responseLength); if (response == null) { return null; } //ack byte[] ack = new byte[] { ACK, ut, CR }; _serialPort.Write(ack, 0, ack.Length); WriteInfoMsg(1, ack); return response; } catch(Exception ex) { _connected = false; WriteErrorMsg(ex.Message); return null; } } /// /// 计算获取检验和数组 /// /// /// private byte[] CalculateCheckSum(byte[] checkSumData) { short checksum = 0; for(int i=0;i /// 获取温度数组(10|1|0.1|0.01) /// /// /// private byte[] GetDecadeBytes(double temperature) { byte decade = GetSendByteData((byte)Math.Floor(temperature / 10)); byte unit = GetSendByteData((byte)Math.Floor(temperature % 10)); byte digital = GetSendByteData((byte)Math.Floor(temperature * 10 % 10)); return new byte[4] { decade, unit, digital, ADD_FLAG }; } /// /// 获取Offset数组(正/负|1|0.1|0.01) /// /// /// private byte[] GetOffsetBytes(double temperature) { byte decade = temperature>0?ADD_FLAG:MINUS_FLAG; byte unit = GetSendByteData((byte)Math.Floor(temperature % 10)); byte digital = GetSendByteData((byte)Math.Floor(temperature * 10 % 10)); byte digital2 = GetSendByteData((byte)Math.Floor(temperature * 100 % 10)); return new byte[4] { decade, unit, digital, digital2 }; } /// /// 获取Control Operation Model(1000|100|10|1) /// /// /// private byte[] GetKiloBytes(int controlOperationModel) { byte kilo= GetSendByteData((byte)(controlOperationModel / 1000)); byte hundred = GetSendByteData((byte)(controlOperationModel %1000/ 100)); byte decade = GetSendByteData((byte)(controlOperationModel %100/ 10)); byte unit = GetSendByteData((byte)(controlOperationModel % 10)); return new byte[4] { kilo, hundred, decade, unit }; } /// /// 获取发送位数据 /// /// /// private byte GetSendByteData(byte originalData) { return (byte)(ADD_FLAG + originalData); } /// /// 解析源数据 /// /// /// private byte GetOriginalData(byte receivedData) { return (byte)(receivedData - ADD_FLAG); } /// /// 读取数据 /// /// /// private byte[] ReadData(byte id,byte command ,int length) { byte[] response=new byte[length]; DateTime dt = DateTime.Now; int count = 0; while (true) { int bytLength = _serialPort.BytesToRead; if (bytLength > 0) { byte[] bytes = new byte[bytLength]; _serialPort.Read(bytes,0,bytes.Length); WriteInfoMsg(0, bytes); if (bytLength + count >= length) { Array.Copy(bytes, 0, response, count, length-count); break; } else { Array.Copy(bytes, 0, response, count, bytLength); } count += bytLength; } if (DateTime.Now.Subtract(dt).TotalMilliseconds >= _receiveTimeOut) { string err =$"receive id {id} command {command.ToString("X2")} timeout {length}"; TemperatureConfigManager.Instance.UpdataTCPowerConnectDic(_name + '-' + id.ToString(),false);//读取数据超时认为TC断联 WriteErrorMsg(err,false); return null; } else { TemperatureConfigManager.Instance.UpdataTCPowerConnectDic(_name + '-' + id.ToString(),true); } Thread.Sleep(2); } WriteInfoMsg(0, response); return response; } /// /// 记录错误信息 /// /// private void WriteErrorMsg(string msg,bool disConnected=true) { if (disConnected) { _connected = false; _offlineDateTime = DateTime.Now; } bool enableLog = false; if (SC.ContainsItem("Log.EnableTemperatureLog")) { enableLog = SC.GetValue("Log.EnableTemperatureLog"); } if (enableLog) { if (_errorMsg != msg) { _errorMsg = msg; LOG.WriteBackgroundLog(eEvent.ERR_TEMPERATURE, _name, msg); } } } /// /// 写日志 /// /// private void WriteInfoMsg(int logType, byte[] bytes) { bool enableLog = false; if (SC.ContainsItem("Log.EnableTemperatureLog")) { enableLog = SC.GetValue("Log.EnableTemperatureLog"); } if (enableLog) { string str = string.Join(" ", Array.ConvertAll(bytes, x => x.ToString("X2"))); string type = logType == 0 ? "receive" : "send"; LOG.WriteBackgroundLog(eEvent.INFO_TEMPERATURE, _name, $"{type} {str}"); } } /// /// 写日志 /// /// private void WriteInfoMsg(int logType, string str) { bool enableLog = false; if (SC.ContainsItem("Log.EnableTemperatureLog")) { enableLog = SC.GetValue("Log.EnableTemperatureLog"); } if (enableLog) { string type = logType == 0 ? "receive" : "send"; LOG.WriteBackgroundLog(eEvent.INFO_TEMPERATURE, _name, $"{type} {str}"); } } /// /// 清除前面的缓存 /// private void ClearPreCache() { while (_serialPort.BytesToRead != 0) { byte[] bytes = new byte[_serialPort.BytesToRead]; _serialPort.Read(bytes, 0, bytes.Length); } } } /// /// 发送数据类 /// internal class TemperatureSendData { public byte Id { get; set; } public byte Command { get; set; } public byte[] Data { get; set; } /// /// 0-set,1-get /// public byte Type { get; set; } /// /// 变量 /// public string VariableName { get; set; } /// /// 变量数值 /// public object VariableValue { get; set; } /// /// 变量类型(0-十位数据,1-千位数据,2-数组,3-有符号十位数据) /// public TemperatureVariableType VariableType { get; set; } } }