/// <summary> /// Try to find client and server address from the meter. /// </summary> private void DiscoverMeters(object sender, GXAsyncWork work, object[] parameters) { GXDLMSClient cl = new GXDLMSClient(true, 16, 1, Authentication.None, null, (InterfaceType)Settings.Default.PlcInterface); byte[] data = cl.Plc.DiscoverRequest(); ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Count = 8, WaitTime = 10000, }; DateTime start = DateTime.Now; GXByteBuffer rd = new GXByteBuffer(); lock (media.Synchronous) { if (data != null) { media.Send(data, null); start = DateTime.Now; } GXReplyData reply = new GXReplyData(); rd = new GXByteBuffer(p.Reply); try { while (!work.IsCanceled) { p.Reply = null; //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = cl.GetFrameSize(rd); } if (!media.IsOpen) { throw new InvalidOperationException("Media is closed."); } if (!media.Receive(p)) { //It's OK if there is no reply. Read again continue; } rd.Position = 0; rd.Set(p.Reply); if (cl.GetData(rd, reply)) { List <GXDLMSPlcMeterInfo> list = cl.Plc.ParseDiscover(reply.Data, (UInt16)reply.TargetAddress, (UInt16)reply.SourceAddress); BeginInvoke(new AppendMeterEventHandler(OnAppendMeter), list); } } } catch (Exception) { //Throw original exception. throw; } } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, GXReplyData reply) { if (data == null && !reply.IsStreaming()) { return; } GXReplyData notify = new GXReplyData(); reply.Error = 0; object eop = (byte)0x7E; //In network connection terminator is not used. if (Client.InterfaceType == InterfaceType.WRAPPER && Media is GXNet) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = eop, WaitTime = WaitTime, }; if (eop == null) { p.Count = 8; } else { p.Count = 5; } GXByteBuffer rd = new GXByteBuffer(); lock (Media.Synchronous) { while (!succeeded && pos != 3) { if (!reply.IsStreaming()) { WriteTrace("TX:\t" + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true)); Media.Send(data, null); } succeeded = Media.Receive(p); if (!succeeded) { if (++pos >= RetryCount) { throw new Exception("Failed to receive reply from the device in given time."); } //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } //Try to read again... System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); } } rd = new GXByteBuffer(p.Reply); try { pos = 0; //Loop until whole COSEM packet is received. while (!Client.GetData(rd, reply, notify)) { p.Reply = null; if (notify.Data.Data != null) { //Handle notify. if (!notify.IsMoreData) { //Show received push message as XML. string xml; GXDLMSTranslator t = new GXDLMSTranslator(TranslatorOutputType.SimpleXml); t.DataToXml(notify.Data, out xml); Console.WriteLine(xml); notify.Clear(); } continue; } else if (p.Eop == null) { p.Count = Client.GetFrameSize(rd); } while (!Media.Receive(p)) { if (++pos >= RetryCount) { throw new Exception("Failed to receive reply from the device in given time."); } //If echo. if (rd == null || rd.Size == data.Length) { Media.Send(data, null); } //Try to read again... System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); } rd.Set(p.Reply); } } catch (Exception ex) { WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd); throw ex; } } WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd); if (reply.Error != 0) { if (reply.Error == (short)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, reply); } } }