From 0ed02db481122aef00b3d0592fe7c9e4fa53ae9b Mon Sep 17 00:00:00 2001 From: Jacob Laursen Date: Sun, 16 Apr 2023 21:54:02 +0200 Subject: [PATCH 1/3] Add device properties Resolves #14828 Signed-off-by: Jacob Laursen --- .../internal/BoschIndegoBindingConstants.java | 8 ++- .../internal/IndegoController.java | 6 ++- .../internal/IndegoDeviceController.java | 12 +++++ .../response/DevicePropertiesResponse.java | 49 +++++++++++++++++++ .../serialization/InstantDeserializer.java | 44 +++++++++++++++++ .../internal/handler/BoschIndegoHandler.java | 30 +++++++++++- 6 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/response/DevicePropertiesResponse.java create mode 100644 bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/serialization/InstantDeserializer.java diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoBindingConstants.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoBindingConstants.java index 11be02c7dae8b..f24eff511c8c2 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoBindingConstants.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/BoschIndegoBindingConstants.java @@ -32,6 +32,8 @@ public class BoschIndegoBindingConstants { public static final ThingTypeUID THING_TYPE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account"); public static final ThingTypeUID THING_TYPE_INDEGO = new ThingTypeUID(BINDING_ID, "indego"); + public static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT, THING_TYPE_INDEGO); + // List of all Channel ids public static final String STATE = "state"; public static final String TEXTUAL_STATE = "textualstate"; @@ -48,7 +50,11 @@ public class BoschIndegoBindingConstants { public static final String GARDEN_SIZE = "gardenSize"; public static final String GARDEN_MAP = "gardenMap"; - public static final Set SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT, THING_TYPE_INDEGO); + // Device properties + public static final String PROPERTY_BARE_TOOL_NUMBER = "bareToolNumber"; + public static final String PROPERTY_SERVICE_COUNTER = "serviceCounter"; + public static final String PROPERTY_NEEDS_SERVICE = "needsService"; + public static final String PROPERTY_RENEW_DATE = "renewDate"; // Bosch SingleKey ID OAuth2 private static final String BSK_BASE_URI = "https://prodindego.b2clogin.com/prodindego.onmicrosoft.com/b2c_1a_signup_signin/oauth2/v2.0/"; diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java index 5e1c716fb0625..b755c51931ba2 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java @@ -15,6 +15,7 @@ import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*; import java.io.IOException; +import java.time.Instant; import java.util.Arrays; import java.util.Collection; import java.util.concurrent.ExecutionException; @@ -33,6 +34,7 @@ import org.eclipse.jetty.http.HttpStatus; import org.openhab.binding.boschindego.internal.dto.response.ErrorResponse; import org.openhab.binding.boschindego.internal.dto.response.Mower; +import org.openhab.binding.boschindego.internal.dto.serialization.InstantDeserializer; import org.openhab.binding.boschindego.internal.exceptions.IndegoAuthenticationException; import org.openhab.binding.boschindego.internal.exceptions.IndegoException; import org.openhab.binding.boschindego.internal.exceptions.IndegoInvalidCommandException; @@ -48,6 +50,7 @@ import org.slf4j.LoggerFactory; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonParseException; /** @@ -62,11 +65,10 @@ public class IndegoController { private static final String BASE_URL = "https://api.indego-cloud.iot.bosch-si.com/api/v1/"; private static final String CONTENT_TYPE_HEADER = "application/json"; - private static final String BEARER = "Bearer "; private final Logger logger = LoggerFactory.getLogger(IndegoController.class); - private final Gson gson = new Gson(); + private final Gson gson = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantDeserializer()).create(); private final HttpClient httpClient; private final OAuthClientService oAuthClientService; private final String userAgent; diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java index a6f016230f82d..21192cfe60696 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java @@ -24,6 +24,7 @@ import org.openhab.binding.boschindego.internal.dto.PredictiveStatus; import org.openhab.binding.boschindego.internal.dto.request.SetStateRequest; import org.openhab.binding.boschindego.internal.dto.response.DeviceCalendarResponse; +import org.openhab.binding.boschindego.internal.dto.response.DevicePropertiesResponse; import org.openhab.binding.boschindego.internal.dto.response.DeviceStateResponse; import org.openhab.binding.boschindego.internal.dto.response.LocationWeatherResponse; import org.openhab.binding.boschindego.internal.dto.response.OperatingDataResponse; @@ -71,6 +72,17 @@ public IndegoDeviceController(HttpClient httpClient, OAuthClientService oAuthCli this.serialNumber = serialNumber; } + /** + * Queries the serial number and device service properties from the server. + * + * @return the device serial number and properties + * @throws IndegoAuthenticationException if request was rejected as unauthorized + * @throws IndegoException if any communication or parsing error occurred + */ + public DevicePropertiesResponse getDeviceProperties() throws IndegoAuthenticationException, IndegoException { + return getRequest(SERIAL_NUMBER_SUBPATH + serialNumber + "/", DevicePropertiesResponse.class); + } + /** * Queries the device state from the server. * diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/response/DevicePropertiesResponse.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/response/DevicePropertiesResponse.java new file mode 100644 index 0000000000000..2083c146eb2f9 --- /dev/null +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/response/DevicePropertiesResponse.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2023 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.boschindego.internal.dto.response; + +import java.time.Instant; + +import com.google.gson.annotations.SerializedName; + +/** + * Response for serial number and other device service properties. + * + * @author Jacob Laursen - Initial contribution + */ +public class DevicePropertiesResponse { + + @SerializedName("alm_sn") + public String serialNumber = ""; + + @SerializedName("service_counter") + public int serviceCounter; + + @SerializedName("needs_service") + public boolean needsService; + + /** + * Mode: manual, smart + */ + @SerializedName("alm_mode") + public String mode; + + @SerializedName("bareToolnumber") + public String bareToolNumber; + + @SerializedName("alm_firmware_version") + public String firmwareVersion; + + @SerializedName("renew_date") + public Instant renewDate; +} diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/serialization/InstantDeserializer.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/serialization/InstantDeserializer.java new file mode 100644 index 0000000000000..bb3c11100a2db --- /dev/null +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/dto/serialization/InstantDeserializer.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2010-2023 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.boschindego.internal.dto.serialization; + +import java.lang.reflect.Type; +import java.time.Instant; +import java.time.format.DateTimeParseException; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; + +/** + * The {@link InstantDeserializer} converts a formatted UTC string to {@link Instant}. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class InstantDeserializer implements JsonDeserializer { + + @Override + public @Nullable Instant deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) + throws JsonParseException { + try { + return Instant.parse(element.getAsString()); + } catch (DateTimeParseException e) { + throw new JsonParseException("Could not parse as Instant: " + element.getAsString(), e); + } + } +} diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java index f57798bbca76f..49fe5577117dc 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java @@ -17,8 +17,10 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.Instant; +import java.time.LocalDateTime; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; +import java.util.Map; import java.util.Optional; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -31,6 +33,7 @@ import org.openhab.binding.boschindego.internal.IndegoDeviceController; import org.openhab.binding.boschindego.internal.config.BoschIndegoConfiguration; import org.openhab.binding.boschindego.internal.dto.DeviceCommand; +import org.openhab.binding.boschindego.internal.dto.response.DevicePropertiesResponse; import org.openhab.binding.boschindego.internal.dto.response.DeviceStateResponse; import org.openhab.binding.boschindego.internal.dto.response.OperatingDataResponse; import org.openhab.binding.boschindego.internal.exceptions.IndegoAuthenticationException; @@ -75,6 +78,7 @@ public class BoschIndegoHandler extends BaseThingHandler { private static final String MAP_POSITION_STROKE_COLOR = "#8c8b6d"; private static final String MAP_POSITION_FILL_COLOR = "#fff701"; private static final int MAP_POSITION_RADIUS = 10; + private static final Duration DEVICE_PROPERTIES_VALIDITY_PERIOD = Duration.ofDays(1); private static final Duration MAP_REFRESH_INTERVAL = Duration.ofDays(1); private static final Duration OPERATING_DATA_INACTIVE_REFRESH_INTERVAL = Duration.ofHours(6); @@ -87,6 +91,7 @@ public class BoschIndegoHandler extends BaseThingHandler { private final HttpClient httpClient; private final BoschIndegoTranslationProvider translationProvider; private final TimeZoneProvider timeZoneProvider; + private Instant devicePropertiesUpdated = Instant.MIN; private @NonNullByDefault({}) OAuthClientService oAuthClientService; private @NonNullByDefault({}) IndegoDeviceController controller; @@ -133,7 +138,8 @@ public void initialize() { return; } - this.updateProperty(Thing.PROPERTY_SERIAL_NUMBER, config.serialNumber); + devicePropertiesUpdated = Instant.MIN; + updateProperty(Thing.PROPERTY_SERIAL_NUMBER, config.serialNumber); controller = new IndegoDeviceController(httpClient, oAuthClientService, config.serialNumber); @@ -306,6 +312,10 @@ private void refreshState() throws IndegoAuthenticationException, IndegoExceptio DeviceStatus deviceStatus = DeviceStatus.fromCode(state.state); updateState(state); + if (devicePropertiesUpdated.isBefore(Instant.now().minus(DEVICE_PROPERTIES_VALIDITY_PERIOD))) { + refreshDeviceProperties(); + } + // Update map and start tracking positions if mower is active. if (state.mapUpdateAvailable) { cachedMapTimestamp = Instant.MIN; @@ -348,6 +358,24 @@ private void refreshState() throws IndegoAuthenticationException, IndegoExceptio rescheduleStatePollAccordingToState(deviceStatus); } + private void refreshDeviceProperties() throws IndegoAuthenticationException, IndegoException { + DevicePropertiesResponse deviceProperties = controller.getDeviceProperties(); + Map properties = editProperties(); + if (deviceProperties.firmwareVersion != null) { + properties.put(Thing.PROPERTY_FIRMWARE_VERSION, deviceProperties.firmwareVersion); + } + if (deviceProperties.bareToolNumber != null) { + properties.put(PROPERTY_BARE_TOOL_NUMBER, deviceProperties.bareToolNumber); + } + properties.put(PROPERTY_SERVICE_COUNTER, String.valueOf(deviceProperties.serviceCounter)); + properties.put(PROPERTY_NEEDS_SERVICE, String.valueOf(deviceProperties.needsService)); + properties.put(PROPERTY_RENEW_DATE, + LocalDateTime.ofInstant(deviceProperties.renewDate, timeZoneProvider.getTimeZone()).toString()); + + updateProperties(properties); + devicePropertiesUpdated = Instant.now(); + } + private void rescheduleStatePollAccordingToState(DeviceStatus deviceStatus) { int refreshIntervalSeconds; if (deviceStatus.isActive()) { From c6817b085b5eb45f9df4c07e535012476ea6f483 Mon Sep 17 00:00:00 2001 From: Jacob Laursen Date: Mon, 17 Apr 2023 20:46:14 +0200 Subject: [PATCH 2/3] Add vendor and model properties Signed-off-by: Jacob Laursen --- .../internal/IndegoTypeDatabase.java | 65 +++++++++++++++++++ .../internal/handler/BoschIndegoHandler.java | 3 + .../resources/OH-INF/thing/thing-types.xml | 4 ++ 3 files changed, 72 insertions(+) create mode 100644 bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoTypeDatabase.java diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoTypeDatabase.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoTypeDatabase.java new file mode 100644 index 0000000000000..ccb5648e1f96c --- /dev/null +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoTypeDatabase.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2010-2023 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.boschindego.internal; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * Translates from tool number to model names. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class IndegoTypeDatabase { + + /** + * Return tool name from tool type number. + * + * @see https://www.boschtoolservice.com/gb/en/boschdiy/spareparts/search-results?q=Indego + * + * @param toolTypeNumber condensed tool type number, e.g. "3600HA2200" rather than "3 600 HA2 200". + * @return tool type name + */ + public static String nameFromTypeNumber(String toolTypeNumber) { + String name = switch (toolTypeNumber) { + case "3600HA2103" -> "800"; + case "3600HA2104" -> "850"; + case "3600HA2200", "3600HA2201" -> "1300"; + case "3600HA2300" -> "1000 Connect"; + case "3600HA2301" -> "1200 Connect"; + case "3600HA2302" -> "1100 Connect"; + case "3600HA2303" -> "13C"; + case "3600HA2304" -> "10C"; + case "3600HB0000" -> "350"; + case "3600HB0001" -> "400"; + case "3600HB0004" -> "XS 300"; + case "3600HB0006" -> "350"; + case "3600HB0007" -> "400"; + case "3600HB0100" -> "350 Connect"; + case "3600HB0101" -> "400 Connect"; + case "3600HB0102" -> "S+ 350"; + case "3600HB0103" -> "S+ 400"; + case "3600HB0105" -> "S+ 350"; + case "3600HB0106" -> "S+ 400"; + case "3600HB0201" -> "M"; + case "3600HB0202" -> "S 500"; + case "3600HB0203" -> "M 700"; + case "3600HB0301" -> "M+"; + case "3600HB0302" -> "S+ 500"; + case "3600HB0303" -> "M+ 700"; + default -> ""; + }; + + return (name.isEmpty() ? "Indego" : "Indego " + name); + } +} diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java index 49fe5577117dc..672a9756cd757 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschIndegoHandler.java @@ -31,6 +31,7 @@ import org.openhab.binding.boschindego.internal.BoschIndegoTranslationProvider; import org.openhab.binding.boschindego.internal.DeviceStatus; import org.openhab.binding.boschindego.internal.IndegoDeviceController; +import org.openhab.binding.boschindego.internal.IndegoTypeDatabase; import org.openhab.binding.boschindego.internal.config.BoschIndegoConfiguration; import org.openhab.binding.boschindego.internal.dto.DeviceCommand; import org.openhab.binding.boschindego.internal.dto.response.DevicePropertiesResponse; @@ -365,6 +366,8 @@ private void refreshDeviceProperties() throws IndegoAuthenticationException, Ind properties.put(Thing.PROPERTY_FIRMWARE_VERSION, deviceProperties.firmwareVersion); } if (deviceProperties.bareToolNumber != null) { + properties.put(Thing.PROPERTY_MODEL_ID, + IndegoTypeDatabase.nameFromTypeNumber(deviceProperties.bareToolNumber)); properties.put(PROPERTY_BARE_TOOL_NUMBER, deviceProperties.bareToolNumber); } properties.put(PROPERTY_SERVICE_COUNTER, String.valueOf(deviceProperties.serviceCounter)); diff --git a/bundles/org.openhab.binding.boschindego/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.boschindego/src/main/resources/OH-INF/thing/thing-types.xml index 85a005481f8d0..2fc4705ede2a1 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.boschindego/src/main/resources/OH-INF/thing/thing-types.xml @@ -34,6 +34,10 @@ + + Bosch + + serialNumber From 6ef5836138810b4e4aa993e5b6c4c1a63f34a537 Mon Sep 17 00:00:00 2001 From: Jacob Laursen Date: Mon, 17 Apr 2023 21:21:19 +0200 Subject: [PATCH 3/3] Use model as label in discovery Signed-off-by: Jacob Laursen --- .../boschindego/internal/IndegoController.java | 14 ++++++++++++++ .../internal/IndegoDeviceController.java | 2 +- .../discovery/IndegoDiscoveryService.java | 12 +++++++----- .../internal/handler/BoschAccountHandler.java | 17 +++++++++++++++-- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java index b755c51931ba2..cf6da6fa16573 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoController.java @@ -32,6 +32,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; +import org.openhab.binding.boschindego.internal.dto.response.DevicePropertiesResponse; import org.openhab.binding.boschindego.internal.dto.response.ErrorResponse; import org.openhab.binding.boschindego.internal.dto.response.Mower; import org.openhab.binding.boschindego.internal.dto.serialization.InstantDeserializer; @@ -98,6 +99,19 @@ public Collection getSerialNumbers() throws IndegoAuthenticationExceptio return Arrays.stream(mowers).map(m -> m.serialNumber).toList(); } + /** + * Queries the serial number and device service properties from the server. + * + * @param serialNumber the serial number of the device + * @return the device serial number and properties + * @throws IndegoAuthenticationException if request was rejected as unauthorized + * @throws IndegoException if any communication or parsing error occurred + */ + public DevicePropertiesResponse getDeviceProperties(String serialNumber) + throws IndegoAuthenticationException, IndegoException { + return getRequest(SERIAL_NUMBER_SUBPATH + serialNumber + "/", DevicePropertiesResponse.class); + } + private String getAuthorizationUrl() { try { return oAuthClientService.getAuthorizationUrl(BSK_REDIRECT_URI, BSK_SCOPE, null); diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java index 21192cfe60696..eb506b771667b 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/IndegoDeviceController.java @@ -80,7 +80,7 @@ public IndegoDeviceController(HttpClient httpClient, OAuthClientService oAuthCli * @throws IndegoException if any communication or parsing error occurred */ public DevicePropertiesResponse getDeviceProperties() throws IndegoAuthenticationException, IndegoException { - return getRequest(SERIAL_NUMBER_SUBPATH + serialNumber + "/", DevicePropertiesResponse.class); + return super.getDeviceProperties(serialNumber); } /** diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/discovery/IndegoDiscoveryService.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/discovery/IndegoDiscoveryService.java index 4d9d911403e92..311b09edf2ada 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/discovery/IndegoDiscoveryService.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/discovery/IndegoDiscoveryService.java @@ -20,6 +20,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.boschindego.internal.IndegoTypeDatabase; +import org.openhab.binding.boschindego.internal.dto.response.DevicePropertiesResponse; import org.openhab.binding.boschindego.internal.exceptions.IndegoException; import org.openhab.binding.boschindego.internal.handler.BoschAccountHandler; import org.openhab.core.config.discovery.AbstractDiscoveryService; @@ -71,15 +73,15 @@ public Set getSupportedThingTypes() { @Override public void startScan() { try { - Collection serialNumbers = accountHandler.getSerialNumbers(); + Collection devices = accountHandler.getDevices(); ThingUID bridgeUID = accountHandler.getThing().getUID(); - for (String serialNumber : serialNumbers) { - ThingUID thingUID = new ThingUID(THING_TYPE_INDEGO, bridgeUID, serialNumber); + for (DevicePropertiesResponse device : devices) { + ThingUID thingUID = new ThingUID(THING_TYPE_INDEGO, bridgeUID, device.serialNumber); DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID) - .withProperty(Thing.PROPERTY_SERIAL_NUMBER, serialNumber).withBridge(bridgeUID) + .withProperty(Thing.PROPERTY_SERIAL_NUMBER, device.serialNumber).withBridge(bridgeUID) .withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER) - .withLabel("Indego (" + serialNumber + ")").build(); + .withLabel(IndegoTypeDatabase.nameFromTypeNumber(device.bareToolNumber)).build(); thingDiscovered(discoveryResult); } diff --git a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschAccountHandler.java b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschAccountHandler.java index 8b30b621e26ab..69ffed8fd5421 100644 --- a/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschAccountHandler.java +++ b/bundles/org.openhab.binding.boschindego/src/main/java/org/openhab/binding/boschindego/internal/handler/BoschAccountHandler.java @@ -15,6 +15,7 @@ import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -22,6 +23,7 @@ import org.eclipse.jetty.client.HttpClient; import org.openhab.binding.boschindego.internal.IndegoController; import org.openhab.binding.boschindego.internal.discovery.IndegoDiscoveryService; +import org.openhab.binding.boschindego.internal.dto.response.DevicePropertiesResponse; import org.openhab.binding.boschindego.internal.exceptions.IndegoAuthenticationException; import org.openhab.binding.boschindego.internal.exceptions.IndegoException; import org.openhab.core.auth.client.oauth2.AccessTokenResponse; @@ -119,7 +121,18 @@ public OAuthClientService getOAuthClientService() { return oAuthClientService; } - public Collection getSerialNumbers() throws IndegoException { - return controller.getSerialNumbers(); + public Collection getDevices() throws IndegoException { + Collection serialNumbers = controller.getSerialNumbers(); + List devices = new ArrayList(serialNumbers.size()); + + for (String serialNumber : serialNumbers) { + DevicePropertiesResponse properties = controller.getDeviceProperties(serialNumber); + if (properties.serialNumber == null) { + properties.serialNumber = serialNumber; + } + devices.add(properties); + } + + return devices; } }