private void ParseReadoutReply(GXPacket packet, GXMBusCategory category) { List<byte> dataBuff = new List<byte>(); dataBuff.Add((byte)packet.Bop); dataBuff.AddRange((byte[])packet.ExtractData(typeof(byte[]), 0, -1)); dataBuff.Add((byte)packet.Checksum); dataBuff.Add((byte)packet.Eop); List<MBusRegister> registers = MBus.ParseReadReply(dataBuff.ToArray()); for (int pos = 0; pos < registers.Count; ++pos) { foreach (GXMBusProperty it in category.Properties) { if (it.Ordinal == pos) { it.SetValue(registers[pos].Value, false, PropertyStates.ValueChangedByDevice); break; } } } }
public override void ImportFromDevice(Control[] addinPages, GXDevice device, IGXMedia media) { media.Open(); GXMBusDevice dev = device as GXMBusDevice; object data; //Handshake ShortFrame sf = new ShortFrame(); sf.AddressField = dev.DeviceAddress; sf.ControlField = (byte)CFieldFunctions.SendSlaveInit; sf.CountChecksum(); data = sf.ToByteArray(); ReceiveParameters<byte[]> recParams = new ReceiveParameters<byte[]>() { Count = 1, Peek = false, WaitTime = device.WaitTime }; lock (media.Synchronous) { media.Send(data, null); if (!media.Receive(recParams)) { throw new Exception("Failed to receive reply from the device in given time."); } if (recParams.Reply.Length < 1 || recParams.Reply[0] != 0xE5) { throw new Exception("Handshake failed."); } bool morePacketsAvailable = false; byte fcb = 1; List<MBusRegister> items = new List<MBusRegister>(); do { sf = new ShortFrame(); sf.AddressField = dev.DeviceAddress; if (fcb == 1) { sf.ControlField = (byte)CFieldFunctions.RequestClass2Data; } else { sf.ControlField = (byte)CFieldFunctions.RequestClass2Data | (byte)CFieldRequest.FrameCountBit; } sf.CountChecksum(); recParams.AllData = true; recParams.Count = 1; recParams.Eop = (byte)0x16; recParams.Reply = null; int cnt = 0; //Some meters can't answer right a way. do { media.Send(sf.ToByteArray(), null); if (++cnt == 6) { throw new Exception("Failed to receive reply from the device in given time."); } } while (!media.Receive(recParams)); while (!VerifyReadReplyCheckSum(recParams.Reply)) { recParams.Count = 0; recParams.Reply = null; bool gotData = media.Receive(recParams); if (!gotData) { break; } } morePacketsAvailable = recParams.Reply.Length > 5 && (recParams.Reply[4] & 0x10) != 0; items.AddRange(ParseReadReply(recParams.Reply)); } while (morePacketsAvailable); GXMBusCategory defaultCategory = null; if ((defaultCategory = (GXMBusCategory)device.Categories.Find("Default")) == null) { defaultCategory = new GXMBusCategory(); defaultCategory.Name = "Default"; device.Categories.Add(defaultCategory); } for (int pos = 0; pos < items.Count; ++pos) { MBusRegister item = items[pos]; GXMBusProperty prop = new GXMBusProperty(); prop.Ordinal = pos; if (item.IsVariableData) { string name = item.MBusType; int len = name.IndexOf('_'); if (len != -1) { name = name.Substring(0, len); } name += " " + item.Function.ToString(); if (item.Tariff != 0) { name += " Tariff " + item.Tariff.ToString(); } prop.Name = name; prop.Unit = item.Unit; prop.DataLength = item.DataLength; item.Mask.Reverse(); prop.InfoMask = item.Mask.ToArray(); prop.Type = item.Type; if (item.MBusType.ToLower().Contains("date") || item.MBusType.ToLower().Contains("timepoint")) { prop.ValueType = typeof(DateTime); } else { prop.ValueType = typeof(string); } } else { prop.Name = item.MBusType; prop.Unit = item.Unit; prop.ValueType = typeof(string); prop.DataLength = 4; } prop.InfoBytes = item.InformationBytes.Reverse().ToArray(); defaultCategory.Properties.Add(prop); } } }