]> git.basschouten.com Git - openhab-addons.git/commitdiff
[homeconnect] Delay update of state options when not accessible (#10784)
authorlolodomo <lg.hc@free.fr>
Sat, 5 Jun 2021 17:30:43 +0000 (19:30 +0200)
committerGitHub <noreply@github.com>
Sat, 5 Jun 2021 17:30:43 +0000 (19:30 +0200)
* [homeconnect] Delay update of state options when not accessible

Fix #10705

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Review comment: parseBoolean

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.binding.homeconnect/src/main/java/org/openhab/binding/homeconnect/internal/client/HomeConnectApiClient.java
bundles/org.openhab.binding.homeconnect/src/main/java/org/openhab/binding/homeconnect/internal/handler/AbstractHomeConnectThingHandler.java
bundles/org.openhab.binding.homeconnect/src/main/java/org/openhab/binding/homeconnect/internal/handler/HomeConnectDryerHandler.java
bundles/org.openhab.binding.homeconnect/src/main/java/org/openhab/binding/homeconnect/internal/handler/HomeConnectWasherDryerHandler.java
bundles/org.openhab.binding.homeconnect/src/main/java/org/openhab/binding/homeconnect/internal/handler/HomeConnectWasherHandler.java

index c72a1cd0d2268dc592698639aa450e4817e0eb99..feba2087b4fa090abea35d82b0c93c40eea42cd5 100644 (file)
@@ -79,7 +79,6 @@ public class HomeConnectApiClient {
     private final Logger logger = LoggerFactory.getLogger(HomeConnectApiClient.class);
     private final HttpClient client;
     private final String apiUrl;
-    private final Map<String, List<AvailableProgramOption>> availableProgramOptionsCache;
     private final Map<String, List<AvailableProgram>> programsCache;
     private final OAuthClientService oAuthClientService;
     private final CircularQueue<ApiRequest> communicationQueue;
@@ -91,7 +90,6 @@ public class HomeConnectApiClient {
         this.oAuthClientService = oAuthClientService;
         this.apiBridgeConfiguration = apiBridgeConfiguration;
 
-        availableProgramOptionsCache = new ConcurrentHashMap<>();
         programsCache = new ConcurrentHashMap<>();
         apiUrl = simulated ? API_SIMULATOR_BASE_URL : API_BASE_URL;
         communicationQueue = new CircularQueue<>(COMMUNICATION_QUEUE_SIZE);
@@ -631,12 +629,6 @@ public class HomeConnectApiClient {
 
     public List<AvailableProgramOption> getProgramOptions(String haId, String programKey)
             throws CommunicationException, AuthorizationException, ApplianceOfflineException {
-        if (availableProgramOptionsCache.containsKey(programKey)) {
-            logger.debug("Returning cached options for '{}'.", programKey);
-            List<AvailableProgramOption> availableProgramOptions = availableProgramOptionsCache.get(programKey);
-            return availableProgramOptions != null ? availableProgramOptions : Collections.emptyList();
-        }
-
         Request request = createRequest(HttpMethod.GET, BASE_PATH + haId + "/programs/available/" + programKey);
         try {
             ContentResponse response = sendRequest(request, apiBridgeConfiguration.getClientId());
@@ -652,11 +644,8 @@ public class HomeConnectApiClient {
                         responseBody == null ? "" : responseBody);
             }
 
-            List<AvailableProgramOption> availableProgramOptions = response.getStatus() == HttpStatus.OK_200
-                    ? mapToAvailableProgramOption(responseBody, haId)
+            return response.getStatus() == HttpStatus.OK_200 ? mapToAvailableProgramOption(responseBody, haId)
                     : List.of();
-            availableProgramOptionsCache.put(programKey, availableProgramOptions);
-            return availableProgramOptions;
         } catch (InterruptedException | TimeoutException | ExecutionException e) {
             logger.warn("Failed to get program options! haId={}, programKey={}, error={}", haId, programKey,
                     e.getMessage());
index 344bf511e3a3119ec7b80ba3369cfc15caf2f228..f042a56d020d677797e704062401e26d08c45dbf 100644 (file)
@@ -21,6 +21,7 @@ import static org.openhab.core.library.unit.Units.*;
 import static org.openhab.core.thing.ThingStatus.*;
 
 import java.time.Duration;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -96,6 +97,7 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
     private @Nullable ScheduledFuture<?> reinitializationFuture2;
     private @Nullable ScheduledFuture<?> reinitializationFuture3;
     private boolean ignoreEventSourceClosedEvent;
+    private @Nullable String programOptionsDelayedUpdate;
 
     private final ConcurrentHashMap<String, EventHandler> eventHandlers;
     private final ConcurrentHashMap<String, ChannelUpdateHandler> channelUpdateHandlers;
@@ -103,6 +105,7 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
     private final ExpiringStateMap expiringStateMap;
     private final AtomicBoolean accessible;
     private final Logger logger = LoggerFactory.getLogger(AbstractHomeConnectThingHandler.class);
+    private final Map<String, List<AvailableProgramOption>> availableProgramOptionsCache;
 
     public AbstractHomeConnectThingHandler(Thing thing,
             HomeConnectDynamicStateDescriptionProvider dynamicStateDescriptionProvider) {
@@ -112,6 +115,7 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
         this.dynamicStateDescriptionProvider = dynamicStateDescriptionProvider;
         expiringStateMap = new ExpiringStateMap(Duration.ofSeconds(CACHE_TTL_SEC));
         accessible = new AtomicBoolean(false);
+        availableProgramOptionsCache = new ConcurrentHashMap<>();
 
         configureEventHandlers(eventHandlers);
         configureChannelUpdateHandlers(channelUpdateHandlers);
@@ -855,15 +859,41 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
         });
     }
 
+    protected EventHandler updateRemoteControlActiveAndProgramOptionsStateEventHandler() {
+        return event -> {
+            defaultBooleanEventHandler(CHANNEL_REMOTE_CONTROL_ACTIVE_STATE).handle(event);
+
+            // update available program options if update was previously delayed and remote control is enabled
+            try {
+                String programKey = programOptionsDelayedUpdate;
+                if (programKey != null && Boolean.parseBoolean(event.getValue())) {
+                    logger.debug("Delayed update of options for program {}", programKey);
+                    updateProgramOptionsStateDescriptions(programKey, null);
+                    programOptionsDelayedUpdate = null;
+                }
+            } catch (CommunicationException | ApplianceOfflineException | AuthorizationException e) {
+                logger.debug("Could not update program options. {}", e.getMessage());
+            }
+        };
+    }
+
     protected EventHandler updateProgramOptionsAndSelectedProgramStateEventHandler() {
         return event -> {
             defaultSelectedProgramStateEventHandler().handle(event);
 
             // update available program options
             try {
+                Optional<HomeConnectApiClient> apiClient = getApiClient();
                 String programKey = event.getValue();
-                if (programKey != null) {
-                    updateProgramOptionsStateDescriptions(programKey, null);
+                if (apiClient.isPresent() && programKey != null) {
+                    // Delay the update if options are not yet cached and remote control is disabled
+                    if (availableProgramOptionsCache.get(programKey) == null
+                            && !apiClient.get().isRemoteControlActive(getThingHaId())) {
+                        logger.debug("Delay update of options for program {}", programKey);
+                        programOptionsDelayedUpdate = programKey;
+                    } else {
+                        updateProgramOptionsStateDescriptions(programKey, null);
+                    }
                 }
             } catch (CommunicationException | ApplianceOfflineException | AuthorizationException e) {
                 logger.debug("Could not update program options. {}", e.getMessage());
@@ -1322,8 +1352,16 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
             throws CommunicationException, AuthorizationException, ApplianceOfflineException {
         Optional<HomeConnectApiClient> apiClient = getApiClient();
         if (apiClient.isPresent()) {
-            List<AvailableProgramOption> availableProgramOptions = apiClient.get().getProgramOptions(getThingHaId(),
-                    programKey);
+            List<AvailableProgramOption> availableProgramOptions;
+            if (availableProgramOptionsCache.containsKey(programKey)) {
+                logger.debug("Returning cached options for '{}'.", programKey);
+                availableProgramOptions = availableProgramOptionsCache.get(programKey);
+                availableProgramOptions = availableProgramOptions != null ? availableProgramOptions
+                        : Collections.emptyList();
+            } else {
+                availableProgramOptions = apiClient.get().getProgramOptions(getThingHaId(), programKey);
+                availableProgramOptionsCache.put(programKey, availableProgramOptions);
+            }
 
             Optional<Channel> channelSpinSpeed = getThingChannel(CHANNEL_WASHER_SPIN_SPEED);
             Optional<Channel> channelTemperature = getThingChannel(CHANNEL_WASHER_TEMPERATURE);
index 2ec9c169715db087cd5933079a062c8017577e43..cab3ad3e3188c9e1a7555535e001f27ff79317ba 100644 (file)
@@ -66,7 +66,7 @@ public class HomeConnectDryerHandler extends AbstractHomeConnectThingHandler {
     protected void configureEventHandlers(Map<String, EventHandler> handlers) {
         // register default event handlers
         handlers.put(EVENT_DOOR_STATE, defaultDoorStateEventHandler());
-        handlers.put(EVENT_REMOTE_CONTROL_ACTIVE, defaultBooleanEventHandler(CHANNEL_REMOTE_CONTROL_ACTIVE_STATE));
+        handlers.put(EVENT_REMOTE_CONTROL_ACTIVE, updateRemoteControlActiveAndProgramOptionsStateEventHandler());
         handlers.put(EVENT_REMOTE_CONTROL_START_ALLOWED,
                 defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
         handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
index 24a0afec9dc4a695fb2d39e9ae4383d3ab284f96..9d1d97d2ac2f83002cedb2877d90ee4862582cd4 100644 (file)
@@ -85,7 +85,7 @@ public class HomeConnectWasherDryerHandler extends AbstractHomeConnectThingHandl
     protected void configureEventHandlers(Map<String, EventHandler> handlers) {
         // register default event handlers
         handlers.put(EVENT_DOOR_STATE, defaultDoorStateEventHandler());
-        handlers.put(EVENT_REMOTE_CONTROL_ACTIVE, defaultBooleanEventHandler(CHANNEL_REMOTE_CONTROL_ACTIVE_STATE));
+        handlers.put(EVENT_REMOTE_CONTROL_ACTIVE, updateRemoteControlActiveAndProgramOptionsStateEventHandler());
         handlers.put(EVENT_REMOTE_CONTROL_START_ALLOWED,
                 defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
         handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
index 3224d4a353e182b7a91687c31f163da4c9c55b3d..964d9bcad75f82863dc2618a5a41f68d890ba1e0 100644 (file)
@@ -85,7 +85,7 @@ public class HomeConnectWasherHandler extends AbstractHomeConnectThingHandler {
     protected void configureEventHandlers(Map<String, EventHandler> handlers) {
         // register default event handlers
         handlers.put(EVENT_DOOR_STATE, defaultDoorStateEventHandler());
-        handlers.put(EVENT_REMOTE_CONTROL_ACTIVE, defaultBooleanEventHandler(CHANNEL_REMOTE_CONTROL_ACTIVE_STATE));
+        handlers.put(EVENT_REMOTE_CONTROL_ACTIVE, updateRemoteControlActiveAndProgramOptionsStateEventHandler());
         handlers.put(EVENT_REMOTE_CONTROL_START_ALLOWED,
                 defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
         handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());