]> git.basschouten.com Git - openhab-addons.git/commitdiff
[opensprinkler] Make http connection more resilient (#14998)
authorwzbfyb <57131473+wzbfyb@users.noreply.github.com>
Thu, 14 Dec 2023 20:55:12 +0000 (21:55 +0100)
committerGitHub <noreply@github.com>
Thu, 14 Dec 2023 20:55:12 +0000 (21:55 +0100)
Signed-off-by: Bernhard Kreuz <bernhard@kreuz.wien>
Signed-off-by: wzbfyb <57131473+wzbfyb@users.noreply.github.com>
Co-authored-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
Co-authored-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.binding.opensprinkler/README.md
bundles/org.openhab.binding.opensprinkler/src/main/java/org/openhab/binding/opensprinkler/internal/OpenSprinklerBindingConstants.java
bundles/org.openhab.binding.opensprinkler/src/main/java/org/openhab/binding/opensprinkler/internal/api/OpenSprinklerHttpApiV100.java
bundles/org.openhab.binding.opensprinkler/src/main/java/org/openhab/binding/opensprinkler/internal/config/OpenSprinklerHttpInterfaceConfig.java
bundles/org.openhab.binding.opensprinkler/src/main/resources/OH-INF/i18n/opensprinkler.properties
bundles/org.openhab.binding.opensprinkler/src/main/resources/OH-INF/thing/thing-types.xml

index 03ca4c97af2442b5f412cd08d2b7ed417ca7ce99..613463b32b77807399f72a7b3acbf90f86cf5fc6 100644 (file)
@@ -28,6 +28,8 @@ Due to this method used, it is very slow at finding devices and can saturate net
 - port: Port the OpenSprinkler device is listening on. Usually 80.
 - password: Admin password of the API. Factory default is: opendoor
 - refresh: Number of seconds in between refreshing the Thing state with the API.
+- timeout: (optional) Number of seconds to wait for a timeout when calling the OpenSprinkler HTTP API.
+- retry: (optional) Number of retries on connection timeouts.
 - basicUsername: (optional) Only needed when the OpenSprinkler device is behind a basic auth enforcing reverse proxy.
 - basicPassword: (optional) Only needed when the OpenSprinkler device is behind a basic auth enforcing reverse proxy.
 
index d16fab814533e59d1546fc11b4212333c21e47e5..193330eb16d24fdfded44240cadf8e34416fb871 100644 (file)
@@ -48,6 +48,8 @@ public class OpenSprinklerBindingConstants {
     public static final String JSON_OPTION_STATION_COUNT = "nstations";
     public static final String JSON_OPTION_RESULT = "result";
     public static final int DEFAULT_REFRESH_RATE = 60;
+    public static final int DEFAULT_TIMEOUT = 5;
+    public static final int DEFFAULT_RETRIES = 3;
     public static final int DISCOVERY_THREAD_POOL_SIZE = 15;
     public static final boolean DISCOVERY_DEFAULT_AUTO_DISCOVER = false;
     public static final int DISCOVERY_DEFAULT_TIMEOUT_RATE = 500;
index b282523f702ce4ac8dd10c18b85fa5dd636f1267..afba8e3674f45444acbcc7871ce4d673a810c3af 100644 (file)
  */
 package org.openhab.binding.opensprinkler.internal.api;
 
-import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.*;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.CMD_DISABLE_MANUAL_MODE;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.CMD_ENABLE_MANUAL_MODE;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.CMD_OPTIONS_INFO;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.CMD_PASSWORD;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.CMD_STATION_INFO;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.CMD_STATUS_INFO;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.DEFAULT_STATION_COUNT;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.HTTPS_REQUEST_URL_PREFIX;
+import static org.openhab.binding.opensprinkler.internal.OpenSprinklerBindingConstants.HTTP_REQUEST_URL_PREFIX;
 
 import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
@@ -379,22 +387,34 @@ class OpenSprinklerHttpApiV100 implements OpenSprinklerApi {
             } else {
                 location = url;
             }
-            ContentResponse response;
-            try {
-                response = withGeneralProperties(httpClient.newRequest(location)).timeout(5, TimeUnit.SECONDS)
-                        .method(HttpMethod.GET).send();
-            } catch (InterruptedException | TimeoutException | ExecutionException e) {
-                throw new CommunicationApiException("Request to OpenSprinkler device failed: " + e.getMessage());
+            ContentResponse response = null;
+            int retriesLeft = Math.max(1, config.retry);
+            boolean connectionSuccess = false;
+            while (connectionSuccess == false && retriesLeft > 0) {
+                retriesLeft--;
+                try {
+                    response = withGeneralProperties(httpClient.newRequest(location))
+                            .timeout(config.timeout, TimeUnit.SECONDS).method(HttpMethod.GET).send();
+                    connectionSuccess = true;
+                } catch (InterruptedException | TimeoutException | ExecutionException e) {
+                    logger.warn("Request to OpenSprinkler device failed (retries left: {}): {}", retriesLeft,
+                            e.getMessage());
+                }
             }
-            if (response.getStatus() != HTTP_OK_CODE) {
+            if (connectionSuccess == false) {
+                throw new CommunicationApiException("Request to OpenSprinkler device failed");
+            }
+            if (response != null && response.getStatus() != HTTP_OK_CODE) {
                 throw new CommunicationApiException(
                         "Error sending HTTP GET request to " + url + ". Got response code: " + response.getStatus());
+            } else if (response != null) {
+                String content = response.getContentAsString();
+                if ("{\"result\":2}".equals(content)) {
+                    throw new UnauthorizedApiException("Unauthorized, check your password is correct");
+                }
+                return content;
             }
-            String content = response.getContentAsString();
-            if ("{\"result\":2}".equals(content)) {
-                throw new UnauthorizedApiException("Unauthorized, check your password is correct");
-            }
-            return content;
+            return "";
         }
 
         private Request withGeneralProperties(Request request) {
index 3ba46b388b128d49a3923289c82583ee8dfaaa85..52811650ea28fbb3f45af123409f31b17df4bab2 100644 (file)
@@ -43,6 +43,17 @@ public class OpenSprinklerHttpInterfaceConfig {
      * Number of seconds in between refreshes from the OpenSprinkler device.
      */
     public int refresh = 60;
+
+    /**
+     * Number of seconds for connection timeouts
+     */
+    public int timeout = 5;
+
+    /**
+     * Number of retries in case of connection timeouts
+     */
+    public int retry = 3;
+
     /**
      * The basic auth username to use when the OpenSprinkler device is behind a reverse proxy with basic auth enabled.
      */
index 7bb8cf3eea8b95694694a82591d986878d642e48..7840ee4047d586f6e8bc2b967dea49b4119ba1db 100644 (file)
@@ -26,6 +26,10 @@ thing-type.config.opensprinkler.http.port.label = Port
 thing-type.config.opensprinkler.http.port.description = Port of the OpenSprinkler Web API interface.
 thing-type.config.opensprinkler.http.refresh.label = Refresh Interval
 thing-type.config.opensprinkler.http.refresh.description = Specifies the refresh interval in seconds.
+thing-type.config.opensprinkler.http.retry.label = Retry Count
+thing-type.config.opensprinkler.http.retry.description = Specifies the number of retries on connection timeouts.
+thing-type.config.opensprinkler.http.timeout.label = Timeout
+thing-type.config.opensprinkler.http.timeout.description = Specifies the connection timeout in seconds.
 thing-type.config.opensprinkler.station.stationIndex.label = Station Index
 thing-type.config.opensprinkler.station.stationIndex.description = The index of the station, starting with 0, of the station.
 
index bdd001917a5a3bf1596bb3af98ba68f359c53e51..4d9f3611599675ec5e472aea0493a61c18eb167c 100644 (file)
                                <description>Specifies the refresh interval in seconds.</description>
                                <default>60</default>
                        </parameter>
+                       <parameter name="retry" type="integer">
+                               <label>Retry Count</label>
+                               <description>Specifies the number of retries on connection timeouts.</description>
+                               <default>3</default>
+                               <advanced>true</advanced>
+                       </parameter>
+                       <parameter name="timeout" type="integer" unit="s">
+                               <label>Timeout</label>
+                               <description>Specifies the connection timeout in seconds.</description>
+                               <default>5</default>
+                               <advanced>true</advanced>
+                       </parameter>
                        <parameter name="basicUsername" type="text">
                                <label>Basic Auth Username</label>
                                <description>Used if the OpenSprinkler device is behind a basic auth protected reverse proxy.</description>