Raspberry OS的BacNet / IP广播无法正常工作

时间:2017-10-03 10:13:31

标签: java linux iot bacnet bacnet4j

请查找以下代码,该代码在Windows 10系统上正常运行,并且能够通过网络发现远程设备。在Linux上,我们使用 java -jar test.jar

从代码中创建一个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();
    }
}

在Linux上,我们无法发现在Windows操作系统上运行的设备,但在Windows上运行的应用程序能够发现Linux BacNet localDevice。代码相同,但仍然无法在Linux上发现BacNet设备。

请帮助我们找到解决方案。

2 个答案:

答案 0 :(得分:0)

这样的问题(部分可见性)经常导致我的不匹配&#39; IP参数。我注意到你有硬编码&#34; 192.168.1.255&#34;。这真的是PI的广播IP地址吗?

答案 1 :(得分:0)

通过删除广播和LocalBindAddress解决了该问题。