diff --git a/bundles/org.openhab.binding.froniuswattpilot/src/main/java/org/openhab/binding/froniuswattpilot/internal/FroniusWattpilotHandler.java b/bundles/org.openhab.binding.froniuswattpilot/src/main/java/org/openhab/binding/froniuswattpilot/internal/FroniusWattpilotHandler.java index 91531ce056..b250b71e43 100644 --- a/bundles/org.openhab.binding.froniuswattpilot/src/main/java/org/openhab/binding/froniuswattpilot/internal/FroniusWattpilotHandler.java +++ b/bundles/org.openhab.binding.froniuswattpilot/src/main/java/org/openhab/binding/froniuswattpilot/internal/FroniusWattpilotHandler.java @@ -68,6 +68,7 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil private @Nullable FroniusWattpilotConfiguration config; private @Nullable ScheduledFuture reconnectJob; + private volatile boolean isDisposed = false; public FroniusWattpilotHandler(Thing thing, HttpClient httpClient) { super(thing); @@ -200,6 +201,10 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil @Override public void initialize() { + if (isDisposed) { + logger.debug("Skipping initialization because handler is already disposed."); + return; + } config = getConfigAs(FroniusWattpilotConfiguration.class); FroniusWattpilotConfiguration config = this.config; @@ -231,21 +236,37 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil @Override public void dispose() { - try { - client.disconnect().get(3, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - logger.error("Failed to disconnect", e); + isDisposed = true; + synchronized (this) { + var reconnectJob = this.reconnectJob; + if (reconnectJob != null) { + reconnectJob.cancel(false); + this.reconnectJob = null; + } } client.removeListener(this); + try { + client.disconnect().get(3, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.error("Failed to disconnect", e); + } catch (ExecutionException | TimeoutException e) { + logger.error("Failed to disconnect", e); + } } @Override public void connected(WattpilotInfo info) { + if (isDisposed) { + return; + } logger.debug("Connected to Wattpilot."); - var reconnectJob = this.reconnectJob; - if (reconnectJob != null) { - reconnectJob.cancel(false); - this.reconnectJob = null; + synchronized (this) { + var reconnectJob = this.reconnectJob; + if (reconnectJob != null) { + reconnectJob.cancel(false); + this.reconnectJob = null; + } } updateStatus(ThingStatus.ONLINE); updateDeviceProperties(info); @@ -253,17 +274,25 @@ public class FroniusWattpilotHandler extends BaseThingHandler implements Wattpil @Override public void disconnected(String reason, @Nullable Throwable cause) { + if (isDisposed) { + return; + } logger.debug("Disconnected from Wattpilot: {}", reason, cause); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, reason); - var reconnectJob = this.reconnectJob; - if (cause != null && reconnectJob == null) { - logger.debug("Connection to Wattpilot lost, scheduling reconnection job ...", cause); - this.reconnectJob = scheduler.scheduleAtFixedRate(this::initialize, 30L, 60L, TimeUnit.SECONDS); + synchronized (this) { + var reconnectJob = this.reconnectJob; + if (cause != null && reconnectJob == null && !isDisposed) { + logger.debug("Connection to Wattpilot lost, scheduling reconnection job ...", cause); + this.reconnectJob = scheduler.scheduleAtFixedRate(this::initialize, 30L, 60L, TimeUnit.SECONDS); + } } } @Override public void statusChanged(WattpilotStatus status) { + if (isDisposed) { + return; + } updateChannelsControl(status); updateChannelsStatus(status); updateChannelsMetrics(status);