javalinuxiotbacnetbacnet4j

BacNet/IP Broadcast from Raspberry OS not working


Please find below code, which runs fine on Windows 10 System and is able to discover remote devices across the network. On Linux we are creating a jar out of the code and running it using java -jar test.jar

package main;

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

import com.serotonin.bacnet4j.LocalDevice;
import com.serotonin.bacnet4j.RemoteDevice;
import com.serotonin.bacnet4j.RemoteObject;
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.npdu.ip.IpNetworkBuilder;
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;

public class test {

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

        IpNetwork network = new IpNetworkBuilder().broadcastIp("192.168.1.255").localBindAddress("192.168.1.164").port(47808).build();
        Transport transport = new DefaultTransport(network);
        transport.setTimeout(500000);
        transport.setSegTimeout(15000);
        LocalDevice localDevice = new LocalDevice(21312, transport);             

        localDevice.getEventHandler().addListener(new DeviceEventAdapter() {
            @Override
            public void iAmReceived(RemoteDevice device) {
                System.out.println("Discovered device " + device);
                System.out.println("device Address" + device.getAddress().getMacAddress().getDescription());
                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());

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

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

On Linux we are unable to discover the devices that are running on Windows OS but the application that is running on Windows is able to discover Linux BacNet localDevice. Code is same but still unable to discover BacNet devices on Linux.

Please help us find any solution.


Solution

  • Resolved the problem by removing the broadcast and LocalBindAddress.