[boschindego] Add device properties (#14829)
* Add device properties * Add vendor and model properties * Use model as label in discovery Resolves #14828 --------- Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
parent
b21913f5be
commit
275329d485
@ -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_ACCOUNT = new ThingTypeUID(BINDING_ID, "account");
|
||||||
public static final ThingTypeUID THING_TYPE_INDEGO = new ThingTypeUID(BINDING_ID, "indego");
|
public static final ThingTypeUID THING_TYPE_INDEGO = new ThingTypeUID(BINDING_ID, "indego");
|
||||||
|
|
||||||
|
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT, THING_TYPE_INDEGO);
|
||||||
|
|
||||||
// List of all Channel ids
|
// List of all Channel ids
|
||||||
public static final String STATE = "state";
|
public static final String STATE = "state";
|
||||||
public static final String TEXTUAL_STATE = "textualstate";
|
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_SIZE = "gardenSize";
|
||||||
public static final String GARDEN_MAP = "gardenMap";
|
public static final String GARDEN_MAP = "gardenMap";
|
||||||
|
|
||||||
public static final Set<ThingTypeUID> 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
|
// 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/";
|
private static final String BSK_BASE_URI = "https://prodindego.b2clogin.com/prodindego.onmicrosoft.com/b2c_1a_signup_signin/oauth2/v2.0/";
|
||||||
|
|||||||
@ -15,6 +15,7 @@ package org.openhab.binding.boschindego.internal;
|
|||||||
import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*;
|
import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -31,8 +32,10 @@ import org.eclipse.jetty.client.util.StringContentProvider;
|
|||||||
import org.eclipse.jetty.http.HttpHeader;
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
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.ErrorResponse;
|
||||||
import org.openhab.binding.boschindego.internal.dto.response.Mower;
|
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.IndegoAuthenticationException;
|
||||||
import org.openhab.binding.boschindego.internal.exceptions.IndegoException;
|
import org.openhab.binding.boschindego.internal.exceptions.IndegoException;
|
||||||
import org.openhab.binding.boschindego.internal.exceptions.IndegoInvalidCommandException;
|
import org.openhab.binding.boschindego.internal.exceptions.IndegoInvalidCommandException;
|
||||||
@ -48,6 +51,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,11 +66,10 @@ public class IndegoController {
|
|||||||
|
|
||||||
private static final String BASE_URL = "https://api.indego-cloud.iot.bosch-si.com/api/v1/";
|
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 CONTENT_TYPE_HEADER = "application/json";
|
||||||
|
|
||||||
private static final String BEARER = "Bearer ";
|
private static final String BEARER = "Bearer ";
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(IndegoController.class);
|
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 HttpClient httpClient;
|
||||||
private final OAuthClientService oAuthClientService;
|
private final OAuthClientService oAuthClientService;
|
||||||
private final String userAgent;
|
private final String userAgent;
|
||||||
@ -96,6 +99,19 @@ public class IndegoController {
|
|||||||
return Arrays.stream(mowers).map(m -> m.serialNumber).toList();
|
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() {
|
private String getAuthorizationUrl() {
|
||||||
try {
|
try {
|
||||||
return oAuthClientService.getAuthorizationUrl(BSK_REDIRECT_URI, BSK_SCOPE, null);
|
return oAuthClientService.getAuthorizationUrl(BSK_REDIRECT_URI, BSK_SCOPE, null);
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import org.openhab.binding.boschindego.internal.dto.PredictiveAdjustment;
|
|||||||
import org.openhab.binding.boschindego.internal.dto.PredictiveStatus;
|
import org.openhab.binding.boschindego.internal.dto.PredictiveStatus;
|
||||||
import org.openhab.binding.boschindego.internal.dto.request.SetStateRequest;
|
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.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.DeviceStateResponse;
|
||||||
import org.openhab.binding.boschindego.internal.dto.response.LocationWeatherResponse;
|
import org.openhab.binding.boschindego.internal.dto.response.LocationWeatherResponse;
|
||||||
import org.openhab.binding.boschindego.internal.dto.response.OperatingDataResponse;
|
import org.openhab.binding.boschindego.internal.dto.response.OperatingDataResponse;
|
||||||
@ -71,6 +72,17 @@ public class IndegoDeviceController extends IndegoController {
|
|||||||
this.serialNumber = serialNumber;
|
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 super.getDeviceProperties(serialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries the device state from the server.
|
* Queries the device state from the server.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,6 +20,8 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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.exceptions.IndegoException;
|
||||||
import org.openhab.binding.boschindego.internal.handler.BoschAccountHandler;
|
import org.openhab.binding.boschindego.internal.handler.BoschAccountHandler;
|
||||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||||
@ -71,15 +73,15 @@ public class IndegoDiscoveryService extends AbstractDiscoveryService implements
|
|||||||
@Override
|
@Override
|
||||||
public void startScan() {
|
public void startScan() {
|
||||||
try {
|
try {
|
||||||
Collection<String> serialNumbers = accountHandler.getSerialNumbers();
|
Collection<DevicePropertiesResponse> devices = accountHandler.getDevices();
|
||||||
|
|
||||||
ThingUID bridgeUID = accountHandler.getThing().getUID();
|
ThingUID bridgeUID = accountHandler.getThing().getUID();
|
||||||
for (String serialNumber : serialNumbers) {
|
for (DevicePropertiesResponse device : devices) {
|
||||||
ThingUID thingUID = new ThingUID(THING_TYPE_INDEGO, bridgeUID, serialNumber);
|
ThingUID thingUID = new ThingUID(THING_TYPE_INDEGO, bridgeUID, device.serialNumber);
|
||||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID)
|
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)
|
.withRepresentationProperty(Thing.PROPERTY_SERIAL_NUMBER)
|
||||||
.withLabel("Indego (" + serialNumber + ")").build();
|
.withLabel(IndegoTypeDatabase.nameFromTypeNumber(device.bareToolNumber)).build();
|
||||||
|
|
||||||
thingDiscovered(discoveryResult);
|
thingDiscovered(discoveryResult);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
@ -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<Instant> {
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ package org.openhab.binding.boschindego.internal.handler;
|
|||||||
import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*;
|
import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstants.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.openhab.binding.boschindego.internal.IndegoController;
|
import org.openhab.binding.boschindego.internal.IndegoController;
|
||||||
import org.openhab.binding.boschindego.internal.discovery.IndegoDiscoveryService;
|
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.IndegoAuthenticationException;
|
||||||
import org.openhab.binding.boschindego.internal.exceptions.IndegoException;
|
import org.openhab.binding.boschindego.internal.exceptions.IndegoException;
|
||||||
import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
|
import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
|
||||||
@ -119,7 +121,18 @@ public class BoschAccountHandler extends BaseBridgeHandler {
|
|||||||
return oAuthClientService;
|
return oAuthClientService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getSerialNumbers() throws IndegoException {
|
public Collection<DevicePropertiesResponse> getDevices() throws IndegoException {
|
||||||
return controller.getSerialNumbers();
|
Collection<String> serialNumbers = controller.getSerialNumbers();
|
||||||
|
List<DevicePropertiesResponse> devices = new ArrayList<DevicePropertiesResponse>(serialNumbers.size());
|
||||||
|
|
||||||
|
for (String serialNumber : serialNumbers) {
|
||||||
|
DevicePropertiesResponse properties = controller.getDeviceProperties(serialNumber);
|
||||||
|
if (properties.serialNumber == null) {
|
||||||
|
properties.serialNumber = serialNumber;
|
||||||
|
}
|
||||||
|
devices.add(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,8 +17,10 @@ import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstan
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -29,8 +31,10 @@ import org.eclipse.jetty.client.HttpClient;
|
|||||||
import org.openhab.binding.boschindego.internal.BoschIndegoTranslationProvider;
|
import org.openhab.binding.boschindego.internal.BoschIndegoTranslationProvider;
|
||||||
import org.openhab.binding.boschindego.internal.DeviceStatus;
|
import org.openhab.binding.boschindego.internal.DeviceStatus;
|
||||||
import org.openhab.binding.boschindego.internal.IndegoDeviceController;
|
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.config.BoschIndegoConfiguration;
|
||||||
import org.openhab.binding.boschindego.internal.dto.DeviceCommand;
|
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.DeviceStateResponse;
|
||||||
import org.openhab.binding.boschindego.internal.dto.response.OperatingDataResponse;
|
import org.openhab.binding.boschindego.internal.dto.response.OperatingDataResponse;
|
||||||
import org.openhab.binding.boschindego.internal.exceptions.IndegoAuthenticationException;
|
import org.openhab.binding.boschindego.internal.exceptions.IndegoAuthenticationException;
|
||||||
@ -75,6 +79,7 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
private static final String MAP_POSITION_STROKE_COLOR = "#8c8b6d";
|
private static final String MAP_POSITION_STROKE_COLOR = "#8c8b6d";
|
||||||
private static final String MAP_POSITION_FILL_COLOR = "#fff701";
|
private static final String MAP_POSITION_FILL_COLOR = "#fff701";
|
||||||
private static final int MAP_POSITION_RADIUS = 10;
|
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 MAP_REFRESH_INTERVAL = Duration.ofDays(1);
|
||||||
private static final Duration OPERATING_DATA_INACTIVE_REFRESH_INTERVAL = Duration.ofHours(6);
|
private static final Duration OPERATING_DATA_INACTIVE_REFRESH_INTERVAL = Duration.ofHours(6);
|
||||||
@ -87,6 +92,7 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
private final HttpClient httpClient;
|
private final HttpClient httpClient;
|
||||||
private final BoschIndegoTranslationProvider translationProvider;
|
private final BoschIndegoTranslationProvider translationProvider;
|
||||||
private final TimeZoneProvider timeZoneProvider;
|
private final TimeZoneProvider timeZoneProvider;
|
||||||
|
private Instant devicePropertiesUpdated = Instant.MIN;
|
||||||
|
|
||||||
private @NonNullByDefault({}) OAuthClientService oAuthClientService;
|
private @NonNullByDefault({}) OAuthClientService oAuthClientService;
|
||||||
private @NonNullByDefault({}) IndegoDeviceController controller;
|
private @NonNullByDefault({}) IndegoDeviceController controller;
|
||||||
@ -133,7 +139,8 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
return;
|
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);
|
controller = new IndegoDeviceController(httpClient, oAuthClientService, config.serialNumber);
|
||||||
|
|
||||||
@ -306,6 +313,10 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
DeviceStatus deviceStatus = DeviceStatus.fromCode(state.state);
|
DeviceStatus deviceStatus = DeviceStatus.fromCode(state.state);
|
||||||
updateState(state);
|
updateState(state);
|
||||||
|
|
||||||
|
if (devicePropertiesUpdated.isBefore(Instant.now().minus(DEVICE_PROPERTIES_VALIDITY_PERIOD))) {
|
||||||
|
refreshDeviceProperties();
|
||||||
|
}
|
||||||
|
|
||||||
// Update map and start tracking positions if mower is active.
|
// Update map and start tracking positions if mower is active.
|
||||||
if (state.mapUpdateAvailable) {
|
if (state.mapUpdateAvailable) {
|
||||||
cachedMapTimestamp = Instant.MIN;
|
cachedMapTimestamp = Instant.MIN;
|
||||||
@ -348,6 +359,26 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
rescheduleStatePollAccordingToState(deviceStatus);
|
rescheduleStatePollAccordingToState(deviceStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshDeviceProperties() throws IndegoAuthenticationException, IndegoException {
|
||||||
|
DevicePropertiesResponse deviceProperties = controller.getDeviceProperties();
|
||||||
|
Map<String, String> properties = editProperties();
|
||||||
|
if (deviceProperties.firmwareVersion != null) {
|
||||||
|
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));
|
||||||
|
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) {
|
private void rescheduleStatePollAccordingToState(DeviceStatus deviceStatus) {
|
||||||
int refreshIntervalSeconds;
|
int refreshIntervalSeconds;
|
||||||
if (deviceStatus.isActive()) {
|
if (deviceStatus.isActive()) {
|
||||||
|
|||||||
@ -34,6 +34,10 @@
|
|||||||
<channel id="gardenMap" typeId="gardenMap"/>
|
<channel id="gardenMap" typeId="gardenMap"/>
|
||||||
</channels>
|
</channels>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<property name="vendor">Bosch</property>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<representation-property>serialNumber</representation-property>
|
<representation-property>serialNumber</representation-property>
|
||||||
|
|
||||||
<config-description>
|
<config-description>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user