internal byte[] ReadDLMSPacket(GXDLMSClient cosem, Gurux.Common.IGXMedia media, byte[] data, int wt) { if (data == null) { return null; } ReceiveParameters<byte[]> args = new ReceiveParameters<byte[]>() { Eop = (byte)0x7E, Count = 5, WaitTime = wt }; if (cosem.InterfaceType == InterfaceType.Net) { args.Eop = null; args.Count = 8; args.AllData = true; } int pos = 0; bool succeeded = false; lock (media.Synchronous) { media.Send(data, null); while (!succeeded && pos != 3) { succeeded = media.Receive(args); if (!succeeded) { //Try to read again... if (++pos != 3) { 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, (byte[])args.Reply); throw new Exception(err); } } //Loop until whole m_Cosem packet is received. while (!(succeeded = cosem.IsDLMSPacketComplete(args.Reply))) { if (!media.Receive(args)) { //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data receive failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, (byte[])args.Reply); throw new Exception(err); } } } object[,] errors = cosem.CheckReplyErrors(data, args.Reply); if (errors != null) { int error = (int)errors[0, 0]; throw new GXDLMSException(error); } return args.Reply; }
public override void ImportFromDevice(Control[] addinPages, GXDevice device, Gurux.Common.IGXMedia media) { media.Eop = device.GXClient.Eop; GXDLT645Device dev = device as GXDLT645Device; dev.Parser.IgnoreFrame = false; Dictionary<ulong, object> items = GXDLT645Property.ReadDataID(); GXCategory cat = device.Categories.Find("Default"); if (cat == null) { cat = new GXCategory("Default"); device.Categories.Add(cat); } media.Open(); int count = 0; foreach (var it in items) { Progress(++count, items.Count); byte[] data = dev.Parser.ReadValue(it.Key); lock (media.Synchronous) { media.Send(data, null); ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = media.Eop, WaitTime = device.WaitTime }; bool compleate = false; try { while (!(compleate = dev.Parser.IsPacketComplete(it.Key, p.Reply))) { if (!media.Receive<byte[]>(p)) { break; } } } catch (Exception ex) { Trace(ex.Message + Environment.NewLine); } // If data is not received or error has occurred. if (!compleate || dev.Parser.IsError(p.Reply)) { continue; } GXDLT645Data d = it.Value as GXDLT645Data; if (d != null) { Trace(it.Key + " " + d.Name + Environment.NewLine); cat.Properties.Add(new GXDLT645Property(it.Key, d.Name, d.Type, d.Access)); } else { GXDLT645TableTemplate t = it.Value as GXDLT645TableTemplate; Trace(it.Key + " " + t.Name + Environment.NewLine); GXDLT645Table table = new GXDLT645Table(); table.Name = t.Name; table.DataID = it.Key; foreach (GXDLT645Data col in t.Columns) { table.Columns.Add(new GXDLT645Property(it.Key, col.Name, col.Type, col.Access)); } device.Tables.Add(table); } } } }
/// <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); }