Reputation: 31
I am new to BACnet4J. I am trying to read and write values as a client using BACnet4J 6.0.1 . I have tried 2 test servers. With the test server from https://sourceforge.net/projects/bacnetserver/ I got at least a jerk message from the device with the ID 260002. However, if I now want to read the information from the device, I get a BADTIMEOUT.
With the second TestServer "BACsim" from "PolarSoft® Inc." I get an other error message with the same code already when I initialize the localDevice.
I have read several times that the port must be different if I get this error message but I have to listen on the same port as the server is acting.
But I am not sure if I need a localdevice at all to be able to read or write values.
Eclpise Consol with TestServer 1: TimeOut at: DiscoveryUtils.getExtendedDeviceInformation(localDevice, device);
Device: 1: BACnet4J device 1 Discovered device RemoteDevice(instanceNumber=260002, address=Address [networkNumber=0, macAddress=[c0,a8,38,1,ba,c0]]) InstanceNumber: 260002 Timeout: The device did not respond in time. Error fetching extended device information: null com.serotonin.bacnet4j.exception.BACnetTimeoutException at com.serotonin.bacnet4j.transport.ServiceFutureImpl.result(ServiceFutureImpl.java:75) at com.serotonin.bacnet4j.transport.ServiceFutureImpl.get(ServiceFutureImpl.java:64) at com.serotonin.bacnet4j.util.DiscoveryUtils.getExtendedDeviceInformation(DiscoveryUtils.java:48) at Main$3.iAmReceived(Main.java:499) at com.serotonin.bacnet4j.event.DeviceEventHandler.fireIAmReceived(DeviceEventHandler.java:97) at com.serotonin.bacnet4j.service.unconfirmed.IAmRequest.lambda$handle$0(IAmRequest.java:115) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: com.serotonin.bacnet4j.exception.BACnetTimeoutException at com.serotonin.bacnet4j.transport.DefaultTransport.lambda$expire$1(DefaultTransport.java:957) at com.serotonin.bacnet4j.transport.UnackedMessageContext.useConsumer(UnackedMessageContext.java:162) at com.serotonin.bacnet4j.transport.DefaultTransport.expire(DefaultTransport.java:957) at com.serotonin.bacnet4j.transport.DefaultTransport.run(DefaultTransport.java:525) ... 1 more
Console TestServer 1:
Eclpise Consol with TestServer 2:
Device: 1: BACnet4J device 1 java.net.BindException: Address already in use: Cannot bind at java.base/java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method) at java.base/java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:84) at java.base/java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:135) at java.base/java.net.DatagramSocket.bind(DatagramSocket.java:394) at com.serotonin.bacnet4j.npdu.ip.IpNetwork.initialize(IpNetwork.java:167) at com.serotonin.bacnet4j.transport.DefaultTransport.initialize(DefaultTransport.java:186) at com.serotonin.bacnet4j.LocalDevice.initialize(LocalDevice.java:318) at com.serotonin.bacnet4j.LocalDevice.initialize(LocalDevice.java:311) at Main.test5(Main.java:514) at Main.main(Main.java:56)
This is all my code so far:
IpNetwork network = new IpNetworkBuilder()
.withLocalBindAddress("192.168.XX.X")
.withBroadcast("192.168.XX.XXX", 24)
.withPort(47808)
.withReuseAddress(true)
.build();
DefaultTransport transport = new DefaultTransport(network);
transport.setTimeout(5000);
transport.setSegTimeout(2000);
final LocalDevice localDevice = new LocalDevice(1, transport);
System.out.println("Device: " + localDevice);
localDevice.getEventHandler().addListener(new DeviceEventAdapter() {
@Override
public void iAmReceived(RemoteDevice device) {
System.out.println("Discovered device " + device);
System.out.println("InstanceNumber: " + device.getInstanceNumber());
ObjectIdentifier deviceObjectIdentifier = new ObjectIdentifier(ObjectType.device, device.getInstanceNumber());
ReadPropertyRequest request = new ReadPropertyRequest(deviceObjectIdentifier, PropertyIdentifier.vendorName);
try {
Address deviceAddress = device.getAddress();
ReadPropertyAck ack = localDevice.send(deviceAddress, request).get();
if (ack != null) {
System.out.println("Vendor Name: " + ack.getValue());
} else {
System.out.println("Ack was null. The device might not have responded.");
}
} catch (BACnetTimeoutException e) {
System.out.println("Timeout: The device did not respond in time.");
} catch (BACnetException e) {
e.printStackTrace();
}
// Erweiterte Geräteinformationen abrufen
try {
DiscoveryUtils.getExtendedDeviceInformation(localDevice, device);
System.out.println("Extended device information retrieved successfully.");
} catch (BACnetException e) {
System.out.println("Error fetching extended device information: " + e.getMessage());
e.printStackTrace();
}
}
@Override
public void iHaveReceived(RemoteDevice device, RemoteObject object) {
System.out.println("Value reported " + device + " " + object);
}
});
try {
localDevice.initialize();
} catch (Exception e) {
e.printStackTrace();
}
localDevice.sendGlobalBroadcast(new WhoIsRequest());
List<RemoteDevice> remoteDevices = localDevice.getRemoteDevices();
for (RemoteDevice device : remoteDevices) {
System.out.println("Remote device: " + device);
}
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
localDevice.terminate();
}
I also listened to the port with WireShark to see if there was any data transfer at all:
I am not sure if I have understood the topic correctly and if this is the right approach at all, but unfortunately this is the only thing I could find.
Many thanks in advance!
Upvotes: 0
Views: 41
Reputation: 488
The simple answer (or at least starting point) would be to change the port number (or even change it to use a different NIC/network-card's address instead), as it looks to be clashing with the server's use of the same IPv4 address & port # (- it's hard to know for sure as you've replaced the last two IP address octets/bytes with 'XX.X' & 'XX.XXX' but that's unnecessary/there's no value in doing so as you appear to be using a private network address); hence the "Address already in use: Cannot bind ..." error/exception message.
I.E. You have specified to reuse the address (- reuse-address/'SO_REUSEADDR' socket-option), but not to reuse the port # (- which apparently the reuse-port/'SO_REUSEPORT' socket-option is not as well supported as the reuse-address option).
Upvotes: 0