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