Клиент BACnet не подключается к интерфейсу BACnet с помощью BACnet4j
Я новичок в BACnet и других протоколах автоматизации. Мы собираемся написать один клиент BACnet, который, как ожидается, будет подключаться к интерфейсу BACnet для извлечения объектов, и далее мы собираемся принимать эти объекты на нашем уровне микросервисов. Наша инфраструктура сервера содержит LumInsight Рабочий стол, который будет передавать данные на интерфейс BACnet. Мы ссылаемся на один пример кода, но во время его выполнения я получаю следующую проблему:
> 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();
}
}
2 ответа
Ошибка не требует пояснений: "Адрес уже используется", проверьте, не запущен ли другой клиент и не используется ли порт 47808 (порт по умолчанию).
Пожалуйста, перезапустите программу после завершения всех текущих задач в вашем затмении. Или выполните команду netstat -a, чтобы проверить, какое приложение получает 47808.
Самое простое решение - изменить локальный порт по умолчанию на другой, например, 47809 или что-то выше 1024.
На случай, если у вас все еще есть проблемы. Пожалуйста, прокомментируйте, я создал несколько клиентов, используя BACnet4j.
Теоретически, вы можете использовать тот же (сокет) порт # только если вы установили сокет как "неисключительный" и для "повторного использования" - перед тем, как "привязать" его, но тогда, вероятно, нет смысла пытаться поделиться им, так как только 1 слушатель /"клиент" может получить ответы на / от этого порта UDP.
Всегда рассматривайте возможность отправки ("клиентских") запросов на другой порт; и однозначно прослушивать ("серверные" ответы) стандартный порт № - 47808/0xBAC0, если вы можете (- предполагая, что он активно не используется / вы не можете отказаться от существующего использования порта # вместо этого / ваше новое использование / необходимость).
Для Windows вы можете использовать инструмент "netstat -ao" cmd-line из "Командной строки", чтобы увидеть "PID" (идентификатор процесса) приложения, которое удерживает / использует порт #, и затем вы можете отобразить столбец PID в "Диспетчере задач" Windows, чтобы увидеть, к какому приложению относится PID.