*/
package org.openhab.binding.knx.internal.config;
-import java.math.BigDecimal;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
@NonNullByDefault
public class BridgeConfiguration {
private int autoReconnectPeriod = 0;
- private BigDecimal readingPause = BigDecimal.valueOf(0);
- private BigDecimal readRetriesLimit = BigDecimal.valueOf(0);
- private BigDecimal responseTimeout = BigDecimal.valueOf(0);
+ private int readingPause = 0;
+ private int readRetriesLimit = 0;
+ private int responseTimeout = 0;
public int getAutoReconnectPeriod() {
return autoReconnectPeriod;
}
- public BigDecimal getReadingPause() {
+ public int getReadingPause() {
return readingPause;
}
- public BigDecimal getReadRetriesLimit() {
+ public int getReadRetriesLimit() {
return readRetriesLimit;
}
- public BigDecimal getResponseTimeout() {
+ public int getResponseTimeout() {
return responseTimeout;
}
*/
package org.openhab.binding.knx.internal.config;
-import java.math.BigDecimal;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
private String address = "";
private boolean fetch = false;
- private BigDecimal pingInterval = BigDecimal.valueOf(0);
- private BigDecimal readInterval = BigDecimal.valueOf(0);
+ private int pingInterval = 0;
+ private int readInterval = 0;
public String getAddress() {
return address;
return fetch;
}
- public BigDecimal getPingInterval() {
+ public int getPingInterval() {
return pingInterval;
}
- public BigDecimal getReadInterval() {
+ public int getReadInterval() {
return readInterval;
}
}
*/
package org.openhab.binding.knx.internal.config;
-import java.math.BigDecimal;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
private boolean useNAT = false;
private String type = "";
private String ipAddress = "";
- private BigDecimal portNumber = BigDecimal.valueOf(0);
+ private int portNumber = 0;
private String localIp = "";
private String localSourceAddr = "";
private String routerBackboneKey = "";
return ipAddress;
}
- public BigDecimal getPortNumber() {
+ public int getPortNumber() {
return portNumber;
}
if (!filledDescription && config.getFetch()) {
Future<?> descriptionJob = this.descriptionJob;
if (descriptionJob == null || descriptionJob.isCancelled()) {
- long initialDelay = Math.round(config.getPingInterval().longValue() * random.nextFloat());
+ long initialDelay = Math.round(config.getPingInterval() * random.nextFloat());
this.descriptionJob = getBackgroundScheduler().schedule(() -> {
filledDescription = describeDevice(address);
}, initialDelay, TimeUnit.SECONDS);
updateStatus(ThingStatus.UNKNOWN);
address = new IndividualAddress(config.getAddress());
- long pingInterval = config.getPingInterval().longValue();
+ long pingInterval = config.getPingInterval();
long initialPingDelay = Math.round(INITIAL_PING_DELAY * random.nextFloat());
ScheduledFuture<?> pollingJob = this.pollingJob;
public void initialize() {
super.initialize();
DeviceConfig config = getConfigAs(DeviceConfig.class);
- readInterval = config.getReadInterval().intValue();
+ readInterval = config.getReadInterval();
initializeGroupAddresses();
}
// initialisation would take too long and show a warning during binding startup
// KNX secure is adding serious delay
updateStatus(ThingStatus.UNKNOWN);
- initJob = scheduler.submit(() -> {
- initializeLater();
- });
+ initJob = scheduler.submit(this::initializeLater);
}
public void initializeLater() {
}
String localSource = config.getLocalSourceAddr();
String connectionTypeString = config.getType();
- int port = config.getPortNumber().intValue();
+ int port = config.getPortNumber();
String ip = config.getIpAddress();
InetSocketAddress localEndPoint = null;
boolean useNAT = false;
updateStatus(ThingStatus.UNKNOWN);
client = new IPClient(ipConnectionType, ip, localSource, port, localEndPoint, useNAT, autoReconnectPeriod,
secureRouting.backboneGroupKey, secureRouting.latencyToleranceMs, secureTunnel.devKey,
- secureTunnel.user, secureTunnel.userKey, thing.getUID(), config.getResponseTimeout().intValue(),
- config.getReadingPause().intValue(), config.getReadRetriesLimit().intValue(), getScheduler(), this);
+ secureTunnel.user, secureTunnel.userKey, thing.getUID(), config.getResponseTimeout(),
+ config.getReadingPause(), config.getReadRetriesLimit(), getScheduler(), this);
final var tmpClient = client;
if (tmpClient != null) {
*/
package org.openhab.binding.knx.internal.handler;
+import java.util.concurrent.Future;
+
import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.openhab.binding.knx.internal.client.AbstractKNXClient;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.knx.internal.client.KNXClient;
+import org.openhab.binding.knx.internal.client.NoOpClient;
import org.openhab.binding.knx.internal.client.SerialClient;
import org.openhab.binding.knx.internal.config.SerialBridgeConfiguration;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ThingStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* The {@link IPBridgeThingHandler} is responsible for handling commands, which are
@NonNullByDefault
public class SerialBridgeThingHandler extends KNXBridgeBaseThingHandler {
- private final SerialClient client;
+ private @Nullable SerialClient client = null;
+ private @Nullable Future<?> initJob = null;
+
+ private final Logger logger = LoggerFactory.getLogger(SerialBridgeThingHandler.class);
public SerialBridgeThingHandler(Bridge bridge) {
super(bridge);
- SerialBridgeConfiguration config = getConfigAs(SerialBridgeConfiguration.class);
- client = new SerialClient(config.getAutoReconnectPeriod(), thing.getUID(),
- config.getResponseTimeout().intValue(), config.getReadingPause().intValue(),
- config.getReadRetriesLimit().intValue(), getScheduler(), config.getSerialPort(), config.useCemi(),
- this);
}
@Override
public void initialize() {
+ // create new instance using current configuration settings;
+ // when a parameter change is done from UI, dispose() and initialize() are called
+ SerialBridgeConfiguration config = getConfigAs(SerialBridgeConfiguration.class);
+ client = new SerialClient(config.getAutoReconnectPeriod(), thing.getUID(), config.getResponseTimeout(),
+ config.getReadingPause(), config.getReadRetriesLimit(), getScheduler(), config.getSerialPort(),
+ config.useCemi(), this);
+
updateStatus(ThingStatus.UNKNOWN);
- client.initialize();
+ // delay actual initialization, allow for longer runtime of actual initialization
+ initJob = scheduler.submit(this::initializeLater);
+ }
+
+ public void initializeLater() {
+ final var tmpClient = client;
+ if (tmpClient != null) {
+ tmpClient.initialize();
+ }
}
@Override
public void dispose() {
- client.dispose();
+ final var tmpInitJob = initJob;
+ if (tmpInitJob != null) {
+ if (!tmpInitJob.isDone()) {
+ logger.trace("Bridge {}, shutdown during init, trying to cancel", thing.getUID());
+ tmpInitJob.cancel(true);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ logger.trace("Bridge {}, cancellation interrupted", thing.getUID());
+ }
+ }
+ initJob = null;
+ }
+
+ final var tmpClient = client;
+ if (tmpClient != null) {
+ tmpClient.dispose();
+ client = null;
+ }
super.dispose();
}
@Override
- protected AbstractKNXClient getClient() {
- return client;
+ protected KNXClient getClient() {
+ KNXClient ret = client;
+ if (ret == null) {
+ return new NoOpClient();
+ }
+ return ret;
}
}