using Aurora.Api; using Aurora.Api.DataType; using Aurora.Api.Devices; using Hermes; using PropertyTools.Wpf; using System; using System.Data.SqlClient; using System.Text; using System.Threading; using System.Windows.Input; using System.Windows.Markup; using static System.Net.Mime.MediaTypeNames; namespace AuroraMassFlowMeter.MFC { public partial class MassFlowMeterMKPrecision : SerialConn, IMassFlowMeter { private int DeviceID { get; set; } private readonly object locker = new object(); public enum ErrorCode { PowerOver = 1, SensorFail = 2, HeaterPowerLow = 4, } private SerialConnConfig _connConfig; public MassFlowMeterMKPrecision(string deviceId, bool isSimul = false) : base(deviceId, isSimul) { } public int Connect(SerialConnConfig config) { _connConfig = config; if (IsPortOpen()) { return E1.OK; } return Open(config); } public int Disconnect() { return Close(); } public int Reconnect() { // 1. 컴포트가 열려있으면 닫기 Disconnect(); // 2. 연결 if (IsPortOpen()) { return E1.OK; } return Open(_connConfig); } public bool SetZero() { //return Send(CMD_SET_ZERO); return false; } private bool Send(string command) { return Write(command + "\r\n"); } public bool CheckSystemStatus(out bool isOk) { isOk = true; // var reply = SendAndRepely(CMD_CHECK_SYS_STATUS); var reply = "string"; if (string.IsNullOrEmpty(reply)) return false; if (reply.Equals("T")) { isOk = false; } return true; } public bool CheckErrorCount(out int count) { count = 0; //var reply = SendAndRepely(CMD_CHECK_SYS_STATUS); //return int.TryParse(reply, out count); return false; } public bool ClearError() { //return Send(CMD_CLEAR_ERROR); return false; } private byte[] SendAndReply(string command) { lock(locker) { try { var ReadBytes = new byte[128]; var bytes = Encoding.ASCII.GetBytes(command); if (!Write(bytes, bytes.Length)) return null; Thread.Sleep(50); if (Read(ReadBytes) > 0) return ReadBytes; return ReadBytes; } catch (Exception ex) { return null; } } } private string SendAndRepely(string commmand) { //var bytes = Encoding.ASCII.GetBytes(commnad); //var commandAscii = Encoding.ASCII.GetString(bytes); var ReturnMessageforBytes = SendAndReply(commmand); if (ReturnMessageforBytes is null) return null; string ReturnMessage = ASCIIEncoding.ASCII.GetString(ReturnMessageforBytes); if (string.IsNullOrEmpty(ReturnMessage)) { return null; } // \r, \n, ' ' (공백), 제거 return ReturnMessage.Trim("\r".ToCharArray()); } public bool SendAndRepely(string Command, string DataType, string DataString, out string ReturnData) { ReturnData = ""; string Message; if (!MakeMessage(Command, DataType, DataString, out Message)) return false; var ReturnMessageforBytes = SendAndReply(Message); if (ReturnMessageforBytes is null) return false; string ReturnMessage = ASCIIEncoding.ASCII.GetString(ReturnMessageforBytes); if (!ParsingReturnMessage(Command, ReturnMessage, out ReturnData)) return false; return true; } private bool MakeMessage(string Command, string DataType, string Data, out string MessageString) { // | 1 | 2 3 | 4 5 | 6 7 | 8 9 | 10 11 | 12 | // | Start | Device ID | Command | Data Type | Data | Check Sum | End | // | : | 0 1 | 7 0 | 0 2 | 0 2 | 3 C | \r | // | 0X3A | 0X30 0X31 | 0X37 0X30 | 0X30 0X32 | 0X30 0X32 | 0X33 0X43 | 0X0D | int MessageLength = 1 + 2 + Command.Length + DataType.Length + Data.Length + 2 + 1 ; byte[] Message = new byte[MessageLength]; int Index = 0; MessageString = ""; Message[Index++] = CMD_START; string DeviceIDString = DeviceID.ToString("X2"); if (DeviceIDString.Length != 2) return false; Message[Index++] = (byte)DeviceIDString[0]; Message[Index++] = (byte)DeviceIDString[1]; if (Command.Length != 2) return false; Message[Index++] = (byte)Command[0]; Message[Index++] = (byte)Command[1]; if (DataType.Length != 2) return false; Message[Index++] = (byte)DataType[0]; Message[Index++] = (byte)DataType[1]; int DataLength = GetDataByteLength(DataType); if(Data.Length != DataLength) return false; for (int i = 0; i < DataLength; i++) Message[Index++] = (byte)Data[i]; string CheckSum = MakeCheckSum(Message); if (CheckSum.Length != 2) return false; Message[Index++] = (byte)CheckSum[0]; Message[Index++] = (byte)CheckSum[1]; Message[Index++] = CMD_END; MessageString = Encoding.ASCII.GetString(Message); return true; } private bool ParsingReturnMessage(string Command, string ReturnMessage, out string Data) { // | 1 | 2 3 | 4 5 | 6 7 | 8 9 | 10 11 | 12 | // | Start | Device ID | Command | Data Type | Data | Check Sum | End | // | : | 0 1 | 7 0 | 0 2 | 0 2 | 3 C | \r | // | 0X3A | 0X30 0X31 | 0X37 0X30 | 0X30 0X32 | 0X30 0X32 | 0X33 0X43 | 0X0D | Data = ""; if (ReturnMessage == null) // 적어도 7개 데이터 필요 return false; if (ReturnMessage.Length < 7 ) // 적어도 7개 데이터 필요 return false; if (CMD_START != ReturnMessage[0]) return false; string ReturnDeviceID = ReturnMessage.Substring(1, 2); if(!ReturnDeviceID.Equals(DeviceID.ToString("X2"))) return false; string ReturnCommand = ReturnMessage.Substring(3, 2); int number = Convert.ToInt32(Command, 16); number |= 0x80; if (!ReturnCommand.Equals(number.ToString("X2"))) return false; string ReturnDataType = ReturnMessage.Substring(5, 2); int DataLength = GetDataByteLength(ReturnDataType); string ReturnData = ""; if (DataLength != 0) ReturnData = ReturnMessage.Substring(7, DataLength); string ReturnCheckSum = ReturnMessage.Substring(7 + DataLength, 2); byte[] byteArray = Encoding.UTF8.GetBytes(ReturnMessage.Substring(0, 7 + DataLength)); string CheckSum = MakeCheckSum(byteArray); if(ReturnCheckSum != CheckSum) return false; Data = ReturnData; return true; } private string ConvertIEEE754(float Data) { byte[] bytes = BitConverter.GetBytes(Data); Array.Reverse(bytes); return BitConverter.ToString(bytes).Replace("-", ""); } private double DeConvertIEEE754(string Data) { byte[] bytesFromHex = new byte[4]; for (int i = 0; i < 4; i++) { bytesFromHex[i] = Convert.ToByte(Data.Substring(i * 2, 2), 16); } Array.Reverse(bytesFromHex); return BitConverter.ToSingle(bytesFromHex, 0); } private byte DeConvertByte(string Data) { byte bytesFromHex; bytesFromHex = Convert.ToByte(Data, 16); return bytesFromHex; } private string MakeCheckSum(byte[] MessageFrame) { byte xorResult = 0; foreach( byte b in MessageFrame) { xorResult ^= b; } return xorResult.ToString("X2"); } public void SetDeviceID(int NewDeviceID) { DeviceID = NewDeviceID; } private int GetDataByteLength(string DataType) { int DataLength = 0; switch (DataType) { case DATA_NO_DATA: DataLength = 0; break; case DATA_SIGNED_CHAR: DataLength = 2; break; case DATA_UNSIGNED_CHAR: DataLength = 2; break; case DATA_SIGNED_SHORT: DataLength = 2; break; case DATA_UNSIGNED_SHORT: DataLength = 2; break; case DATA_SIGNED_LONG: DataLength = 8; break; case DATA_UNSIGNED_LONG: DataLength = 8; break; case DATA_FLOAT: DataLength = 8; break; case DATA_DOUBLE: DataLength = 8; break; default: byte bytesFromHex; bytesFromHex = Convert.ToByte(DataType, 16); DataLength = bytesFromHex & 0x3F; break; } return DataLength; } public bool WriteSetPoint(double FlowData) { string DataString = ConvertIEEE754((float)FlowData); string ReturnData = ""; bool Result = SendAndRepely(CMD_WRITE_SET_POINT, DATA_FLOAT, DataString, out ReturnData); if (Result) { if (ReturnData.Equals(DataString)) { return true; } else return false; } else return false; } public bool ReadSetPoint(ref double SetPoint) { SetPoint = 0.0f; string DataString = ""; string ReturnData = ""; bool Result = SendAndRepely(CMD_READ_SET_POINT, DATA_NO_DATA, DataString, out ReturnData); if (Result) { SetPoint = DeConvertIEEE754(ReturnData); return true; } else return false; } public bool ReadFlow(ref double ReadFlow) { //ReadFlow = 0.0f; string DataString = ""; string ReturnData = ""; bool Result = SendAndRepely(CMD_READ_FLOW, DATA_NO_DATA, DataString, out ReturnData); if (Result) { ReadFlow = DeConvertIEEE754(ReturnData); return true; } else return false; } public bool ReadReadingError(out double ReadReadingError) { ReadReadingError = double.NaN; string DataString = ""; string ReturnData = ""; bool Result = SendAndRepely(CMD_READ_READING_ERROR, DATA_NO_DATA, DataString, out ReturnData); if (Result) { ReadReadingError = DeConvertIEEE754(ReturnData); return true; } else return false; } public bool WriteReadingError(double WriteReadingError) { string DataString = ConvertIEEE754((float)WriteReadingError); string ReturnData = ""; bool Result = SendAndRepely(CMD_WRITE_READING_ERROR, DATA_FLOAT, DataString, out ReturnData); if (Result) { if (ReturnData.Equals(DataString)) { return true; } else return false; } else return false; } public bool ReadMFCStatus(out byte ReadMFCStatus) { ReadMFCStatus = 0; string DataString = ""; string ReturnData = ""; bool Result = SendAndRepely(CMD_READ_MFC_STATUS, DATA_NO_DATA, DataString, out ReturnData); if (Result) { ReadMFCStatus = DeConvertByte(ReturnData); return true; } else return false; } public bool WriteDeviceId(int DeviceID) { string DataString = DeviceID.ToString("X2"); string ReturnData = ""; bool Result = SendAndRepely(CMD_WRITE_DEVICE_ID, DATA_UNSIGNED_CHAR, DataString, out ReturnData); if (Result) { if (ReturnData.Equals(DataString)) { return true; } else return false; } else return false; } public bool ReadDeviceId(out int DeviceID) { DeviceID = 0; string DataString = ""; string ReturnData = ""; bool Result = SendAndRepely(CMD_READ_DEVICE_ID, DATA_NO_DATA, DataString, out ReturnData); if (Result) { DeviceID = int.Parse(ReturnData); return true; } else return false; } public bool ReadOperationMode(out eOperationMode OperationMode) { OperationMode = 0; string DataString = ""; string ReturnData = ""; bool Result = SendAndRepely(CMD_READ_OPERATION_MODE, DATA_NO_DATA, DataString, out ReturnData); if (Result) { OperationMode = (eOperationMode)int.Parse(ReturnData); return true; } else return false; } public bool WriteOperationMode(eOperationMode WriteOperationMode) { string DataString = WriteOperationMode.ToString("X2"); string ReturnData = ""; bool Result = SendAndRepely(CMD_WRITE_OPERATION_MODE, DATA_UNSIGNED_CHAR, DataString, out ReturnData); if (Result) { if (ReturnData.Equals(DataString)) { return true; } else return false; } else return false; } public bool ReadModelName(out string ReadModelName) { ReadModelName = ""; string DataString = ""; string ReturnData = ""; bool Result = SendAndRepely(CMD_READ_MODEL_NAME, DATA_NO_DATA, DataString, out ReturnData); if (Result) { ReadModelName = ReturnData; return true; } else return false; } public bool ReadFirmwareRevision(out string ReadFirmwareRevision) { string DataString = ""; string Message; ReadFirmwareRevision = ""; if (!MakeMessage(CMD_READ_FIRMWARE_REVISION, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_FIRMWARE_REVISION, ReturnMessage, out ReturnData); if (Result) { ReadFirmwareRevision = ReturnData; return true; } else return false; } public bool ReadHardwareRevision(out string ReadHardwareRevision) { string DataString = ""; string Message; ReadHardwareRevision = ""; if (!MakeMessage(CMD_READ_HARDWARE_REVISION, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_HARDWARE_REVISION, ReturnMessage, out ReturnData); if (Result) { ReadHardwareRevision = ReturnData; return true; } else return false; } public bool ReadSerial(out string ReadSerial) { string DataString = ""; string Message; ReadSerial = ""; if (!MakeMessage(CMD_READ_SERIAL, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_SERIAL, ReturnMessage, out ReturnData); if (Result) { ReadSerial = ReturnData; return true; } else return false; } public bool ReadBaudRate(out eBaudRate ReadBaudRate) { string DataString = ""; string Message; ReadBaudRate = 0; if (!MakeMessage(CMD_READ_BAUD_RATE, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_BAUD_RATE, ReturnMessage, out ReturnData); if (Result) { ReadBaudRate = (eBaudRate)int.Parse(ReturnData); return true; } else return false; } public bool WriteBaudRate(eBaudRate WriteBaudRate) { string DataString = WriteBaudRate.ToString("X2"); string Message; if (!MakeMessage(CMD_WRITE_BAUD_RATE, DATA_UNSIGNED_CHAR, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_WRITE_BAUD_RATE, ReturnMessage, out ReturnData); if (Result) { if (ReturnData.Equals(DataString)) { return true; } else return false; } else return false; } public bool ReadGasName(out string ReadGasName) { string DataString = ""; string Message; ReadGasName = ""; if (!MakeMessage(CMD_READ_GAS_NAME, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_GAS_NAME, ReturnMessage, out ReturnData); if (Result) { ReadGasName = ReturnData; return true; } else return false; } public bool ReadFullScale(out double ReadFullScale) { string DataString = ""; string Message; ReadFullScale = 0.0f; if (!MakeMessage(CMD_READ_FULL_SCALE, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_FULL_SCALE, ReturnMessage, out ReturnData); if (Result) { ReadFullScale = DeConvertIEEE754(ReturnData); return true; } else return false; } public bool ReadFlowUnit(out eFlowUnit ReadFlowUnit) { string DataString = ""; string Message; ReadFlowUnit = 0; if (!MakeMessage(CMD_READ_FLOW_UNIT, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_FLOW_UNIT, ReturnMessage, out ReturnData); if (Result) { ReadFlowUnit = (eFlowUnit)int.Parse(ReturnData); return true; } else return false; } public bool ReadIntegration(out double ReadIntegration) { string DataString = ""; string Message; ReadIntegration = 0.0f; if (!MakeMessage(CMD_READ_INTEGRATION, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_INTEGRATION, ReturnMessage, out ReturnData); if (Result) { ReadIntegration = DeConvertIEEE754(ReturnData); return true; } else return false; } public bool ResetIntegration(out double ResetIntegration) { string DataString = ""; string Message; ResetIntegration = 0.0f; if (!MakeMessage(CMD_RESET_INTEGRATION, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_RESET_INTEGRATION, ReturnMessage, out ReturnData); if (Result) { ResetIntegration = DeConvertIEEE754(ReturnData); return true; } else return false; } public bool ReadIntegrationOn(out eIntegrationOn ReadIntegrationOn) { string DataString = ""; string Message; ReadIntegrationOn = 0; if (!MakeMessage(CMD_READ_INTEGRATION_ON, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_READ_INTEGRATION_ON, ReturnMessage, out ReturnData); if (Result) { ReadIntegrationOn = (eIntegrationOn)int.Parse(ReturnData); return true; } else return false; } public bool WriteIntegrationOn(eIntegrationOn WriteIntegrationOn) { string DataString = WriteIntegrationOn.ToString("X2"); string Message; if (!MakeMessage(CMD_WRITE_INTEGRATION_ON, DATA_UNSIGNED_CHAR, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_WRITE_INTEGRATION_ON, ReturnMessage, out ReturnData); if (Result) { if (ReturnData.Equals(DataString)) { return true; } else return false; } else return false; } public bool WriteRampSetPoint(double Time, double SetPoint) { string DataString = ConvertIEEE754((float)Time); DataString += ConvertIEEE754((float)SetPoint); string Message; if (!MakeMessage(CMD_WRITE_SET_POINT, DATA_DOUBLE, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_WRITE_SET_POINT, ReturnMessage, out ReturnData); if (Result) { if (ReturnData.Equals(DataString)) { return true; } else return false; } else return false; } public bool ZeroOffset() { string DataString = ""; string Message; if (!MakeMessage(CMD_ZERO_OFFSET, DATA_NO_DATA, DataString, out Message)) return false; string ReturnMessage = SendAndRepely(Message); string ReturnData = ""; bool Result = ParsingReturnMessage(CMD_ZERO_OFFSET, ReturnMessage, out ReturnData); if (Result) { if(DeConvertIEEE754(ReturnData) == 0.0) return true; else return false; } else return false; } } }