From ad033d9b6bdab535f2ca3040cbee77340cf82def Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Thu, 20 Jul 2023 22:35:34 +0200 Subject: [PATCH 01/10] added timestamp channel, updated thing description Signed-off-by: Michael Weger --- .../org.openhab.binding.speedtest/README.md | 2 ++ .../internal/SpeedtestBindingConstants.java | 1 + .../speedtest/internal/SpeedtestHandler.java | 19 ++++++++++++++++++- .../OH-INF/i18n/speedtest.properties | 6 ++++-- .../OH-INF/i18n/speedtest_it.properties | 4 ++-- .../resources/OH-INF/thing/thing-types.xml | 11 +++++++++-- 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/bundles/org.openhab.binding.speedtest/README.md b/bundles/org.openhab.binding.speedtest/README.md index 733cff9e26d34..713e249c74d52 100644 --- a/bundles/org.openhab.binding.speedtest/README.md +++ b/bundles/org.openhab.binding.speedtest/README.md @@ -76,6 +76,7 @@ Ensure that the user that openHAB is running with, has the permissions to access | Channel | Type | Description | |-----------------------|---------------------------|-------------------------------------------------------------------| | `server` | `String` | The remote server that the Speedtest was run against | +| `timestamp` | `DateTime` | Timestamp of the Speedtest run | | `pingJitter` | `Number:Time` | Ping Jitter - the variation in the response time | | `pingLatency` | `Number:Time` | Ping Latency - the reaction time of your internet connection | | `downloadBandwidth` | `Number:DataTransferRate` | Download bandwidth, e.g. in Mbit/s | @@ -102,6 +103,7 @@ Thing speedtest:speedtest:myspeedtest "Ookla Speedtest" [ execPath="/usr/ ```java String Speedtest_Server "Server" { channel="speedtest:speedtest:myspeedtest:server" } +DateTime Speedtest_Timestamp "Timestamp" { channel="speedtest:speedtest:myspeedtest:timestamp" } Number:Time Speedtest_Ping_Jitter "Ping Jitter" { channel="speedtest:speedtest:myspeedtest:pingJitter" } Number:Time Speedtest_Ping_Latency "Ping Latency" { channel="speedtest:speedtest:myspeedtest:pingLatency" } Number:DataTransferRate Speedtest_Download_Bandwith "Download Bandwith" { channel="speedtest:speedtest:myspeedtest:downloadBandwidth" } diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java index cc9a9a364b94f..68cb90bbbc46f 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java @@ -40,6 +40,7 @@ public class SpeedtestBindingConstants { // Channels public static final String SERVER = "server"; + public static final String TIMESTAMP = "timestamp"; public static final String PING_JITTER = "pingJitter"; public static final String PING_LATENCY = "pingLatency"; public static final String DOWNLOAD_BANDWIDTH = "downloadBandwidth"; diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java index 6c43ef3cffadd..7eeb7063a62bb 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java @@ -17,6 +17,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeParseException; import java.util.Arrays; import java.util.Map; import java.util.concurrent.ScheduledFuture; @@ -27,6 +30,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.speedtest.internal.dto.ResultContainer; import org.openhab.binding.speedtest.internal.dto.ResultsContainerServerList; +import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; @@ -82,6 +86,7 @@ public class SpeedtestHandler extends BaseThingHandler { private String interfaceExternalIp = ""; private String resultUrl = ""; private String server = ""; + private String timestamp = ""; /** * Contains information about which operating system openHAB is running on. @@ -286,6 +291,7 @@ private void getSpeed() { ResultContainer.class); if (tmpCont != null) { if ("result".equals(tmpCont.getType())) { + timestamp = tmpCont.getTimestamp(); pingJitter = tmpCont.getPing().getJitter(); pingLatency = tmpCont.getPing().getLatency(); downloadBandwidth = tmpCont.getDownload().getBandwidth(); @@ -331,8 +337,19 @@ private void getSpeed() { */ private void updateChannels() { logger.debug("Updating channels"); + State newState; - State newState = new QuantityType<>(Double.parseDouble(pingJitter) / 1000.0, Units.SECOND); + // timestamp format: "2023-07-20T19:34:54Z" + try { + ZonedDateTime zonedDateTime = ZonedDateTime.parse(timestamp).withZoneSameInstant(ZoneId.systemDefault()); + newState = new DateTimeType(zonedDateTime); + logger.debug("timestamp: {}", newState); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.TIMESTAMP), newState); + } catch (DateTimeParseException e) { + logger.debug("Exception: {}", e.getMessage()); + } + + newState = new QuantityType<>(Double.parseDouble(pingJitter) / 1000.0, Units.SECOND); logger.debug("pingJitter: {}", newState); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.PING_JITTER), newState); diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties index 4ab1de8187886..6d69a0ea68f98 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties @@ -5,8 +5,8 @@ addon.speedtest.description = Binding for Ookla Speedtest (https://www.speedtest # thing types -thing-type.speedtest.speedtest.label = Speedtest Binding -thing-type.speedtest.speedtest.description = Binding for Ookla Speedtest (https://www.speedtest.net/) +thing-type.speedtest.speedtest.label = Ookla Speedtest +thing-type.speedtest.speedtest.description = Ookla Speedtest (https://www.speedtest.net/) # thing types config @@ -47,6 +47,8 @@ channel-type.speedtest.resultUrl.label = Result URL channel-type.speedtest.resultUrl.description = The URL to the Speedtest results in HTML on the Ookla webserver channel-type.speedtest.server.label = Server channel-type.speedtest.server.description = The remote server that the Speedtest was run against +channel-type.speedtest.timestamp.label = Timestamp +channel-type.speedtest.timestamp.description = Timestamp of the Speedtest run channel-type.speedtest.triggerTest.label = Trigger Test channel-type.speedtest.triggerTest.description = Trigger in order to run Speedtest manually channel-type.speedtest.uploadBandwidth.label = Upload Bandwidth diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties index 53ea5c3e947d9..ff99eba4d4939 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties @@ -5,8 +5,8 @@ addon.speedtest.description = Binding per Ookla Speedtest (https\://www.speedtes # thing types -thing-type.speedtest.speedtest.label = Binding Speedtest -thing-type.speedtest.speedtest.description = Binding per Ookla Speedtest (https\://www.speedtest.net/) +thing-type.speedtest.speedtest.label = Ookla Speedtest +thing-type.speedtest.speedtest.description = Ookla Speedtest (https\://www.speedtest.net/) # thing types config diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml index bf2162555ab3a..eb20010a43633 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml @@ -5,10 +5,11 @@ xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd"> - - Binding for Ookla Speedtest (https://www.speedtest.net/) + + Ookla Speedtest (https://www.speedtest.net/) + @@ -78,6 +79,12 @@ The remote server that the Speedtest was run against + + DateTime + + Timestamp of the Speedtest run + + Number:Time From 830e984acb536808f74c7a5c0d0d8c71b3ac5311 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Sun, 20 Aug 2023 16:42:17 +0200 Subject: [PATCH 02/10] added resultImage Signed-off-by: Michael Weger --- .../org.openhab.binding.speedtest/README.md | 2 + .../internal/SpeedtestBindingConstants.java | 5 +- .../speedtest/internal/SpeedtestHandler.java | 51 +++++++++++++++++-- .../internal/SpeedtestHandlerFactory.java | 12 ++++- .../OH-INF/i18n/speedtest.properties | 2 + .../resources/OH-INF/thing/thing-types.xml | 7 +++ 6 files changed, 72 insertions(+), 7 deletions(-) diff --git a/bundles/org.openhab.binding.speedtest/README.md b/bundles/org.openhab.binding.speedtest/README.md index 713e249c74d52..5f84faa23fb6c 100644 --- a/bundles/org.openhab.binding.speedtest/README.md +++ b/bundles/org.openhab.binding.speedtest/README.md @@ -89,6 +89,7 @@ Ensure that the user that openHAB is running with, has the permissions to access | `interfaceInternalIp` | `String` | IP address of the internal interface that was used for the test | | `interfaceExternalIp` | `String` | IP address of the external interface that was used for the test | | `resultUrl` | `String` | The URL to the Speedtest results in HTML on the Ookla webserver | +| `resultImage` | `Image ` | The Speedtest results as image | | `triggerTest` | `Switch` | Trigger in order to run Speedtest manually | ## Full Example @@ -116,5 +117,6 @@ String Speedtest_ISP "ISP" String Speedtest_Interface_InternalIP "Internal IP Address" { channel="speedtest:speedtest:myspeedtest:interfaceInternalIp" } String Speedtest_Interface_ExternalIP "External IP Address" { channel="speedtest:speedtest:myspeedtest:interfaceExternalIp" } String Speedtest_ResultURL "Result URL" { channel="speedtest:speedtest:myspeedtest:resultUrl" } +Image Speedtest_ResultImage "Result Image" { channel="speedtest:speedtest:myspeedtest:resultImage" } Switch Speedtest_TriggerTest "Trigger Test" { channel="speedtest:speedtest:myspeedtest:triggerTest" } ``` diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java index 68cb90bbbc46f..86e8d68a439ca 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java @@ -53,6 +53,7 @@ public class SpeedtestBindingConstants { public static final String INTERFACE_INTERNALIP = "interfaceInternalIp"; public static final String INTERFACE_EXTERNALIP = "interfaceExternalIp"; public static final String RESULT_URL = "resultUrl"; + public static final String RESULT_IMAGE = "resultImage"; public static final String TRIGGER_TEST = "triggerTest"; public static final String PROPERTY_SERVER_LIST1 = "Server List 1"; @@ -66,7 +67,7 @@ public class SpeedtestBindingConstants { public static final String PROPERTY_SERVER_LIST9 = "Server List 9"; public static final String PROPERTY_SERVER_LIST10 = "Server List 10"; - public static final Set SUPPORTED_CHANNEL_IDS = Set.of(SERVER, PING_JITTER, PING_LATENCY, + public static final Set SUPPORTED_CHANNEL_IDS = Set.of(SERVER, TIMESTAMP, PING_JITTER, PING_LATENCY, DOWNLOAD_BANDWIDTH, DOWNLOAD_BYTES, DOWNLOAD_ELAPSED, UPLOAD_BANDWIDTH, UPLOAD_BYTES, UPLOAD_ELAPSED, ISP, - INTERFACE_INTERNALIP, INTERFACE_EXTERNALIP, RESULT_URL); + INTERFACE_INTERNALIP, INTERFACE_EXTERNALIP, RESULT_URL, TRIGGER_TEST); } diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java index 7eeb7063a62bb..09088eb1efe01 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java @@ -22,17 +22,26 @@ import java.time.format.DateTimeParseException; import java.util.Arrays; 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.PatternSyntaxException; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; import org.openhab.binding.speedtest.internal.dto.ResultContainer; import org.openhab.binding.speedtest.internal.dto.ResultsContainerServerList; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.types.RawType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.Units; import org.openhab.core.thing.ChannelUID; @@ -62,6 +71,8 @@ public class SpeedtestHandler extends BaseThingHandler { private static Runtime rt = Runtime.getRuntime(); private long pollingInterval = 60; private String serverID = ""; + private static final long API_REQUEST_TIMEOUT_SECONDS = 16L; + private @Nullable HttpClient httpClient; private @Nullable ScheduledFuture pollingJob; public volatile boolean isRunning = false; @@ -100,8 +111,9 @@ public enum OS { NOT_SET } - public SpeedtestHandler(Thing thing) { + public SpeedtestHandler(Thing thing, HttpClient httpClient) { super(thing); + this.httpClient = httpClient; } @Override @@ -387,9 +399,40 @@ private void updateChannels() { new StringType(interfaceInternalIp)); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.ISP), new StringType(isp)); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.RESULT_URL), - new StringType(resultUrl)); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.SERVER), new StringType(server)); - } + HttpClient client = httpClient; + if (client == null) { + logger.debug("Unable to download image because httpClient is not set"); + } else { + try { + String url = String.valueOf(resultUrl) + ".png"; + logger.debug("Downloading result image from: {}", url); + Request request = client.newRequest(url); + request.method(HttpMethod.GET); + request.timeout(API_REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS); + + ContentResponse contentResponse = request.send(); + switch (contentResponse.getStatus()) { + case HttpStatus.OK_200: + RawType image = new RawType(contentResponse.getContent(), + contentResponse.getHeaders().get(HttpHeader.CONTENT_TYPE)); + + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.RESULT_IMAGE), image); + default: + logger.debug("HTTP GET failed: {}, {}", contentResponse.getStatus(), + contentResponse.getReason()); + break; + } + } catch (TimeoutException e) { + logger.debug("TimeoutException: Download of result image timed out"); + } catch (ExecutionException e) { + logger.debug("ExecutionException: {}", e.getMessage()); + } catch (InterruptedException e) { + logger.debug("InterruptedException: {}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.SERVER), + new StringType(String.valueOf(server))); } /** * Checks to make sure the executable for speedtest is valid diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java index 87024fe7f4cd6..a5e2af02bcfa5 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java @@ -19,12 +19,16 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jetty.client.HttpClient; +import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.binding.BaseThingHandlerFactory; import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.ThingHandlerFactory; +import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; /** * The {@link SpeedtestHandlerFactory} is responsible for creating things and thing @@ -37,6 +41,12 @@ public class SpeedtestHandlerFactory extends BaseThingHandlerFactory { private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_SPEEDTEST); + private final HttpClient httpClient; + + @Activate + public SpeedtestHandlerFactory(@Reference HttpClientFactory httpClientFactory) { + this.httpClient = httpClientFactory.getCommonHttpClient(); + } @Override public boolean supportsThingType(ThingTypeUID thingTypeUID) { @@ -48,7 +58,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (THING_TYPE_SPEEDTEST.equals(thingTypeUID)) { - return new SpeedtestHandler(thing); + return new SpeedtestHandler(thing, httpClient); } return null; diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties index 6d69a0ea68f98..03d72a3bf0c29 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest.properties @@ -43,6 +43,8 @@ channel-type.speedtest.pingJitter.label = Ping Jitter channel-type.speedtest.pingJitter.description = Ping Jitter - the variation in the response time channel-type.speedtest.pingLatency.label = Ping Latency channel-type.speedtest.pingLatency.description = Ping Latency - the reaction time of your internet connection +channel-type.speedtest.resultImage.label = Result Image +channel-type.speedtest.resultImage.description = The Speedtest results as image channel-type.speedtest.resultUrl.label = Result URL channel-type.speedtest.resultUrl.description = The URL to the Speedtest results in HTML on the Ookla webserver channel-type.speedtest.server.label = Server diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml index eb20010a43633..41e8c8a5e39a0 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml @@ -28,6 +28,7 @@ + @@ -157,6 +158,12 @@ The URL to the Speedtest results in HTML on the Ookla webserver + + Image + + The Speedtest results as image + + Switch From 6feda7d18e505c1995b7502b87656153d0c20452 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Sat, 2 Sep 2023 20:54:41 +0200 Subject: [PATCH 03/10] added missing 'break' Signed-off-by: Michael Weger --- .../org/openhab/binding/speedtest/internal/SpeedtestHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java index 09088eb1efe01..e8538f3bac5a0 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java @@ -417,6 +417,7 @@ private void updateChannels() { contentResponse.getHeaders().get(HttpHeader.CONTENT_TYPE)); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.RESULT_IMAGE), image); + break; default: logger.debug("HTTP GET failed: {}, {}", contentResponse.getStatus(), contentResponse.getReason()); From d20339a17b4b6b29fb944aa95ff90f44a97ace24 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Sun, 10 Sep 2023 08:54:54 +0200 Subject: [PATCH 04/10] implemented review findings Signed-off-by: Michael Weger --- .../speedtest/internal/SpeedtestHandler.java | 199 ++++++++++-------- .../internal/SpeedtestHandlerFactory.java | 8 +- 2 files changed, 116 insertions(+), 91 deletions(-) diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java index e8538f3bac5a0..f5b0ace889c9d 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java @@ -17,7 +17,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeParseException; import java.util.Arrays; @@ -38,6 +37,7 @@ import org.eclipse.jetty.http.HttpStatus; import org.openhab.binding.speedtest.internal.dto.ResultContainer; import org.openhab.binding.speedtest.internal.dto.ResultsContainerServerList; +import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; @@ -52,6 +52,7 @@ import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -73,6 +74,7 @@ public class SpeedtestHandler extends BaseThingHandler { private String serverID = ""; private static final long API_REQUEST_TIMEOUT_SECONDS = 16L; private @Nullable HttpClient httpClient; + private final TimeZoneProvider timeZoneProvider; private @Nullable ScheduledFuture pollingJob; public volatile boolean isRunning = false; @@ -84,20 +86,21 @@ public class SpeedtestHandler extends BaseThingHandler { private static volatile OS os = OS.NOT_SET; private static final Object LOCK = new Object(); - private String pingJitter = ""; - private String pingLatency = ""; - private String downloadBandwidth = ""; - private String downloadBytes = ""; - private String downloadElapsed = ""; - private String uploadBandwidth = ""; - private String uploadBytes = ""; - private String uploadElapsed = ""; + private State pingJitter = UnDefType.NULL; + private State pingLatency = UnDefType.NULL; + private State downloadBandwidth = UnDefType.NULL; + private State downloadBytes = UnDefType.NULL; + private State downloadElapsed = UnDefType.NULL; + private State uploadBandwidth = UnDefType.NULL; + private State uploadBytes = UnDefType.NULL; + private State uploadElapsed = UnDefType.NULL; private String isp = ""; private String interfaceInternalIp = ""; private String interfaceExternalIp = ""; private String resultUrl = ""; + private State resultImage = UnDefType.NULL; private String server = ""; - private String timestamp = ""; + private State timestamp = UnDefType.NULL; /** * Contains information about which operating system openHAB is running on. @@ -111,9 +114,10 @@ public enum OS { NOT_SET } - public SpeedtestHandler(Thing thing, HttpClient httpClient) { + public SpeedtestHandler(Thing thing, HttpClient httpClient, TimeZoneProvider timeZoneProvider) { super(thing); this.httpClient = httpClient; + this.timeZoneProvider = timeZoneProvider; } @Override @@ -303,19 +307,70 @@ private void getSpeed() { ResultContainer.class); if (tmpCont != null) { if ("result".equals(tmpCont.getType())) { - timestamp = tmpCont.getTimestamp(); - pingJitter = tmpCont.getPing().getJitter(); - pingLatency = tmpCont.getPing().getLatency(); - downloadBandwidth = tmpCont.getDownload().getBandwidth(); - downloadBytes = tmpCont.getDownload().getBytes(); - downloadElapsed = tmpCont.getDownload().getElapsed(); - uploadBandwidth = tmpCont.getUpload().getBandwidth(); - uploadBytes = tmpCont.getUpload().getBytes(); - uploadElapsed = tmpCont.getUpload().getElapsed(); + try { + // timestamp format: "2023-07-20T19:34:54Z" + ZonedDateTime zonedDateTime = ZonedDateTime.parse(tmpCont.getTimestamp()) + .withZoneSameInstant(timeZoneProvider.getTimeZone()); + timestamp = new DateTimeType(zonedDateTime); + } catch (DateTimeParseException e) { + timestamp = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + + pingJitter = new QuantityType<>(Double.parseDouble(tmpCont.getPing().getJitter()) / 1000.0, + Units.SECOND); + pingLatency = new QuantityType<>(Double.parseDouble(tmpCont.getPing().getLatency()) / 1000.0, + Units.SECOND); + downloadBandwidth = new QuantityType<>( + Double.parseDouble(tmpCont.getDownload().getBandwidth()) / 125000.0, Units.MEGABIT_PER_SECOND); + downloadBytes = new QuantityType<>(Double.parseDouble(tmpCont.getDownload().getBytes()), Units.BYTE); + downloadElapsed = new QuantityType<>(Double.parseDouble(tmpCont.getDownload().getElapsed()) / 1000.0, + Units.SECOND); + uploadBandwidth = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getBandwidth()) / 125000.0, + Units.MEGABIT_PER_SECOND); + uploadBytes = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getBytes()), Units.BYTE); + uploadElapsed = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getElapsed()) / 1000.0, + Units.SECOND); isp = tmpCont.getIsp(); interfaceInternalIp = tmpCont.getInterface().getInternalIp(); interfaceExternalIp = tmpCont.getInterface().getExternalIp(); resultUrl = tmpCont.getResult().getUrl(); + + HttpClient client = httpClient; + if (client == null) { + logger.debug("Unable to download image because httpClient is not set"); + } else { + try { + String url = String.valueOf(resultUrl) + ".png"; + logger.debug("Downloading result image from: {}", url); + Request request = client.newRequest(url); + request.method(HttpMethod.GET); + request.timeout(API_REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS); + + ContentResponse contentResponse = request.send(); + switch (contentResponse.getStatus()) { + case HttpStatus.OK_200: + resultImage = new RawType(contentResponse.getContent(), + contentResponse.getHeaders().get(HttpHeader.CONTENT_TYPE)); + break; + default: + logger.debug("HTTP GET failed: {}, {}", contentResponse.getStatus(), + contentResponse.getReason()); + break; + } + } catch (TimeoutException e) { + resultImage = UnDefType.NULL; + logger.debug("TimeoutException: Download of result image timed out"); + } catch (ExecutionException e) { + resultImage = UnDefType.NULL; + logger.debug("ExecutionException: {}", e.getMessage()); + } catch (InterruptedException e) { + resultImage = UnDefType.NULL; + logger.debug("InterruptedException: {}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + server = tmpCont.getServer().getName() + " (" + tmpCont.getServer().getId().toString() + ") " + tmpCont.getServer().getLocation(); updateChannels(); @@ -349,91 +404,56 @@ private void getSpeed() { */ private void updateChannels() { logger.debug("Updating channels"); - State newState; - // timestamp format: "2023-07-20T19:34:54Z" - try { - ZonedDateTime zonedDateTime = ZonedDateTime.parse(timestamp).withZoneSameInstant(ZoneId.systemDefault()); - newState = new DateTimeType(zonedDateTime); - logger.debug("timestamp: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.TIMESTAMP), newState); - } catch (DateTimeParseException e) { - logger.debug("Exception: {}", e.getMessage()); - } + logger.debug("timestamp: {}", timestamp); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.TIMESTAMP), timestamp); - newState = new QuantityType<>(Double.parseDouble(pingJitter) / 1000.0, Units.SECOND); - logger.debug("pingJitter: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.PING_JITTER), newState); + logger.debug("pingJitter: {}", pingJitter); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.PING_JITTER), pingJitter); - newState = new QuantityType<>(Double.parseDouble(pingLatency) / 1000.0, Units.SECOND); - logger.debug("pingLatency: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.PING_LATENCY), newState); + logger.debug("pingLatency: {}", pingLatency); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.PING_LATENCY), pingLatency); - newState = new QuantityType<>(Double.parseDouble(downloadBandwidth) / 125000.0, Units.MEGABIT_PER_SECOND); - logger.debug("downloadBandwidth: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.DOWNLOAD_BANDWIDTH), newState); + logger.debug("downloadBandwidth: {}", downloadBandwidth); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.DOWNLOAD_BANDWIDTH), + downloadBandwidth); - newState = new QuantityType<>(Double.parseDouble(downloadBytes), Units.BYTE); - logger.debug("downloadBytes: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.DOWNLOAD_BYTES), newState); + logger.debug("downloadBytes: {}", downloadBytes); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.DOWNLOAD_BYTES), downloadBytes); - newState = new QuantityType<>(Double.parseDouble(downloadElapsed) / 1000.0, Units.SECOND); - logger.debug("downloadElapsed: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.DOWNLOAD_ELAPSED), newState); + logger.debug("downloadElapsed: {}", downloadElapsed); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.DOWNLOAD_ELAPSED), downloadElapsed); - newState = new QuantityType<>(Double.parseDouble(uploadBandwidth) / 125000.0, Units.MEGABIT_PER_SECOND); - logger.debug("uploadBandwidth: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.UPLOAD_BANDWIDTH), newState); + logger.debug("uploadBandwidth: {}", uploadBandwidth); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.UPLOAD_BANDWIDTH), uploadBandwidth); - newState = new QuantityType<>(Double.parseDouble(uploadBytes), Units.BYTE); - logger.debug("uploadBytes: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.UPLOAD_BYTES), newState); + logger.debug("uploadBytes: {}", uploadBytes); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.UPLOAD_BYTES), uploadBytes); - newState = new QuantityType<>(Double.parseDouble(uploadElapsed) / 1000.0, Units.SECOND); - logger.debug("uploadElapsed: {}", newState); - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.UPLOAD_ELAPSED), newState); + logger.debug("uploadElapsed: {}", uploadElapsed); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.UPLOAD_ELAPSED), uploadElapsed); + logger.debug("interfaceExternalIp: {}", interfaceExternalIp); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.INTERFACE_EXTERNALIP), new StringType(interfaceExternalIp)); + + logger.debug("interfaceInternalIp: {}", interfaceInternalIp); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.INTERFACE_INTERNALIP), new StringType(interfaceInternalIp)); + + logger.debug("isp: {}", isp); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.ISP), new StringType(isp)); + + logger.debug("resultUrl: {}", resultUrl); updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.RESULT_URL), - HttpClient client = httpClient; - if (client == null) { - logger.debug("Unable to download image because httpClient is not set"); - } else { - try { - String url = String.valueOf(resultUrl) + ".png"; - logger.debug("Downloading result image from: {}", url); - Request request = client.newRequest(url); - request.method(HttpMethod.GET); - request.timeout(API_REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS); - - ContentResponse contentResponse = request.send(); - switch (contentResponse.getStatus()) { - case HttpStatus.OK_200: - RawType image = new RawType(contentResponse.getContent(), - contentResponse.getHeaders().get(HttpHeader.CONTENT_TYPE)); - - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.RESULT_IMAGE), image); - break; - default: - logger.debug("HTTP GET failed: {}, {}", contentResponse.getStatus(), - contentResponse.getReason()); - break; - } - } catch (TimeoutException e) { - logger.debug("TimeoutException: Download of result image timed out"); - } catch (ExecutionException e) { - logger.debug("ExecutionException: {}", e.getMessage()); - } catch (InterruptedException e) { - logger.debug("InterruptedException: {}", e.getMessage()); - Thread.currentThread().interrupt(); - } - } - updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.SERVER), - new StringType(String.valueOf(server))); } + new StringType(resultUrl)); + + logger.debug("resultImage: "); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.RESULT_IMAGE), resultImage); + + logger.debug("server: {}", server); + updateState(new ChannelUID(getThing().getUID(), SpeedtestBindingConstants.SERVER), new StringType(server)); + } /** * Checks to make sure the executable for speedtest is valid @@ -595,3 +615,4 @@ public boolean checkFileExecutable(File file) { return file.canExecute(); } } + diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java index a5e2af02bcfa5..13c88fae55deb 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java @@ -20,6 +20,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jetty.client.HttpClient; +import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; @@ -42,10 +43,13 @@ public class SpeedtestHandlerFactory extends BaseThingHandlerFactory { private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_SPEEDTEST); private final HttpClient httpClient; + private final TimeZoneProvider timeZoneProvider; @Activate - public SpeedtestHandlerFactory(@Reference HttpClientFactory httpClientFactory) { + public SpeedtestHandlerFactory(@Reference HttpClientFactory httpClientFactory, + final @Reference TimeZoneProvider timeZoneProvider) { this.httpClient = httpClientFactory.getCommonHttpClient(); + this.timeZoneProvider = timeZoneProvider; } @Override @@ -58,7 +62,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (THING_TYPE_SPEEDTEST.equals(thingTypeUID)) { - return new SpeedtestHandler(thing, httpClient); + return new SpeedtestHandler(thing, httpClient, timeZoneProvider); } return null; From c31356c03a3bc0e3ee5d3dbb060a7e78d91e1cd8 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Sun, 10 Sep 2023 08:59:55 +0200 Subject: [PATCH 05/10] reverted changes in *_it.properties - review finding Signed-off-by: Michael Weger --- .../src/main/resources/OH-INF/i18n/speedtest_it.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties index ff99eba4d4939..53ea5c3e947d9 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/i18n/speedtest_it.properties @@ -5,8 +5,8 @@ addon.speedtest.description = Binding per Ookla Speedtest (https\://www.speedtes # thing types -thing-type.speedtest.speedtest.label = Ookla Speedtest -thing-type.speedtest.speedtest.description = Ookla Speedtest (https\://www.speedtest.net/) +thing-type.speedtest.speedtest.label = Binding Speedtest +thing-type.speedtest.speedtest.description = Binding per Ookla Speedtest (https\://www.speedtest.net/) # thing types config From 8d1516a3a2f6bd60a64baaf57e60645fc1124b7b Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Sun, 10 Sep 2023 09:19:04 +0200 Subject: [PATCH 06/10] added update/instructions.xml Signed-off-by: Michael Weger --- .../resources/OH-INF/update/instructions.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml new file mode 100644 index 0000000000000..31ad30b023e03 --- /dev/null +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml @@ -0,0 +1,21 @@ + + + + + + + speedtest:timestamp + + Timestamp of the Speedtest run + + + speedtest:resultImage + + The Speedtest results as image + + + + + From 7fd99113e70d86290a5ab44892368c77972ac935 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Sun, 10 Sep 2023 09:52:08 +0200 Subject: [PATCH 07/10] added thingTypeVersion to thing-types.xml Signed-off-by: Michael Weger --- .../src/main/resources/OH-INF/thing/thing-types.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml index 41e8c8a5e39a0..6aa2a9dd93df5 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml @@ -43,6 +43,7 @@ + 1 From bbd8a1396b23191bd47c700992be9dda824babb2 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Sun, 17 Sep 2023 21:55:27 +0200 Subject: [PATCH 08/10] mvn spotless:apply Signed-off-by: Michael Weger --- .../org/openhab/binding/speedtest/internal/SpeedtestHandler.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java index f5b0ace889c9d..de58914b6443d 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java @@ -615,4 +615,3 @@ public boolean checkFileExecutable(File file) { return file.canExecute(); } } - From d60cb2fb8f9888152eb081b306f491c9a8295a02 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Thu, 19 Oct 2023 21:20:57 +0200 Subject: [PATCH 09/10] implemented review findings Signed-off-by: Michael Weger --- .../internal/SpeedtestBindingConstants.java | 2 +- .../speedtest/internal/SpeedtestHandler.java | 125 +++++++++--------- .../internal/SpeedtestHandlerFactory.java | 5 +- .../resources/OH-INF/thing/thing-types.xml | 2 +- .../resources/OH-INF/update/instructions.xml | 4 - 5 files changed, 68 insertions(+), 70 deletions(-) diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java index 86e8d68a439ca..b365943d9ab3c 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestBindingConstants.java @@ -69,5 +69,5 @@ public class SpeedtestBindingConstants { public static final Set SUPPORTED_CHANNEL_IDS = Set.of(SERVER, TIMESTAMP, PING_JITTER, PING_LATENCY, DOWNLOAD_BANDWIDTH, DOWNLOAD_BYTES, DOWNLOAD_ELAPSED, UPLOAD_BANDWIDTH, UPLOAD_BYTES, UPLOAD_ELAPSED, ISP, - INTERFACE_INTERNALIP, INTERFACE_EXTERNALIP, RESULT_URL, TRIGGER_TEST); + INTERFACE_INTERNALIP, INTERFACE_EXTERNALIP, RESULT_URL, RESULT_IMAGE, TRIGGER_TEST); } diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java index de58914b6443d..d87d6fd6c6337 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandler.java @@ -21,23 +21,16 @@ import java.time.format.DateTimeParseException; import java.util.Arrays; 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.PatternSyntaxException; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpStatus; import org.openhab.binding.speedtest.internal.dto.ResultContainer; import org.openhab.binding.speedtest.internal.dto.ResultsContainerServerList; import org.openhab.core.i18n.TimeZoneProvider; +import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; @@ -72,8 +65,6 @@ public class SpeedtestHandler extends BaseThingHandler { private static Runtime rt = Runtime.getRuntime(); private long pollingInterval = 60; private String serverID = ""; - private static final long API_REQUEST_TIMEOUT_SECONDS = 16L; - private @Nullable HttpClient httpClient; private final TimeZoneProvider timeZoneProvider; private @Nullable ScheduledFuture pollingJob; @@ -114,9 +105,8 @@ public enum OS { NOT_SET } - public SpeedtestHandler(Thing thing, HttpClient httpClient, TimeZoneProvider timeZoneProvider) { + public SpeedtestHandler(Thing thing, TimeZoneProvider timeZoneProvider) { super(thing); - this.httpClient = httpClient; this.timeZoneProvider = timeZoneProvider; } @@ -316,59 +306,74 @@ private void getSpeed() { timestamp = UnDefType.NULL; logger.debug("Exception: {}", e.getMessage()); } - - pingJitter = new QuantityType<>(Double.parseDouble(tmpCont.getPing().getJitter()) / 1000.0, - Units.SECOND); - pingLatency = new QuantityType<>(Double.parseDouble(tmpCont.getPing().getLatency()) / 1000.0, - Units.SECOND); - downloadBandwidth = new QuantityType<>( - Double.parseDouble(tmpCont.getDownload().getBandwidth()) / 125000.0, Units.MEGABIT_PER_SECOND); - downloadBytes = new QuantityType<>(Double.parseDouble(tmpCont.getDownload().getBytes()), Units.BYTE); - downloadElapsed = new QuantityType<>(Double.parseDouble(tmpCont.getDownload().getElapsed()) / 1000.0, - Units.SECOND); - uploadBandwidth = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getBandwidth()) / 125000.0, - Units.MEGABIT_PER_SECOND); - uploadBytes = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getBytes()), Units.BYTE); - uploadElapsed = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getElapsed()) / 1000.0, - Units.SECOND); + try { + pingJitter = new QuantityType<>(Double.parseDouble(tmpCont.getPing().getJitter()) / 1000.0, + Units.SECOND); + } catch (NumberFormatException e) { + pingJitter = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + try { + pingLatency = new QuantityType<>(Double.parseDouble(tmpCont.getPing().getLatency()) / 1000.0, + Units.SECOND); + } catch (NumberFormatException e) { + pingLatency = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + try { + downloadBandwidth = new QuantityType<>( + Double.parseDouble(tmpCont.getDownload().getBandwidth()) / 125000.0, + Units.MEGABIT_PER_SECOND); + } catch (NumberFormatException e) { + downloadBandwidth = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + try { + downloadBytes = new QuantityType<>(Double.parseDouble(tmpCont.getDownload().getBytes()), + Units.BYTE); + } catch (NumberFormatException e) { + downloadBytes = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + try { + downloadElapsed = new QuantityType<>( + Double.parseDouble(tmpCont.getDownload().getElapsed()) / 1000.0, Units.SECOND); + } catch (NumberFormatException e) { + downloadElapsed = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + try { + uploadBandwidth = new QuantityType<>( + Double.parseDouble(tmpCont.getUpload().getBandwidth()) / 125000.0, + Units.MEGABIT_PER_SECOND); + } catch (NumberFormatException e) { + uploadBandwidth = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + try { + uploadBytes = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getBytes()), Units.BYTE); + } catch (NumberFormatException e) { + uploadBytes = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } + try { + uploadElapsed = new QuantityType<>(Double.parseDouble(tmpCont.getUpload().getElapsed()) / 1000.0, + Units.SECOND); + } catch (NumberFormatException e) { + uploadElapsed = UnDefType.NULL; + logger.debug("Exception: {}", e.getMessage()); + } isp = tmpCont.getIsp(); interfaceInternalIp = tmpCont.getInterface().getInternalIp(); interfaceExternalIp = tmpCont.getInterface().getExternalIp(); resultUrl = tmpCont.getResult().getUrl(); - - HttpClient client = httpClient; - if (client == null) { - logger.debug("Unable to download image because httpClient is not set"); + String url = String.valueOf(resultUrl) + ".png"; + logger.debug("Downloading result image from: {}", url); + RawType image = HttpUtil.downloadImage(url); + if (image != null) { + resultImage = image; } else { - try { - String url = String.valueOf(resultUrl) + ".png"; - logger.debug("Downloading result image from: {}", url); - Request request = client.newRequest(url); - request.method(HttpMethod.GET); - request.timeout(API_REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS); - - ContentResponse contentResponse = request.send(); - switch (contentResponse.getStatus()) { - case HttpStatus.OK_200: - resultImage = new RawType(contentResponse.getContent(), - contentResponse.getHeaders().get(HttpHeader.CONTENT_TYPE)); - break; - default: - logger.debug("HTTP GET failed: {}, {}", contentResponse.getStatus(), - contentResponse.getReason()); - break; - } - } catch (TimeoutException e) { - resultImage = UnDefType.NULL; - logger.debug("TimeoutException: Download of result image timed out"); - } catch (ExecutionException e) { - resultImage = UnDefType.NULL; - logger.debug("ExecutionException: {}", e.getMessage()); - } catch (InterruptedException e) { - resultImage = UnDefType.NULL; - logger.debug("InterruptedException: {}", e.getMessage()); - Thread.currentThread().interrupt(); - } + resultImage = UnDefType.NULL; } server = tmpCont.getServer().getName() + " (" + tmpCont.getServer().getId().toString() + ") " diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java index 13c88fae55deb..5551aab8cd177 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java @@ -19,7 +19,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jetty.client.HttpClient; import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.thing.Thing; @@ -42,13 +41,11 @@ public class SpeedtestHandlerFactory extends BaseThingHandlerFactory { private static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_SPEEDTEST); - private final HttpClient httpClient; private final TimeZoneProvider timeZoneProvider; @Activate public SpeedtestHandlerFactory(@Reference HttpClientFactory httpClientFactory, final @Reference TimeZoneProvider timeZoneProvider) { - this.httpClient = httpClientFactory.getCommonHttpClient(); this.timeZoneProvider = timeZoneProvider; } @@ -62,7 +59,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (THING_TYPE_SPEEDTEST.equals(thingTypeUID)) { - return new SpeedtestHandler(thing, httpClient, timeZoneProvider); + return new SpeedtestHandler(thing, timeZoneProvider); } return null; diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml index 6aa2a9dd93df5..8c09222917a50 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/thing/thing-types.xml @@ -85,7 +85,7 @@ DateTime Timestamp of the Speedtest run - + Number:Time diff --git a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml index 31ad30b023e03..0e105def47ea0 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml +++ b/bundles/org.openhab.binding.speedtest/src/main/resources/OH-INF/update/instructions.xml @@ -7,13 +7,9 @@ speedtest:timestamp - - Timestamp of the Speedtest run speedtest:resultImage - - The Speedtest results as image From 309a38eefdd29be55d13b39acb1462605129e390 Mon Sep 17 00:00:00 2001 From: Michael Weger Date: Thu, 19 Oct 2023 22:08:07 +0200 Subject: [PATCH 10/10] implemented review finding Signed-off-by: Michael Weger --- .../binding/speedtest/internal/SpeedtestHandlerFactory.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java index 5551aab8cd177..388461c9b9e06 100644 --- a/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java +++ b/bundles/org.openhab.binding.speedtest/src/main/java/org/openhab/binding/speedtest/internal/SpeedtestHandlerFactory.java @@ -20,7 +20,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.i18n.TimeZoneProvider; -import org.openhab.core.io.net.http.HttpClientFactory; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.binding.BaseThingHandlerFactory; @@ -44,8 +43,7 @@ public class SpeedtestHandlerFactory extends BaseThingHandlerFactory { private final TimeZoneProvider timeZoneProvider; @Activate - public SpeedtestHandlerFactory(@Reference HttpClientFactory httpClientFactory, - final @Reference TimeZoneProvider timeZoneProvider) { + public SpeedtestHandlerFactory(final @Reference TimeZoneProvider timeZoneProvider) { this.timeZoneProvider = timeZoneProvider; }