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_HRSMonitoringItems : IMonitoringItems, ICloneable { public double TargetTemp { get; set; } public double CurrentTemp { get; set; } public double WarningRange { get; set; } public double ErrorRange { get; set; } public int AlamSt1 { get; set; } public int AlamSt2 { get; set; } public int AlamSt3 { get; set; } public int Status1 { get; set; } public int Status2 { get; set; } public object Clone() { return new SmcChiller_HRSMonitoringItems() { TargetTemp = TargetTemp, CurrentTemp = CurrentTemp, WarningRange = WarningRange, ErrorRange = ErrorRange, AlamSt1 = AlamSt1, AlamSt2 = AlamSt2, AlamSt3 = AlamSt3, Status1 = Status1, Status2 = Status2 }; } } public class SmcChiller_HRS : 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_HRSMonitoringItems MonitoringItems; private bool bIsSimpleCommMode = false; public SmcChillerConfig _Config { get; set; } #region Simulation private double SimulTargetTemp; #endregion public SmcChiller_HRS(string deviceId) : base(deviceId) { MonitoringItems = new SmcChiller_HRSMonitoringItems(); } 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.Status1 & (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" + "0000" + "0011"; 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)'1' || responseMsg[6] != (byte)'6') return false; string msgStr = Encoding.Default.GetString(responseMsg); //Information of 0000h string dataStr = msgStr.Substring(7, 4); int CurrentTemp = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); MonitoringItems.CurrentTemp = (double)CurrentTemp / 10; //Information of 0001h dataStr = msgStr.Substring(11, 4); //int ExternalTemp = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); //MonitoringItems.ExternalTemp = (double)ExternalTemp / 100; //Information of 0002h dataStr = msgStr.Substring(15, 4); int CirculatingPressure = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); //MonitoringItems.CurrentTemp = (double)CirculatingPressure / 100; //Information of 0003h dataStr = msgStr.Substring(19, 4); int ElectricResisivity = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); //MonitoringItems.Status1 = ElectricResisivity; //Information of 0004h dataStr = msgStr.Substring(23, 4); int Status1 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); MonitoringItems.Status1 = Status1; //int pressure = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); //Information of 0005h dataStr = msgStr.Substring(27, 4); int Alarm1 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); MonitoringItems.AlamSt1 = Alarm1; //Information of 0006h dataStr = msgStr.Substring(31, 4); int Alarm2 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); MonitoringItems.AlamSt2 = Alarm2; //Information of 0007h dataStr = msgStr.Substring(35, 4); int Alarm3 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); MonitoringItems.AlamSt3 = Alarm3; //Information of 0008h //responseMsg[30,31,32] dataStr = msgStr.Substring(39, 4); int Reserved = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); //Information of 0009h dataStr = msgStr.Substring(43, 4); int Status2 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); MonitoringItems.Status2 = Status2; //Information of 000Ah dataStr = msgStr.Substring(47, 4); int Reserved2 = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); //Information of 000Bh dataStr = msgStr.Substring(51, 4); int TargetTemp = Int32.Parse(dataStr, System.Globalization.NumberStyles.HexNumber); MonitoringItems.TargetTemp = (double)TargetTemp / 10; 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 / 10; 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 = "000C"; //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 * 10); string strReg = "06"; string strValue = iValue.ToString("X4"); strFunc = "000B"; 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; } } }