]> git.basschouten.com Git - openhab-addons.git/commitdiff
[Netatmo] Fix duplicate id on single home (#14765)
authorGaël L'hopital <gael@lhopital.org>
Sun, 9 Apr 2023 20:21:22 +0000 (22:21 +0200)
committerGitHub <noreply@github.com>
Sun, 9 Apr 2023 20:21:22 +0000 (22:21 +0200)
* Solve duplicate id on single home
* Solving "Handler DeviceHandler of thing netatmo:welcome:compte:maison:camera tried accessing its bridge although the handler was already disposed."

Signed-off-by: clinique <gael@lhopital.org>
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/CommonInterface.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/AlarmEventCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/CameraCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/HomeCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/HomeSecurityThingCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/PersonCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/PresenceCapability.java

index 14d6823cc7a27e6e16042e4353027bf8246ac84d..c80eec1df168366819abe9bb115767c5ba8ccb5b 100644 (file)
@@ -121,13 +121,12 @@ public interface CommonInterface {
                 .filter(channel -> ChannelKind.STATE.equals(channel.getKind()) && isLinked(channel.getUID()));
     }
 
-    default Optional<CommonInterface> getHomeHandler() {
-        CommonInterface bridgeHandler = getBridgeHandler();
-        if (bridgeHandler != null) {
-            return bridgeHandler.getCapabilities().get(HomeCapability.class).isPresent() ? Optional.of(bridgeHandler)
-                    : Optional.empty();
+    default Optional<CommonInterface> recurseUpToHomeHandler(@Nullable CommonInterface handler) {
+        if (handler == null) {
+            return Optional.empty();
         }
-        return Optional.empty();
+        return handler.getCapabilities().get(HomeCapability.class).isPresent() ? Optional.of(handler)
+                : recurseUpToHomeHandler(handler.getBridgeHandler());
     }
 
     default List<CommonInterface> getActiveChildren() {
@@ -146,7 +145,8 @@ public interface CommonInterface {
     }
 
     default <T extends RestCapability<?>> Optional<T> getHomeCapability(Class<T> clazz) {
-        return getHomeHandler().map(handler -> handler.getCapabilities().get(clazz)).orElse(Optional.empty());
+        return recurseUpToHomeHandler(this).map(handler -> handler.getCapabilities().get(clazz))
+                .orElse(Optional.empty());
     }
 
     default void setNewData(NAObject newData) {
index 44005b0db225a6db6479438ddc7a886150b88892..83c4a1256714f185651158150e646d1c3b668d78 100644 (file)
@@ -36,7 +36,7 @@ public class AlarmEventCapability extends HomeSecurityThingCapability {
 
     @Override
     public List<NAObject> updateReadings() {
-        return securityCapability.map(cap -> cap.getDeviceLastEvent(handler.getId(), moduleType.apiName))
+        return getSecurityCapability().map(cap -> cap.getDeviceLastEvent(handler.getId(), moduleType.apiName))
                 .map(event -> List.of((NAObject) event)).orElse(List.of());
     }
 }
index 558636e49b9bcea36fb73c781ee6f9c02df0ee1c..fbc6418c87231d8f786258104e39ff7046688c31 100644 (file)
@@ -14,7 +14,6 @@ package org.openhab.binding.netatmo.internal.handler.capability;
 
 import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
 import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*;
-import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.toStringType;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -71,7 +70,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
         String newVpnUrl = newData.getVpnUrl();
         if (newVpnUrl != null && !newVpnUrl.equals(vpnUrl)) {
             // This will also decrease the number of requests emitted toward Netatmo API.
-            localUrl = newData.isLocal() ? securityCapability.map(cap -> cap.ping(newVpnUrl)).orElse(null) : null;
+            localUrl = newData.isLocal() ? getSecurityCapability().map(cap -> cap.ping(newVpnUrl)).orElse(null) : null;
             cameraHelper.setUrls(newVpnUrl, localUrl);
             eventHelper.setUrls(newVpnUrl, localUrl);
         }
@@ -107,14 +106,15 @@ public class CameraCapability extends HomeSecurityThingCapability {
         // The channel should get triggered at last (after super and sub methods), because this allows rules to access
         // the new updated data from the other channels.
         final String eventType = event.getEventType().name();
-        handler.getHomeHandler().ifPresent(homeHandler -> homeHandler.triggerChannel(CHANNEL_HOME_EVENT, eventType));
+        handler.recurseUpToHomeHandler(handler)
+                .ifPresent(homeHandler -> homeHandler.triggerChannel(CHANNEL_HOME_EVENT, eventType));
         handler.triggerChannel(CHANNEL_HOME_EVENT, eventType);
     }
 
     @Override
     public void handleCommand(String channelName, Command command) {
         if (command instanceof OnOffType && CHANNEL_MONITORING.equals(channelName)) {
-            securityCapability.ifPresent(cap -> cap.changeStatus(localUrl, OnOffType.ON.equals(command)));
+            getSecurityCapability().ifPresent(cap -> cap.changeStatus(localUrl, OnOffType.ON.equals(command)));
         } else {
             super.handleCommand(channelName, command);
         }
@@ -123,7 +123,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
     @Override
     protected void beforeNewData() {
         super.beforeNewData();
-        securityCapability.ifPresent(cap -> {
+        getSecurityCapability().ifPresent(cap -> {
             NAObjectMap<HomeDataPerson> persons = cap.getPersons();
             descriptionProvider.setStateOptions(personChannelUID, persons.values().stream()
                     .map(p -> new StateOption(p.getId(), p.getName())).collect(Collectors.toList()));
@@ -133,7 +133,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
     @Override
     public List<NAObject> updateReadings() {
         List<NAObject> result = new ArrayList<>();
-        securityCapability.ifPresent(cap -> {
+        getSecurityCapability().ifPresent(cap -> {
             HomeEvent event = cap.getDeviceLastEvent(handler.getId(), moduleType.apiName);
             if (event != null) {
                 result.add(event);
index 79891fc43564e7331dc0c8c690548b4c62e67634..537c1dfa6fd07e76839a316ab91d397723db59bf 100644 (file)
@@ -47,7 +47,7 @@ public class HomeCapability extends RestCapability<HomeApi> {
     private final Logger logger = LoggerFactory.getLogger(HomeCapability.class);
     private final Set<FeatureArea> featureAreas = new HashSet<>();
     private final NetatmoDescriptionProvider descriptionProvider;
-    private Set<String> homeIds = Set.of();
+    private final Set<String> homeIds = new HashSet<>();
 
     public HomeCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
         super(handler, HomeApi.class);
@@ -58,7 +58,19 @@ public class HomeCapability extends RestCapability<HomeApi> {
     public void initialize() {
         super.initialize();
         HomeConfiguration config = handler.getConfiguration().as(HomeConfiguration.class);
-        homeIds = Set.of(config.getId(), config.energyId, config.securityId);
+        homeIds.add(config.getId());
+        if (!config.energyId.isBlank()) {
+            homeIds.add(config.energyId);
+        }
+        if (!config.securityId.isBlank()) {
+            homeIds.add(config.securityId);
+        }
+    }
+
+    @Override
+    public void dispose() {
+        homeIds.clear();
+        super.dispose();
     }
 
     @Override
index 84e5ae2c0a5d2b5ed8301089b07ca55b8c3dd85f..07296dcf68fe4f60a1ada3039c5eb85a4a5ea2ef 100644 (file)
@@ -36,8 +36,8 @@ public class HomeSecurityThingCapability extends Capability {
     protected final EventChannelHelper eventHelper;
 
     private Optional<WebhookServlet> webhook = Optional.empty();
-    protected Optional<SecurityCapability> securityCapability = Optional.empty();
-    protected Optional<HomeCapability> homeCapability = Optional.empty();
+    private Optional<SecurityCapability> securityCapability = Optional.empty();
+    private Optional<HomeCapability> homeCapability = Optional.empty();
 
     public HomeSecurityThingCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider,
             List<ChannelHelper> channelHelpers) {
@@ -49,16 +49,23 @@ public class HomeSecurityThingCapability extends Capability {
         eventHelper.setModuleType(moduleType);
     }
 
-    @Override
-    public void initialize() {
-        super.initialize();
-        securityCapability = handler.getHomeCapability(SecurityCapability.class);
-        homeCapability = handler.getHomeCapability(HomeCapability.class);
-        ApiBridgeHandler accountHandler = handler.getAccountHandler();
-        if (accountHandler != null) {
-            webhook = accountHandler.getWebHookServlet();
-            webhook.ifPresent(servlet -> servlet.registerDataListener(handler.getId(), this));
+    protected Optional<SecurityCapability> getSecurityCapability() {
+        if (securityCapability.isEmpty()) {
+            securityCapability = handler.getHomeCapability(SecurityCapability.class);
+            ApiBridgeHandler accountHandler = handler.getAccountHandler();
+            if (accountHandler != null) {
+                webhook = accountHandler.getWebHookServlet();
+                webhook.ifPresent(servlet -> servlet.registerDataListener(handler.getId(), this));
+            }
+        }
+        return securityCapability;
+    }
+
+    protected Optional<HomeCapability> getHomeCapability() {
+        if (homeCapability.isEmpty()) {
+            homeCapability = handler.getHomeCapability(HomeCapability.class);
         }
+        return homeCapability;
     }
 
     @Override
index 596fad6a565f63086beef78f81f6404223d028d7..ce73a84cafd0fc1488976021df5d984f5810aa2b 100644 (file)
@@ -56,7 +56,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
     @Override
     protected void beforeNewData() {
         super.beforeNewData();
-        securityCapability.ifPresent(cap -> {
+        getSecurityCapability().ifPresent(cap -> {
             Stream<HomeDataModule> cameras = cap.getModules().values().stream()
                     .filter(module -> module.getType() == ModuleType.WELCOME);
             descriptionProvider.setStateOptions(cameraChannelUID,
@@ -67,7 +67,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
     @Override
     public void handleCommand(String channelName, Command command) {
         if ((command instanceof OnOffType) && CHANNEL_PERSON_AT_HOME.equals(channelName)) {
-            securityCapability.ifPresent(cap -> cap.setPersonAway(handler.getId(), OnOffType.OFF.equals(command)));
+            getSecurityCapability().ifPresent(cap -> cap.setPersonAway(handler.getId(), OnOffType.OFF.equals(command)));
         }
     }
 
@@ -88,7 +88,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
     @Override
     public List<NAObject> updateReadings() {
         List<NAObject> result = new ArrayList<>();
-        securityCapability.ifPresent(cap -> {
+        getSecurityCapability().ifPresent(cap -> {
             HomeEvent event = cap.getLastPersonEvent(handler.getId());
             if (event != null) {
                 result.add(event);
index 05ee7e892b463b6aad47e5e34e909cf8b62a2236..d615d7dc9f589080754951f0ce13995e91e85e20 100644 (file)
@@ -62,6 +62,6 @@ public class PresenceCapability extends CameraCapability {
     }
 
     private void changeFloodlightMode(FloodLightMode mode) {
-        securityCapability.ifPresent(cap -> cap.changeFloodlightMode(handler.getId(), mode));
+        getSecurityCapability().ifPresent(cap -> cap.changeFloodlightMode(handler.getId(), mode));
     }
 }