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);
}
}
}
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