From 7a26af7164007c0954fc3f401ec635335c9d0a5f Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Fri, 14 Apr 2023 23:08:25 +0200 Subject: [PATCH] [windcentrale] Discover windmills when account goes online (#14807) Signed-off-by: Wouter Born --- .../WindcentraleDiscoveryService.java | 17 ++++++++++- .../handler/WindcentraleAccountHandler.java | 26 +++++++++++++++++ .../listener/ThingStatusListener.java | 28 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/listener/ThingStatusListener.java diff --git a/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/WindcentraleDiscoveryService.java b/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/WindcentraleDiscoveryService.java index 0c78e75cd..cd859847c 100644 --- a/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/WindcentraleDiscoveryService.java +++ b/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/WindcentraleDiscoveryService.java @@ -31,8 +31,11 @@ import org.openhab.binding.windcentrale.internal.exception.FailedGettingDataExce import org.openhab.binding.windcentrale.internal.exception.InvalidAccessTokenException; import org.openhab.binding.windcentrale.internal.handler.WindcentraleAccountHandler; import org.openhab.binding.windcentrale.internal.handler.WindcentraleWindmillHandler; +import org.openhab.binding.windcentrale.internal.listener.ThingStatusListener; import org.openhab.core.config.discovery.AbstractDiscoveryService; import org.openhab.core.config.discovery.DiscoveryResultBuilder; +import org.openhab.core.thing.Thing; +import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingUID; import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.ThingHandlerService; @@ -47,7 +50,8 @@ import org.slf4j.LoggerFactory; * @author Wouter Born - Initial contribution */ @NonNullByDefault -public class WindcentraleDiscoveryService extends AbstractDiscoveryService implements ThingHandlerService { +public class WindcentraleDiscoveryService extends AbstractDiscoveryService + implements ThingHandlerService, ThingStatusListener { private final Logger logger = LoggerFactory.getLogger(WindcentraleDiscoveryService.class); private @NonNullByDefault({}) WindcentraleAccountHandler accountHandler; @@ -64,6 +68,7 @@ public class WindcentraleDiscoveryService extends AbstractDiscoveryService imple public void deactivate() { cancelDiscoveryJob(); super.deactivate(); + accountHandler.removeThingStatusListener(this); } @Override @@ -74,12 +79,14 @@ public class WindcentraleDiscoveryService extends AbstractDiscoveryService imple @Override public void setThingHandler(ThingHandler handler) { if (handler instanceof WindcentraleAccountHandler accountHandler) { + accountHandler.addThingStatusListener(this); this.accountHandler = accountHandler; } } @Override protected void startScan() { + logger.debug("Discover windmills (manual discovery)"); cancelDiscoveryJob(); discoveryJob = scheduler.submit(this::discoverWindmills); } @@ -90,6 +97,14 @@ public class WindcentraleDiscoveryService extends AbstractDiscoveryService imple super.stopScan(); } + @Override + public void thingStatusChanged(Thing thing, ThingStatus status) { + if (ThingStatus.ONLINE.equals(status)) { + logger.debug("Discover windmills (account online)"); + discoverWindmills(); + } + } + private void cancelDiscoveryJob() { Future localDiscoveryJob = discoveryJob; if (localDiscoveryJob != null) { diff --git a/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/handler/WindcentraleAccountHandler.java b/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/handler/WindcentraleAccountHandler.java index 19b8da986..d84761fee 100644 --- a/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/handler/WindcentraleAccountHandler.java +++ b/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/handler/WindcentraleAccountHandler.java @@ -17,6 +17,7 @@ import static java.util.function.Predicate.not; import java.util.Collection; import java.util.List; import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -30,6 +31,7 @@ import org.openhab.binding.windcentrale.internal.api.WindcentraleAPI; import org.openhab.binding.windcentrale.internal.config.AccountConfiguration; import org.openhab.binding.windcentrale.internal.exception.FailedGettingDataException; import org.openhab.binding.windcentrale.internal.exception.InvalidAccessTokenException; +import org.openhab.binding.windcentrale.internal.listener.ThingStatusListener; import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; @@ -52,6 +54,7 @@ public class WindcentraleAccountHandler extends BaseBridgeHandler { private final Logger logger = LoggerFactory.getLogger(WindcentraleAccountHandler.class); private final HttpClientFactory httpClientFactory; + private final List thingStatusListeners = new CopyOnWriteArrayList<>(); private @Nullable WindcentraleAPI api; private @Nullable Exception apiException; @@ -80,6 +83,11 @@ public class WindcentraleAccountHandler extends BaseBridgeHandler { this.httpClientFactory = httpClientFactory; } + public void addThingStatusListener(ThingStatusListener listener) { + thingStatusListeners.add(listener); + listener.thingStatusChanged(thing, thing.getStatus()); + } + @Override public void dispose() { Future localFuture = initializeFuture; @@ -135,6 +143,24 @@ public class WindcentraleAccountHandler extends BaseBridgeHandler { public void handleCommand(ChannelUID channelUID, Command command) { } + public void removeThingStatusListener(ThingStatusListener listener) { + thingStatusListeners.remove(listener); + } + + @Override + protected void updateStatus(ThingStatus status, ThingStatusDetail detail, @Nullable String comment) { + ThingStatus oldStatus = thing.getStatus(); + super.updateStatus(status, detail, comment); + ThingStatus newStatus = thing.getStatus(); + + if (!oldStatus.equals(newStatus)) { + logger.debug("Updating listeners with status {}", status); + for (ThingStatusListener listener : thingStatusListeners) { + listener.thingStatusChanged(thing, status); + } + } + } + private void updateThingStatus() { Exception e = apiException; if (e != null) { diff --git a/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/listener/ThingStatusListener.java b/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/listener/ThingStatusListener.java new file mode 100644 index 000000000..69199ccde --- /dev/null +++ b/bundles/org.openhab.binding.windcentrale/src/main/java/org/openhab/binding/windcentrale/internal/listener/ThingStatusListener.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2010-2023 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.windcentrale.internal.listener; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.thing.Thing; +import org.openhab.core.thing.ThingStatus; + +/** + * Interface for listeners of thing status changes. + * + * @author Wouter Born - Initial contribution + */ +@NonNullByDefault +public interface ThingStatusListener { + + public void thingStatusChanged(Thing thing, ThingStatus status); +}