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