Skip to main content
Home
for DLMS smart meters

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Push Listener Example How It Works + Tcp Stream Issue

Push listener example how it works + tcp stream issue

By Bela, 16 May, 2025
Forums
Gurux DLMS for Java

Hi there,

I have tried the GuruxDlmsPushListenerExample.
When my smart meter mock send a message to the client I have got this on the console:
 

Starting to listen Push messages in port 4060
Press X to close and Enter to send a Push message.
Client Connected.
<- 00 01 00 01 00 66 00 38 0F 00 00 00 07 0C 07 E9 04 0E 01 0C 0D 36 FF 00 00 80 02 03 09 0F 34 34 30 32 31 32 32 33 30 30 39 39 35 34 36 09 0C 07 E9 04 0E 01 0C 0D 36 FF 00 00 80 06 00 00 00 80
Size of the push object list is different than values.
Client Disconnected.

I do not understand why, because the translator can translate it:


<WRAPPER len="64" >
<TargetAddress Value="1" />
<SourceAddress Value="102" />
<PDU>
<DataNotification>
 <LongInvokeIdAndPriority Value="7" />
 <!--2025-04-14 12:13:54-->
 <DateTime Value="07E9040E010C0D36FF000080" />
 <NotificationBody>
   <DataValue>
     <Structure Qty="3" >
       <!--440212230099546-->
       <OctetString Value="343430323132323330303939353436" />
       <!--2025-04-14 12:13:54-->
       <OctetString Value="07E9040E010C0D36FF000080" />
       <UInt32 Value="128" />
     </Structure>
   </DataValue>
 </NotificationBody>
</DataNotification>
</PDU>
</WRAPPER>

What setup is missing from the listener? Or what is wrong with that?
I have created my own listener, and after reading the inputstream I could use the GXDLMSTranslator to get the xml above. So the working mechanism is different from mine. I just wanted to try the "official" listener, because mine is not seem stable if there are a lot of incoming message especially its missed when a new client connected. For example I have sent 2 messages from one meter, but one of them was missed. Or sent 1-1 messages from 2 meters, and one of the meter connection was missed.

my mocked smart meter push message sender:
 

try (Socket socket = new Socket("localhost", 4060)) {
OutputStream outputStream = socket.getOutputStream();
for(String m : list) {
System.out.println(m);

byte[] byteMessage = hexStringToByteArray(m);
outputStream.write(byteMessage);
outputStream.flush();
Thread.sleep(0);
}

System.out.println("Message sent to port 4060");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}

my listener:


           while (true) {
               Socket clientSocket = serverSocket.accept();
               logger.info("New client connected: " + clientSocket.getRemoteSocketAddress());
               // Handle each client in a separate thread
               clientHandlerPool.execute(() -> handleClient(clientSocket));
           }


handleClient:


   private static void handleClient(Socket clientSocket) {
       try (InputStream inputStream = clientSocket.getInputStream();
            ByteArrayOutputStream rawLog = new ByteArrayOutputStream()) {
           byte[] chunk = new byte[1024];
           int bytesRead;
           MessageType type = null;
           ByteArrayOutputStream messageCollector = new ByteArrayOutputStream();
           boolean collecting = false;
           while ((bytesRead = inputStream.read(chunk)) != -1) {
               rawLog.write(chunk, 0, bytesRead);
               MessageType singleType = MessageType.fromHex(chunk, 8, 5);
               MessageType multiType = MessageType.fromHex(chunk, 16, 5);
               if(singleType != MessageType.UNKNOWN) {
                   type = singleType;
                   logger.info("Message type: " + type + " - Received raw message: " + bytesToHex(rawLog.toByteArray()));
                   rawLog.reset();
                   handleMessage(clientSocket.getLocalSocketAddress(), type, chunk); //here use the GXDLMSTranslator
                   continue;
               }
               if (multiType != MessageType.UNKNOWN) {
                   if(messageCollector.size() > 0) {
                       logger.info("Message type: " + type + " - Received raw message: " + bytesToHex(rawLog.toByteArray()));
                       rawLog.reset();
                       handleMessage(clientSocket.getLocalSocketAddress(), type, messageCollector.toByteArray()); //here use the GXDLMSTranslator
                       messageCollector.reset();
                   }
                   collecting = true;
                   type = multiType;
                   byte[] result = removeRange(chunk, 8, 16);
                   messageCollector.write(result, 0, bytesRead);
                   continue;
               }
               if (collecting) {
                   byte[] result = removeRange(chunk, 0, 16);
                   messageCollector.write(result, 0, bytesRead);
                   if (isLastBlock(translateBytesToXml(chunk))) {
                       logger.info("Message type: " + type + " - Received raw message: " + bytesToHex(rawLog.toByteArray()));
                       rawLog.reset();
                       handleMessage(clientSocket.getLocalSocketAddress(), type, messageCollector.toByteArray()); //here use the GXDLMSTranslator
                       messageCollector.reset();
                       collecting = false;
                   }
               }
           }
           if (messageCollector.size() > 0) {
               logger.info("Message type: " + type + " - Received raw message: " + bytesToHex(rawLog.toByteArray()));
               rawLog.reset();
               handleMessage(clientSocket.getLocalSocketAddress(), type, messageCollector.toByteArray()); //here use the GXDLMSTranslator
               messageCollector.reset();
           }
       } catch (Exception e) {
           logger.error("Error handling client: " + e);
       } finally {
           try {
               clientSocket.close();
           } catch (IOException e) {
               logger.error("Error closing socket: " + e);
           }
       }
   }
Profile picture for user Kurumi

Kurumi

4 weeks 1 day ago

Hi, The Push object list or…

Hi,

The Push object list or the push setup differs from the data received in the push message.

You need to add the same COSEM objects to the push object list that you are sending.

https://gurux.fi/Gurux.DLMS.Objects.GXDLMSPushSetup

BR,
Mikko

  • Log in or register to post comments
  • Create new account
  • Reset your password

Hire Us!

Latest Releases

  • Tue, 06/17/2025 - 13:03
    Gurux.DLMS.Python 1.0.182
  • Wed, 06/04/2025 - 13:35
    gurux.dlms.c 9.0.2506.0401
  • Fri, 05/30/2025 - 08:30
    gurux.dlms.c 9.0.2505.3001
  • Tue, 05/27/2025 - 08:10
    Gurux.Serial.Android 2.0.12
  • Mon, 05/26/2025 - 08:39
    gurux.dlms.c 9.0.2505.2601

New forum topics

  • Day profile action item add error (String is not recognized as valid DateTime value)
  • Create gateway protocol in c
  • Error while reading event log object
  • GXDLMS Simulator – AssociationLogicalName Not Listed
  • Failed to read meter through raspberry pi 5 and probe
More
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin