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;
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);
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());
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());
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;
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;
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) {
this.dynamicStateDescriptionProvider = dynamicStateDescriptionProvider;
expiringStateMap = new ExpiringStateMap(Duration.ofSeconds(CACHE_TTL_SEC));
accessible = new AtomicBoolean(false);
+ availableProgramOptionsCache = new ConcurrentHashMap<>();
configureEventHandlers(eventHandlers);
configureChannelUpdateHandlers(channelUpdateHandlers);
});
}
+ 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());
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);