I'm trying to build app for get meter serial number using Android DLMS package. not able to get data from the meter.
My code is:
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import gurux.common.ReceiveParameters;
import gurux.common.enums.TraceLevel;
import gurux.common.GXCommon;
import gurux.dlms.GXDLMSClient;
import gurux.dlms.GXReplyData;
import gurux.dlms.enums.Authentication;
import gurux.dlms.enums.InterfaceType;
import gurux.dlms.objects.GXDLMSData;
import gurux.io.BaudRate;
import gurux.io.Parity;
import gurux.io.StopBits;
import gurux.serial.GXPort;
import gurux.serial.GXSerial;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MeterReader";
private TextView tvMeterValue;
private TextView tvStatus;
private Button btnRead;
private GXSerial media;
private GXDLMSClient client;
private final Handler uiHandler = new Handler(Looper.getMainLooper());
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final Object serialLock = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvMeterValue = findViewById(R.id.tvMeterValue);
tvStatus = findViewById(R.id.tvStatus);
btnRead = findViewById(R.id.btnRead);
client = new GXDLMSClient(
true,
32,
1,
Authentication.LOW,
"lnt1",
InterfaceType.HDLC
);
media = new GXSerial(this);
media.setTrace(TraceLevel.VERBOSE);
btnRead.setOnClickListener(v -> startRead());
}
private void startRead() {
btnRead.setEnabled(false);
tvMeterValue.setText("---");
logStatus("Scanning for ports...");
executor.execute(() -> {
try {
synchronized (serialLock) {
if (!media.isOpen()) {
GXPort[] ports = media.getPorts();
if (ports == null || ports.length == 0) {
throw new Exception("No optical probe detected. Please reconnect it.");
}
media.setPort(ports[0]);
media.setBaudRate(BaudRate.BAUD_RATE_9600);
media.setDataBits(8);
media.setParity(Parity.NONE);
media.setStopBits(StopBits.ONE);
logStatus("Opening: " + ports[0].getPort());
media.open();
try {
media.setRtsEnable(true);
media.setDtrEnable(true);
} catch (Exception e) {
Log.w(TAG, "Failed to set control lines", e);
}
Thread.sleep(1000);
}
logStatus("Connecting to meter...");
initializeConnection();
logStatus("Reading Serial Number...");
GXDLMSData snObj = new GXDLMSData("0.0.96.1.0.255");
GXReplyData reply = new GXReplyData();
// Read attribute 2 (Value)
readDLMS(client.read(snObj, 2), reply);
final String serialNum = String.valueOf(reply.getValue());
uiHandler.post(() -> {
tvMeterValue.setText(serialNum);
btnRead.setEnabled(true);
Toast.makeText(this, "Read Successful!", Toast.LENGTH_SHORT).show();
});
logStatus("Success");
}
} catch (Exception e) {
logStatus("Error: " + e.getMessage());
Log.e(TAG, "Communication error", e);
uiHandler.post(() -> btnRead.setEnabled(true));
try {
synchronized (serialLock) {
media.close();
}
} catch (Exception ignored) {
}
}
});
}
private void initializeConnection() throws Exception {
GXReplyData reply = new GXReplyData();
// 1. SNRM
logStatus("Sending SNRM...");
readDLMS(client.snrmRequest(), reply);
// 2. AARQ
logStatus("Sending AARQ...");
readDLMS(client.aarqRequest(), reply);
}
private void readDLMS(byte[] data, GXReplyData reply) throws Exception {
readDLMS(new byte[][]{data}, reply);
}
private void readDLMS(byte[][] data, GXReplyData reply) throws Exception {
if (data == null) return;
for (byte[] frame : data) {
if (frame == null || frame.length == 0) continue;
media.resetSynchronousBuffer();
Log.d(TAG, "TX: " + GXCommon.bytesToHex(frame));
media.send(frame);
reply.clear();
long startTime = System.currentTimeMillis();
while (!reply.isComplete()) {
if (System.currentTimeMillis() - startTime > 10000) {
throw new Exception("Meter response timeout");
}
ReceiveParameters<byte[]> rp = new ReceiveParameters<>(byte[].class);
rp.setWaitTime(5000);
rp.setEop((byte) 0x7E); // HDLC frame end character
rp.setCount(1); // Wait for at least 1 byte
if (media.receive(rp)) {
byte[] response = rp.getReply();
if (response != null && response.length > 0) {
Log.d(TAG, "RX: " + GXCommon.bytesToHex(response));
client.getData(response, reply);
}
}
}
if (reply.getError() != 0) {
throw new Exception("DLMS Error Code: " + reply.getError());
}
}
}
private void logStatus(String msg) {
uiHandler.post(() -> tvStatus.setText(msg));
Log.d(TAG, msg);
}
@Override
protected void onDestroy() {
super.onDestroy();
executor.shutdownNow();
if (media != null) {
try {
synchronized (serialLock) {
media.close();
}
} catch (Exception ignored) {
}
}
}
}
Catlog Output: cat log: …
Catlog Output:
cat log:
2026-01-31 11:47:15.755 4298-4298 MirrorManager com.example.meterreader W this model don't Support
2026-01-31 11:47:15.759 4298-4298 MiuiMultiWindowUtils com.example.meterreader D freeform resolution args raw data:{ "wide_default":{ "freeform_args": { "vertical_portrait":{"aspect_ratio":0.626, "original_ratio":0.5643,"original_scale":0.74,"top_margin":0.168,"left_margin":0.484}, "horizontal_portrait":{"aspect_ratio":0.626, "original_ratio":0.5643,"original_scale":0.74,"top_margin":0.1222,"left_margin":0.59745}, "vertical_landscape":{"aspect_ratio":1.6, "original_ratio":1,"original_scale":0.604,"top_margin":0.2596,"left_margin":0.2624}, "horizontal_landscape":{"aspect_ratio":1.6, "original_ratio":1,"original_scale":0.604,"top_margin":0.213,"left_margin":0.3758} }, "mini_freeform_args":{ "vertical_portrait":{"original_ratio":0.147}, "horizontal_portrait":{"original_ratio":0.147}, "vertical_landscape":{"original_ratio":0.165}, "horizontal_landscape":{"original_ratio":0.165} } }, "narrow_default": { "freeform_args": { "vertical_portrait":{"aspect_ratio":0.626, "original_ratio":1,"original_scale":0.74,"top_margin":0.0753,"left_margin":-1}, "horizontal_portrait":{"aspect_ratio":0.626, "original_ratio":1,"original_scale":0.5756,"top_margin":-1,"left_margin":0.0753}, "vertical_landscape":{"aspect_ratio":1.6, "original_ratio":0.6847,"original_scale":0.587,"top_margin":0.0753,"left_margin":-1}, "horizontal_landscape":{"aspect_ratio":1.6, "original_ratio":0.6847,"original_scale":0.587,"top_margin":-1,"left_margin":0.0753} }, "mini_freeform_args":{ "vertical_portrait":{"original_ratio":0.26}, "horizontal_portrait":{"original_ratio":0.26}, "vertical_landscape":{"original_ratio":0.293}, "horizontal_landscape":{"original_ratio":0.293} } }, "regular_default": { "freeform_args": { "vertical_portrait":{"aspect_ratio":0.625, "original_ratio":1,"original_scale":0.7,"top_margin":0.109,"left_margin":-1}, "horizontal_portrait":{"aspect_ratio":0.6667, "original_ratio":1,"original_scale":0.6102,"top_margin":-1,"left_margin":0.026}, "vertical_landscape":{"aspect_ratio":1.6, "original_ratio":1,"original_scale":0.4244,"top_margin":0.109,"left_margin":-1}, "horizontal_landscape":{"aspect_ratio":1.6, "original_ratio":1,"original_scale":0.4244,"top_margin":-1,"left_margin":0.026} }, "mini_freeform_args":{ "vertical_portrait":{"original_ratio":0.25}, "horizontal_portrait":{"original_ratio":0.25}, "vertical_landscape":{"original_ratio":0.25}, "horizontal_landscape":{"original_ratio":0.25} } }, "pad_default": { "freeform_args": { "vertical_portrait":{"aspect_ratio":0.5625, "original_ratio":0.375,"original_scale":0.835,"top_margin":0.049,"left_margin":0.2775}, "horizontal_portrait":{"aspect_ratio":0.5625, "original_ratio":0.375,"original_scale":0.835,"top_margin":-1,"left_margin":0.6525}, "vertical_landscape":{"aspect_ratio":-1, "original_ratio":1,"original_scale":0.468,"top_margin":0.049,"left_margin":-1}, "horizontal_landscape":{"aspect_ratio":-1, "original_ratio":1,"original_scale":0.468,"top_margin":-1,"left_margin":0.4976} }, "mini_freeform_args":{ "vertical_portrait":{"original_ratio":0.144}, "horizontal_portrait":{"original_ratio":0.144}, "vertical_landscape":{"original_ratio":0.2}, "horizontal_landscape":{"original_ratio":0.2} } }}
2026-01-31 11:47:15.763 4298-4298 MiuiMultiWindowUtils com.example.meterreader D initFreeFormResolutionArgs failed, device is breeze
2026-01-31 11:47:15.764 4298-4298 IS_CTS_MODE com.example.meterreader D false
2026-01-31 11:47:15.764 4298-4298 MULTI_WIND...CH_ENABLED com.example.meterreader D false
2026-01-31 11:47:15.771 4298-4309 ple.meterreader com.example.meterreader W userfaultfd: MOVE ioctl seems unsupported: Connection timed out
2026-01-31 11:47:15.799 4298-4298 MeterReader com.example.meterreader D Scanning for ports...
2026-01-31 11:47:15.803 4298-4407 Compatibil...geReporter com.example.meterreader D Compat change id reported: 160794467; UID 10393; state: ENABLED
2026-01-31 11:47:15.848 4298-4407 UsbDeviceConnectionJNI com.example.meterreader D close
2026-01-31 11:47:15.850 4298-4407 MeterReader com.example.meterreader D Opening: /dev/bus/usb/002/003
2026-01-31 11:47:16.866 4298-4407 MeterReader com.example.meterreader D Connecting to meter...
2026-01-31 11:47:16.871 4298-4407 MeterReader com.example.meterreader D Sending SNRM...
2026-01-31 11:47:16.890 4298-4407 MeterReader com.example.meterreader D TX: 7E A0 07 03 41 93 5A 64 7E
2026-01-31 11:47:26.896 4298-4407 MeterReader com.example.meterreader D Error: Meter response timeout
2026-01-31 11:47:26.899 4298-4407 MeterReader com.example.meterreader E Communication error (Explain with AI) java.lang.Exception: Meter response timeout
at com.example.meterreader.MainActivity.readDLMS(MainActivity.java:178)
at com.example.meterreader.MainActivity.readDLMS(MainActivity.java:156)
at com.example.meterreader.MainActivity.initializeConnection(MainActivity.java:148)
at com.example.meterreader.MainActivity.lambda$startRead$3$com-example-meterreader-MainActivity(MainActivity.java:112)
at com.example.meterreader.MainActivity$$ExternalSyntheticLambda4.run(D8$$SyntheticClass:0)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1154)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:652)
at java.lang.Thread.run(Thread.java:1563)
2026-01-31 11:47:26.899 4298-4407 UsbDeviceConnectionJNI com.example.meterreader D close
Anyone, please check my code…
Anyone, please check my code and suggest what is wrong with it.
Hi, Please, don't add the…
Hi,
Please, don't add the code from the example; it doesn't help at all. One of your settings is different from what the meter expects.
Try to connect with GXDLMSDirector and check the correct settings.
BR,
Mikko