/// <summary> /// Read table data from the meter. /// </summary> /// <remarks> /// With commmand R6 data can be read one row at the time and it is parsed on the fly. /// With other commands all data must first read before data can be parse. /// </remarks> /// <param name="media"></param> /// <param name="wt"></param> /// <param name="name"></param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="level"></param> /// <returns></returns> public static object[][] ReadTable(Gurux.Common.IGXMedia media, int wt, string name, DateTime start, DateTime end, string parameters, int level, int count, out string[] columns) { columns = null; List <byte> reply = new List <byte>(); string header, frame; //Read CRC. ReceiveParameters <byte[]> crc = new ReceiveParameters <byte[]>() { Count = 1, WaitTime = wt }; List <byte> data = new List <byte>(); data.Add(1); data.AddRange(GenerateReadTable(name, start, end, parameters, level, count)); data.Add(3); data.Add(CalculateChecksum(data, 1, data.Count - 1)); lock (media.Synchronous) { do { List <byte> tmp = new List <byte>(SendData(media, data == null ? null : data.ToArray(), '\0', wt, true, level == 6, false)); data = null; if (level != 6 && tmp[tmp.Count - 1] == 0x3) { crc.Count = 1; if (!media.Receive(crc)) { throw new Exception("Failed to receive reply from the device in given time."); } tmp.AddRange(crc.Reply); } else if (level == 6) { if (GetPacket(tmp, true, out header, out frame) == null) { throw new Exception("Failed to receive reply from the device in given time."); } if (tmp[tmp.Count - 2] == 0x4) { //Send ACK if more data is left. data = new List <byte>(); data.Add(6); System.Threading.Thread.Sleep(200); } } reply.AddRange(tmp); }while (reply[reply.Count - 2] != 0x3); } int status = 0; DateTime tm = DateTime.MinValue; int add = 0; return(ParseTableData(reply.ToArray(), ref columns, ref status, ref tm, ref add, name)); }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <remarks> /// If access is denied return null. /// </remarks> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public byte[] ReadDLMSPacket(byte[] data, int tryCount) { if (data == null) { return(null); } object eop = (byte)0x7E; //In network connection terminator is not used. if (m_Cosem.InterfaceType == InterfaceType.Net && Media is GXNet && !Parent.UseRemoteSerial) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Eop = eop, Count = 5, WaitTime = Parent.WaitTime * 1000, }; lock (Media.Synchronous) { if (data != null) { Media.Send(data, null); } while (!succeeded && pos != 3) { succeeded = Media.Receive(p); if (!succeeded) { //Try to read again... if (++pos != tryCount) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); Media.Send(data, null); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } //Loop until whole COSEM packet is received. while (!m_Cosem.IsDLMSPacketComplete(p.Reply)) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } if (!Media.Receive(p)) { //Try to read again... if (++pos != tryCount) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } } GXLogWriter.WriteLog("Received data", p.Reply); object errors = m_Cosem.CheckReplyErrors(data, p.Reply); if (errors != null) { object[,] arr = (object[, ])errors; int error = (int)arr[0, 0]; if (error == -1) { //If data is reply to the previous packet sent. //This might happens sometimes. if (m_Cosem.IsPreviousPacket(data, p.Reply)) { return(ReadDLMSPacket(null)); } else { throw new Exception(arr[0, 1].ToString()); } } throw new GXDLMSException(error); } return(p.Reply); }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <remarks> /// If access is denied return null. /// </remarks> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, int tryCount, GXReplyData reply) { if (data == null) { return; } object eop = (byte)0x7E; //In network connection terminator is not used. if (client.InterfaceType == InterfaceType.WRAPPER && media is GXNet && !parent.UseRemoteSerial) { eop = null; } if (parent.OnTrace != null) { parent.OnTrace(parent, "<- " + DateTime.Now.ToLongTimeString() + " " + GXCommon.ToHex(data, true)); //if (data[data.Length - 1] == 0x7E && data[data.Length - 2] == 0xC5 && data[data.Length - 3] == 0x13) // data[data.Length - 1] = 0x7E; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Eop = eop, Count = 5, WaitTime = parent.WaitTime * 1000, }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); } while (!succeeded && pos != 3) { succeeded = media.Receive(p); if (!succeeded) { //Try to read again... if (++pos != tryCount) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); media.Send(data, null); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } try { //Loop until whole COSEM packet is received. while (!client.GetData(p.Reply, reply)) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } if (!media.Receive(p)) { //Try to read again... if (++pos != tryCount) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } } catch (Exception ex) { GXLogWriter.WriteLog("Received data", p.Reply); throw ex; } } if (parent.OnTrace != null) { parent.OnTrace(parent, "-> " + DateTime.Now.ToLongTimeString() + " " + GXCommon.ToHex(p.Reply, true)); } GXLogWriter.WriteLog("Received data", p.Reply); cnt++; System.Diagnostics.Debug.Write(cnt.ToString()); System.Diagnostics.Debug.Write(" Received data "); System.Diagnostics.Debug.WriteLine(BitConverter.ToString(p.Reply)); if (reply.Error != 0) { if (reply.Error == (int)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, tryCount, reply); } else { throw new GXDLMSException(reply.Error); } } }