using Aitex.Common.Util;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.Device.TemperatureController;
using MECF.Framework.Simulator.Core.Driver;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MECF.Framework.Simulator.Core.Commons
{
public class TemperatureControllerSerialPortDevice : BaseSerialSimulator
{
#region 常量
private const string PORT_NAME = "com12";
private const byte ADD_FLAG = 0x30;
#endregion
#region 内部变量
///
/// 控制字字典
///
private Dictionary dic = new Dictionary()
{
{ 0x05,"ENQ" },
{ 0x02,"STX" },
{ 0x03,"ETX" },
{ 0x06,"ACK" },
{ 0x0D,"CR" },
{ 0x01,"SOH" }
};
///
/// 命令字典
///
private Dictionary comdic = new Dictionary()
{
{ 0x31,"Target Temp" },
{ 0x32,"Internal" },
{ 0x33,"External" },
{ 0x34,"Alarm" },
{ 0x35,"Average" },
{ 0x36,"offset" },
{ 0x39,"control" },
{ 0x41,"PB" },
{ 0x42,"ARW" },
{ 0x43,"IConstant" },
{ 0x44,"DConstant" },
{ 0x45,"OutPutRatio" },
{ 0x46,"HeatingLimit" },
{ 0x47,"CoolingLimit" },
{ 0x48,"Saved" }
};
private double[] _reserviorValues = new double[10];
private double[] _heatValues = new double[10];
private double[] _targetValues = new double[10];
private int _controlOperation = 0;
//private byte[] alarm = new byte[12] { 0,0,0,0,1,0,0,0,0,0,0,0};
private byte[] alarm = new byte[3] {0x30,0x33,0x30};
System.Timers.Timer[] _timers;
private int _tcCount = 1;
#endregion
///
/// 构造函数
///
///
///
public TemperatureControllerSerialPortDevice(string port) : base(port, SerialType.BUFFER)
{
Init(port);
}
///
/// 初始化
///
///
private void Init(string port)
{
//加载TC配置
try
{
string oldXmlPath = PathManager.GetCfgDir();
string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\SMCCfg.xml";
TemperatureConfig cfg = CustomXmlSerializer.Deserialize(new FileInfo(newXmlPath));
if (cfg != null)
{
foreach (TemperatureDeviceConfig config in cfg.TemperatureDeviceConfigs)
{
if (int.TryParse(config.Port.Substring(3,2), out int result1) && int.TryParse(port.Substring(3, 2), out int result2))
{
if(result1 + 1 == result2) _tcCount = config.TemperatureDevices.Count;
}
}
}
}
catch (Exception ex)
{
}
//
_timers = new System.Timers.Timer[_tcCount];
for(int i = 0; i < _tcCount; i++)
{
_heatValues[i] = 16.5;
_targetValues[i] = 0;
_reserviorValues[i] = 16.6;
_timers[i] = new System.Timers.Timer(50);
switch (i)
{
case 0:
_timers[0].Elapsed += Timer_Elapsed0;
break;
case 1:
_timers[1].Elapsed += Timer_Elapsed1;
break;
case 2:
_timers[2].Elapsed += Timer_Elapsed2;
break;
case 3:
_timers[3].Elapsed += Timer_Elapsed3;
break;
case 4:
_timers[4].Elapsed += Timer_Elapsed4;
break;
default:
break;
}
}
}
///
/// TC1-1的调温
///
///
///
private void Timer_Elapsed0(object sender, System.Timers.ElapsedEventArgs e)
{
if (Math.Abs(_heatValues[0] - _targetValues[0]) >= 0.2)
{
//内部调温
if (_heatValues[0] < _targetValues[0])
{
_heatValues[0] += 0.1;
}
else
{
_heatValues[0] -= 0.1;
}
//外部调温
if (_reserviorValues[0] < _targetValues[0])
{
_reserviorValues[0] += 0.1;
}
else
{
_reserviorValues[0] -= 0.1;
}
}
else
{
_timers[0].Stop();
}
}
///
/// TC1-2的调温
///
///
///
private void Timer_Elapsed1(object sender, System.Timers.ElapsedEventArgs e)
{
if (Math.Abs(_heatValues[1] - _targetValues[1]) >= 0.2)
{
//内部调温
if (_heatValues[1] < _targetValues[1])
{
_heatValues[1] += 0.1;
}
else
{
_heatValues[1] -= 0.1;
}
//外部调温
if (_reserviorValues[1] < _targetValues[1])
{
_reserviorValues[1] += 0.1;
}
else
{
_reserviorValues[1] -= 0.1;
}
}
else
{
_timers[1].Stop();
}
}
///
/// TC1-3的调温
///
///
///
private void Timer_Elapsed2(object sender, System.Timers.ElapsedEventArgs e)
{
if (Math.Abs(_heatValues[2] - _targetValues[2]) >= 0.2)
{
//内部调温
if (_heatValues[2] < _targetValues[2])
{
_heatValues[2] += 0.1;
}
else
{
_heatValues[2] -= 0.1;
}
//外部调温
if (_reserviorValues[2] < _targetValues[2])
{
_reserviorValues[2] += 0.1;
}
else
{
_reserviorValues[2] -= 0.1;
}
}
else
{
_timers[2].Stop();
}
}
///
/// TC1-4的调温
///
///
///
private void Timer_Elapsed3(object sender, System.Timers.ElapsedEventArgs e)
{
if (Math.Abs(_heatValues[3] - _targetValues[3]) >= 0.2)
{
//内部调温
if (_heatValues[3] < _targetValues[3])
{
_heatValues[3] += 0.1;
}
else
{
_heatValues[3] -= 0.1;
}
//外部调温
if (_reserviorValues[3] < _targetValues[3])
{
_reserviorValues[3] += 0.1;
}
else
{
_reserviorValues[3] -= 0.1;
}
}
else
{
_timers[3].Stop();
}
}
///
/// TC1-5的调温
///
///
///
private void Timer_Elapsed4(object sender, System.Timers.ElapsedEventArgs e)
{
if (Math.Abs(_heatValues[4] - _targetValues[4]) >= 0.2)
{
//内部调温
if (_heatValues[4] < _targetValues[4])
{
_heatValues[4] += 0.1;
}
else
{
_heatValues[4] -= 0.1;
}
//外部调温
if (_reserviorValues[4] < _targetValues[4])
{
_reserviorValues[4] += 0.1;
}
else
{
_reserviorValues[4] -= 0.1;
}
}
else
{
_timers[4].Stop();
}
}
protected override string MessageConvert(byte[] byt)
{
string str = "";
for(int i=0;i7)
{
byte[] byt = new byte[data.Length - 3];
Array.Copy(data, 3, byt, 0, byt.Length);
ProcessNormalCommand(byt);
}
else if (data[0] == 0x01)
{
ProcessNormalCommand(data);
}
}
private void ProcessNormalCommand(byte[] data)
{
if (data[0] == 0x01 && data[data.Length-1]==0x0D)
{
if (data.Length == 7)
{
ProcessReadCommand(data);
}
else if (data.Length > 7)
{
ProcessSetCommand(data);
}
}
}
private void ProcessReadCommand(byte[] data)
{
switch(data[3])
{
case 0x31:
ReadTargetValue(data);
break;
case 0x32:
ReadReserviorValue(data);
break;
case 0x33:
ReadHeatValue(data);
break;
case 0x34:
ReadAlarmValue(data);
break;
case 0x39:
ReadControlOperationValue(data);
break;
}
}
private void ProcessSetCommand(byte[] data)
{
switch(data[3])
{
case 0x31:
_targetValues[data[1] - ADD_FLAG - 1] = (data[4] - ADD_FLAG) * 10 + (data[5] - ADD_FLAG) + (data[6]-ADD_FLAG)*0.1;
_timers[data[1] - ADD_FLAG -1].Start();
break;
case 0x39:
_controlOperation = data[7] - ADD_FLAG;
if(_controlOperation == 0)
{
//停止调温
_timers[data[1] - ADD_FLAG - 1].Stop();
}
else
{
//继续调温
_timers[data[1] - ADD_FLAG - 1].Start();
}
break;
}
WriteConfirmData(data[1]);
}
///
/// 回复确认
///
///
private void WriteConfirmData(byte id)
{
byte[] confirm = new byte[3];
confirm[0] = 0x06;
confirm[1] = id;
confirm[2] = 0x0d;
WriteBuffer(confirm);
}
private void ReadTargetValue(byte[] data)
{
byte[] byt = new byte[12];
byt[0] = data[0];
byt[1] = data[1];
byt[2] = 0x02;
byt[3] = data[3];
byte[] decadeByte = GetDecadeBytes(_targetValues[data[1] - ADD_FLAG - 1]);
Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
byt[5 + decadeByte.Length] = 0;
byt[6 + decadeByte.Length] = 0;
byt[11] = 0x0D;
WriteBuffer(byt);
}
private void ReadReserviorValue(byte[] data)
{
byte[] byt = new byte[12];
byt[0] = data[0];
byt[1] = data[1];
byt[2] = 0x02;
byt[3] = data[3];
byte[] decadeByte = GetDecadeBytes(_reserviorValues[data[1] - ADD_FLAG - 1]);
Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
byt[5 + decadeByte.Length] = 0;
byt[6 + decadeByte.Length] = 0;
byt[11] = 0x0D;
WriteBuffer(byt);
}
private void ReadHeatValue(byte[] data)
{
byte[] byt = new byte[12];
byt[0] = data[0];
byt[1] = data[1];
byt[2] = 0x02;
byt[3] = data[3];
byte[] decadeByte = GetDecadeBytes(_heatValues[data[1] - ADD_FLAG - 1]);
Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
byt[5 + decadeByte.Length] = 0;
byt[6 + decadeByte.Length] = 0;
byt[11] = 0x0D;
WriteBuffer(byt);
}
private void ReadControlOperationValue(byte[] data)
{
byte[] byt = new byte[12];
byt[0] = data[0];
byt[1] = data[1];
byt[2] = 0x02;
byt[3] = data[3];
byte[] decadeByte = GetKilloBytes(_controlOperation);
Array.Copy(decadeByte, 0, byt, 4, decadeByte.Length);
byt[5 + decadeByte.Length] = 0;
byt[6 + decadeByte.Length] = 0;
byt[11] = 0x0D;
WriteBuffer(byt);
}
private void ReadAlarmValue(byte[] data)
{
byte[] byt = new byte[8+alarm.Length];
byt[0] = data[0];
byt[1] = data[1];
byt[2] = 0x02;
byt[3] = data[3];
Array.Copy(alarm, 0, byt, 4, alarm.Length);
byt[5 + alarm.Length] = 0;
byt[6 + alarm.Length] = 0;
byt[7+alarm.Length] = 0x0D;
WriteBuffer(byt);
}
///
/// 获取温度数组(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 };
}
///
/// 获取千级数组(1000|100|10|1)
///
///
///
private byte[] GetKilloBytes(double temperature)
{
byte kilo = GetSendByteData((byte)Math.Floor(temperature / 1000));
byte hundred = GetSendByteData((byte)Math.Floor(temperature % 1000/100));
byte decade = GetSendByteData((byte)Math.Floor(temperature % 100 / 10));
byte unit = GetSendByteData((byte)Math.Floor(temperature % 10));
return new byte[4] { kilo, hundred, decade, unit };
}
///
/// 获取发送位数据
///
///
///
private byte GetSendByteData(byte originalData)
{
return (byte)(ADD_FLAG + originalData);
}
}
}