1

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.

Rahul
  • 51
  • 1
  • 4

2 Answers2

0

Issues like this (partial visibility) are often caused my a 'mismatch' of IP parameters. I notice you have hardcoded "192.168.1.255". Is this really the broadcast IP address from the PI's perspective?

Edward
  • 334
  • 1
  • 3
  • Thanks Edward, we have our network 192.168.1.*, but have also tried 255.255.255.255 as broadcast IP. – Rahul Oct 04 '17 at 03:49
  • Just to clarify: You have a BACnet client running on Windows, that can discover other BACnet servers, but cannot see the BACnet server running on the Pi. Correct? So, 1) run Wireshark on the Windows platform, set a capture filter to "udp port 47808" and observe the traffic. 2) Pay _close_ attention to whatever multiple adapters you have on both the Windows platform and the Pi. BACnet on either side may bind() to the 'wrong' 'Network Interface' (eth0, wlan0) etc. etc. and not see some of the traffic - because the traffic may be on a different subnet. – Edward Oct 05 '17 at 17:08
0

Resolved the problem by removing the broadcast and LocalBindAddress.

Rahul
  • 51
  • 1
  • 4