[homeconnect] Delay update of state options when not accessible (#10784)
* [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>
This commit is contained in:
parent
3dc7b9ed25
commit
17eb0d5d78
@ -79,7 +79,6 @@ public class HomeConnectApiClient {
|
|||||||
private final Logger logger = LoggerFactory.getLogger(HomeConnectApiClient.class);
|
private final Logger logger = LoggerFactory.getLogger(HomeConnectApiClient.class);
|
||||||
private final HttpClient client;
|
private final HttpClient client;
|
||||||
private final String apiUrl;
|
private final String apiUrl;
|
||||||
private final Map<String, List<AvailableProgramOption>> availableProgramOptionsCache;
|
|
||||||
private final Map<String, List<AvailableProgram>> programsCache;
|
private final Map<String, List<AvailableProgram>> programsCache;
|
||||||
private final OAuthClientService oAuthClientService;
|
private final OAuthClientService oAuthClientService;
|
||||||
private final CircularQueue<ApiRequest> communicationQueue;
|
private final CircularQueue<ApiRequest> communicationQueue;
|
||||||
@ -91,7 +90,6 @@ public class HomeConnectApiClient {
|
|||||||
this.oAuthClientService = oAuthClientService;
|
this.oAuthClientService = oAuthClientService;
|
||||||
this.apiBridgeConfiguration = apiBridgeConfiguration;
|
this.apiBridgeConfiguration = apiBridgeConfiguration;
|
||||||
|
|
||||||
availableProgramOptionsCache = new ConcurrentHashMap<>();
|
|
||||||
programsCache = new ConcurrentHashMap<>();
|
programsCache = new ConcurrentHashMap<>();
|
||||||
apiUrl = simulated ? API_SIMULATOR_BASE_URL : API_BASE_URL;
|
apiUrl = simulated ? API_SIMULATOR_BASE_URL : API_BASE_URL;
|
||||||
communicationQueue = new CircularQueue<>(COMMUNICATION_QUEUE_SIZE);
|
communicationQueue = new CircularQueue<>(COMMUNICATION_QUEUE_SIZE);
|
||||||
@ -631,12 +629,6 @@ public class HomeConnectApiClient {
|
|||||||
|
|
||||||
public List<AvailableProgramOption> getProgramOptions(String haId, String programKey)
|
public List<AvailableProgramOption> getProgramOptions(String haId, String programKey)
|
||||||
throws CommunicationException, AuthorizationException, ApplianceOfflineException {
|
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);
|
Request request = createRequest(HttpMethod.GET, BASE_PATH + haId + "/programs/available/" + programKey);
|
||||||
try {
|
try {
|
||||||
ContentResponse response = sendRequest(request, apiBridgeConfiguration.getClientId());
|
ContentResponse response = sendRequest(request, apiBridgeConfiguration.getClientId());
|
||||||
@ -652,11 +644,8 @@ public class HomeConnectApiClient {
|
|||||||
responseBody == null ? "" : responseBody);
|
responseBody == null ? "" : responseBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AvailableProgramOption> availableProgramOptions = response.getStatus() == HttpStatus.OK_200
|
return response.getStatus() == HttpStatus.OK_200 ? mapToAvailableProgramOption(responseBody, haId)
|
||||||
? mapToAvailableProgramOption(responseBody, haId)
|
|
||||||
: List.of();
|
: List.of();
|
||||||
availableProgramOptionsCache.put(programKey, availableProgramOptions);
|
|
||||||
return availableProgramOptions;
|
|
||||||
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||||
logger.warn("Failed to get program options! haId={}, programKey={}, error={}", haId, programKey,
|
logger.warn("Failed to get program options! haId={}, programKey={}, error={}", haId, programKey,
|
||||||
e.getMessage());
|
e.getMessage());
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import static org.openhab.core.library.unit.Units.*;
|
|||||||
import static org.openhab.core.thing.ThingStatus.*;
|
import static org.openhab.core.thing.ThingStatus.*;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -96,6 +97,7 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
|
|||||||
private @Nullable ScheduledFuture<?> reinitializationFuture2;
|
private @Nullable ScheduledFuture<?> reinitializationFuture2;
|
||||||
private @Nullable ScheduledFuture<?> reinitializationFuture3;
|
private @Nullable ScheduledFuture<?> reinitializationFuture3;
|
||||||
private boolean ignoreEventSourceClosedEvent;
|
private boolean ignoreEventSourceClosedEvent;
|
||||||
|
private @Nullable String programOptionsDelayedUpdate;
|
||||||
|
|
||||||
private final ConcurrentHashMap<String, EventHandler> eventHandlers;
|
private final ConcurrentHashMap<String, EventHandler> eventHandlers;
|
||||||
private final ConcurrentHashMap<String, ChannelUpdateHandler> channelUpdateHandlers;
|
private final ConcurrentHashMap<String, ChannelUpdateHandler> channelUpdateHandlers;
|
||||||
@ -103,6 +105,7 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
|
|||||||
private final ExpiringStateMap expiringStateMap;
|
private final ExpiringStateMap expiringStateMap;
|
||||||
private final AtomicBoolean accessible;
|
private final AtomicBoolean accessible;
|
||||||
private final Logger logger = LoggerFactory.getLogger(AbstractHomeConnectThingHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(AbstractHomeConnectThingHandler.class);
|
||||||
|
private final Map<String, List<AvailableProgramOption>> availableProgramOptionsCache;
|
||||||
|
|
||||||
public AbstractHomeConnectThingHandler(Thing thing,
|
public AbstractHomeConnectThingHandler(Thing thing,
|
||||||
HomeConnectDynamicStateDescriptionProvider dynamicStateDescriptionProvider) {
|
HomeConnectDynamicStateDescriptionProvider dynamicStateDescriptionProvider) {
|
||||||
@ -112,6 +115,7 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
|
|||||||
this.dynamicStateDescriptionProvider = dynamicStateDescriptionProvider;
|
this.dynamicStateDescriptionProvider = dynamicStateDescriptionProvider;
|
||||||
expiringStateMap = new ExpiringStateMap(Duration.ofSeconds(CACHE_TTL_SEC));
|
expiringStateMap = new ExpiringStateMap(Duration.ofSeconds(CACHE_TTL_SEC));
|
||||||
accessible = new AtomicBoolean(false);
|
accessible = new AtomicBoolean(false);
|
||||||
|
availableProgramOptionsCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
configureEventHandlers(eventHandlers);
|
configureEventHandlers(eventHandlers);
|
||||||
configureChannelUpdateHandlers(channelUpdateHandlers);
|
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() {
|
protected EventHandler updateProgramOptionsAndSelectedProgramStateEventHandler() {
|
||||||
return event -> {
|
return event -> {
|
||||||
defaultSelectedProgramStateEventHandler().handle(event);
|
defaultSelectedProgramStateEventHandler().handle(event);
|
||||||
|
|
||||||
// update available program options
|
// update available program options
|
||||||
try {
|
try {
|
||||||
|
Optional<HomeConnectApiClient> apiClient = getApiClient();
|
||||||
String programKey = event.getValue();
|
String programKey = event.getValue();
|
||||||
if (programKey != null) {
|
if (apiClient.isPresent() && programKey != null) {
|
||||||
updateProgramOptionsStateDescriptions(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) {
|
} catch (CommunicationException | ApplianceOfflineException | AuthorizationException e) {
|
||||||
logger.debug("Could not update program options. {}", e.getMessage());
|
logger.debug("Could not update program options. {}", e.getMessage());
|
||||||
@ -1322,8 +1352,16 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
|
|||||||
throws CommunicationException, AuthorizationException, ApplianceOfflineException {
|
throws CommunicationException, AuthorizationException, ApplianceOfflineException {
|
||||||
Optional<HomeConnectApiClient> apiClient = getApiClient();
|
Optional<HomeConnectApiClient> apiClient = getApiClient();
|
||||||
if (apiClient.isPresent()) {
|
if (apiClient.isPresent()) {
|
||||||
List<AvailableProgramOption> availableProgramOptions = apiClient.get().getProgramOptions(getThingHaId(),
|
List<AvailableProgramOption> availableProgramOptions;
|
||||||
programKey);
|
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> channelSpinSpeed = getThingChannel(CHANNEL_WASHER_SPIN_SPEED);
|
||||||
Optional<Channel> channelTemperature = getThingChannel(CHANNEL_WASHER_TEMPERATURE);
|
Optional<Channel> channelTemperature = getThingChannel(CHANNEL_WASHER_TEMPERATURE);
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public class HomeConnectDryerHandler extends AbstractHomeConnectThingHandler {
|
|||||||
protected void configureEventHandlers(Map<String, EventHandler> handlers) {
|
protected void configureEventHandlers(Map<String, EventHandler> handlers) {
|
||||||
// register default event handlers
|
// register default event handlers
|
||||||
handlers.put(EVENT_DOOR_STATE, defaultDoorStateEventHandler());
|
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,
|
handlers.put(EVENT_REMOTE_CONTROL_START_ALLOWED,
|
||||||
defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
|
defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
|
||||||
handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
|
handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
|
||||||
|
|||||||
@ -85,7 +85,7 @@ public class HomeConnectWasherDryerHandler extends AbstractHomeConnectThingHandl
|
|||||||
protected void configureEventHandlers(Map<String, EventHandler> handlers) {
|
protected void configureEventHandlers(Map<String, EventHandler> handlers) {
|
||||||
// register default event handlers
|
// register default event handlers
|
||||||
handlers.put(EVENT_DOOR_STATE, defaultDoorStateEventHandler());
|
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,
|
handlers.put(EVENT_REMOTE_CONTROL_START_ALLOWED,
|
||||||
defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
|
defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
|
||||||
handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
|
handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
|
||||||
|
|||||||
@ -85,7 +85,7 @@ public class HomeConnectWasherHandler extends AbstractHomeConnectThingHandler {
|
|||||||
protected void configureEventHandlers(Map<String, EventHandler> handlers) {
|
protected void configureEventHandlers(Map<String, EventHandler> handlers) {
|
||||||
// register default event handlers
|
// register default event handlers
|
||||||
handlers.put(EVENT_DOOR_STATE, defaultDoorStateEventHandler());
|
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,
|
handlers.put(EVENT_REMOTE_CONTROL_START_ALLOWED,
|
||||||
defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
|
defaultBooleanEventHandler(CHANNEL_REMOTE_START_ALLOWANCE_STATE));
|
||||||
handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
|
handlers.put(EVENT_FINISH_IN_RELATIVE, defaultRemainingProgramTimeEventHandler());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user