BACnet client not connecting to BACnet interface using BACnet4j

1.9k views Asked by At

I am a newbie to BACnet and other automation protocols.We are going to write one BACnet client which is expected to connect to BACnet interface to fetch the objects and further we are going to ingest these objects in our microservices layer.Our server infrastructure contains LumInsight Desktop which will push the data onto BACnet interface. We are referring one example code but while running it I am getting below issue:

> inside main....com.serotonin.bacnet4j.transport.DefaultTransport@7b7221a0
inside main....3996: BACnet device
Exception in thread "main" java.net.BindException: Address already in use: Cannot bind
    at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
    at java.net.DualStackPlainDatagramSocketImpl.bind0(Unknown Source)
    at java.net.AbstractPlainDatagramSocketImpl.bind(Unknown Source)
    at java.net.DatagramSocket.bind(Unknown Source)
    at java.net.DatagramSocket.<init>(Unknown Source)
    at com.serotonin.bacnet4j.npdu.ip.IpNetwork.initialize(IpNetwork.java:215)
    at com.serotonin.bacnet4j.transport.DefaultTransport.initialize(DefaultTransport.java:183)
    at com.serotonin.bacnet4j.LocalDevice.initialize(LocalDevice.java:228)
    at com.bacnet.Main.main(Main.java:110)


    package com.bacnet;

    import com.serotonin.bacnet4j.LocalDevice;
    import com.serotonin.bacnet4j.RemoteDevice;
    import com.serotonin.bacnet4j.ServiceFuture;
    import com.serotonin.bacnet4j.event.DeviceEventAdapter;
    import com.serotonin.bacnet4j.exception.BACnetException;
    import com.serotonin.bacnet4j.exception.ErrorAPDUException;
    import com.serotonin.bacnet4j.npdu.ip.IpNetwork;
    import com.serotonin.bacnet4j.service.acknowledgement.ReadPropertyAck;
    import com.serotonin.bacnet4j.service.acknowledgement.ReadPropertyMultipleAck;
    import com.serotonin.bacnet4j.service.confirmed.*;
    import com.serotonin.bacnet4j.service.unconfirmed.WhoIsRequest;
    import com.serotonin.bacnet4j.transport.DefaultTransport;
    import com.serotonin.bacnet4j.transport.Transport;
    import com.serotonin.bacnet4j.type.constructed.ReadAccessResult;
    import com.serotonin.bacnet4j.type.constructed.ReadAccessSpecification;
    import com.serotonin.bacnet4j.type.constructed.SequenceOf;
    import com.serotonin.bacnet4j.type.enumerated.ObjectType;
    import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
    import com.serotonin.bacnet4j.type.enumerated.Segmentation;
    import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
    import com.serotonin.bacnet4j.type.primitive.Real;
    import com.serotonin.bacnet4j.util.DiscoveryUtils;
    import com.serotonin.bacnet4j.RemoteObject;

    import java.util.ArrayList;
    import java.util.List;

    public class Main {
        public static void main(String[] args) throws Exception {

            IpNetwork network = new IpNetwork("10.44.55.5", IpNetwork.DEFAULT_PORT);

            Transport transport = new DefaultTransport(network);
            System.out.println("inside main...." + transport);
            transport.setTimeout(500);
            transport.setSegTimeout(150);
            final LocalDevice localDevice = new LocalDevice(3996, transport);
            System.out.println("inside main...." + localDevice);
            localDevice.getEventHandler().addListener(new DeviceEventAdapter() {
                @Override
                public void iAmReceived(RemoteDevice device) {
                    System.out.println("inside I am received...");
                    System.out.println("Discovered device " + device);
                    localDevice.addRemoteDevice(device);

                    final RemoteDevice remoteDevice = localDevice
                            .getRemoteDevice(device.getAddress());

                    remoteDevice
                            .setSegmentationSupported(Segmentation.segmentedBoth);
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                try {
                                    DiscoveryUtils.getExtendedDeviceInformation(
                                            localDevice, remoteDevice);
                                } catch (BACnetException e) {
                                    e.printStackTrace();
                                }
                                System.out.println(remoteDevice.getName() + " "
                                        + remoteDevice.getVendorName() + " "
                                        + remoteDevice.getModelName() + " "
                                        + remoteDevice.getAddress() + " "
                                        + remoteDevice.getProtocolRevision() + " "
                                        + remoteDevice.getProtocolVersion());

                                ReadPropertyAck ack = localDevice.send(
                                        remoteDevice,
                                        new ReadPropertyRequest(remoteDevice
                                                .getObjectIdentifier(),
                                                PropertyIdentifier.objectList))
                                        .get();
                                SequenceOf<ObjectIdentifier> value = ack.getValue();

                                for (ObjectIdentifier id : value) {

                                    List<ReadAccessSpecification> specs = new ArrayList<ReadAccessSpecification>();
                                    specs.add(new ReadAccessSpecification(id,
                                            PropertyIdentifier.presentValue));
                                    specs.add(new ReadAccessSpecification(id,
                                            PropertyIdentifier.units));
                                    specs.add(new ReadAccessSpecification(id,
                                            PropertyIdentifier.objectName));
                                    specs.add(new ReadAccessSpecification(id,
                                            PropertyIdentifier.description));
                                    specs.add(new ReadAccessSpecification(id,
                                            PropertyIdentifier.objectType));
                                    ReadPropertyMultipleRequest multipleRequest = new ReadPropertyMultipleRequest(
                                            new SequenceOf<ReadAccessSpecification>(
                                                    specs));

                                    ReadPropertyMultipleAck send = localDevice
                                            .send(remoteDevice, multipleRequest)
                                            .get();
                                    SequenceOf<ReadAccessResult> readAccessResults = send
                                            .getListOfReadAccessResults();

                                    System.out.print(id.getInstanceNumber() + " "
                                            + id.getObjectType() + ", ");
                                    for (ReadAccessResult result : readAccessResults) {
                                        for (ReadAccessResult.Result r : result
                                                .getListOfResults()) {
                                            System.out.print(r.getReadResult()
                                                    + ", ");
                                        }
                                    }
                                    System.out.println();
                                }

                                ObjectIdentifier mode = new ObjectIdentifier(
                                        ObjectType.analogValue, 11);

                                ServiceFuture send = localDevice.send(remoteDevice,
                                        new WritePropertyRequest(mode,
                                                PropertyIdentifier.presentValue,
                                                null, new Real(2), null));
                                System.out.println(send.getClass());
                                System.out.println(send.get().getClass());

                            } catch (ErrorAPDUException e) {
                                System.out.println("Could not read value "
                                        + e.getApdu().getError() + " " + e);
                            } catch (BACnetException e) {
                                e.printStackTrace();
                            }

                        }
                    }).start();
                }

                @Override
                public void iHaveReceived(RemoteDevice device, RemoteObject object) {
                    System.out.println("Value reported " + device + " " + object);
                }
            });

            localDevice.initialize();
            localDevice.sendGlobalBroadcast(new WhoIsRequest());

            List<RemoteDevice> remoteDevices = localDevice.getRemoteDevices();
            for (RemoteDevice device : remoteDevices) {
                System.out.println("Remote dev " + device);
            }

            System.in.read();
            localDevice.terminate();
        }

    }
3

There are 3 answers

0
Rahul On

The error is self explanatory "Address already in use", please check if have any other client running and using the port 47808 (Default Port).

0
Ashwani Garg On

Please rerun you program after terminating all currently running task in your eclipse. Or do netstat -a to check which application is acquiring 47808.

Simplest solution change your local default port to other like 47809 or anything above 1024.

In case you still have any issue. Please comment back, I have created several clients using BACnet4j.

0
DennisVM-D2i On

In theory, you can only use the same (socket) port # if you've set the socket to be 'non-exclusive' and for 'reuse' - before you 'bind' to it, but then there's probably no point trying to share it as only 1 listener/"client" might receive the responses upon/from that UDP port.

Always consider sending ("client") requests on another port anyway; and uniquely listen (to "server" responses) upon the standard port # - 47808/0xBAC0, if you can (- assuming it's not actively been used already / you can't relinquish the existing use of the port # in place of this/your new usage/need).

For Windows, you can use the 'netstat -ao' cmd-line tool from the 'Command Prompt', to see the "PID" (Process ID) of the application that is holding/using the port #, and then you can display the PID column within the Windows 'Task Manager' to see which app the PID maps to.