diff --git a/bundles/org.openhab.binding.autelis/src/main/java/org/openhab/binding/autelis/internal/handler/AutelisHandler.java b/bundles/org.openhab.binding.autelis/src/main/java/org/openhab/binding/autelis/internal/handler/AutelisHandler.java index 3669f87a5..0766da21f 100644 --- a/bundles/org.openhab.binding.autelis/src/main/java/org/openhab/binding/autelis/internal/handler/AutelisHandler.java +++ b/bundles/org.openhab.binding.autelis/src/main/java/org/openhab/binding/autelis/internal/handler/AutelisHandler.java @@ -18,8 +18,10 @@ import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -190,88 +192,94 @@ public class AutelisHandler extends BaseThingHandler { @Override public void handleCommand(ChannelUID channelUID, Command command) { - logger.debug("handleCommand channel: {} command: {}", channelUID.getId(), command); - if (AutelisBindingConstants.CMD_LIGHTS.equals(channelUID.getId())) { - /* - * lighting command possible values, but we will let anything - * through. alloff, allon, csync, cset, cswim, party, romance, - * caribbean, american, sunset, royalty, blue, green, red, white, - * magenta, hold, recall - */ - getUrl(baseURL + "/lights.cgi?val=" + command.toString(), TIMEOUT_SECONDS); - } else if (AutelisBindingConstants.CMD_REBOOT.equals(channelUID.getId()) && command == OnOffType.ON) { - getUrl(baseURL + "/userreboot.cgi?do=true" + command.toString(), TIMEOUT_SECONDS); - updateState(channelUID, OnOffType.OFF); - } else { - String[] args = channelUID.getId().split("-"); - if (args.length < 2) { - logger.warn("Unown channel {} for command {}", channelUID, command); - return; - } - String type = args[0]; - String name = args[1]; - - if (AutelisBindingConstants.CMD_EQUIPMENT.equals(type)) { - String cmd = "value"; - int value; - if (command == OnOffType.OFF) { - value = 0; - } else if (command == OnOffType.ON) { - value = 1; - } else if (command instanceof DecimalType) { - value = ((DecimalType) command).intValue(); - if (!isJandy() && value >= 3) { - // this is a autelis dim type. not sure what 2 does - cmd = "dim"; - } - } else { - logger.error("command type {} is not supported", command); - return; - } - String response = getUrl(baseURL + "/set.cgi?name=" + name + "&" + cmd + "=" + value, TIMEOUT_SECONDS); - logger.debug("equipment set {} {} {} : result {}", name, cmd, value, response); - } else if (AutelisBindingConstants.CMD_TEMP.equals(type)) { - String value; - if (command == IncreaseDecreaseType.INCREASE) { - value = "up"; - } else if (command == IncreaseDecreaseType.DECREASE) { - value = "down"; - } else if (command == OnOffType.OFF) { - value = "0"; - } else if (command == OnOffType.ON) { - value = "1"; - } else { - value = command.toString(); - } - - String cmd; - // name ending in sp are setpoints, ht are heater? - if (name.endsWith("sp")) { - cmd = "temp"; - } else if (name.endsWith("ht")) { - cmd = "hval"; - } else { - logger.error("Unknown temp type {}", name); - return; - } - String response = getUrl(baseURL + "/set.cgi?wait=1&name=" + name + "&" + cmd + "=" + value, - TIMEOUT_SECONDS); - logger.debug("temp set name:{} cmd:{} value:{} : result {}", name, cmd, value, response); - } else if (AutelisBindingConstants.CMD_CHEM.equals(type)) { - String response = getUrl(baseURL + "/set.cgi?name=" + name + "&chem=" + command.toString(), - TIMEOUT_SECONDS); - logger.debug("chlrp {} {}: result {}", name, command, response); - } else if (AutelisBindingConstants.CMD_PUMPS.equals(type)) { - String response = getUrl(baseURL + "/set.cgi?name=" + name + "&speed=" + command.toString(), - TIMEOUT_SECONDS); - logger.debug("pumps {} {}: result {}", name, command, response); + try { + logger.debug("handleCommand channel: {} command: {}", channelUID.getId(), command); + if (AutelisBindingConstants.CMD_LIGHTS.equals(channelUID.getId())) { + /* + * lighting command possible values, but we will let anything + * through. alloff, allon, csync, cset, cswim, party, romance, + * caribbean, american, sunset, royalty, blue, green, red, white, + * magenta, hold, recall + */ + getUrl(baseURL + "/lights.cgi?val=" + command.toString(), TIMEOUT_SECONDS); + } else if (AutelisBindingConstants.CMD_REBOOT.equals(channelUID.getId()) && command == OnOffType.ON) { + getUrl(baseURL + "/userreboot.cgi?do=true" + command.toString(), TIMEOUT_SECONDS); + updateState(channelUID, OnOffType.OFF); } else { - logger.error("Unsupported type {}", type); + String[] args = channelUID.getId().split("-"); + if (args.length < 2) { + logger.warn("Unown channel {} for command {}", channelUID, command); + return; + } + String type = args[0]; + String name = args[1]; + + if (AutelisBindingConstants.CMD_EQUIPMENT.equals(type)) { + String cmd = "value"; + int value; + if (command == OnOffType.OFF) { + value = 0; + } else if (command == OnOffType.ON) { + value = 1; + } else if (command instanceof DecimalType) { + value = ((DecimalType) command).intValue(); + if (!isJandy() && value >= 3) { + // this is a autelis dim type. not sure what 2 does + cmd = "dim"; + } + } else { + logger.error("command type {} is not supported", command); + return; + } + String response = getUrl(baseURL + "/set.cgi?name=" + name + "&" + cmd + "=" + value, + TIMEOUT_SECONDS); + logger.debug("equipment set {} {} {} : result {}", name, cmd, value, response); + } else if (AutelisBindingConstants.CMD_TEMP.equals(type)) { + String value; + if (command == IncreaseDecreaseType.INCREASE) { + value = "up"; + } else if (command == IncreaseDecreaseType.DECREASE) { + value = "down"; + } else if (command == OnOffType.OFF) { + value = "0"; + } else if (command == OnOffType.ON) { + value = "1"; + } else { + value = command.toString(); + } + + String cmd; + // name ending in sp are setpoints, ht are heater? + if (name.endsWith("sp")) { + cmd = "temp"; + } else if (name.endsWith("ht")) { + cmd = "hval"; + } else { + logger.error("Unknown temp type {}", name); + return; + } + String response = getUrl(baseURL + "/set.cgi?wait=1&name=" + name + "&" + cmd + "=" + value, + TIMEOUT_SECONDS); + logger.debug("temp set name:{} cmd:{} value:{} : result {}", name, cmd, value, response); + } else if (AutelisBindingConstants.CMD_CHEM.equals(type)) { + String response = getUrl(baseURL + "/set.cgi?name=" + name + "&chem=" + command.toString(), + TIMEOUT_SECONDS); + logger.debug("chlrp {} {}: result {}", name, command, response); + } else if (AutelisBindingConstants.CMD_PUMPS.equals(type)) { + String response = getUrl(baseURL + "/set.cgi?name=" + name + "&speed=" + command.toString(), + TIMEOUT_SECONDS); + logger.debug("pumps {} {}: result {}", name, command, response); + } else { + logger.error("Unsupported type {}", type); + } } + clearState(true); + // reset the schedule for our next poll which at that time will reflect if our command was successful or + // not. + initPolling(COMMAND_UPDATE_TIME_SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } - clearState(true); - // reset the schedule for our next poll which at that time will reflect if our command was successful or not. - initPolling(COMMAND_UPDATE_TIME_SECONDS); } /** @@ -349,7 +357,7 @@ public class AutelisHandler extends BaseThingHandler { * Poll the Autelis controller for updates. This will retrieve various xml documents and update channel states from * its contents. */ - private void pollAutelisController() { + private void pollAutelisController() throws InterruptedException { logger.trace("Connecting to {}", baseURL); // clear our cached stated IF it is time. @@ -466,16 +474,13 @@ public class AutelisHandler extends BaseThingHandler { * @param timeout * @return */ - private synchronized String getUrl(String url, int timeout) { + private synchronized String getUrl(String url, int timeout) throws InterruptedException { // throttle commands for a very short time to avoid 'loosing' them long now = System.currentTimeMillis(); long nextReq = lastRequestTime + THROTTLE_TIME_MILLISECONDS; if (nextReq > now) { - try { - logger.trace("Throttling request for {} mills", nextReq - now); - Thread.sleep(nextReq - now); - } catch (InterruptedException ignored) { - } + logger.trace("Throttling request for {} mills", nextReq - now); + Thread.sleep(nextReq - now); } String getURL = url + (url.contains("?") ? "&" : "?") + "timestamp=" + System.currentTimeMillis(); logger.trace("Getting URL {} ", getURL); @@ -490,7 +495,7 @@ public class AutelisHandler extends BaseThingHandler { } lastRequestTime = System.currentTimeMillis(); return response.getContentAsString(); - } catch (Exception e) { + } catch (ExecutionException | TimeoutException e) { logger.debug("Could not make http connection", e); } return null; diff --git a/bundles/org.openhab.binding.automower/src/main/java/org/openhab/binding/automower/internal/rest/api/automowerconnect/AutomowerConnectApi.java b/bundles/org.openhab.binding.automower/src/main/java/org/openhab/binding/automower/internal/rest/api/automowerconnect/AutomowerConnectApi.java index 98522a5d7..64b00eab0 100644 --- a/bundles/org.openhab.binding.automower/src/main/java/org/openhab/binding/automower/internal/rest/api/automowerconnect/AutomowerConnectApi.java +++ b/bundles/org.openhab.binding.automower/src/main/java/org/openhab/binding/automower/internal/rest/api/automowerconnect/AutomowerConnectApi.java @@ -90,7 +90,10 @@ public class AutomowerConnectApi extends HusqvarnaApi { ContentResponse response; try { response = request.send(); - } catch (InterruptedException | TimeoutException | ExecutionException e) { + } catch (TimeoutException | ExecutionException e) { + throw new AutomowerCommunicationException(e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new AutomowerCommunicationException(e); } return response; diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java index cb298b542..8eb2854ac 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java @@ -242,9 +242,13 @@ public class FritzAhaWebInterface { String content = contentResponse.getContentAsString(); logger.debug("GET response complete: {}", content); return content; - } catch (ExecutionException | InterruptedException | TimeoutException e) { + } catch (ExecutionException | TimeoutException e) { logger.debug("response failed: {}", e.getLocalizedMessage(), e); return null; + } catch (InterruptedException e) { + logger.debug("response interrupted: {}", e.getLocalizedMessage(), e); + Thread.currentThread().interrupt(); + return null; } } diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandler.java index a683a1f5d..98e6d856e 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandler.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/BoschSHCHandler.java @@ -56,7 +56,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { class DeviceService { /** * Constructor. - * + * * @param service Service which belongs to the device. * @param affectedChannels Channels which are affected by the state of this service. */ @@ -99,7 +99,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { /** * Returns the unique id of the Bosch device. - * + * * @return Unique id of the Bosch device. */ public @Nullable String getBoschID() { @@ -132,7 +132,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { /** * Handles the refresh command of all registered services. Override it to handle custom commands (e.g. to update * states of services). - * + * * @param channelUID {@link ChannelUID} of the channel to which the command was sent * @param command {@link Command} */ @@ -144,10 +144,15 @@ public abstract class BoschSHCHandler extends BaseThingHandler { if (deviceService.affectedChannels.contains(channelUID.getIdWithoutGroup())) { try { deviceService.service.refreshState(); - } catch (InterruptedException | TimeoutException | ExecutionException | BoschSHCException e) { + } catch (TimeoutException | ExecutionException | BoschSHCException e) { this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, String.format("Error when trying to refresh state from service %s: %s", deviceService.service.getServiceName(), e.getMessage())); + } catch (InterruptedException e) { + this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, + String.format("Interrupted refresh state from service %s: %s", + deviceService.service.getServiceName(), e.getMessage())); + Thread.currentThread().interrupt(); } } } @@ -156,7 +161,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { /** * Processes an update which is received from the bridge. - * + * * @param serviceName Name of service the update came from. * @param stateData Current state of device service. Serialized as JSON. */ @@ -178,7 +183,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { /** * Returns the bridge handler for this thing handler. - * + * * @return Bridge handler for this thing handler. Null if no or an invalid bridge was set in the configuration. * @throws BoschSHCException If bridge for handler is not set or an invalid bridge is set. */ @@ -196,7 +201,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { /** * Query the Bosch Smart Home Controller for the state of the service with the specified name. - * + * * @note Use services instead of directly requesting a state. * * @param stateName Name of the service to query @@ -210,16 +215,21 @@ public abstract class BoschSHCHandler extends BaseThingHandler { try { BoschSHCBridgeHandler bridgeHandler = this.getBridgeHandler(); return bridgeHandler.getState(deviceId, stateName, classOfT); - } catch (InterruptedException | TimeoutException | ExecutionException | BoschSHCException e) { + } catch (TimeoutException | ExecutionException | BoschSHCException e) { this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, String.format("Error when trying to refresh state from service %s: %s", stateName, e.getMessage())); return null; + } catch (InterruptedException e) { + this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, + String.format("Interrupted refresh state from service %s: %s", stateName, e.getMessage())); + Thread.currentThread().interrupt(); + return null; } } /** * Creates and registers a new service for this device. - * + * * @param Type of service. * @param Type of service state. * @param newService Supplier function to create a new instance of the service. @@ -240,7 +250,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { /** * Registers a service for this device. - * + * * @param Type of service. * @param Type of service state. * @param service Service to register. @@ -269,7 +279,7 @@ public abstract class BoschSHCHandler extends BaseThingHandler { /** * Updates the state of a device service. * Sets the status of the device to offline if setting the state fails. - * + * * @param Type of service. * @param Type of service state. * @param service Service to set state for. @@ -279,15 +289,19 @@ public abstract class BoschSHCHandler extends BaseThingHandler { TService service, TState state) { try { service.setState(state); - } catch (InterruptedException | TimeoutException | ExecutionException e) { + } catch (TimeoutException | ExecutionException e) { this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, String.format( "Error when trying to update state for service %s: %s", service.getServiceName(), e.getMessage())); + } catch (InterruptedException e) { + this.updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, String + .format("Interrupted update state for service %s: %s", service.getServiceName(), e.getMessage())); + Thread.currentThread().interrupt(); } } /** * Registers a service of this device. - * + * * @param service Service which belongs to this device * @param affectedChannels Channels which are affected by the state of this * service diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/BoschSHCBridgeHandler.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/BoschSHCBridgeHandler.java index aa1a96e21..c575d7586 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/BoschSHCBridgeHandler.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/BoschSHCBridgeHandler.java @@ -12,8 +12,7 @@ */ package org.openhab.binding.boschshc.internal.devices.bridge; -import static org.eclipse.jetty.http.HttpMethod.GET; -import static org.eclipse.jetty.http.HttpMethod.PUT; +import static org.eclipse.jetty.http.HttpMethod.*; import java.lang.reflect.Type; import java.util.ArrayList; @@ -30,7 +29,10 @@ import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.openhab.binding.boschshc.internal.devices.BoschSHCHandler; -import org.openhab.binding.boschshc.internal.devices.bridge.dto.*; +import org.openhab.binding.boschshc.internal.devices.bridge.dto.Device; +import org.openhab.binding.boschshc.internal.devices.bridge.dto.DeviceStatusUpdate; +import org.openhab.binding.boschshc.internal.devices.bridge.dto.LongPollResult; +import org.openhab.binding.boschshc.internal.devices.bridge.dto.Room; import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException; import org.openhab.binding.boschshc.internal.exceptions.LongPollingFailedException; import org.openhab.binding.boschshc.internal.exceptions.PairingFailedException; @@ -233,12 +235,13 @@ public class BoschSHCBridgeHandler extends BaseBridgeHandler { } catch (InterruptedException e) { this.updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.UNKNOWN.NONE, "@text/offline.interrupted"); + Thread.currentThread().interrupt(); } } /** * Get a list of connected devices from the Smart-Home Controller - * + * * @throws InterruptedException in case bridge is stopped */ private boolean getDevices() throws InterruptedException { @@ -354,7 +357,7 @@ public class BoschSHCBridgeHandler extends BaseBridgeHandler { /** * Get a list of rooms from the Smart-Home controller - * + * * @throws InterruptedException in case bridge is stopped */ private boolean getRooms() throws InterruptedException { @@ -451,11 +454,11 @@ public class BoschSHCBridgeHandler extends BaseBridgeHandler { /** * Sends a state change for a device to the controller - * + * * @param deviceId Id of device to change state for * @param serviceName Name of service of device to change state for * @param state New state data to set for service - * + * * @return Response of request * @throws InterruptedException * @throws ExecutionException diff --git a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/LongPolling.java b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/LongPolling.java index 96a402251..9b7b25449 100644 --- a/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/LongPolling.java +++ b/bundles/org.openhab.binding.boschshc/src/main/java/org/openhab/binding/boschshc/internal/devices/bridge/LongPolling.java @@ -37,7 +37,7 @@ import com.google.gson.Gson; /** * Handles the long polling to the Smart Home Controller. - * + * * @author Christian Oeing - Initial contribution */ @NonNullByDefault @@ -100,7 +100,7 @@ public class LongPolling { /** * Subscribe to events and store the subscription ID needed for long polling. - * + * * @param httpClient Http client to use for sending subscription request * @return Subscription id */ @@ -116,16 +116,21 @@ public class LongPolling { logger.debug("Subscribe: Got subscription ID: {} {}", response.getResult(), response.getJsonrpc()); String subscriptionId = response.getResult(); return subscriptionId; - } catch (TimeoutException | ExecutionException | InterruptedException e) { + } catch (TimeoutException | ExecutionException e) { throw new LongPollingFailedException( String.format("Error on subscribe (Http client: %s): %s", httpClient.toString(), e.getMessage()), e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new LongPollingFailedException( + String.format("Interrupted subscribe (Http client: %s): %s", httpClient.toString(), e.getMessage()), + e); } } /** * Create a new subscription for long polling. - * + * * @param httpClient Http client to send requests to */ private void resubscribe(BoschHttpClient httpClient) { @@ -171,7 +176,7 @@ public class LongPolling { /** * This is the handler for responses of long poll requests. - * + * * @param httpClient HTTP client which received the response * @param subscriptionId Id of subscription the response is for * @param result Complete result of the response