[homeconnect] Catch exception when appropriate (#10929)
* [homeconnect] Catch exception when appropriate Fix #10904 Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
parent
fc9864f434
commit
64a418829f
|
@ -548,7 +548,7 @@ public class HomeConnectApiClient {
|
||||||
* Get active program of device.
|
* Get active program of device.
|
||||||
*
|
*
|
||||||
* @param haId home appliance id
|
* @param haId home appliance id
|
||||||
* @return {@link Data} or null if there is no active program
|
* @return {@link Program} or null if there is no active program
|
||||||
* @throws CommunicationException API communication exception
|
* @throws CommunicationException API communication exception
|
||||||
* @throws AuthorizationException oAuth authorization exception
|
* @throws AuthorizationException oAuth authorization exception
|
||||||
* @throws ApplianceOfflineException appliance is not connected to the cloud
|
* @throws ApplianceOfflineException appliance is not connected to the cloud
|
||||||
|
@ -562,7 +562,7 @@ public class HomeConnectApiClient {
|
||||||
* Get selected program of device.
|
* Get selected program of device.
|
||||||
*
|
*
|
||||||
* @param haId home appliance id
|
* @param haId home appliance id
|
||||||
* @return {@link Data} or null if there is no selected program
|
* @return {@link Program} or null if there is no selected program
|
||||||
* @throws CommunicationException API communication exception
|
* @throws CommunicationException API communication exception
|
||||||
* @throws AuthorizationException oAuth authorization exception
|
* @throws AuthorizationException oAuth authorization exception
|
||||||
* @throws ApplianceOfflineException appliance is not connected to the cloud
|
* @throws ApplianceOfflineException appliance is not connected to the cloud
|
||||||
|
@ -627,7 +627,17 @@ public class HomeConnectApiClient {
|
||||||
return getAvailablePrograms(haId, BASE_PATH + haId + "/programs/available");
|
return getAvailablePrograms(haId, BASE_PATH + haId + "/programs/available");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AvailableProgramOption> getProgramOptions(String haId, String programKey)
|
/**
|
||||||
|
* Get the available options of a program.
|
||||||
|
*
|
||||||
|
* @param haId home appliance id
|
||||||
|
* @param programKey program id
|
||||||
|
* @return list of {@link AvailableProgramOption} or null if the program is unsupported by the API
|
||||||
|
* @throws CommunicationException API communication exception
|
||||||
|
* @throws AuthorizationException oAuth authorization exception
|
||||||
|
* @throws ApplianceOfflineException appliance is not connected to the cloud
|
||||||
|
*/
|
||||||
|
public @Nullable List<AvailableProgramOption> getProgramOptions(String haId, String programKey)
|
||||||
throws CommunicationException, AuthorizationException, ApplianceOfflineException {
|
throws CommunicationException, AuthorizationException, ApplianceOfflineException {
|
||||||
Request request = createRequest(HttpMethod.GET, BASE_PATH + haId + "/programs/available/" + programKey);
|
Request request = createRequest(HttpMethod.GET, BASE_PATH + haId + "/programs/available/" + programKey);
|
||||||
try {
|
try {
|
||||||
|
@ -644,8 +654,7 @@ public class HomeConnectApiClient {
|
||||||
responseBody == null ? "" : responseBody);
|
responseBody == null ? "" : responseBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.getStatus() == HttpStatus.OK_200 ? mapToAvailableProgramOption(responseBody, haId)
|
return response.getStatus() == HttpStatus.OK_200 ? mapToAvailableProgramOption(responseBody, haId) : null;
|
||||||
: List.of();
|
|
||||||
} 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());
|
||||||
|
|
|
@ -1026,7 +1026,6 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
|
||||||
updateState(channel.getUID(), UnDefType.UNDEF);
|
updateState(channel.getUID(), UnDefType.UNDEF);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
return OnOffType.from(enabled);
|
return OnOffType.from(enabled);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1458,54 +1457,66 @@ public abstract class AbstractHomeConnectThingHandler extends BaseThingHandler i
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateProgramOptionsStateDescriptions(String programKey)
|
protected void updateProgramOptionsStateDescriptions(String programKey)
|
||||||
throws CommunicationException, AuthorizationException, ApplianceOfflineException {
|
throws AuthorizationException, ApplianceOfflineException {
|
||||||
Optional<HomeConnectApiClient> apiClient = getApiClient();
|
Optional<HomeConnectApiClient> apiClient = getApiClient();
|
||||||
if (apiClient.isPresent()) {
|
if (apiClient.isPresent()) {
|
||||||
|
boolean cacheToSet = false;
|
||||||
List<AvailableProgramOption> availableProgramOptions;
|
List<AvailableProgramOption> availableProgramOptions;
|
||||||
if (availableProgramOptionsCache.containsKey(programKey)) {
|
if (availableProgramOptionsCache.containsKey(programKey)) {
|
||||||
logger.debug("Returning cached options for '{}'.", programKey);
|
logger.debug("Returning cached options for program '{}'.", programKey);
|
||||||
availableProgramOptions = availableProgramOptionsCache.get(programKey);
|
availableProgramOptions = availableProgramOptionsCache.get(programKey);
|
||||||
availableProgramOptions = availableProgramOptions != null ? availableProgramOptions
|
availableProgramOptions = availableProgramOptions != null ? availableProgramOptions
|
||||||
: Collections.emptyList();
|
: Collections.emptyList();
|
||||||
} else {
|
} else {
|
||||||
availableProgramOptions = apiClient.get().getProgramOptions(getThingHaId(), programKey);
|
// Depending on the current program operation state, the APi request could trigger a
|
||||||
availableProgramOptionsCache.put(programKey, availableProgramOptions);
|
// CommunicationException exception due to returned status code 409
|
||||||
|
try {
|
||||||
|
availableProgramOptions = apiClient.get().getProgramOptions(getThingHaId(), programKey);
|
||||||
|
if (availableProgramOptions == null) {
|
||||||
|
// Program is unsupported, save in cache an empty list of options to avoid calling again the API
|
||||||
|
// for this program
|
||||||
|
availableProgramOptions = emptyList();
|
||||||
|
logger.debug("Saving empty options in cache for unsupported program '{}'.", programKey);
|
||||||
|
availableProgramOptionsCache.put(programKey, availableProgramOptions);
|
||||||
|
} else {
|
||||||
|
cacheToSet = true;
|
||||||
|
}
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
availableProgramOptions = emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
Optional<Channel> channelDryingTarget = getThingChannel(CHANNEL_DRYER_DRYING_TARGET);
|
Optional<Channel> channelDryingTarget = getThingChannel(CHANNEL_DRYER_DRYING_TARGET);
|
||||||
|
|
||||||
if (availableProgramOptions.isEmpty()) {
|
Optional<AvailableProgramOption> optionsSpinSpeed = availableProgramOptions.stream()
|
||||||
channelSpinSpeed.ifPresent(
|
.filter(option -> OPTION_WASHER_SPIN_SPEED.equals(option.getKey())).findFirst();
|
||||||
channel -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(), emptyList()));
|
Optional<AvailableProgramOption> optionsTemperature = availableProgramOptions.stream()
|
||||||
channelTemperature.ifPresent(
|
.filter(option -> OPTION_WASHER_TEMPERATURE.equals(option.getKey())).findFirst();
|
||||||
channel -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(), emptyList()));
|
Optional<AvailableProgramOption> optionsDryingTarget = availableProgramOptions.stream()
|
||||||
channelDryingTarget.ifPresent(
|
.filter(option -> OPTION_DRYER_DRYING_TARGET.equals(option.getKey())).findFirst();
|
||||||
channel -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(), emptyList()));
|
|
||||||
|
// Save options in cache only if we got options for all expected channels
|
||||||
|
if (cacheToSet && (!channelSpinSpeed.isPresent() || optionsSpinSpeed.isPresent())
|
||||||
|
&& (!channelTemperature.isPresent() || optionsTemperature.isPresent())
|
||||||
|
&& (!channelDryingTarget.isPresent() || optionsDryingTarget.isPresent())) {
|
||||||
|
logger.debug("Saving options in cache for program '{}'.", programKey);
|
||||||
|
availableProgramOptionsCache.put(programKey, availableProgramOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
availableProgramOptions.forEach(option -> {
|
channelSpinSpeed.ifPresent(channel -> optionsSpinSpeed.ifPresentOrElse(
|
||||||
switch (option.getKey()) {
|
option -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(),
|
||||||
case OPTION_WASHER_SPIN_SPEED: {
|
createStateOptions(option, this::convertWasherSpinSpeed)),
|
||||||
channelSpinSpeed
|
() -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(), emptyList())));
|
||||||
.ifPresent(channel -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(),
|
channelTemperature.ifPresent(channel -> optionsTemperature.ifPresentOrElse(
|
||||||
createStateOptions(option, this::convertWasherSpinSpeed)));
|
option -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(),
|
||||||
break;
|
createStateOptions(option, this::convertWasherTemperature)),
|
||||||
}
|
() -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(), emptyList())));
|
||||||
case OPTION_WASHER_TEMPERATURE: {
|
channelDryingTarget.ifPresent(channel -> optionsDryingTarget.ifPresentOrElse(
|
||||||
channelTemperature
|
option -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(),
|
||||||
.ifPresent(channel -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(),
|
createStateOptions(option, this::mapStringType)),
|
||||||
createStateOptions(option, this::convertWasherTemperature)));
|
() -> dynamicStateDescriptionProvider.setStateOptions(channel.getUID(), emptyList())));
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OPTION_DRYER_DRYING_TARGET: {
|
|
||||||
channelDryingTarget.ifPresent(channel -> dynamicStateDescriptionProvider
|
|
||||||
.setStateOptions(channel.getUID(), createStateOptions(option, this::mapStringType)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ public class HomeConnectHoodHandler extends AbstractHomeConnectThingHandler {
|
||||||
try {
|
try {
|
||||||
List<AvailableProgramOption> availableProgramOptions = apiClient.get()
|
List<AvailableProgramOption> availableProgramOptions = apiClient.get()
|
||||||
.getProgramOptions(getThingHaId(), PROGRAM_HOOD_VENTING);
|
.getProgramOptions(getThingHaId(), PROGRAM_HOOD_VENTING);
|
||||||
if (availableProgramOptions.isEmpty()) {
|
if (availableProgramOptions == null || availableProgramOptions.isEmpty()) {
|
||||||
throw new CommunicationException("Program " + PROGRAM_HOOD_VENTING + " is unsupported");
|
throw new CommunicationException("Program " + PROGRAM_HOOD_VENTING + " is unsupported");
|
||||||
}
|
}
|
||||||
availableProgramOptions.forEach(option -> {
|
availableProgramOptions.forEach(option -> {
|
||||||
|
|
Loading…
Reference in New Issue