545 lines
16 KiB
C#
545 lines
16 KiB
C#
using Aurora.Api;
|
|
using Aurora.Api.Devices;
|
|
using Hermes;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Markup;
|
|
|
|
namespace AuroraChiller
|
|
{
|
|
//우선 Aurora의 SmcChiller를 가져와서 LASA에 필요한 부분을 넣어주자
|
|
|
|
public class SmcChiller_HECRMonitoringItems : IMonitoringItems, ICloneable
|
|
{
|
|
public double TargetTemp { get; set; }
|
|
public double InternalTemp { get; set; }
|
|
public double ExternalTemp { get; set; }
|
|
public double AverageTemp { get; set; }
|
|
|
|
public double WarningRange { get; set; }
|
|
public double ErrorRange { get; set; }
|
|
|
|
public int AlamSt1 { get; set; }
|
|
public int AlamSt2 { get; set; }
|
|
|
|
public int Status { get; set; }
|
|
|
|
public object Clone()
|
|
{
|
|
return new SmcChiller_HECRMonitoringItems()
|
|
{
|
|
TargetTemp = TargetTemp,
|
|
InternalTemp = InternalTemp,
|
|
ExternalTemp = ExternalTemp,
|
|
AverageTemp = AverageTemp,
|
|
WarningRange = WarningRange,
|
|
ErrorRange = ErrorRange,
|
|
AlamSt1 = AlamSt1,
|
|
AlamSt2 = AlamSt2,
|
|
Status = Status
|
|
};
|
|
}
|
|
}
|
|
|
|
public class SmcChiller_HECR : SerialPortDevice, ISmcChiller
|
|
{
|
|
public const byte BYTE_STX = 0x02; // 02
|
|
public const byte BYTE_ETX = 0x03; // 03
|
|
public const byte BYTE_ACK = 0x06; // 06
|
|
public const byte BYTE_NAK = 0x15; // 21
|
|
public const byte BYTE_0 = 0x30; // 48
|
|
public const byte BYTE_1 = 0x31; // 49
|
|
public const byte BYTE_5 = 0x35; // 53
|
|
|
|
public const byte BYTE_CR = 0x0D;
|
|
public const byte BYTE_LF = 0x0A;
|
|
|
|
public const string CMD_PV1 = "PV1";
|
|
public const string CMD_SV1 = "SV1";
|
|
public const string CMD_LOC = "LOC";
|
|
public const string CMD_STR = "STR";
|
|
|
|
public const byte BYTE_REQ_READ = 0x52; // 82
|
|
public const byte BYTE_REQ_WRITE = 0x57; // 87
|
|
|
|
public const byte LENGTH_READ_REQUEST_MSG = 8;
|
|
public const byte LENGTH_WRITE_REQUEST_MSG = 13;
|
|
public const byte LENGTH_SAVE_REQUEST_MSG = 8;
|
|
public const byte LENGTH_RESPONSE_MSG = 14;
|
|
public const byte LENGTH_SLAVE_ADDRESS = 2;
|
|
public const byte LENGTH_WRITE_ADDRESS = 4;
|
|
public const byte LENGTH_CMD = 3;
|
|
public const byte LENGTH_DATA_INTEGER = 4;
|
|
public const byte LENGTH_DATA_DECIMAL_FRACTION = 1;
|
|
public const byte LENGTH_DATA = 4;
|
|
|
|
public const byte LENGTH_READ_REGISTER_MSG = 17;
|
|
public const byte LENGTH_RESPONSE_REGISTER_MSG = 255;
|
|
|
|
private SmcChiller_HECRMonitoringItems MonitoringItems;
|
|
|
|
private bool bIsSimpleCommMode = false;
|
|
|
|
public SmcChillerConfig _Config { get; set; }
|
|
|
|
#region Simulation
|
|
private double SimulTargetTemp;
|
|
#endregion
|
|
|
|
public SmcChiller_HECR(string deviceId) : base(deviceId)
|
|
{
|
|
MonitoringItems = new SmcChiller_HECRMonitoringItems();
|
|
}
|
|
|
|
protected override int DoActivate(IDeviceConfig config)
|
|
{
|
|
_Config = config as SmcChillerConfig;
|
|
|
|
//임시
|
|
if (IsSimul)
|
|
{
|
|
return E1.OK;
|
|
}
|
|
|
|
var result = Open(_Config.ConnConfig as SerialConnConfig);
|
|
if (result != E1.OK) {
|
|
return result;
|
|
}
|
|
|
|
return Init();
|
|
|
|
}
|
|
|
|
private int Init()
|
|
{
|
|
// Set init vaues from config
|
|
if (!IsValidSlaveAddress(_Config.SlaveAddress))
|
|
{
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
if (IsSimul)
|
|
{
|
|
SimulTargetTemp = 10;
|
|
}
|
|
else
|
|
{
|
|
// TargetTemperature 설정은 장치에서 직접 설정한다.
|
|
// SetTargetTemp(_Config.TargetTemperature);
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
public int Open(SmcChillerConfig config)
|
|
{
|
|
var result = Open(config.ConnConfig as SerialConnConfig);
|
|
_Config = config as SmcChillerConfig;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
public int PortClose()
|
|
{
|
|
return Close();
|
|
}
|
|
|
|
public bool GetConnected()
|
|
{
|
|
if (!IsPortOpen())
|
|
{
|
|
Log.E("SMC Chiller Serial Port is NOT Open!");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public bool GetChillerRunningFlag()
|
|
{
|
|
bool bReturn = ((MonitoringItems.Status & (1 << 1)) > 0) ? true : false;
|
|
return bReturn;
|
|
}
|
|
|
|
private bool IsValidSlaveAddress(int slaveAddress)
|
|
{
|
|
return (1 <= slaveAddress && slaveAddress <= 99);
|
|
}
|
|
|
|
protected override int DoDeactivate()
|
|
{
|
|
if (IsSimul)
|
|
{
|
|
return E1.OK;
|
|
}
|
|
else
|
|
{
|
|
return Close();
|
|
}
|
|
}
|
|
public int GetCurrentTemp(int Channel,out double temperature)
|
|
{
|
|
temperature = 0;
|
|
return E1.OK;
|
|
}
|
|
|
|
public int GetTargetTemp(int channel,out double temperature)
|
|
{
|
|
temperature = 0;
|
|
return E1.OK;
|
|
}
|
|
|
|
public int GetTargetTemp(out double temperature)
|
|
{
|
|
if (IsSimul)
|
|
{
|
|
temperature = SimulTargetTemp;
|
|
return E1.OK;
|
|
}
|
|
else
|
|
{
|
|
temperature = MonitoringItems.TargetTemp;
|
|
return E1.OK;
|
|
}
|
|
}
|
|
|
|
private static byte CalculateBcc(byte[] msg)
|
|
{
|
|
if (msg.Length == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (msg.Length == 1)
|
|
{
|
|
return msg[0];
|
|
}
|
|
|
|
byte bcc = (byte)(msg[0] ^ msg[1]);
|
|
for (int i = 2; i < msg.Length; i++)
|
|
{
|
|
bcc ^= msg[i];
|
|
}
|
|
|
|
return bcc;
|
|
}
|
|
|
|
private static string ConvertSlaveAddressIntToString(int address)
|
|
{
|
|
return string.Format("{0:00}", address);
|
|
}
|
|
|
|
|
|
public int UpdateMonitoringItems()
|
|
{
|
|
lock (LockThis)
|
|
{
|
|
|
|
if (IsSimul)
|
|
{
|
|
return E1.OK;
|
|
}
|
|
ReadRegister();
|
|
ReadTargetTemp();
|
|
return E1.OK;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public IMonitoringItems GetMonitoringItems()
|
|
{
|
|
lock (LockThis)
|
|
{
|
|
return MonitoringItems.Clone() as IMonitoringItems;
|
|
}
|
|
}
|
|
private byte[] CreateReadRegisterMsg()
|
|
{
|
|
string strReadMessage = ConvertSlaveAddressIntToString(_Config.SlaveAddress) + "03" + "0040" + "0007";
|
|
byte[] requestMsg = new byte[LENGTH_READ_REGISTER_MSG];
|
|
|
|
byte[] bccMessage = HexStringToByteArray(strReadMessage);
|
|
byte[] byteReadMessage = Encoding.Default.GetBytes(strReadMessage);
|
|
byte[] bcc = CalculateLRC(bccMessage);
|
|
|
|
requestMsg[0] = (byte)(':');
|
|
|
|
Array.Copy(byteReadMessage, 0, requestMsg, 1, byteReadMessage.Length);
|
|
|
|
Array.Copy(bcc, 0, requestMsg, 13, bcc.Length);
|
|
|
|
requestMsg[15] = BYTE_CR;
|
|
requestMsg[16] = BYTE_LF;
|
|
string check = Encoding.Default.GetString(requestMsg);
|
|
return requestMsg;
|
|
}
|
|
|
|
private byte[] CreateReadTargetTempMsg()
|
|
{
|
|
string strReadMessage = ConvertSlaveAddressIntToString(_Config.SlaveAddress) + "03" + "0051" + "0001";
|
|
byte[] requestMsg = new byte[LENGTH_READ_REGISTER_MSG];
|
|
|
|
byte[] bccMessage = HexStringToByteArray(strReadMessage);
|
|
byte[] byteReadMessage = Encoding.Default.GetBytes(strReadMessage);
|
|
byte[] bcc = CalculateLRC(bccMessage);
|
|
|
|
requestMsg[0] = (byte)(':');
|
|
|
|
Array.Copy(byteReadMessage, 0, requestMsg, 1, byteReadMessage.Length);
|
|
|
|
Array.Copy(bcc, 0, requestMsg, 13, bcc.Length);
|
|
|
|
requestMsg[15] = BYTE_CR;
|
|
requestMsg[16] = BYTE_LF;
|
|
string check = Encoding.Default.GetString(requestMsg);
|
|
return requestMsg;
|
|
}
|
|
|
|
private bool ParsingRegisterData(byte[] responseMsg)
|
|
{
|
|
if (responseMsg[3] != (byte)'0' || responseMsg[4] != (byte)'3')
|
|
return false;
|
|
if (responseMsg[5] != (byte)'0' || responseMsg[6] != (byte)'E')
|
|
return false;
|
|
|
|
string msgStr = Encoding.Default.GetString(responseMsg);
|
|
//Information of 0040h
|
|
//responseMsg[7,8,9,10]
|
|
string dataStr = msgStr.Substring(7, 4);
|
|
int InternalTemp = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
MonitoringItems.InternalTemp = (double)InternalTemp / 100;
|
|
|
|
//Information of 0041h
|
|
//responseMsg[11,12,13,14]
|
|
dataStr = msgStr.Substring(11, 4);
|
|
int ExternalTemp = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
MonitoringItems.ExternalTemp = (double)ExternalTemp / 100;
|
|
//Information of 0042h
|
|
//responseMsg[15,16,17,18]
|
|
dataStr = msgStr.Substring(15, 4);
|
|
int AverageTemp = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
MonitoringItems.AverageTemp = (double)AverageTemp / 100;
|
|
|
|
//Information of 0043h
|
|
//responseMsg[19,20,21,22]
|
|
dataStr = msgStr.Substring(19, 4);
|
|
int Status = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
MonitoringItems.Status = Status;
|
|
|
|
//Information of 0044h
|
|
//responseMsg[23,24,25,26]
|
|
dataStr = msgStr.Substring(23, 4);
|
|
int Alarm1 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
MonitoringItems.AlamSt1 = Alarm1;
|
|
//int pressure = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
|
|
//Information of 0045h
|
|
//responseMsg[27,28,29,30]
|
|
dataStr = msgStr.Substring(27, 4);
|
|
int Alarm2 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
MonitoringItems.AlamSt2 = Alarm2;
|
|
|
|
//Information of 0046h
|
|
//responseMsg[30,31,32]
|
|
dataStr = msgStr.Substring(31, 4);
|
|
int OutputRatio = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
|
|
return true;
|
|
}
|
|
|
|
private bool ParsingTargetTempData(byte[] responseMsg)
|
|
{
|
|
if (responseMsg[3] != (byte)'0' || responseMsg[4] != (byte)'3')
|
|
return false;
|
|
if (responseMsg[5] != (byte)'0' || responseMsg[6] != (byte)'2')
|
|
return false;
|
|
|
|
string msgStr = Encoding.Default.GetString(responseMsg);
|
|
//Information of 0040h
|
|
//responseMsg[7,8,9,10]
|
|
string dataStr = msgStr.Substring(7, 4);
|
|
int TargetTemp = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber);
|
|
MonitoringItems.TargetTemp = (double)TargetTemp / 100;
|
|
|
|
return true;
|
|
}
|
|
|
|
private int ReadRegister()
|
|
{
|
|
if (!IsPortOpen())
|
|
{
|
|
Log.E("Serial Port is NOT Open!");
|
|
return E1.NETWORK;
|
|
}
|
|
|
|
lock (LockThis)
|
|
{
|
|
byte[] requestMsg = CreateReadRegisterMsg();
|
|
if (Write(requestMsg))
|
|
{
|
|
byte[] responseMsg = new byte[LENGTH_RESPONSE_REGISTER_MSG];
|
|
if (ReadMessage(responseMsg, (byte)(':'), BYTE_LF) <= 0)
|
|
{
|
|
Log.E("ReadError");
|
|
return E1.GENERIC;
|
|
}
|
|
if (ParsingRegisterData(responseMsg) == false)
|
|
return E1.GENERIC;
|
|
}
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
private int ReadTargetTemp()
|
|
{
|
|
if (!IsPortOpen()) {
|
|
Log.E("Serial Port is NOT Open!");
|
|
return E1.NETWORK;
|
|
}
|
|
|
|
lock (LockThis) {
|
|
byte[] requestMsg = CreateReadTargetTempMsg();
|
|
if (Write(requestMsg)) {
|
|
byte[] responseMsg = new byte[LENGTH_RESPONSE_REGISTER_MSG];
|
|
if (ReadMessage(responseMsg, (byte)(':'), BYTE_LF) <= 0) {
|
|
Log.E("ReadError");
|
|
return E1.GENERIC;
|
|
}
|
|
if (ParsingTargetTempData(responseMsg) == false)
|
|
return E1.GENERIC;
|
|
}
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
public int SetRunStart(bool bStart)
|
|
{
|
|
if (IsSimul) {
|
|
return E1.OK;
|
|
}
|
|
if (bStart) {
|
|
SetControlMode(1);
|
|
return E1.OK;
|
|
|
|
} else {
|
|
SetControlMode(0);
|
|
return E1.OK;
|
|
}
|
|
|
|
}
|
|
|
|
public int SetControlMode(int Value)
|
|
{
|
|
if (IsSimul) {
|
|
return E1.OK;
|
|
}
|
|
string strFunc = "";
|
|
string strReg = "06";
|
|
string strValue = Value.ToString("X4");
|
|
strFunc = "0050"; //64.ToString("X4");//ConvertDataIntToString(40);
|
|
|
|
return WriteRegister(strReg, strValue, strFunc);
|
|
}
|
|
|
|
public int SetTargetTemp(string channel, double value)
|
|
{
|
|
return E1.OK;
|
|
}
|
|
|
|
public int SetTargetTemp(double value)
|
|
{
|
|
if (IsSimul)
|
|
{
|
|
SimulTargetTemp = value;
|
|
return E1.OK;
|
|
}
|
|
string strFunc = "";
|
|
int iValue = (int)(value * 100);
|
|
string strReg = "06";
|
|
string strValue = iValue.ToString("X4");
|
|
strFunc = "0051";
|
|
|
|
return WriteRegister(strReg, strValue, strFunc);
|
|
}
|
|
|
|
|
|
private int WriteRegister(string Reg, string value, string Func)
|
|
{
|
|
if (!IsPortOpen())
|
|
{
|
|
Log.E("Serial Port is NOT Open!");
|
|
return E1.NETWORK;
|
|
}
|
|
|
|
lock (LockThis)
|
|
{
|
|
byte[] requestMsg = CreateWriteRegisterMsg(Reg, value, Func);
|
|
if (Write(requestMsg))
|
|
{
|
|
byte[] responseMsg = new byte[LENGTH_RESPONSE_REGISTER_MSG];
|
|
if (ReadMessage(responseMsg, (byte)(':'), BYTE_LF) <= 0)
|
|
{
|
|
Log.E("ReadError");
|
|
return E1.GENERIC;
|
|
}
|
|
}
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
private byte[] CreateWriteRegisterMsg(string Reg, string value, string Func)
|
|
{
|
|
string strWriteMessage = ConvertSlaveAddressIntToString(_Config.SlaveAddress) + Reg + Func + value;
|
|
byte[] requestMsg = new byte[LENGTH_READ_REGISTER_MSG];
|
|
byte[] bccMessage = HexStringToByteArray(strWriteMessage);
|
|
byte[] byteWriteMessage = Encoding.Default.GetBytes(strWriteMessage);
|
|
byte[] bcc = CalculateLRC(bccMessage);
|
|
|
|
requestMsg[0] = (byte)(':');
|
|
|
|
Array.Copy(byteWriteMessage, 0, requestMsg, 1, byteWriteMessage.Length);
|
|
|
|
Array.Copy(bcc, 0, requestMsg, 13, bcc.Length);
|
|
|
|
requestMsg[15] = BYTE_CR;
|
|
requestMsg[16] = BYTE_LF;
|
|
string check = Encoding.Default.GetString(requestMsg);
|
|
return requestMsg;
|
|
}
|
|
private byte[] CalculateLRC(byte[] bytes)
|
|
{
|
|
int sum = 0;
|
|
foreach (byte b in bytes)
|
|
{
|
|
sum += b;
|
|
}
|
|
byte truncatedSum = (byte)(sum & 0xFF);
|
|
byte lrc = (byte)((~truncatedSum + 1) & 0xFF);
|
|
string lrcHex = lrc.ToString("X2");
|
|
|
|
return new byte[]
|
|
{
|
|
(byte)lrcHex[0], (byte)lrcHex[1]
|
|
};
|
|
|
|
}
|
|
private byte[] HexStringToByteArray(string hex)
|
|
{
|
|
int length = hex.Length;
|
|
byte[] bytes = new byte[length / 2];
|
|
for(int i=0; i< length; i += 2)
|
|
{
|
|
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
|
|
}
|
|
}
|