BacNet/IP Broadcast от ОС Raspberry не работает
Ниже приведен код, который отлично работает в системе Windows 10 и может обнаруживать удаленные устройства в сети. В Linux мы создаем jar-код из кода и запускаем его с помощью 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();
}
}
В Linux мы не можем обнаружить устройства, работающие в ОС Windows, но приложение, работающее в Windows, может обнаружить Linux BacNet localDevice. Код такой же, но все еще не может обнаружить устройства BacNet в Linux.
Пожалуйста, помогите нам найти решение.
2 ответа
Решение
Решил проблему, удалив широковещательную рассылку и LocalBindAddress.
Подобные проблемы (частичная видимость) часто являются причиной "несоответствия" параметров IP. Я заметил, что вы жестко закодировали "192.168.1.255". Это действительно широковещательный IP-адрес с точки зрения PI?